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

@@ -7,7 +7,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")
set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} qad_widgets)
set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${QT_QTXML_LIBRARY} qad_widgets)
find_package(OpenGL REQUIRED)
list(APPEND LIBS ${OPENGL_LIBRARIES})
@@ -42,4 +42,4 @@ endif ()
qt4_wrap_cpp(CMOCS_TEST "mainwindow.h" OPTIONS -nw)
qt4_wrap_ui(CUIS_TEST "mainwindow.ui")
add_executable(qglview_test "main.cpp" "mainwindow.cpp" ${CMOCS_TEST} ${CUIS_TEST})
target_link_libraries(qglview_test ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} qglview qad_widgets)
target_link_libraries(qglview_test ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${QT_QTXML_LIBRARY} qglview qad_widgets)

View File

@@ -32,6 +32,8 @@ GLObjectBase::GLObjectBase() {
blend_src = GL_SRC_ALPHA;
blend_dest = GL_ONE_MINUS_SRC_ALPHA;
type_ = Mesh;
raw_matrix = false;
mat_.setToIdentity();
view_ = 0;
}
@@ -44,6 +46,8 @@ GLObjectBase * GLObjectBase::clone(bool withChildren) {
o->accept_fog = accept_fog;
o->visible_ = visible_;
o->type_ = type_;
o->raw_matrix = raw_matrix;
o->mat_ = mat_;
o->pos_ = pos_;
o->angles_ = angles_;
o->scale_ = scale_;
@@ -58,8 +62,12 @@ GLObjectBase * GLObjectBase::clone(bool withChildren) {
o->puvws = puvws;
o->faces = faces;
o->uvws = uvws;
o->norms = norms;
o->normals = normals;
o->vbo = vbo;
o->vbo.vertices_ = vbo.vertices_;
o->vbo.normals_ = vbo.normals_;
o->vbo.texcoords_ = vbo.texcoords_;
o->vbo.colors_ = vbo.colors_;
o->view_ = 0;
o->children_.clear();
if (withChildren) {
@@ -126,16 +134,31 @@ void GLObjectBase::calculateBoundingBox() {
}
void GLObjectBase::setTransform(const QMatrix4x4 & t) {
raw_matrix = true;
mat_ = t;
pos_ = mat_.column(3).toVector3D();
mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
buildTransform();
}
void GLObjectBase::buildTransform() {
itransform_.setToIdentity();
GLObjectBase * p = parent_;
if (p != 0)
itransform_ *= p->itransform_;
itransform_.translate(pos_);
itransform_.rotate(angles_.z(), 0., 0., 1.);
itransform_.rotate(angles_.y(), 0., 1., 0.);
itransform_.rotate(angles_.x(), 1., 0., 0.);
itransform_.scale(scale_);
if (raw_matrix) {
itransform_.translate(pos_);
itransform_ *= mat_;
//qDebug() << "raw_matrix" << itransform_;
} else {
itransform_.translate(pos_);
itransform_.rotate(angles_.z(), 0., 0., 1.);
itransform_.rotate(angles_.y(), 0., 1., 0.);
itransform_.rotate(angles_.x(), 1., 0., 0.);
itransform_.scale(scale_);
}
foreach (GLObjectBase * i, children_)
i->buildTransform();
}
@@ -151,10 +174,14 @@ void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_
if (!visible_) return;
glPushMatrix();
if (pos_.x() != 0. || pos_.y() != 0. || pos_.z() != 0.) glTranslated(pos_.x(), pos_.y(), pos_.z());
if (angles_.z() != 0.) glRotated(angles_.z(), 0., 0., 1.);
if (angles_.y() != 0.) glRotated(angles_.y(), 0., 1., 0.);
if (angles_.x() != 0.) glRotated(angles_.x(), 1., 0., 0.);
if (scale_.x() != 1. || scale_.y() != 1. || scale_.z() != 1.) glScaled(scale_.x(), scale_.y(), scale_.z());
if (raw_matrix) {
qglMultMatrix(mat_);
} else {
if (angles_.z() != 0.) glRotated(angles_.z(), 0., 0., 1.);
if (angles_.y() != 0.) glRotated(angles_.y(), 0., 1., 0.);
if (angles_.x() != 0.) glRotated(angles_.x(), 1., 0., 0.);
if (scale_.x() != 1. || scale_.y() != 1. || scale_.z() != 1.) glScaled(scale_.x(), scale_.y(), scale_.z());
}
material_.apply();
if (id != 0) {
++(*id);

View File

@@ -40,7 +40,7 @@ public:
QString name() const {return name_;}
void setName(const QString & name) {name_ = name;}
//virtual GLuint hList() {return list;}
virtual void init() {calculateBoundingBox(); vbo.init(); vbo.rebuffer(); material_.reflection.create(); /*qDebug() << "init" << vbo.buffer_;*/ is_init = true;}
virtual void init() {calculateBoundingBox(); vbo.init(); vbo.rebuffer(); /*material_.reflection.create();*/ /*qDebug() << "init" << vbo.buffer_;*/ is_init = true;}
virtual void draw(bool simplest = false);
virtual void update() {}
bool isInit() const {return is_init;}
@@ -99,37 +99,39 @@ public:
double posZ() const {return pos_.z();}
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();}
void rotateX(GLdouble a) {angles_.setX(angles_.x() + a); buildTransform();}
void rotateY(GLdouble a) {angles_.setY(angles_.y() + a); buildTransform();}
void rotateZ(GLdouble a) {angles_.setZ(angles_.z() + a); while (angles_.z() < -360.) angles_.setZ(angles_.z() + 360.); while (angles_.z() > 360.) angles_.setZ(angles_.z() - 360.); buildTransform();}
void setRotationX(GLdouble a) {angles_.setX(a); buildTransform();}
void setRotationY(GLdouble a) {angles_.setY(a); buildTransform();}
void setRotationZ(GLdouble a) {angles_.setZ(a); while (angles_.z() < -360.) angles_.setZ(angles_.z() + 360.); while (angles_.z() > 360.) angles_.setZ(angles_.z() - 360.); buildTransform();}
void setRotation(const QVector3D & a) {angles_= a; buildTransform();}
void resetRotation() {angles_ = QVector3D(0., 0., 0.); buildTransform();}
QVector3D rotation() const {return angles_;}
double rotationX() const {return angles_.x();}
double rotationY() const {return angles_.y();}
double rotationZ() const {return angles_.z();}
void rotateX(GLdouble a) {raw_matrix = false; angles_.setX(angles_.x() + a); buildTransform();}
void rotateY(GLdouble a) {raw_matrix = false; angles_.setY(angles_.y() + a); buildTransform();}
void rotateZ(GLdouble a) {raw_matrix = false; angles_.setZ(angles_.z() + a); while (angles_.z() < -360.) angles_.setZ(angles_.z() + 360.); while (angles_.z() > 360.) angles_.setZ(angles_.z() - 360.); buildTransform();}
void setRotationX(GLdouble a) {raw_matrix = false; angles_.setX(a); buildTransform();}
void setRotationY(GLdouble a) {raw_matrix = false; angles_.setY(a); buildTransform();}
void setRotationZ(GLdouble a) {raw_matrix = false; angles_.setZ(a); while (angles_.z() < -360.) angles_.setZ(angles_.z() + 360.); while (angles_.z() > 360.) angles_.setZ(angles_.z() - 360.); buildTransform();}
void setRotation(const QVector3D & a) {raw_matrix = false; angles_= a; buildTransform();}
void resetRotation() {raw_matrix = false; angles_ = QVector3D(0., 0., 0.); buildTransform();}
QVector3D scale() {return scale_;}
double scaleX() {return scale_.x();}
double scaleY() {return scale_.y();}
double scaleZ() {return scale_.z();}
void scale(const QVector3D & sv) {scale_ *= sv; buildTransform();}
void scale(GLdouble sx, GLdouble sy, GLdouble sz) {scale(QVector3D(sx, sy, sz)); buildTransform();}
void scale(GLdouble sx, GLdouble sy) {scale(QVector3D(sx, sy, sy)); buildTransform();}
void scale(GLdouble sx) {scale(QVector3D(sx, sx, sx)); buildTransform();}
void scaleX(GLdouble a) {scale_.setX(scale_.x() + a); buildTransform();}
void scaleY(GLdouble a) {scale_.setY(scale_.y() + a); buildTransform();}
void scaleZ(GLdouble a) {scale_.setZ(scale_.z() + a); buildTransform();}
void setScale(const QVector3D & a) {scale_ = a; buildTransform();}
void setScale(GLdouble a) {scale_ = QVector3D(a, a, a); buildTransform();}
void setScaleX(GLdouble a) {scale_.setX(a); buildTransform();}
void setScaleY(GLdouble a) {scale_.setY(a); buildTransform();}
void setScaleZ(GLdouble a) {scale_.setZ(a); buildTransform();}
void resetScale() {scale_ = QVector3D(1., 1., 1.); buildTransform();}
void scale(const QVector3D & sv) {raw_matrix = false; scale_ *= sv; buildTransform();}
void scale(GLdouble sx, GLdouble sy, GLdouble sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();}
void scale(GLdouble sx, GLdouble sy) {raw_matrix = false; scale(QVector3D(sx, sy, sy)); buildTransform();}
void scale(GLdouble sx) {raw_matrix = false; scale(QVector3D(sx, sx, sx)); buildTransform();}
void scaleX(GLdouble a) {raw_matrix = false; scale_.setX(scale_.x() + a); buildTransform();}
void scaleY(GLdouble a) {raw_matrix = false; scale_.setY(scale_.y() + a); buildTransform();}
void scaleZ(GLdouble a) {raw_matrix = false; scale_.setZ(scale_.z() + a); buildTransform();}
void setScale(const QVector3D & a) {raw_matrix = false; scale_ = a; buildTransform();}
void setScale(GLdouble a) {raw_matrix = false; scale_ = QVector3D(a, a, a); buildTransform();}
void setScaleX(GLdouble a) {raw_matrix = false; scale_.setX(a); buildTransform();}
void setScaleY(GLdouble a) {raw_matrix = false; scale_.setY(a); buildTransform();}
void setScaleZ(GLdouble a) {raw_matrix = false; scale_.setZ(a); buildTransform();}
void resetScale() {raw_matrix = false; scale_ = QVector3D(1., 1., 1.); buildTransform();}
QMatrix4x4 transform() {return mat_;}
void setTransform(const QMatrix4x4 & t);
bool isAcceptLight() const {return accept_light;}
void setAcceptLight(bool yes) {accept_light = yes;}
@@ -164,7 +166,7 @@ public:
QVector3D pos_h;
QVector<Vector3d> points, puvws;
QVector<Vector3i> faces, uvws;
QVector<Vector3i> faces, uvws, norms;
QVector<Vector3d> normals;
//QVector<GLfloat> d_vertices, d_normals, d_uvs;
@@ -180,7 +182,7 @@ protected:
void checkPass();
int pass_; // Pass
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_;
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix;
double line_width;
Type type_;
GeomPrimitives geom_prim;
@@ -190,7 +192,7 @@ protected:
QVector3D pos_, angles_, scale_;
QList<GLObjectBase * > children_;
QList<GLuint> textures;
QMatrix4x4 itransform_;
QMatrix4x4 itransform_, mat_;
//QColor color_;
QString name_;
GLenum blend_src, blend_dest;

View File

@@ -43,12 +43,25 @@ bool GLTextureManager::loadTextures() {
void GLTextureManager::deleteTextures() {
QList<GLuint> texs = tex_ids.values();
qDebug() << "[TextureManager] Delete" << texs.size() << "textures";
if (!texs.isEmpty()) glDeleteTextures(texs.size(), &texs[0]);
tex_ids.clear();
for (int i = 0; i < 2; ++i) {
QList<GLuint> texs = tex_ids[i].values();
qDebug() << "[TextureManager] Delete" << texs.size() << "textures";
if (!texs.isEmpty()) glDeleteTextures(texs.size(), &texs[0]);
tex_ids[i].clear();
}
qDebug() << "[TextureManager] Delete" << anim_ids.size() << "animations";
for (int i = 0; i < anim_ids.size(); ++i)
glDeleteTextures(anim_ids[i].second.bitmaps.size(), anim_ids[i].second.bitmaps.data());
anim_ids.clear();
}
void GLTextureManager::deleteTexture(const QString & name) {
for (int i = 0; i < 2; ++i) {
if (tex_ids[i].contains(name)) {
GLuint id = tex_ids[i][name];
glDeleteTextures(1, &id);
tex_ids[i].remove(name);
}
}
}

View File

@@ -39,13 +39,13 @@ public:
void addAnimation(const QString & dir, const QString & name) {anim_pathes << QPair<QString, QString>(dir, name);}
bool loadTextures();
void deleteTextures();
void deleteTexture(const QString & name) {if (tex_ids.contains(name)) {glDeleteTextures(1, &tex_ids[name]); tex_ids.remove(name);}}
void deleteTexture(const QString & name);
Animation * findAnimation(const QString & name) {for (int i = 0; i < anim_ids.size(); ++i) if (anim_ids[i].first == name) return &(anim_ids[i].second); return 0;}
QVector<QPair<QString, Animation> > anim_ids;
private:
QList<QString> tex_pathes;
QStringList tex_pathes;
QList<QPair<QString, QString> > anim_pathes;
};

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();

View File

@@ -134,10 +134,12 @@ inline double urand(const double & scale = 1.) {return ((double)rand() / RAND_MA
// return [0, 1]
inline double uprand(const double & scale = 1.) {return ((double)rand() / RAND_MAX) * scale;}
QString readCharsUntilNull(QDataStream & s);
QString findFile(const QString & file, const QStringList & pathes);
inline QColor operator *(const QColor & c, double v) {return QColor(c.red() * v, c.green() * v, c.blue() * v, c.alpha() * v);}
inline QColor operator /(const QColor & c, double v) {return QColor(c.red() / v, c.green() / v, c.blue() / v, c.alpha() / v);}
inline void qglColor(const QColor & c) {glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());}
void qglMultMatrix(const QMatrix4x4 & m);
inline void glActiveTextureChannel(int channel) {glActiveTexture(GL_TEXTURE0 + channel); glClientActiveTexture(GL_TEXTURE0 + channel);}
inline void glResetAllTransforms() {glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}
inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();}
@@ -227,12 +229,16 @@ class GLTextureManager;
class GLTextureManagerBase {
public:
static GLuint loadTexture(const QString & path, bool ownership = true);
static GLuint loadTexture(const QImage & image, bool ownership = true);
int textureID(const QString & path) {return tex_ids[path];}
static void addSearchPath(const QString & path) {search_pathes << path;}
static QStringList searchPathes() {return search_pathes;}
static GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);
static GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false);
int textureID(const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];}
protected:
QMap<QString, GLuint> tex_ids;
static void convertToNormal(QImage & im);
static QStringList search_pathes;
QMap<QString, GLuint> tex_ids[2];
};
@@ -335,6 +341,7 @@ struct Map {
struct Material {
enum LightModel {Phong = 0, CookTorrance = 1, Minnaert = 2, Strauss = 3, OrenNayar = 4};
Material();
QString name;
void apply();
void loadTextures(GLTextureManagerBase * tm = 0);
QColor color_diffuse;

View File

@@ -121,6 +121,14 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
}
Material Loader3DS::materialByName(const QVector<Material> & materials, const QString & name) {
foreach (const Material & m, materials)
if (m.name == name)
return m;
return Material();
}
GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
QFile f(filepath);
if (!f.exists()) {
@@ -129,14 +137,19 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
}
f.open(QIODevice::ReadOnly);
QDataStream stream(&f);
//QVector<Material> materials;
QVector<Material> materials;
QVector<uint> smooth;
QVector<ushort> face_mats;
GLObjectBase * root = new GLObjectBase(), * co = 0;
Material mat;
Loader3DS::Chunk cc;
Loader3DS::Face face;
Vector3d pos;
QString str;
ushort cnt;
QString name;
QByteArray ba;
int cur_map = 0;
float fl, fl1, matrix[3][3];
uint col;
root->setName(QFileInfo(f).baseName());
@@ -178,6 +191,15 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
co->faces[i].p2 = face.v2;
}
break;
case LOADER_3DS_CHUNK_FACEMAT:
name = readCharsUntilNull(stream);
stream.readRawData((char * )&cnt, sizeof(ushort));
face_mats.resize(cnt);
for (int i = 0; i < cnt; ++i)
stream.readRawData((char * )&(face_mats[i]), sizeof(ushort));
//qDebug() << " facemat name" << name << cnt;
co->material().name = name;
break;
case LOADER_3DS_CHUNK_MAPLIST:
stream.readRawData((char * )&cnt, sizeof(ushort));
co->puvws.resize(cnt);
@@ -264,13 +286,64 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
globject_cast<Light * >(co)->decay_end = fl;
//qDebug() << " range end" << fl;
break;
case LOADER_3DS_CHUNK_MATERIAL:
//stream.skipRawData(cc.size - 6);
if (!mat.name.isEmpty())
materials << mat;
mat = Material();
break;
case LOADER_3DS_CHUNK_MATERIAL_NAME:
mat.name = readCharsUntilNull(stream);
//qDebug() << "matname" << mat.name;
break;
case LOADER_3DS_CHUNK_AMBIENT_COLOR:
stream.skipRawData(cc.size - 9);
stream.readRawData((char * )&col, 3);
mat.color_self_illumination = QColor::fromRgb(((uchar * )&col)[0], ((uchar * )&col)[1], ((uchar * )&col)[2]);
//qDebug() << "mat diffuse" << mat.color_diffuse;
break;
case LOADER_3DS_CHUNK_DIFFUSE_COLOR:
stream.skipRawData(cc.size - 9);
stream.readRawData((char * )&col, 3);
mat.color_diffuse = QColor::fromRgb(((uchar * )&col)[0], ((uchar * )&col)[1], ((uchar * )&col)[2]);
//qDebug() << "mat diffuse" << mat.color_diffuse;
break;
case LOADER_3DS_CHUNK_SPECULAR_COLOR:
stream.skipRawData(cc.size - 9);
stream.readRawData((char * )&col, 3);
mat.color_specular = QColor::fromRgb(((uchar * )&col)[0], ((uchar * )&col)[1], ((uchar * )&col)[2]);
//qDebug() << "mat diffuse" << mat.color_diffuse;
break;
case LOADER_3DS_CHUNK_TEXTURE_MAP:
cur_map = LOADER_3DS_CHUNK_TEXTURE_MAP;
break;
case LOADER_3DS_CHUNK_BUMP_MAP:
cur_map = LOADER_3DS_CHUNK_BUMP_MAP;
break;
case LOADER_3DS_CHUNK_REFLECTION_MAP:
cur_map = LOADER_3DS_CHUNK_REFLECTION_MAP;
break;
case LOADER_3DS_CHUNK_MAP_FILENAME:
name = readCharsUntilNull(stream);
//qDebug() << " mat map" << QString::number(cur_map, 16) << name;
switch (cur_map) {
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.diffuse.bitmap_path = name; break;
case LOADER_3DS_CHUNK_BUMP_MAP: mat.bump.bitmap_path = name; break;
}
break;
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);
}
}
if (!mat.name.isEmpty())
materials << mat;
foreach (const Material & m, materials)
qDebug() << m.name;
if (co != 0) {
Loader3DS::init3DSMesh(co, smooth);
root->addChild(co);
}
for (int i = 0; i < root->childCount(); ++i)
root->child(i)->material() = Loader3DS::materialByName(materials, root->child(i)->material().name);
qDebug() << "[Loader 3DS] Loaded" << root->childCount() << "objects from" << filepath;
return root;
}

