git-svn-id: svn://db.shs.com.ru/libs@42 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user