git-svn-id: svn://db.shs.com.ru/libs@42 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2015-11-16 18:20:13 +00:00
parent c27e345c51
commit ddcd5c716a
18 changed files with 389 additions and 158 deletions

View File

@@ -24,6 +24,7 @@ GLTextureManager * currentGLTextureManager;
Camera * currentCamera;
QMatrix4x4 globCameraMatrix;
QMutex globMutex;
QStringList GLTextureManagerBase::search_pathes(".");
QString readCharsUntilNull(QDataStream & s) {
@@ -38,6 +39,22 @@ QString readCharsUntilNull(QDataStream & s) {
}
QString findFile(const QString & file, const QStringList & pathes) {
QFileInfo fi(QString(file).replace("\\", "/"));
//qDebug() << "search" << file << "in" << pathes;
if (fi.exists()) return fi.absoluteFilePath();
QString fn = fi.fileName();
if (fn.contains("/")) fn = fn.mid(fn.lastIndexOf("/"));
foreach (QString p, pathes) {
QFileInfoList fil = QDir(p).entryInfoList(QStringList(fn), QDir::Files | QDir::NoDotAndDotDot);
//qDebug() << "findFile" << fn << "in" << p << "->" << fil.size();
if (!fil.isEmpty())
return fil[0].absoluteFilePath();
}
return QString();
}
void glDrawQuad(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
glResetAllTransforms();
glSetPolygonMode(GL_FILL);
@@ -61,6 +78,16 @@ QMatrix4x4 getGLMatrix(GLenum matrix) {
}
void qglMultMatrix(const QMatrix4x4 & m) {
GLdouble gm[16];
qreal qm[16];
m.transposed().copyDataTo(qm);
for (int i = 0; i < 16; ++i)
gm[i] = qm[i];
glMultMatrixd(gm);
}
void createGLTexture(GLuint & tex, int width, int height, const GLenum & format, const GLenum & target) {
glClearError();
if (tex == 0) {
@@ -105,19 +132,27 @@ void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format,
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir) {
prog->removeAllShaders();
QDir d(dir);
QFileInfoList sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot);
QFileInfoList sl;
//qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath();
#if QT_VERSION >= 0x040700
foreach (const QFileInfo & i, sl)
sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) {
qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
prog->addShaderFromSourceFile(QGLShader::Geometry, i.absoluteFilePath());
}
#endif
sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl)
foreach (const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
prog->addShaderFromSourceFile(QGLShader::Vertex, i.absoluteFilePath());
}
sl = d.entryInfoList(QStringList(name + ".frag"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl)
foreach (const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
prog->addShaderFromSourceFile(QGLShader::Fragment, i.absoluteFilePath());
}
if (!prog->link()) {
qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log();
//qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log();
return false;
}
return true;
@@ -204,59 +239,99 @@ void GLCubeTexture::loadPathesFromDirectory(const QString & dir) {
GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership) {
int tid = ((GLTextureManagerBase*)currentGLTextureManager)->textureID(path);
GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership, bool bump) {
QString p = findFile(path, search_pathes);
if (p.isEmpty()) return 0;
int tid = ((GLTextureManagerBase*)currentGLTextureManager)->textureID(p, bump);
if (tid > 0) {
//qDebug() << "[TextureManager] Found" << path << "as" << tid;
return tid;
}
tid = currentQGLView->bindTexture(QImage(path), GL_TEXTURE_2D/*, GL_RGBA, QGLContext::MipmapBindOption*/);
QImage image(p);
if (bump) convertToNormal(image);
//qDebug() << p << image.width() << image.height() << image.format() << bump;
tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, QGLContext::MipmapBindOption*/);
if (tid == 0) {
qDebug() << "[TextureManager] Can`t load" << path;
qDebug() << "[TextureManager] Can`t load" << p;
return tid;
}
qDebug() << "[TextureManager] Loaded" << path << "as" << tid;
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids.insert(path, tid);
/*GLenum err(0);
im = currentQGLView->convertToGLFormat(im);
glClearError();
glGenTextures(1, &tid);
err = glGetError();
if (err != GL_NO_ERROR) {
qDebug() << "can`t generate texture," << err;
return false;
}
//glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
glClearError();
glBindTexture(GL_TEXTURE_2D, tid);
qDebug() << "load" << im.width() << "x" << im.height();
glClearError();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, im.width(), im.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, im.bits());
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glBindTexture(GL_TEXTURE_2D, 0);
err = glGetError();
if (err != GL_NO_ERROR) {
glDeleteTextures(1, &tid);
qDebug() << "can`t load" << path << "," << err;
return false;
}
currentGLTextureManager->tex_ids << tid;
qDebug() << "loaded" << path << "as" << tid;*/
qDebug() << "[TextureManager] Loaded" << p << "as" << tid;
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(p, tid);
return tid;
}
GLuint GLTextureManagerBase::loadTexture(const QImage & image, bool ownership) {
GLuint tid = currentQGLView->bindTexture(image);
GLuint GLTextureManagerBase::loadTexture(const QImage & im, bool ownership, bool bump) {
if (im.isNull()) return 0;
QImage image(im);
if (bump) convertToNormal(image);
GLuint tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D);
if (tid == 0) {
qDebug() << "[TextureManager] Can`t load image";
return tid;
}
//qDebug() << "[TextureManager] Loaded image as" << tid;
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids.insert(QString(), tid);
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(QString(), tid);
return tid;
}
Vector3d colorVector(QRgb c) {return Vector3d(((uchar*)(&c))[0] / 255., ((uchar*)(&c))[1] / 255., ((uchar*)(&c))[2] / 255.);}
void GLTextureManagerBase::convertToNormal(QImage & im) {
if (im.isNull()) return;
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
double sum[3] = {0., 0., 0.};
llong a = 0;
const uchar * sd = sim.constBits();
for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) {
sum[2] += double(sd[a]) / 255. - 0.5; ++a;
sum[1] += double(sd[a]) / 255. - 0.5; ++a;
sum[0] += double(sd[a]) / 255. - 0.5; ++a;
++a;
}
}
double wh = sim.width() * sim.height();
sum[0] /= wh;
sum[1] /= wh;
sum[2] /= wh;
qDebug() << sum[0] << sum[1] << sum[2];
if ((qAbs(sum[0]) <= 0.05) && (qAbs(sum[1]) <= 0.05) && (sum[2] >= 0.4)) /// already normal
return;
qDebug() << "convert to bump";
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
int tx, ty, w = sim.width(), h = sim.height();
a = 0;
uchar * dd = dim.bits();
for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) {
tx = j - 1;
tx = tx < 0 ? w + tx : tx % w;
ty = i - 1;
ty = ty < 0 ? h + ty : ty % h;
Vector3d p[3], res;
p[0] = colorVector(sim.pixel(j, i));
p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
tx = (j + 1) % w;
ty = (i + 1) % h;
p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
res.z = 1.;
dd[a] = res.z * 255; ++a;
dd[a] = res.x * 255; ++a;
dd[a] = res.y * 255; ++a;
dd[a] = 255; ++a;
}
}
im = dim;
//im.save("_bump.png");
}
void Camera::anglesFromPoints() {
QVector3D dv = aim_ - pos_, tv;
@@ -450,7 +525,8 @@ Material::Material(): reflection(512) {
transparency = reflectivity = 0.f;
bump_scale = relief_scale = iof = 1.f;
dispersion = 0.05f;
shine = shine_strength = 0.f;
shine = 0.5;
shine_strength = 1.f;
light_model = Phong;
}
@@ -480,12 +556,12 @@ void Material::apply() {
void Material::loadTextures(GLTextureManagerBase * tm) {
//qDebug() << "load textures";
if (tm == 0) tm = (GLTextureManagerBase*)currentGLTextureManager;
if (!diffuse.bitmap_path.isEmpty()) diffuse.bitmap_id = tm->loadTexture(diffuse.bitmap_path);
if (!bump.bitmap_path.isEmpty()) bump.bitmap_id = tm->loadTexture(bump.bitmap_path);
if (!bump.bitmap_path.isEmpty()) bump.bitmap_id = tm->loadTexture(bump.bitmap_path, true, true);
if (!relief.bitmap_path.isEmpty()) relief.bitmap_id = tm->loadTexture(relief.bitmap_path);
if (!diffuse_2.bitmap_path.isEmpty()) diffuse_2.bitmap_id = tm->loadTexture(diffuse_2.bitmap_path);
//qDebug() << "load" << reflection.path(0);
reflection.load();
}
@@ -710,10 +786,14 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
Material & mat(o.material_);
glPushMatrix();
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
if (o.raw_matrix) {
qglMultMatrix(o.mat_);
} else {
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
}
if (rp.pass == o.pass_) {
setupTextures(o, rp, false);
mat.apply();