View File

@@ -46,10 +46,15 @@
#define LOADER_3DS_CHUNK_MULTIPLIER 0x465B // [+]
#define LOADER_3DS_CHUNK_CAMERA 0x4700 // [+] объект-камера
#define LOADER_3DS_CHUNK_MATERIAL 0xAFFF // [-] материал
#define LOADER_3DS_CHUNK_MATNAME 0xA000 // [+] название материала
#define LOADER_3DS_CHUNK_TEXTURE 0xA200 // [-] текстура материала
#define LOADER_3DS_CHUNK_MAPFILE 0xA300 // [+] имя файла текстуры
#define LOADER_3DS_CHUNK_MATERIAL_NAME 0xA000
#define LOADER_3DS_CHUNK_AMBIENT_COLOR 0xA010
#define LOADER_3DS_CHUNK_DIFFUSE_COLOR 0xA020
#define LOADER_3DS_CHUNK_SPECULAR_COLOR 0xA030
#define LOADER_3DS_CHUNK_TEXTURE_MAP 0xA200
#define LOADER_3DS_CHUNK_BUMP_MAP 0xA230
#define LOADER_3DS_CHUNK_REFLECTION_MAP 0xA220
#define LOADER_3DS_CHUNK_MAP_FILENAME 0xA300
#define LOADER_3DS_CHUNK_MAP_PARAMETERS 0xA351
namespace Loader3DS {
#pragma pack(push, 1)
@@ -65,6 +70,7 @@ namespace Loader3DS {
};
#pragma pack(pop)
void init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth);
Material materialByName(const QVector<Material> & materials, const QString & name);
}
GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale = 1.0);

View File

@@ -20,10 +20,10 @@
#include <QCleanlooksStyle>
#include <QDebug>
#include <QDir>
#include <GL/glew.h>
//#include "mainwindow.h"
#include "unistd.h"
#include <GL/freeglut.h>
#include "mainwindow.h"
//#include <GL/glew.h>
//#include <GL/freeglut.h>
//#include "unistd.h"
/*void display ()
{
@@ -93,7 +93,7 @@ int main(int argc, char ** argv) {
glutMainLoop();
*/
return 0;
//return 0;
QApplication a(argc, argv);
/*QGLFormat f;
f.setVersion(3, 3);
@@ -101,9 +101,9 @@ int main(int argc, char ** argv) {
f.setProfile(QGLFormat::CoreProfile);
QGLFormat::setDefaultFormat(f);*/
//QApplication::setStyle(new QCleanlooksStyle());
QDir::setCurrent(a.applicationDirPath());
//QDir::setCurrent(a.applicationDirPath());
//a.setWindowIcon(QIcon(":/icons/peri4_paint.png"));
//MainWindow w;
//w.show();
MainWindow w;
w.show();
return a.exec();
}

View File

@@ -17,7 +17,10 @@
*/
#include "mainwindow.h"
#include "loader_obj.h"
#include "loader_dae.h"
#include <QGraphicsRectItem>
#include <QImageReader>
#define EARTH_H 6356863.019 // m
#define EARTH_WL 6378245.000 // m
@@ -39,7 +42,6 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
/*MaterialEditor * o = new MaterialEditor();
o->setWindowOpacity(.666);
view->addObject(o, Qt::Window);*/
view->start(-1);
/**obj = loadFrom3DSFile("data/test.3DS", 0.15);
m.reflectivity = 1;
m.reflection.loadPathesFromDirectory("data/e");
@@ -59,9 +61,15 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
//obj->child("teapot")->setRenderMode(GLObjectBase::Point);
//obj->child("teapot")->setLineWidth(2.);
//obj->child("cone")->setRenderMode(GLObjectBase::Line);
///view->camera().setAim(obj->child("sphere001")->pos());
obj = new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
//view->camera().setAim(obj->child("sphere001")->pos());
QImageReader im("D:/orders/libs/qglview/data/SU-33_maps/Map__14_Mix.tga");
QImage i = im.read();
qDebug() << i.size() << im.errorString();
GLTextureManager::addSearchPath("data");
GLTextureManager::addSearchPath("data/images");
GLTextureManager::addSearchPath("data/SU-33_maps");
obj = loadFromDAEFile("data/su33t.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
//obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube();
view->addObject(obj);
double al = 7.;
@@ -81,13 +89,14 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
view->camera().setPos(QVector3D(10, -20, 20));
view->camera().setAim(QVector3D());
view->camera().flyToDistance(10);
view->camera().flyToDistance(300);
view->setMouseSelectionEnabled(false);
view->setSelectionHaloEnabled(false);
view->setHoverHaloEnabled(false);
Light * l = new Light(view->camera().pos());
l->intensity = 0.8;
view->addObject(l);
view->start(-1);
//view->light(0)->light_type = Light::Omni;
//obj = loadFrom3DSFile("34.3DS", 0.03);
//view->addObject(obj);
@@ -113,7 +122,7 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
box->setLineWidth(2.);
view->addObject(box);
box->hide();*/
while (view->lightsCount() >= 5) view->removeLight(view->lightsCount() - 1);
//while (view->lightsCount() >= 5) view->removeLight(view->lightsCount() - 1);
//view->addObject(box);
//obj = obj->clone(true);
@@ -158,7 +167,7 @@ void MainWindow::changeEvent(QEvent * e) {
void MainWindow::timerEvent(QTimerEvent * ) {
static double t = 0.;
view->light(0)->setPos(view->camera().pos());
view->light(view->lightsCount() - 1)->setPos(view->camera().pos());
((RendererSimple*)(view->renderer()))->mpos = view->mapFromGlobal(QCursor::pos());
/*obj->child("tor")->rotateX(0.5);
obj->child("tor")->rotateZ(0.1);

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>327</width>
<height>588</height>
<height>593</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@@ -97,13 +97,16 @@
<item row="5" column="1">
<widget class="SpinSlider" name="spinShine">
<property name="maximum">
<double>128.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>16.000000000000000</double>
<double>0.010000000000000</double>
</property>
</widget>
</item>

View File

@@ -192,6 +192,7 @@ void QGLView::initializeGL() {
void QGLView::paintGL() {
//QMutexLocker ml_v(&v_mutex);
glEnable(GL_CULL_FACE);
//glDisble(GL_CULL_FACE);
camera_.apply(aspect);
/// Selection detect
@@ -383,10 +384,14 @@ void QGLView::renderSingleSelection(GLObjectBase & o) {
if (!o.visible_ || !o.select_) return;
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_);
}
ids.insert(cid, &o);
if (shaders_supported) shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f,
float((cid >> 16) & 0xFF) / 255.f,

View File

@@ -28,10 +28,14 @@ RendererSimple::RendererSimple(QGLView * view_): GLRendererBase(view_), fbo(2)
void RendererSimple::reloadShaders() {
if (shader_fxaa == 0) shader_fxaa = new QGLShaderProgram(view.context());
loadShaders(shader_fxaa, "FXAA", "shaders");
if (shader == 0) shader = new QGLShaderProgram(view.context()); /// WARNING
loadShaders(shader, "test", "shaders"); /// WARNING
if (shader_fxaa == 0) {
shader_fxaa = new QGLShaderProgram(view.context());
loadShaders(shader_fxaa, "FXAA", "shaders");
}
/*if (shader == 0) {
shader = new QGLShaderProgram(view.context()); /// WARNING
loadShaders(shader, "test", "shaders"); /// WARNING
}*/
}
@@ -73,9 +77,9 @@ void RendererSimple::renderScene() {
fbo_c.bind();
glClearFramebuffer();
shader->bind(); /// WARNING
//shader->bind(); /// WARNING
renderObjects(GLObjectBase::Solid, l, 0, true, view.isLightEnabled(), view.isFogEnabled());
shader->release(); /// WARNING
//shader->release(); /// WARNING
if (QRect(QPoint(), fbo_c.size()).contains(mpos)) {
//qDebug() << mpos;
GLfloat data[4] = {0, 0, 0, 0};

View File

@@ -1,6 +1,6 @@
#version 130
in vec3 src_normal, normal, et;
in vec3 src_normal, normal;//, et;
in vec4 pos, col;
in float fogCoord;
@@ -19,9 +19,13 @@ void main(void) {
if (has_height) hei = dot(texture2D(t2, gl_TexCoord[0].xy).rgb, luma) * height_scale;
if (acc_fog) dc.xyz = mix(dc.rgb, gl_Fog.color.rgb, fogCoord);
vec3 n;
if (has_bump) n = normalize(normal - (texture2D(t1, gl_TexCoord[0].xy).rgb - vec3(0.5, 0.5, 1.)) * bump_scale);
else n = normalize(normal);
vec3 n, dn;
if (has_bump) {
dn = (texture2D(t1, gl_TexCoord[0].xy).rgb - vec3(0.5, 0.5, 1.)) * bump_scale;
dn.x = -dn.x;
dn = dn * mat3(gl_ModelViewMatrixInverse);
n = normalize(normal - dn);
} else n = normalize(normal);
if (has_diffuse) {
@@ -30,7 +34,7 @@ void main(void) {
dpm = gl_ModelViewProjectionMatrixInverse
dpm = dpm * gl_ModelViewProjectionMatrixInverse;
dpm += */
tc += 1-et.xy * hei/10;// / et.z;
//tc += 1+et.xy * hei/10;// / et.z;
dc *= texture2D(t0, tc);
}

View File

@@ -6,7 +6,7 @@ in vec3 normal[];
out vec3 tangent[];
void main() {
for (int i = 0; i < gl_in.length(); i++ ) {
for (int i = 0; i < gl_in.length(); i++) {
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}

View File

@@ -1,6 +1,6 @@
#version 130
out vec3 src_normal, normal, et;
out vec3 src_normal, normal;//, et;
out vec4 pos, col;
out float fogCoord, fs_gid;
@@ -23,19 +23,19 @@ void main(void) {
src_normal = normalize(/*gl_NormalMatrix * */vec3(pos.xy * dt * 2., 0));
//pos = gl_Position;
vec3 v = normalize(-pos.xyz); // vector to the eye
//vec3 v = normalize(-pos.xyz); // vector to the eye
/*vec3 t = gl_NormalMatrix * vec3(1., 0., 0.);
vec3 b = gl_NormalMatrix * vec3(0., 1., 0.);
et = vec3(dot(v, t), dot(v, b), dot(v, normal));*/
vec3 t = normalize(gl_NormalMatrix * vec3(gl_MultiTexCoord0.yx, 1));
vec3 b = cross(normal, t);
//vec3 t = normalize(gl_NormalMatrix * vec3(gl_MultiTexCoord0.yx, 1));
//vec3 b = cross(normal, t);
mat3 tbnMatrix = mat3(t.x, b.x, normal.x,
/*mat3 tbnMatrix = mat3(t.x, b.x, normal.x,
t.y, b.y, normal.y,
t.z, b.z, normal.z);
et = tbnMatrix * v;
et = tbnMatrix * v;*/
pos.w = gl_Position.w;

View File

@@ -8,17 +8,14 @@ uniform int gid, lightsCount;
uniform bool firstPass;
uniform vec2 dt;
uniform vec4 back_color;
//uniform vec3 eye;
//uniform vec4 lpos[8];
uniform mat4 mat;
//uniform float zNear, zFar;
float light_diffuse(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) {return max(0., dot(l, n));}
float light_diffuse(int model, vec3 l, vec3 n) {return max(0., dot(l, n));}
float light_specular(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) {return max(0., pow(dot(n, h), shininess));}
vec4 pos, lpos;
vec3 li, si, ldir, halfV;
float sh, dist, NdotL, spot, ldist;
float sh_pow, sh_mul, dist, NdotL, spot, ldist, diff;
void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
lpos = gl_LightSource[index].position;
@@ -34,14 +31,16 @@ void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
spot = pow(spot, (gl_LightSource[index].spotExponent + 0.001));
}
halfV = normalize(ldir + v);
//i += gl_LightSource[i].diffuse.rgb * NdotL;
//si += gl_LightSource[i].specular.rgb * pow(max(dot(n, halfV), 0.), sh);
spot /= (gl_LightSource[index].constantAttenuation + ldist * (gl_LightSource[index].linearAttenuation + ldist * gl_LightSource[index].quadraticAttenuation));
li += spot * gl_LightSource[index].diffuse.rgb * light_diffuse(0, ldir, n, halfV, v, sh);
si += spot * gl_LightSource[index].specular.rgb * v2.rgb * light_specular(0, ldir, n, halfV, v, sh);
//li += spot * gl_LightSource[index].diffuse.rgb * light_diffuse(0, ldir, n);
//si += spot * gl_LightSource[index].specular.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
float NdotLs = NdotL*NdotL;
float ndlc = (1. - NdotLs) / NdotLs;
float der = NdotLs * (sh_mul + ndlc);
diff = 2. / (1. + sqrt(1. + (1. - sh_mul) * ndlc));
li += spot * gl_LightSource[index].diffuse.rgb * diff * light_diffuse(0, ldir, n);
si += spot * gl_LightSource[index].specular.rgb * (sh_mul / (der*der) / 3.1416);
}
//li = vec3(gl_LightSource[index].spotExponent);
//si = vec3(0);
}
void main(void) {
@@ -51,7 +50,7 @@ void main(void) {
gl_FragColor = back_color;
return;
}
vec4 v1 = texture2D(t1, gl_TexCoord[0].xy), v2 = texture2D(t2, gl_TexCoord[0].xy);//, v3 = texture2D(t3, gl_TexCoord[0].xy);
vec4 v1 = texture2D(t1, gl_TexCoord[0].xy), v2 = texture2D(t2, gl_TexCoord[0].xy);//, v3 = texture2D(t2, gl_TexCoord[0].xy);
vec2 sp = gl_FragCoord.xy * dt * 2 - vec2(1, 1);
vec3 dc = v0.rgb, n = v1.xyz * 2. - vec3(1.);
float height = v2.w;
@@ -62,9 +61,8 @@ void main(void) {
pos *= v0.w;
pos.rgb += n * height;
vec3 v = normalize(-pos.xyz);
sh = v1.w;
//int light_model = int(v3.r * 255. + 0.5);
//li = ambient;
sh_pow = 1. / max((1. - v1.w), 0.0001);
sh_mul = max(1. - v1.w, 0.0001);
if (lightsCount > 0) {
calcLight(0, n, v, v2);
if (lightsCount > 1) {
@@ -89,6 +87,6 @@ void main(void) {
}
}
}
gl_FragColor.rgb = li * dc + si + texture2D(tb, gl_TexCoord[0].xy).rgb;
//gl_FragColor.rgb = v0.rgb;
gl_FragColor.rgb = li * dc + si * v2.rgb + texture2D(tb, gl_TexCoord[0].xy).rgb;
//gl_FragColor.rgb = vec3(v2.rgb);
}