diff --git a/qglview/glcamera.cpp b/qglview/glcamera.cpp
new file mode 100644
index 0000000..8bd5ef9
--- /dev/null
+++ b/qglview/glcamera.cpp
@@ -0,0 +1,255 @@
+/*
+ QGLView
+ Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "gltypes.h"
+#include "qglview.h"
+
+Camera * currentCamera;
+QMatrix4x4 globCameraMatrix;
+
+
+Camera::Camera() {
+ fov_ = 60.;
+ angle_limit_lower_xy = -180.;
+ angle_limit_upper_xy = 180.;
+ depth_start = 0.1;
+ depth_end = 1000.;
+ mirror_x = mirror_y = false;
+}
+
+
+void Camera::anglesFromPoints() {
+ QVector3D dv = aim_ - pos_, tv;
+ tv = QVector3D(dv.x(), dv.y(), 0.);
+ angles_.setZ(atan2(tv.x(), tv.y()) * rad2deg);
+ angles_.setY(piClamp(atan2(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy));
+}
+
+
+void Camera::apply(const GLdouble & aspect) {
+ glMatrixMode(GL_PROJECTION);
+ if (aspect <= 1.)
+ glScaled(aspect, aspect, 1.);
+ QMatrix4x4 pm;// = glMatrixPerspective(fov_, aspect, depth_start, depth_end);
+ pm.perspective(fov_, aspect, depth_start, depth_end);
+ //qDebug() << pm << glMatrixPerspective(fov_, aspect, depth_start, depth_end);;
+ setGLMatrix(pm);
+ glMatrixMode(GL_MODELVIEW);
+ pm.setToIdentity();
+ //qDebug() << pm;
+ pm.translate(0., 0., -distance());
+ pm.rotate(angles_.y(), 1., 0., 0.);
+ pm.rotate(angles_.x(), 0., 1., 0.);
+ pm.rotate(angles_.z(), 0., 0., 1.);
+ pm.translate(-aim_);
+ if (parent_)
+ pm *= parent_->worldTransform().inverted();
+ setGLMatrix(pm);
+}
+
+/*
+void Camera::localTransform(QMatrix4x4 & m) {
+ return;
+ if (parent_)
+ m *= parent_->worldTransform();
+ QMatrix4x4 ret;
+ //qDebug() << "local camera";
+ ret.translate(0., 0., -distance());
+ ret.rotate(angles_.y(), 1., 0., 0.);
+ ret.rotate(angles_.x(), 0., 1., 0.);
+ ret.rotate(angles_.z(), 0., 0., 1.);
+ //m *= ret.inverted();
+}
+*/
+
+void Camera::assign(const Camera & c) {
+ pos_ = c.pos_;
+ aim_ = c.aim_;
+ fov_ = c.fov_;
+ angles_ = c.angles_;
+ angle_limit_lower_xy = c.angle_limit_lower_xy;
+ angle_limit_upper_xy = c.angle_limit_upper_xy;
+ buildTransform();
+}
+
+
+void Camera::panZ(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = QVector2D(dv.x(), dv.y()).length();
+ angles_.setZ(angles_.z() + a);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tl, cos(angles_.z() * deg2rad) * tl, dv.z());
+ aim_ = pos_ + dv;
+ buildTransform();
+}
+
+
+void Camera::panXY(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = dv.length(), tc;
+ angles_.setY(angles_.y() + a);
+ angles_.setY(piClamp(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
+ tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -cos(angles_.y() * deg2rad));
+ aim_ = pos_ + dv * tl;
+ buildTransform();
+}
+
+
+void Camera::rotateZ(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = QVector2D(dv.x(), dv.y()).length();
+ angles_.setZ(angles_.z() + a);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tl, cos(angles_.z() * deg2rad) * tl, dv.z());
+ aim_ = pos_ + dv;
+ buildTransform();
+}
+
+
+void Camera::rotateXY(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = dv.length(), tc;
+ angles_.setY(angles_.y() + a);
+ angles_.setY(piClamp(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
+ tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -cos(angles_.y() * deg2rad));
+ aim_ = pos_ + dv * tl;
+ buildTransform();
+}
+
+
+void Camera::orbitZ(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = QVector2D(dv.x(), dv.y()).length();
+ angles_.setZ(angles_.z() + a);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tl, cos(angles_.z() * deg2rad) * tl, dv.z());
+ pos_ = aim_ - dv;
+ buildTransform();
+}
+
+
+void Camera::orbitXY(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = dv.length(), tc;
+ angles_.setY(angles_.y() + a);
+ angles_.setY(piClamp(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
+ tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -cos(angles_.y() * deg2rad));
+ pos_ = aim_ - dv * tl;
+ buildTransform();
+}
+
+
+void Camera::setAngleZ(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = QVector2D(dv.x(), dv.y()).length();
+ angles_.setZ(a);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tl, cos(angles_.z() * deg2rad) * tl, dv.z());
+ aim_ = pos_ + dv;
+ buildTransform();
+}
+
+
+void Camera::setAngleXY(const double & a) {
+ QVector3D dv = aim_ - pos_;
+ double tl = dv.length(), tc;
+ angles_.setY(a);
+ tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -cos(angles_.y() * deg2rad));
+ //pos_ = aim_ - dv;
+ aim_ = pos_ + dv * tl;
+ buildTransform();
+ //anglesFromPoints();
+}
+
+
+void Camera::moveForward(const double & x, bool withZ) {
+ QVector3D dv;// = aim_ - pos_;
+ double tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, 0.);
+ if (withZ) dv.setZ(-cos(angles_.y() * deg2rad));
+ dv.normalize();
+ dv *= x;
+ pos_ += dv;
+ aim_ += dv;
+ buildTransform();
+}
+
+
+void Camera::moveLeft(const double & x, bool withZ) {
+ QVector3D dv;// = aim_ - pos_;
+ double tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad - M_PI_2) * tc, cos(angles_.z() * deg2rad - M_PI_2) * tc, 0.);
+ if (withZ) dv.setZ(-sin(angles_.x() * deg2rad));
+ dv.normalize();
+ dv *= x;
+ pos_ += dv;
+ aim_ += dv;
+ buildTransform();
+}
+
+
+void Camera::moveUp(const double & x, bool onlyZ) {
+ QVector3D dv;
+ if (onlyZ)
+ dv = QVector3D(0., 0., x);
+ else {
+ double tc = cos(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -sin(angles_.y() * deg2rad));
+ dv.normalize();
+ dv *= x;
+ }
+ pos_ += dv;
+ aim_ += dv;
+ buildTransform();
+}
+
+
+void Camera::flyCloser(const double & s) {
+ QVector3D dv = aim_ - pos_;
+ double tl = dv.length() / (1. + s), tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -cos(angles_.y() * deg2rad));
+ pos_ = aim_ - dv * tl;
+ buildTransform();
+}
+
+
+void Camera::flyFarer(const double & s) {
+ QVector3D dv = aim_ - pos_;
+ double tl = dv.length() * (1. + s), tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -cos(angles_.y() * deg2rad));
+ pos_ = aim_ - dv * tl;
+ buildTransform();
+}
+
+
+void Camera::flyToDistance(const double & d) {
+ QVector3D dv = aim_ - pos_;
+ double tc = -sin(angles_.y() * deg2rad);
+ dv = QVector3D(sin(angles_.z() * deg2rad) * tc, cos(angles_.z() * deg2rad) * tc, -cos(angles_.y() * deg2rad));
+ pos_ = aim_ - dv * d;
+ buildTransform();
+}
+
+/*
+QVector3D Camera::pointFromViewport(int x_, int y_, double z_) {
+ GLsizei mx = x_, my = viewport[3] - y_, mz = z_;
+ GLdouble x,y,z;
+ gluUnProject(mx, my, mz, modelview, projection, viewport, &x, &y, &z);
+ return QVector3D(x,y,z);
+}
+*/
diff --git a/qglview/glcamera.h b/qglview/glcamera.h
new file mode 100644
index 0000000..6fe3ea3
--- /dev/null
+++ b/qglview/glcamera.h
@@ -0,0 +1,108 @@
+/*
+ QGLView
+ Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef GLCAMERA_H
+#define GLCAMERA_H
+
+#include "globject.h"
+
+class Camera;
+
+extern QMatrix4x4 globCameraMatrix;
+extern Camera * currentCamera;
+
+class Camera: public GLObjectBase
+{
+ friend class QGLView;
+ friend class GLParticlesSystem;
+public:
+ Camera();
+
+ void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); buildTransform();}
+ /*void setPosX(const double & o) {QVector3D dv = aim_ - pos_; pos_.setX(o); aim_ = pos_ + dv;}
+ void setPosY(const double & o) {QVector3D dv = aim_ - pos_; pos_.setY(o); aim_ = pos_ + dv;}
+ void setPosZ(const double & o) {QVector3D dv = aim_ - pos_; pos_.setZ(o); aim_ = pos_ + dv;}*/
+ void setAim(const QVector3D & p) {aim_ = p; anglesFromPoints(); buildTransform();}
+ void move(const QVector3D & p) {pos_ += p; aim_ += p; buildTransform();}
+ void move(const double & x, const double & y = 0., const double & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z); buildTransform();}
+ void moveForward(const double & x, bool withZ = true);
+ void moveBackward(const double & x, bool withZ = true) {moveForward(-x, withZ);}
+ void moveLeft(const double & x, bool withZ = true);
+ void moveRight(const double & x, bool withZ = true) {moveLeft(-x, withZ);}
+ void moveUp(const double & x, bool onlyZ = false);
+ void moveDown(const double & x, bool onlyZ = false) {moveUp(-x, onlyZ);}
+ void rotateZ(const double & a);
+ void rotateXY(const double & a);
+ void rotateRoll(const double & a) {angles_.setX(angles_.x() + a); buildTransform();}
+ void orbitZ(const double & a);
+ void orbitXY(const double & a);
+ void panZ(const double & a);
+ void panXY(const double & a);
+ void setFOV(const double & f) {fov_ = f;}
+ void setAngles(const QVector3D & a) {setRotation(a);}
+ void setAngleZ(const double & a);
+ void setAngleXY(const double & a);
+ void setAngleRoll(const double & a) {angles_.setX(a); buildTransform();}
+ void setAngleLowerLimitXY(const double & a) {angle_limit_lower_xy = a; buildTransform();}
+ void setAngleUpperLimitXY(const double & a) {angle_limit_upper_xy = a; buildTransform();}
+ void setAngleLimitsXY(const double & lower, const double & upper) {angle_limit_lower_xy = lower; angle_limit_upper_xy = upper; buildTransform();}
+ void setDepthStart(const double & d) {depth_start = d;}
+ void setDepthEnd(const double & d) {depth_end = d;}
+ void setMirrorX(bool yes) {mirror_x = yes;}
+ void setMirrorY(bool yes) {mirror_y = yes;}
+ void flyCloser(const double & s);
+ void flyFarer(const double & s);
+ void flyToDistance(const double & d);
+
+ QVector3D aim() const {return aim_;}
+ QVector3D angles() const {return rotation();}
+ QVector3D direction() const {return (aim_ - pos_).normalized();}
+ QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();}
+ double FOV() const {return fov_;}
+ double distance() const {return (pos_ - aim_).length();}
+ double angleZ() const {return angles_.z();}
+ double angleXY() const {return angles_.y();}
+ double angleRoll() const {return angles_.x();}
+ double angleLowerLimitXY() const {return angle_limit_lower_xy;}
+ double angleUpperLimitXY() const {return angle_limit_upper_xy;}
+ double depthStart() const {return depth_start;}
+ double depthEnd() const {return depth_end;}
+ bool isMirrorX() const {return mirror_x;}
+ bool isMirrorY() const {return mirror_y;}
+ void anglesFromPoints();
+ void apply(const GLdouble & aspect = 1.);
+ void assign(const Camera & c);
+ //QVector3D pointFromViewport(int x_, int y_, double z_); TODO
+
+private:
+ //void localTransform(QMatrix4x4 & m);
+
+ QVector3D aim_;
+ GLdouble fov_;
+ GLdouble depth_start;
+ GLdouble depth_end;
+ GLdouble angle_limit_lower_xy;
+ GLdouble angle_limit_upper_xy;
+ //GLdouble modelview[16], projection[16];
+ //GLint viewport[4];
+ bool mirror_x;
+ bool mirror_y;
+
+};
+
+#endif // GLCAMERA_H
diff --git a/qglview/glmaterial.cpp b/qglview/glmaterial.cpp
index f7e8aed..bb273c9 100644
--- a/qglview/glmaterial.cpp
+++ b/qglview/glmaterial.cpp
@@ -183,10 +183,10 @@ Material::Material(): map_reflection(512) {
color_self_illumination = Qt::black;
glass = false;
transparency = reflectivity = 0.f;
- roughness = 0.5f;
+ map_specularity.color_amount = 0.5f;
+ map_specular.color_amount = 1.f;
iof = 1.f;
dispersion = 0.05f;
- specular = 1.f;
}
@@ -201,16 +201,16 @@ void Material::apply(QGLShaderProgram * prog) {
mat_diffuse[1] = color_diffuse.greenF();
mat_diffuse[2] = color_diffuse.blueF();
mat_diffuse[3] = color_diffuse.alphaF() * (1.f - transparency);
- mat_specular[0] = specular * color_specular.redF();
- mat_specular[1] = specular * color_specular.greenF();
- mat_specular[2] = specular * color_specular.blueF();
+ mat_specular[0] = map_specular.color_amount * color_specular.redF();
+ mat_specular[1] = map_specular.color_amount * color_specular.greenF();
+ mat_specular[2] = map_specular.color_amount * color_specular.blueF();
mat_emission[0] = color_self_illumination.redF();
mat_emission[1] = color_self_illumination.greenF();
mat_emission[2] = color_self_illumination.blueF();
glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialf(GL_FRONT, GL_SHININESS, (1. - roughness)*100.);
+ glMaterialf(GL_FRONT, GL_SHININESS, (1. - map_specularity.color_amount)*100.);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
}
@@ -221,9 +221,9 @@ void Material::loadTextures(GLTextureManagerBase * tm) {
//qDebug() << "load textures";
if (tm == 0) tm = (GLTextureManagerBase*)currentGLTextureManager;
if (!map_diffuse.bitmap_path.isEmpty()) map_diffuse.bitmap_id = tm->loadTexture(map_diffuse.bitmap_path);
- if (!map_bump.bitmap_path.isEmpty()) map_bump.bitmap_id = tm->loadTexture(map_bump.bitmap_path, true, true);
+ if (!map_normal.bitmap_path.isEmpty()) map_normal.bitmap_id = tm->loadTexture(map_normal.bitmap_path, true, true);
if (!map_relief.bitmap_path.isEmpty()) map_relief.bitmap_id = tm->loadTexture(map_relief.bitmap_path);
- if (!map_roughness.bitmap_path.isEmpty()) map_roughness.bitmap_id = tm->loadTexture(map_roughness.bitmap_path);
+ if (!map_specularity.bitmap_path.isEmpty()) map_specularity.bitmap_id = tm->loadTexture(map_specularity.bitmap_path);
if (!map_specular.bitmap_path.isEmpty()) map_specular.bitmap_id = tm->loadTexture(map_specular.bitmap_path);
if (!map_self_illumination.bitmap_path.isEmpty()) map_self_illumination.bitmap_id = tm->loadTexture(map_self_illumination.bitmap_path);
//if (!map_diffuse_2.bitmap_path.isEmpty()) map_diffuse_2.bitmap_id = tm->loadTexture(map_diffuse_2.bitmap_path);
diff --git a/qglview/glmaterial.h b/qglview/glmaterial.h
index 637399d..2c8ca03 100644
--- a/qglview/glmaterial.h
+++ b/qglview/glmaterial.h
@@ -110,17 +110,15 @@ struct Material {
QColor color_specular;
QColor color_self_illumination;
bool glass;
- float roughness;
- float specular;
float transparency;
float reflectivity;
float iof;
float dispersion;
Map map_diffuse;
- Map map_bump;
+ Map map_normal;
Map map_relief;
Map map_self_illumination;
- Map map_roughness;
+ Map map_specularity;
Map map_specular;
/*Map map_diffuse_2;
Map map_diffuse_3;
@@ -130,7 +128,7 @@ struct Material {
inline QDataStream & operator <<(QDataStream & s, const Map & m) {s << m.bitmap_path << m.color_amount << m.color_offset << m.animation << m.animation_frame_rate; return s;}
inline QDataStream & operator >>(QDataStream & s, Map & m) {s >> m.bitmap_path >> m.color_amount >> m.color_offset >> m.animation >> m.animation_frame_rate; return s;}
-inline QDataStream & operator <<(QDataStream & s, const Material & m) {s << m.name << m.color_diffuse << m.color_specular << m.color_self_illumination << m.roughness << m.specular << m.transparency << m.reflectivity << m.glass << m.map_diffuse << m.map_bump << m.map_relief << m.map_specular << m.map_roughness; return s;}
-inline QDataStream & operator >>(QDataStream & s, Material & m) {s >> m.name >> m.color_diffuse >> m.color_specular >> m.color_self_illumination >> m.roughness >> m.specular >> m.transparency >> m.reflectivity >> m.glass >> m.map_diffuse >> m.map_bump >> m.map_relief >> m.map_specular >> m.map_roughness; return s;}
+inline QDataStream & operator <<(QDataStream & s, const Material & m) {s << m.name << m.color_diffuse << m.color_specular << m.color_self_illumination << m.transparency << m.reflectivity << m.glass << m.map_diffuse << m.map_normal << m.map_relief << m.map_specular << m.map_specularity << m.map_self_illumination; return s;}
+inline QDataStream & operator >>(QDataStream & s, Material & m) {s >> m.name >> m.color_diffuse >> m.color_specular >> m.color_self_illumination >> m.transparency >> m.reflectivity >> m.glass >> m.map_diffuse >> m.map_normal >> m.map_relief >> m.map_specular >> m.map_specularity >> m.map_self_illumination; return s;}
#endif // GLMATERIAL_H
diff --git a/qglview/globject.cpp b/qglview/globject.cpp
index 9c96e57..d086e66 100644
--- a/qglview/globject.cpp
+++ b/qglview/globject.cpp
@@ -152,19 +152,23 @@ void GLObjectBase::buildTransform() {
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_);
- }
+ } else
+ localTransform(itransform_);
//qDebug() << name_ << itransform_;
foreach (GLObjectBase * i, children_)
i->buildTransform();
}
+void GLObjectBase::localTransform(QMatrix4x4 & m) {
+ m.translate(pos_);
+ m.rotate(angles_.z(), 0., 0., 1.);
+ m.rotate(angles_.y(), 0., 1., 0.);
+ m.rotate(angles_.x(), 1., 0., 0.);
+ m.scale(scale_);
+}
+
+
void GLObjectBase::checkPass() {
if (material_.reflectivity > 0.f || material_.color_diffuse.alphaF() * (1.f - material_.transparency) < 1.f) pass_ = Transparent;
else pass_ = Solid;
diff --git a/qglview/globject.h b/qglview/globject.h
index 0b1dcd7..d5a2126 100644
--- a/qglview/globject.h
+++ b/qglview/globject.h
@@ -99,6 +99,7 @@ public:
double posY() const {return pos_.y();}
double posZ() const {return pos_.z();}
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();}
+ QMatrix4x4 worldTransform() const {return itransform_;}
QVector3D rotation() const {return angles_;}
double rotationX() const {return angles_.x();}
@@ -181,6 +182,7 @@ protected:
void initInternal() {init(); loadTextures(); foreach (GLObjectBase * i, children_) i->initInternal();}
void render(int * id = 0, QMap * ids = 0, int sh_id_loc = 0);
void checkPass();
+ virtual void localTransform(QMatrix4x4 & m);
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
int pass_; // Pass
diff --git a/qglview/glparticles_system.cpp b/qglview/glparticles_system.cpp
index 08c45a0..1e7c0ca 100644
--- a/qglview/glparticles_system.cpp
+++ b/qglview/glparticles_system.cpp
@@ -122,9 +122,9 @@ void GLParticlesSystem::draw(QGLShaderProgram * prog, bool) {
tr_b = material_.color_diffuse.blueF(),
tr_a = material_.color_diffuse.alphaF() * (1.f - material_.transparency);
//cxys = sin(camera.angle_xy * deg2rad);
- cxyc = cos(camera.angle_xy * deg2rad);
- czs = sin(camera.angle_z * deg2rad);
- czc = cos(camera.angle_z * deg2rad);
+ cxyc = cos(camera.angles_.y() * deg2rad);
+ czs = sin(camera.angles_.z() * deg2rad);
+ czc = cos(camera.angles_.z() * deg2rad);
dx = -czc;
dy = czs;
diff --git a/qglview/glparticles_system.h b/qglview/glparticles_system.h
index a8b64df..4cd0299 100644
--- a/qglview/glparticles_system.h
+++ b/qglview/glparticles_system.h
@@ -22,6 +22,7 @@
#include
#include "gltexture_manager.h"
#include "globject.h"
+#include "glcamera.h"
class GLParticlesSystem: public GLObjectBase
{
diff --git a/qglview/glrendererbase.cpp b/qglview/glrendererbase.cpp
index 7d31cca..a2235a5 100644
--- a/qglview/glrendererbase.cpp
+++ b/qglview/glrendererbase.cpp
@@ -25,6 +25,9 @@ GLRendererBase::GLRendererBase(QGLView * view_): view(*view_) {
white_image = QImage(1, 1, QImage::Format_ARGB32);
white_image.fill(0xFFFFFFFF);
white_image_id = 0;
+ violent_image = QImage(1, 1, QImage::Format_ARGB32);
+ violent_image.fill(QColor(127, 127, 255));
+ violent_image_id = 0;
}
@@ -105,10 +108,10 @@ void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingPa
}
if (rp.textures) {
BIND_TEXTURE(0, map_diffuse);
- BIND_TEXTURE(1, map_bump);
+ BIND_TEXTURE(1, map_normal);
BIND_TEXTURE(2, map_relief);
BIND_TEXTURE(3, map_self_illumination);
- BIND_TEXTURE(4, map_roughness);
+ BIND_TEXTURE(4, map_specularity);
BIND_TEXTURE(5, map_specular);
glActiveTextureChannel(0);
}
diff --git a/qglview/glrendererbase.h b/qglview/glrendererbase.h
index 12327fe..09b4583 100644
--- a/qglview/glrendererbase.h
+++ b/qglview/glrendererbase.h
@@ -19,6 +19,7 @@
#ifndef GLRENDERERBASE_H
#define GLRENDERERBASE_H
+#include "glcamera.h"
#include "glshaders.h"
class GLRendererBase: public QObject
@@ -60,8 +61,8 @@ protected:
void renderSingleObject(GLObjectBase & o, RenderingParameters & rp);
QGLView & view;
- QImage white_image;
- GLuint white_image_id;
+ QImage white_image, violent_image;
+ GLuint white_image_id, violent_image_id;
};
diff --git a/qglview/glshaders.cpp b/qglview/glshaders.cpp
index c9b1f08..dbba681 100644
--- a/qglview/glshaders.cpp
+++ b/qglview/glshaders.cpp
@@ -22,6 +22,8 @@
const char qgl_vertex_head[] =
"in vec3 _qgl_Vertex;\n"
"in vec3 qgl_Normal;\n"
+ "in vec3 qgl_Tangent;\n"
+ "in vec3 qgl_Bitangent;\n"
"in vec2 qgl_Texture;\n"
"in vec4 qgl_Color;\n"
"out vec2 qgl_FragTexture;\n"
@@ -65,8 +67,6 @@ const char qgl_structs[] =
" sampler2D map;\n"
"};\n"
"struct QGLMaterial {\n"
- " float roughness;\n"
- " float specular;\n"
" float transparency;\n"
" float reflectivity;\n"
" float iof;\n"
@@ -75,10 +75,10 @@ const char qgl_structs[] =
" vec4 color_specular;\n"
" vec4 color_self_illumination;\n"
" QGLMap map_diffuse;\n"
- " QGLMap map_bump;\n"
+ " QGLMap map_normal;\n"
" QGLMap map_relief;\n"
" QGLMap map_self_illumination;\n"
- " QGLMap map_roughness;\n"
+ " QGLMap map_specularity;\n"
" QGLMap map_specular;\n"
"};\n"
"uniform QGLLight qgl_AmbientLight;\n"
@@ -143,20 +143,22 @@ bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString &
void setUniformMatrices(QGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view) {
QMatrix4x4 mvpm = proj * view;
QMatrix3x3 nm = view.normalMatrix();
+ //nm.in;
prog->setUniformValue("qgl_ModelViewMatrix", view);
prog->setUniformValue("qgl_ProjectionMatrix", proj);
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
prog->setUniformValue("qgl_NormalMatrix", nm);
+ //prog->setUniformValue("qgl_BumpMatrix", nm.);
prog->setUniformValue("qgl_ModelViewMatrixTranspose", view.transposed());
prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed());
}
-void setUniformMap(QGLShaderProgram * prog, QString map_name, const Map & map, int channel) {
+void setUniformMap(QGLShaderProgram * prog, QString map_name, const Map & map, int channel, int def_channel) {
prog->setUniformValue(("qgl_Material." + map_name + ".offset").toLatin1().constData(), map.color_offset);
prog->setUniformValue(("qgl_Material." + map_name + ".amount").toLatin1().constData(), map.color_amount);
- prog->setUniformValue(("qgl_Material." + map_name + ".map").toLatin1().constData(), map.bitmap_id > 0 ? channel : 6);
+ prog->setUniformValue(("qgl_Material." + map_name + ".map").toLatin1().constData(), map.bitmap_id > 0 ? channel : def_channel);
}
@@ -167,8 +169,6 @@ void setUniformMaterial(QGLShaderProgram * prog, const Material & mat) {
mat_diffuse[2] = mat.color_diffuse.blueF();
mat_diffuse[3] = mat.color_diffuse.alphaF() * (1.f - mat.transparency);
glVertexAttrib4f(prog->attributeLocation("qgl_Color"), mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
- prog->setUniformValue("qgl_Material.roughness", mat.roughness);
- prog->setUniformValue("qgl_Material.specular", mat.specular);
prog->setUniformValue("qgl_Material.transparency", mat.transparency);
prog->setUniformValue("qgl_Material.reflectivity", mat.reflectivity);
prog->setUniformValue("qgl_Material.iof", mat.iof);
@@ -176,19 +176,19 @@ void setUniformMaterial(QGLShaderProgram * prog, const Material & mat) {
prog->setUniformValue("qgl_Material.color_diffuse", mat.color_diffuse);
prog->setUniformValue("qgl_Material.color_self_illumination", mat.color_self_illumination);
prog->setUniformValue("qgl_Material.color_specular", mat.color_specular);
- setUniformMap(prog, "map_diffuse", mat.map_diffuse, 0);
- setUniformMap(prog, "map_bump", mat.map_bump, 1);
- setUniformMap(prog, "map_relief", mat.map_relief, 2);
- setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3);
- setUniformMap(prog, "map_roughness", mat.map_roughness, 4);
- setUniformMap(prog, "map_specular", mat.map_specular, 5);
+ setUniformMap(prog, "map_diffuse", mat.map_diffuse, 0, 6);
+ setUniformMap(prog, "map_normal", mat.map_normal, 1, 7);
+ setUniformMap(prog, "map_relief", mat.map_relief, 2, 6);
+ setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3, 6);
+ setUniformMap(prog, "map_specularity", mat.map_specularity, 4, 6);
+ setUniformMap(prog, "map_specular", mat.map_specular, 5, 6);
}
-void setUniformLights(QGLShaderProgram * prog, const QVector & lights, const QMatrix4x4 & mat) {
+void setUniformLights(QGLShaderProgram * prog, const QVector & lights, const QMatrix4x4 & mat, const QVector4D & dp) {
for (int i = 0; i < lights.size(); ++i)
- setUniformLight(prog, lights[i], QString("qgl_Light[%1]").arg(i), mat);
+ setUniformLight(prog, lights[i], QString("qgl_Light[%1]").arg(i), mat, dp);
}
/*
" vec3 position;\n"
@@ -198,9 +198,10 @@ void setUniformLights(QGLShaderProgram * prog, const QVector & lights, c
" float linearAttenuation;\n"
" float quadraticAttenuation;\n"
*/
-void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat) {
- QVector4D pos(light->worldPos(), 1.);
- pos = mat * pos;
+void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat, const QVector4D & dp) {
+ QMatrix4x4 m = mat * light->worldTransform();
+ QVector4D pos(0, 0, 0, 1.);
+ pos = m * pos;
//qDebug() << "light" << light->name() << ulightn << pos;
prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos);
prog->setUniformValue((ulightn + ".intensity").toLatin1().constData(), GLfloat(light->intensity));
diff --git a/qglview/glshaders.h b/qglview/glshaders.h
index ac76f60..30556a8 100644
--- a/qglview/glshaders.h
+++ b/qglview/glshaders.h
@@ -28,9 +28,9 @@ class Light;
QString loadShaderFile(QGLShaderProgram * prog, QGLShader::ShaderType type, const QString & file);
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir = QString());
void setUniformMatrices(QGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view);
-void setUniformMap(QGLShaderProgram * prog, const Map & map, int channel);
+void setUniformMap(QGLShaderProgram * prog, const Map & map, int channel, int def_channel);
void setUniformMaterial(QGLShaderProgram * prog, const Material & mat);
-void setUniformLights(QGLShaderProgram * prog, const QVector & lights, const QMatrix4x4 & mat);
-void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat);
+void setUniformLights(QGLShaderProgram * prog, const QVector & lights, const QMatrix4x4 & mat, const QVector4D & dp);
+void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat = QMatrix4x4(), const QVector4D & dp = QVector4D());
#endif // GLSHADERS_H
diff --git a/qglview/gltypes.cpp b/qglview/gltypes.cpp
index 1af680b..c1dc954 100644
--- a/qglview/gltypes.cpp
+++ b/qglview/gltypes.cpp
@@ -16,12 +16,10 @@
along with this program. If not, see .
*/
-#include "gltypes.h"
+#include "glcamera.h"
#include "qglview.h"
QGLWidget * currentQGLView;
-Camera * currentCamera;
-QMatrix4x4 globCameraMatrix;
QMutex globMutex;
@@ -172,195 +170,6 @@ QImage rotateQImageRight(const QImage & im) {
-void Camera::anglesFromPoints() {
- QVector3D dv = aim_ - pos_, tv;
- tv = QVector3D(dv.x(), dv.y(), 0.);
- angle_z = atan2(tv.x(), tv.y()) * rad2deg;
- angle_xy = piClamp(atan2(tv.length(), dv.z()) * rad2deg + 180., angle_limit_lower_xy, angle_limit_upper_xy);
-}
-
-
-void Camera::apply(const GLdouble & aspect) {
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- if (aspect <= 1.)
- glScaled(aspect, aspect, 1.);
- QMatrix4x4 pm;// = glMatrixPerspective(fov_, aspect, depth_start, depth_end);
- pm.perspective(fov_, aspect, depth_start, depth_end);
- //qDebug() << pm << glMatrixPerspective(fov_, aspect, depth_start, depth_end);;
- setGLMatrix(pm);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslated(0., 0., -distance());
- glRotated(angle_xy, 1., 0., 0.);
- glRotated(angle_roll, 0., -1., 0.);
- glRotated(angle_z, 0., 0., 1.);
- //glTranslated(pos_.x(), pos_.y(), pos_.z());
- //if (mirror_y) glScalef(1,-1,-1);
- //if (mirror_x) glScalef(-1,1,-1);
- //glScalef(-1,-1,1);
- glTranslated(-aim_.x(), -aim_.y(), -aim_.z());
- glGetIntegerv(GL_VIEWPORT, viewport);
- glGetDoublev(GL_PROJECTION_MATRIX, projection);
- glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
- //qDebug() << "viewport" << viewport[0] << viewport[1] << viewport[2] << viewport[3];
-}
-
-
-void Camera::panZ(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = QVector2D(dv.x(), dv.y()).length();
- angle_z += a;
- dv = QVector3D(sin(angle_z * deg2rad) * tl, cos(angle_z * deg2rad) * tl, dv.z());
- aim_ = pos_ + dv;
-}
-
-
-void Camera::panXY(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = dv.length(), tc;
- angle_xy += a;
- angle_xy = piClamp(angle_xy, angle_limit_lower_xy, angle_limit_upper_xy);
- tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tl * tc, cos(angle_z * deg2rad) * tl * tc, -cos(angle_xy * deg2rad) * tl);
- aim_ = pos_ + dv;
-}
-
-
-void Camera::rotateZ(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = QVector2D(dv.x(), dv.y()).length();
- angle_z += a;
- dv = QVector3D(sin(angle_z * deg2rad) * tl, cos(angle_z * deg2rad) * tl, dv.z());
- aim_ = pos_ + dv;
-}
-
-
-void Camera::rotateXY(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = dv.length(), tc;
- angle_xy += a;
- angle_xy = piClamp(angle_xy, angle_limit_lower_xy, angle_limit_upper_xy);
- tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tl * tc, cos(angle_z * deg2rad) * tl * tc, -cos(angle_xy * deg2rad) * tl);
- aim_ = pos_ + dv;
-}
-
-
-void Camera::orbitZ(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = QVector2D(dv.x(), dv.y()).length();
- angle_z += a;
- dv = QVector3D(sin(angle_z * deg2rad) * tl, cos(angle_z * deg2rad) * tl, dv.z());
- pos_ = aim_ - dv;
-}
-
-
-void Camera::orbitXY(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = dv.length(), tc;
- angle_xy += a;
- angle_xy = piClamp(angle_xy, angle_limit_lower_xy, angle_limit_upper_xy);
- tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tl * tc, cos(angle_z * deg2rad) * tl * tc, -cos(angle_xy * deg2rad) * tl);
- pos_ = aim_ - dv;
-}
-
-
-void Camera::setAngleZ(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = QVector2D(dv.x(), dv.y()).length();
- angle_z = a;
- dv = QVector3D(sin(angle_z * deg2rad) * tl, cos(angle_z * deg2rad) * tl, dv.z());
- aim_ = pos_ + dv;
-}
-
-
-void Camera::setAngleXY(const double & a) {
- QVector3D dv = aim_ - pos_;
- double tl = dv.length(), tc;
- angle_xy = a;
- tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tl * tc, cos(angle_z * deg2rad) * tl * tc, -cos(angle_xy * deg2rad) * tl);
- //pos_ = aim_ - dv;
- aim_ = pos_ + dv;
- //anglesFromPoints();
-}
-
-
-void Camera::moveForward(const double & x, bool withZ) {
- QVector3D dv;// = aim_ - pos_;
- double tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tc, cos(angle_z * deg2rad) * tc, 0.);
- if (withZ) dv.setZ(-cos(angle_xy * deg2rad));
- dv.normalize();
- dv *= x;
- pos_ += dv;
- aim_ += dv;
-}
-
-
-void Camera::moveLeft(const double & x, bool withZ) {
- QVector3D dv;// = aim_ - pos_;
- double tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad - M_PI_2) * tc, cos(angle_z * deg2rad - M_PI_2) * tc, 0.);
- if (withZ) dv.setZ(-sin(angle_roll * deg2rad));
- dv.normalize();
- dv *= x;
- pos_ += dv;
- aim_ += dv;
-}
-
-
-void Camera::moveUp(const double & x, bool onlyZ) {
- QVector3D dv;
- if (onlyZ)
- dv = QVector3D(0., 0., x);
- else {
- double tc = cos(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tc, cos(angle_z * deg2rad) * tc, -sin(angle_xy * deg2rad));
- dv.normalize();
- dv *= x;
- }
- pos_ += dv;
- aim_ += dv;
-}
-
-
-void Camera::flyCloser(const double & s) {
- QVector3D dv = aim_ - pos_;
- double tl = dv.length() / (1. + s), tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tl * tc, cos(angle_z * deg2rad) * tl * tc, -cos(angle_xy * deg2rad) * tl);
- pos_ = aim_ - dv;
-}
-
-
-void Camera::flyFarer(const double & s) {
- QVector3D dv = aim_ - pos_;
- double tl = dv.length() * (1. + s), tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * tl * tc, cos(angle_z * deg2rad) * tl * tc, -cos(angle_xy * deg2rad) * tl);
- pos_ = aim_ - dv;
-}
-
-
-void Camera::flyToDistance(const double & d) {
- QVector3D dv = aim_ - pos_;
- double tc = -sin(angle_xy * deg2rad);
- dv = QVector3D(sin(angle_z * deg2rad) * d * tc, cos(angle_z * deg2rad) * d * tc, -cos(angle_xy * deg2rad) * d);
- pos_ = aim_ - dv;
-}
-
-
-QVector3D Camera::pointFromViewport(int x_, int y_, double z_) {
- GLsizei mx = x_, my = viewport[3] - y_, mz = z_;
- GLdouble x,y,z;
- gluUnProject(mx, my, mz, modelview, projection, viewport, &x, &y, &z);
- return QVector3D(x,y,z);
-}
-
-
-
-
QColor colorFromString(const QString & str) {
QString s = str.trimmed();
int i = s.indexOf("\t");
@@ -443,9 +252,31 @@ void glDisableDepth() {
void glClearFramebuffer(const QColor & color, bool depth) {
glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
- glClearDepth(1.);
+ //glClearDepth(0.);
if (depth)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
glClear(GL_COLOR_BUFFER_BIT);
}
+
+
+
+
+QGLViewBase::QGLViewBase() {
+ camera_ = new Camera();
+}
+
+
+Camera & QGLViewBase::camera() {
+ return *camera_;
+}
+
+
+const Camera & QGLViewBase::camera() const {
+ return *camera_;
+}
+
+
+void QGLViewBase::setCamera(const Camera & camera) {
+ *camera_ = camera;
+}
diff --git a/qglview/gltypes.h b/qglview/gltypes.h
index 90fa41e..8e8e60a 100644
--- a/qglview/gltypes.h
+++ b/qglview/gltypes.h
@@ -175,93 +175,8 @@ inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true)
//const double rad2deg = 45. / atan(1.);
extern QGLWidget * currentQGLView;
-extern QMatrix4x4 globCameraMatrix;
extern QMutex globMutex;
-class Camera
-{
- friend class QGLView;
- friend class GLParticlesSystem;
-public:
- Camera() {fov_ = 60.; angle_xy = angle_z = angle_roll = 0.; angle_limit_lower_xy = 180.; angle_limit_upper_xy = 360.; depth_start = 0.1; depth_end = 1000.; mirror_x = mirror_y = false;}
-
- void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints();}
- /*void setPosX(const double & o) {QVector3D dv = aim_ - pos_; pos_.setX(o); aim_ = pos_ + dv;}
- void setPosY(const double & o) {QVector3D dv = aim_ - pos_; pos_.setY(o); aim_ = pos_ + dv;}
- void setPosZ(const double & o) {QVector3D dv = aim_ - pos_; pos_.setZ(o); aim_ = pos_ + dv;}*/
- void setAim(const QVector3D & p) {aim_ = p; anglesFromPoints();}
- void move(const QVector3D & p) {pos_ += p; aim_ += p;}
- void move(const double & x, const double & y = 0., const double & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z);}
- void moveForward(const double & x, bool withZ = true);
- void moveBackward(const double & x, bool withZ = true) {moveForward(-x, withZ);}
- void moveLeft(const double & x, bool withZ = true);
- void moveRight(const double & x, bool withZ = true) {moveLeft(-x, withZ);}
- void moveUp(const double & x, bool onlyZ = false);
- void moveDown(const double & x, bool onlyZ = false) {moveUp(-x, onlyZ);}
- void rotateZ(const double & a);
- void rotateXY(const double & a);
- void rotateRoll(const double & a) {angle_roll += a;}
- void orbitZ(const double & a);
- void orbitXY(const double & a);
- void panZ(const double & a);
- void panXY(const double & a);
- void setFOV(const double & f) {fov_ = f;}
- void setAngles(const QVector3D & a) {angle_xy = a.x(); angle_roll = a.y(); angle_z = a.z();}
- void setAngleZ(const double & a);
- void setAngleXY(const double & a);
- void setAngleRoll(const double & a) {angle_roll = a;}
- void setAngleLowerLimitXY(const double & a) {angle_limit_lower_xy = a;}
- void setAngleUpperLimitXY(const double & a) {angle_limit_upper_xy = a;}
- void setAngleLimitsXY(const double & lower, const double & upper) {angle_limit_lower_xy = lower; angle_limit_upper_xy = upper;}
- void setDepthStart(const double & d) {depth_start = d;}
- void setDepthEnd(const double & d) {depth_end = d;}
- void setMirrorX(bool yes) {mirror_x = yes;}
- void setMirrorY(bool yes) {mirror_y = yes;}
- void flyCloser(const double & s);
- void flyFarer(const double & s);
- void flyToDistance(const double & d);
-
- QVector3D pos() const {return pos_;}
- QVector3D aim() const {return aim_;}
- QVector3D angles() const {return QVector3D(angle_xy, angle_roll, angle_z);}
- QVector3D direction() const {return (aim_ - pos_).normalized();}
- QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();}
- double FOV() const {return fov_;}
- double distance() const {return (pos_ - aim_).length();}
- double angleZ() const {return angle_z;}
- double angleXY() const {return angle_xy;}
- double angleRoll() const {return angle_roll;}
- double angleLowerLimitXY() const {return angle_limit_lower_xy;}
- double angleUpperLimitXY() const {return angle_limit_upper_xy;}
- double depthStart() const {return depth_start;}
- double depthEnd() const {return depth_end;}
- bool isMirrorX() const {return mirror_x;}
- bool isMirrorY() const {return mirror_y;}
- void anglesFromPoints();
- void apply(const GLdouble & aspect = 1.);
- void assign(const Camera & c) {pos_ = c.pos_; aim_ = c.aim_; fov_ = c.fov_; angle_z = c.angle_z; angle_xy = c.angle_xy; angle_roll = c.angle_roll; angle_limit_lower_xy = c.angle_limit_lower_xy; angle_limit_upper_xy = c.angle_limit_upper_xy;}
- QVector3D pointFromViewport(int x_, int y_, double z_);
-private:
-
- QVector3D pos_;
- QVector3D aim_;
- GLdouble fov_;
- GLdouble depth_start;
- GLdouble depth_end;
- GLdouble angle_z;
- GLdouble angle_xy;
- GLdouble angle_roll;
- GLdouble angle_limit_lower_xy;
- GLdouble angle_limit_upper_xy;
- GLdouble modelview[16], projection[16];
- GLint viewport[4];
- bool mirror_x;
- bool mirror_y;
-
-};
-
-extern Camera * currentCamera;
-
struct Box3D {
GLfloat x;
GLfloat y;
@@ -345,6 +260,8 @@ struct Vector2d {
Vector2d operator -(const GLfloat v) {return Vector2d(x-v, y-v);}
Vector2d operator +(const Vector3d & v) {return Vector3d(x + v.x, y + v.y);}
Vector2d operator -(const Vector3d & v) {return Vector3d(x - v.x, y - v.y);}
+ Vector2d operator +(const Vector2d & v) {return Vector2d(x + v.x, y + v.y);}
+ Vector2d operator -(const Vector2d & v) {return Vector2d(x - v.x, y - v.y);}
Vector2d & operator *=(const GLfloat & v) {x *= v; y *= v; return *this;}
Vector2d & operator /=(const GLfloat & v) {x /= v; y /= v; return *this;}
Vector2d & operator +=(const GLfloat & v) {x += v; y += v; return *this;}
@@ -398,17 +315,19 @@ inline double frac(const double & x, const double & b) {return x - int(x / b) *
class GLObjectBase;
class QGLView;
class Light;
+class Camera;
class QGLViewBase
{
friend class GLObjectBase;
public:
- QGLViewBase() {}
- Camera & camera() {return camera_;}
- void setCamera(const Camera & camera) {camera_ = camera;}
+ QGLViewBase();
+ Camera & camera();
+ const Camera & camera() const;
+ void setCamera(const Camera & camera);
protected:
virtual void collectLights() = 0;
- Camera camera_;
+ Camera * camera_;
};
#endif // GLTYPES_H
diff --git a/qglview/glvbo.cpp b/qglview/glvbo.cpp
index 64f40ba..35032c9 100644
--- a/qglview/glvbo.cpp
+++ b/qglview/glvbo.cpp
@@ -47,9 +47,42 @@ void GLVBO::destroy() {
}
+void GLVBO::calculateBinormals() {
+ tangents_.clear();
+ bitangents_.clear();
+ if (vertices_.isEmpty() || texcoords_.isEmpty()) return;
+ int vcnt = vertices_.size() / 3;
+ if (texcoords_.size() != vcnt * 2) return;
+ int tcnt = vcnt / 3;
+ //qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "...";
+ for (int t = 0; t < tcnt; ++t) {
+ int vi = t*9, ti = t*6;
+ Vector3d v0(vertices_[vi + 0], vertices_[vi + 1], vertices_[vi + 2]);
+ Vector3d v1(vertices_[vi + 3], vertices_[vi + 4], vertices_[vi + 5]);
+ Vector3d v2(vertices_[vi + 6], vertices_[vi + 7], vertices_[vi + 8]);
+ Vector2d t0(texcoords_[ti + 0], texcoords_[ti + 1]);
+ Vector2d t1(texcoords_[ti + 2], texcoords_[ti + 3]);
+ Vector2d t2(texcoords_[ti + 4], texcoords_[ti + 5]);
+ Vector3d dv1 = v1 - v0, dv2 = v2 - v0;
+ Vector2d dt1 = t1 - t0, dt2 = t2 - t0;
+ Vector3d tan;
+ Vector3d bitan;
+ tan = (dv1 * dt2.y - dv2 * dt1.y).normalize();
+ bitan = (dv2 * dt1.x - dv1 * dt2.x).normalize();
+ for (int i = 0; i < 3; ++i) {
+ tangents_ << tan.x << tan.y << tan.z;
+ bitangents_ << bitan.x << bitan.y << bitan.z;
+ }
+ //qDebug() << " t" << t << vi << ti << dv1.toQVector3D() << "...";
+ }
+ //qDebug() << "calculateBinormals" << vcnt << tcnt << tangents_.size();
+}
+
+
bool GLVBO::rebuffer(bool clear_) {
QVector data;
//data.clear();
+ calculateBinormals();
data << vertices_;
if (!normals_.isEmpty()) {
data << normals_;
@@ -63,6 +96,10 @@ bool GLVBO::rebuffer(bool clear_) {
data << colors_;
has_colors = true;
} else has_colors = false;
+ if (!tangents_.isEmpty()) {
+ data << tangents_ << bitangents_;
+ has_binormals = true;
+ } else has_binormals = false;
//glBindVertexArray(va_);
//qDebug() << "load buffer" << data.size() << buffer_;
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
@@ -84,7 +121,7 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
void * offset = (void*)(vert_count * 3 * sizeof(GLfloat));
//glBindVertexArray(va_);
- void * offsets[3] = {0, 0, 0};
+ void * offsets[5] = {0, 0, 0, 0, 0};
if (has_normals) {
offsets[0] = offset;
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
@@ -95,6 +132,12 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
}
if (has_colors) {
offsets[2] = offset;
+ offset = (void*)(llong(offset) + vert_count * 4 * sizeof(GLfloat));
+ }
+ if (has_binormals) {
+ offsets[3] = offset;
+ offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
+ offsets[4] = offset;
}
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
@@ -103,7 +146,7 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
- int loc = prog->attributeLocation("_qgl_Vertex");
+ int loc = prog->attributeLocation("_qgl_Vertex"), loc2 = 0;
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, 0);
loc = prog->attributeLocation("qgl_Normal");
@@ -124,6 +167,17 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 0, offsets[2]);
} else
glDisableVertexAttribArray(loc);
+ loc = prog->attributeLocation("qgl_Tangent");
+ loc2 = prog->attributeLocation("qgl_Bitangent");
+ if (has_binormals) {
+ glEnableVertexAttribArray(loc);
+ glEnableVertexAttribArray(loc2);
+ glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, offsets[3]);
+ glVertexAttribPointer(loc2, 3, GL_FLOAT, 0, 0, offsets[4]);
+ } else {
+ glDisableVertexAttribArray(loc);
+ glDisableVertexAttribArray(loc2);
+ }
} else {
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
diff --git a/qglview/glvbo.h b/qglview/glvbo.h
index 7c07d82..9c69ee0 100644
--- a/qglview/glvbo.h
+++ b/qglview/glvbo.h
@@ -50,11 +50,13 @@ public:
bool loadFromFile(const QString & filename);
private:
- QVector vertices_, normals_, texcoords_, colors_;
+ void calculateBinormals();
+
+ QVector vertices_, normals_, texcoords_, colors_, tangents_, bitangents_;
GLenum usage;
GLuint buffer_, va_;
int vert_count;
- bool changed, has_normals, has_texcoords, has_colors;
+ bool changed, has_normals, has_texcoords, has_colors, has_binormals;
};
diff --git a/qglview/loader_3ds.cpp b/qglview/loader_3ds.cpp
index 7f8de82..bd446a2 100644
--- a/qglview/loader_3ds.cpp
+++ b/qglview/loader_3ds.cpp
@@ -328,7 +328,7 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
//qDebug() << " mat map" << QString::number(cur_map, 16) << name;
switch (cur_map) {
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.map_diffuse.bitmap_path = name; break;
- case LOADER_3DS_CHUNK_BUMP_MAP: mat.map_bump.bitmap_path = name; break;
+ case LOADER_3DS_CHUNK_BUMP_MAP: mat.map_normal.bitmap_path = name; break;
}
break;
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);
diff --git a/qglview/loader_ase.cpp b/qglview/loader_ase.cpp
index 7547926..d0c1a41 100644
--- a/qglview/loader_ase.cpp
+++ b/qglview/loader_ase.cpp
@@ -120,13 +120,13 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
line = stream.readLine().trimmed();
if (line.left(17) == "*MATERIAL_DIFFUSE") {materials[i].color_diffuse = colorFromString(line.right(line.length() - 18)); continue;} //qDebug() << "diffuse " << i << " = " << colorFromString(line.right(line.length() - 18));
if (line.left(18) == "*MATERIAL_SPECULAR") {materials[i].color_specular = colorFromString(line.right(line.length() - 19)); continue;} //qDebug() << "specular " << i << " = " << colorFromString(line.right(line.length() - 19));
- if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {materials[i].specular = line.right(line.length() - 24).toFloat(); continue;}
- if (line.left(15) == "*MATERIAL_SHINE") {materials[i].roughness = 2. / exp(line.right(line.length() - 16).toFloat()); continue;}
+ if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {materials[i].map_specular.color_amount = line.right(line.length() - 24).toFloat(); continue;}
+ if (line.left(15) == "*MATERIAL_SHINE") {materials[i].map_specularity.color_amount = 2. / exp(line.right(line.length() - 16).toFloat()); continue;}
if (line.left(22) == "*MATERIAL_TRANSPARENCY") {materials[i].transparency = line.right(line.length() - 23).toFloat(); continue;}
if (line.left(12) == "*MAP_DIFFUSE") {
line = stream.readLine().trimmed();
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
- materials[i].map_bump.color_amount = line.right(line.length() - 12).toFloat();
+ materials[i].map_normal.color_amount = line.right(line.length() - 12).toFloat();
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
materials[i].map_diffuse.bitmap_path = line.mid(9, line.length() - 10);
/*if (!materials[i].diffuse.bitmap_path.isEmpty()) {
@@ -141,10 +141,10 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
if (line.left(9) == "*MAP_BUMP") {
line = stream.readLine().trimmed();
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
- materials[i].map_bump.color_amount = line.right(line.length() - 12).toFloat();
+ materials[i].map_normal.color_amount = line.right(line.length() - 12).toFloat();
//qDebug() << "bump amount" << materials[i].bump.color_amount;
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
- materials[i].map_bump.bitmap_path = line.mid(9, line.length() - 10);
+ materials[i].map_normal.bitmap_path = line.mid(9, line.length() - 10);
/*if (!materials[i].bump.bitmap_path.isEmpty()) {
materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path));
parent->textures << materials[i].bump.bitmap_id;
diff --git a/qglview/loader_dae.cpp b/qglview/loader_dae.cpp
index 5abcb03..ea3faee 100644
--- a/qglview/loader_dae.cpp
+++ b/qglview/loader_dae.cpp
@@ -140,7 +140,7 @@ QVector LoaderDAE::readMaterials(QDomElement le, QDomElement li, bool
if (col.isValid()) mat.color_diffuse = col;
col = readXMLColor(pn.firstChildElement("specular"));
if (col.isValid()) mat.color_specular = col;
- mat.roughness = 2. / exp(readXMLFloat(pn.firstChildElement("shininess")));
+ mat.map_specularity.color_amount = 2. / exp(readXMLFloat(pn.firstChildElement("shininess")));
mat.transparency = readXMLFloat(pn.firstChildElement("transparency"));
if (!fbx) mat.transparency = 1. - mat.transparency;
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
@@ -150,7 +150,7 @@ QVector LoaderDAE::readMaterials(QDomElement le, QDomElement li, bool
pn = prof.firstChildElement("technique").firstChildElement("extra").firstChild();
text = readXMLTexture(pn.firstChildElement("bump"), prof, li);
- if (!text.isEmpty()) mat.map_bump.bitmap_path = text;
+ if (!text.isEmpty()) mat.map_normal.bitmap_path = text;
ret << mat;
/*
diff --git a/qglview/loader_obj.cpp b/qglview/loader_obj.cpp
index 5ec5672..f16f1a7 100644
--- a/qglview/loader_obj.cpp
+++ b/qglview/loader_obj.cpp
@@ -156,7 +156,7 @@ QVector readMTL(QString obj_path, QString path) {
}
if (line.startsWith("Ks")) {
Vector3d v = readVector3d(line.mid(2).trimmed());
- mat.specular = v.length();
+ mat.map_specular.color_amount = v.length();
double mc = qMax(v.x, qMax(v.y, v.z));
if (mc > 0.) v /= mc;
mat.color_specular = QColor::fromRgbF(v.x, v.y, v.z);
@@ -164,7 +164,7 @@ QVector readMTL(QString obj_path, QString path) {
continue;
}
if (line.startsWith("Ns")) {
- mat.roughness = 2. / exp(line.mid(2).trimmed().toDouble());
+ mat.map_specularity.color_amount = 2. / exp(line.mid(2).trimmed().toDouble());
continue;
}
if (line.startsWith("d")) {
@@ -181,9 +181,9 @@ QVector readMTL(QString obj_path, QString path) {
line = line.mid(3).trimmed();
QString sv = line.left(line.indexOf(" "));
line = line.mid(sv.size()).trimmed();
- mat.map_bump.color_amount = sv.toDouble();
+ mat.map_normal.color_amount = sv.toDouble();
}
- mat.map_bump.bitmap_path = findFile(line, sp);
+ mat.map_normal.bitmap_path = findFile(line, sp);
//qDebug() << "BUMP" << mat.name << mat.bump_scale << mat.bump.bitmap_path;
continue;
}
diff --git a/qglview/mainwindow.cpp b/qglview/mainwindow.cpp
index 40ef3ec..b8cff43 100644
--- a/qglview/mainwindow.cpp
+++ b/qglview/mainwindow.cpp
@@ -65,11 +65,16 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
GLTextureManager::addSearchPath("data");
GLTextureManager::addSearchPath("data/images");
GLTextureManager::addSearchPath("data/SU-33_maps");
- obj = loadFromDAEFile("data/test.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
+ obj = loadFromDAEFile("data/earth.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
obj->setScale(0.1);
//obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube();
+ for (int i = 0; i < obj->childCount(); ++i)
+ if (obj->child(i)->type() == GLObjectBase::Light)
+ ((Light*)obj->child(i))->intensity = 0.;
view->addObject(obj);
-
+ //obj->child("Box001")->addChild(&(view->camera()));
+ //view->camera().flyToDistance(30);
+
double al = 7.;
obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al));
obj->material().color_diffuse = Qt::darkBlue; obj->setAcceptLight(false);
@@ -87,14 +92,15 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
view->camera().setPos(QVector3D(10, -20, 20));
view->camera().setAim(QVector3D());
- view->camera().flyToDistance(300);
+ view->camera().flyToDistance(100);
+ //view->camera().setMode(Camera::AimMatrix);
view->setMouseSelectionEnabled(false);
view->setSelectionHaloEnabled(false);
view->setHoverHaloEnabled(false);
Light * l = new Light(view->camera().pos());
- l->intensity = 0.8;
+ l->intensity = 0.5;
l->setName("camera");
- //view->addObject(l);
+ view->addObject(l);
view->start(-1);
//view->light(0)->light_type = Light::Omni;
//obj = loadFrom3DSFile("34.3DS", 0.03);
@@ -167,8 +173,12 @@ void MainWindow::changeEvent(QEvent * e) {
void MainWindow::timerEvent(QTimerEvent * ) {
static double t = 0.;
- view->light(view->lightsCount() - 1)->setPos(view->camera().pos());
+ view->light(view->lightsCount() - 1)->setPos(view->camera().worldPos());
((RendererSimple*)(view->renderer()))->mpos = view->mapFromGlobal(QCursor::pos());
+//qDebug() << view->camera().angles();
+ //cam_mat.rotate(e->y(), 0., 1., 0.);
+ //view->camera().setTransform(cam_mat);
+
/*obj->child("tor")->rotateX(0.5);
obj->child("tor")->rotateZ(0.1);
obj->child("cone")->rotateZ(1);
@@ -190,6 +200,13 @@ void MainWindow::on_view_glKeyPressEvent(QKeyEvent * e) {
}
+void MainWindow::on_view_glMouseMoveEvent(QMouseEvent * e) {
+ cam_mat.rotate(e->x(), 0., 0., 1.);
+ cam_mat.rotate(e->y(), 0., 1., 0.);
+ view->camera().setTransform(cam_mat);
+}
+
+
void MainWindow::glInit() {
//view->bindTexture(QImage("e/bottom.jpg"));
diff --git a/qglview/mainwindow.h b/qglview/mainwindow.h
index b83cd19..689547f 100644
--- a/qglview/mainwindow.h
+++ b/qglview/mainwindow.h
@@ -95,6 +95,7 @@ private slots:
void on_colorAmbient_colorChanged(QColor color) {view->setAmbientColor(color);}
void on_colorHalo_colorChanged(QColor color) {view->setSelectionHaloColor(color);}
void on_view_glKeyPressEvent(QKeyEvent * e);
+ void on_view_glMouseMoveEvent(QMouseEvent * e);
void on_view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m);
void hoverChanged(GLObjectBase * cur, GLObjectBase * prev) {/*qDebug() << "hovered" << (cur != 0 ? cur->name() : "0") << ", previous" << (prev != 0 ? prev->name() : "0");*/}
@@ -105,6 +106,9 @@ public slots:
signals:
+private:
+ QMatrix4x4 cam_mat;
+
};
#endif // MAINWINDOW_H
diff --git a/qglview/material_editor.cpp b/qglview/material_editor.cpp
index 40854e3..e70c390 100644
--- a/qglview/material_editor.cpp
+++ b/qglview/material_editor.cpp
@@ -47,8 +47,6 @@ void MaterialEditor::setMaterial(const Material & m) {
ui->colorSpecular->setColor(m.color_specular);
ui->colorSelfIllum->setColor(m.color_self_illumination);
ui->checkGlass->setChecked(m.glass);
- ui->spinRoughness->setValue(m.roughness);
- ui->spinSpecular->setValue(m.specular);
ui->spinTransparent->setValue(m.transparency);
ui->spinReflect->setValue(m.reflectivity);
ui->spinIOF->setValue(m.iof);
@@ -56,8 +54,8 @@ void MaterialEditor::setMaterial(const Material & m) {
ui->mapDiffuse->setMap(m.map_diffuse);
ui->mapSpecular->setMap(m.map_specular);
ui->mapSelfIllum->setMap(m.map_self_illumination);
- ui->mapRoughness->setMap(m.map_roughness);
- ui->mapBump->setMap(m.map_bump);
+ ui->mapSpecularity->setMap(m.map_specularity);
+ ui->mapBump->setMap(m.map_normal);
ui->mapRelief->setMap(m.map_relief);
ui->lineReflFront->setProperty("GLpath", m.map_reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.map_reflection.path(0)).fileName());
ui->lineReflBack->setProperty("GLpath", m.map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.map_reflection.path(1)).fileName());
@@ -75,8 +73,6 @@ Material MaterialEditor::material() {
m.color_specular = ui->colorSpecular->color();
m.color_self_illumination = ui->colorSelfIllum->color();
m.glass = ui->checkGlass->isChecked();
- m.roughness = ui->spinRoughness->value();
- m.specular = ui->spinSpecular->value();
m.transparency = ui->spinTransparent->value();
m.reflectivity = ui->spinReflect->value();
m.iof = ui->spinIOF->value();
@@ -84,8 +80,8 @@ Material MaterialEditor::material() {
m.map_diffuse = ui->mapDiffuse->map();
m.map_specular = ui->mapSpecular->map();
m.map_self_illumination = ui->mapSelfIllum->map();
- m.map_roughness = ui->mapRoughness->map();
- m.map_bump = ui->mapBump->map();
+ m.map_specularity = ui->mapSpecularity->map();
+ m.map_normal = ui->mapBump->map();
m.map_relief = ui->mapRelief->map();
m.map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
m.map_reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
diff --git a/qglview/material_editor.ui b/qglview/material_editor.ui
index 022b899..8286246 100644
--- a/qglview/material_editor.ui
+++ b/qglview/material_editor.ui
@@ -7,7 +7,7 @@
0
0
470
- 692
+ 737
@@ -25,12 +25,18 @@
-
+
+ font:bold;
+
Diffuse
-
+
+ font:normal;
+
Color:
@@ -38,25 +44,38 @@
-
+
+ font:normal;
+
true
-
-
+
+
+ font:normal;
+
+
-
+
+ font:bold;
+
Specular
-
+
+ font:normal;
+
Color:
@@ -64,25 +83,38 @@
-
+
+ font:normal;
+
true
-
-
+
+
+ font:normal;
+
+
-
+
+ font:bold;
+
Self illumination
-
+
+ font:normal;
+
Color:
@@ -90,37 +122,77 @@
-
+
+ font:normal;
+
true
-
-
+
+
+ font:normal;
+
+
+
+
+
+
+ -
+
+
+ font:bold;
+
+
+ Specularity
+
+
+
-
+
+
+ font:normal;
+
+
-
+
+ font:bold;
+
- Bump
+ Normal
-
-
+
+
+ font:normal;
+
+
-
+
+ font:bold;
+
Relief
-
-
+
+
+ font:normal;
+
+
@@ -133,65 +205,13 @@
-
-
-
- Roughness
-
-
-
- -
-
-
- 1.000000000000000
-
-
- 2
-
-
- 0.100000000000000
-
-
- 0.010000000000000
-
-
-
- -
-
-
- Specular
-
-
-
- -
-
-
- 64.000000000000000
-
-
- 1.000000000000000
-
-
- 2
-
-
- 0.100000000000000
-
-
- 1.000000000000000
-
-
- true
-
-
-
- -
Transparency
- -
+
-
1.000000000000000
@@ -207,14 +227,14 @@
- -
+
-
Reflectivity
- -
+
-
1.000000000000000
@@ -230,14 +250,14 @@
- -
+
-
IOF
- -
+
-
2.000000000000000
@@ -256,14 +276,14 @@
- -
+
-
Dispersion
- -
+
-
1.000000000000000
@@ -282,14 +302,14 @@
- -
+
-
Reflection map
- -
+
-
QFrame::StyledPanel
@@ -494,18 +514,6 @@
- -
-
-
- Roughness
-
-
-
-
-
-
-
-
-
@@ -563,38 +571,6 @@
-
- spinRoughness
- valueChanged(double)
- MaterialEditor
- materialChanged()
-
-
- 443
- 404
-
-
- 280
- 95
-
-
-
-
- spinSpecular
- valueChanged(double)
- MaterialEditor
- materialChanged()
-
-
- 443
- 426
-
-
- 283
- 120
-
-
-
spinTransparent
valueChanged(double)
@@ -772,7 +748,7 @@
- mapRoughness
+ mapSpecularity
changed()
MaterialEditor
materialChanged()
diff --git a/qglview/material_map_editor.cpp b/qglview/material_map_editor.cpp
index ab07fd6..c1e9478 100644
--- a/qglview/material_map_editor.cpp
+++ b/qglview/material_map_editor.cpp
@@ -42,6 +42,8 @@ void MaterialMapEditor::changeEvent(QEvent * e) {
void MaterialMapEditor::setMap(const Map & m) {
active = false;
+ ui->sliderAmount->setValue(m.color_amount);
+ ui->sliderOffset->setValue(m.color_offset);
ui->linePath->setProperty("GLpath", m.bitmap_path); ui->linePath->setText(QFileInfo(m.bitmap_path).fileName());
active = true;
}
diff --git a/qglview/qglview.cpp b/qglview/qglview.cpp
index f4f77c2..7d4624e 100644
--- a/qglview/qglview.cpp
+++ b/qglview/qglview.cpp
@@ -63,10 +63,10 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
sel_mode = QGLView::SingleSelection;
sel_pen = QPen(Qt::black, 1, Qt::DashLine);
sel_brush = QBrush(QColor(170, 100, 255, 120));
- camera_.setAim(QVector3D(0,0,5.5));
- camera_.setPos(QVector3D(10, 5, 5.5));
- emit cameraPosChanged(camera_.pos());
- //camera_.aim_ = camera_.pos_;
+ camera().setAim(QVector3D(0,0,5.5));
+ camera().setPos(QVector3D(10, 5, 5.5));
+ emit cameraPosChanged(camera().pos());
+ //camera().aim_ = camera().pos_;
ktm_.restart();
sh_lm_diff << "Phong_diffuse" << "Cook_Torrance_diffuse" << "Minnaert_diffuse" << "Strauss_diffuse" << "Oren_Nayar_diffuse";
sh_lm_spec << "Phong_specular" << "Cook_Torrance_specular" << "Minnaert_specular" << "Strauss_specular" << "Oren_Nayar_specular";
@@ -127,7 +127,7 @@ void QGLView::initializeGL() {
makeCurrent();
currentQGLView = (QGLWidget * )viewport();
currentGLTextureManager = &textures_manager;
- currentCamera = &camera_;
+ currentCamera = &camera();
//glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -195,7 +195,7 @@ void QGLView::paintGL() {
//QMutexLocker ml_v(&v_mutex);
glEnable(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
- camera_.apply(aspect);
+ camera().apply(aspect);
start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
//objects_.buildTransform();
@@ -257,7 +257,7 @@ void QGLView::paintGL() {
glEnableClientState(GL_COLOR_ARRAY);
}
- camera_.apply(aspect);
+ camera().apply(aspect);
static GLRendererBase * prev_rend = 0;
if (prev_rend != renderer_) {
@@ -551,24 +551,25 @@ void QGLView::mouseMoveEvent(QMouseEvent * e) {
double dx = e->x() - lastPos.x();
double dy = e->y() - lastPos.y();
if (e->buttons() & Qt::LeftButton) {
- //camera_.angle_z += dx / 4.;
- //camera_.angle_xy += dy / 4.;
+ //camera().angle_z += dx / 4.;
+ //camera().angle_xy += dy / 4.;
if (cameraOrbit_) {
- camera_.orbitZ(dx / 4.);
- camera_.orbitXY(dy / 4.);
+ camera().orbitZ(dx / 4.);
+ camera().orbitXY(dy / 4.);
} else {
- camera_.rotateZ(dx / 4.);
- camera_.rotateXY(dy / 4.);
+ camera().rotateZ(dx / 4.);
+ camera().rotateXY(dy / 4.);
}
- emit cameraPosChanged(camera_.pos());
+ emit cameraPosChanged(camera().pos());
} else if (e->buttons() & Qt::RightButton) {
- camera_.moveLeft(dx / 100.);
- camera_.moveUp(dy / 100.);
- //camera_.pos.setX(camera_.pos.x() + camera_.pos.z() * dx / 500.);
- //camera_.pos.setY(camera_.pos.y() - camera_.pos.z() * dy / 500.);
- emit cameraPosChanged(camera_.pos());
+ double ad = camera().distance();
+ camera().moveLeft(dx / 1000. * ad);
+ camera().moveUp(dy / 1000. * ad);
+ //camera().pos.setX(camera().pos.x() + camera().pos.z() * dx / 500.);
+ //camera().pos.setY(camera().pos.y() - camera().pos.z() * dy / 500.);
+ emit cameraPosChanged(camera().pos());
}
- //lights[0]->pos_ = camera_.pos();
+ //lights[0]->pos_ = camera().pos();
}
if (customMouseMove_) emit customMouseMoveEvent(e->pos(), lastPos, e->buttons());
lastPos = e->pos();
@@ -600,9 +601,9 @@ void QGLView::wheelEvent(QWheelEvent * e) {
QGraphicsView::wheelEvent(e);
if (scene()->itemAt(mapToScene(e->pos())) != 0) return;
if (mouseRotate_) {
- if (e->delta() > 0) camera_.flyCloser(0.1); //camera_.pos.setZ(camera_.pos.z() - 0.1 * camera_.pos.z());
- if (e->delta() < 0) camera_.flyFarer(0.1); //camera_.pos.setZ(camera_.pos.z() + 0.1 * camera_.pos.z());
- emit cameraPosChanged(camera_.pos());
+ if (e->delta() > 0) camera().flyCloser(0.1); //camera().pos.setZ(camera().pos.z() - 0.1 * camera().pos.z());
+ if (e->delta() < 0) camera().flyFarer(0.1); //camera().pos.setZ(camera().pos.z() + 0.1 * camera().pos.z());
+ emit cameraPosChanged(camera().pos());
}
emit glWheelEvent(e);
}
diff --git a/qglview/qglview.h b/qglview/qglview.h
index 40355f5..6a9c4cc 100644
--- a/qglview/qglview.h
+++ b/qglview/qglview.h
@@ -109,9 +109,9 @@ public:
QColor backColor() const {return backColor_;}
double lineWidth() const {return lineWidth_;}
- double FOV() const {return camera_.fov_;}
- double depthStart() const {return camera_.depth_start;}
- double depthEnd() const {return camera_.depth_end;}
+ double FOV() const {return camera().fov_;}
+ double depthStart() const {return camera().depth_start;}
+ double depthEnd() const {return camera().depth_end;}
double currentFPS() const {return fps_;}
bool linearFiltering() const {return linearFiltering_;}
int anisotropicLevel() const {return anisotropicLevel_;}
@@ -264,9 +264,9 @@ private:
public slots:
void setBackColor(const QColor & arg) {backColor_ = arg;}
void setLineWidth(const double & arg) {lineWidth_ = arg;}
- void setFOV(const double & arg) {camera_.fov_ = arg;}
- void setDepthStart(const double & arg) {camera_.depth_start = arg;}
- void setDepthEnd(const double & arg) {camera_.depth_end = arg;}
+ void setFOV(const double & arg) {camera().fov_ = arg;}
+ void setDepthStart(const double & arg) {camera().depth_start = arg;}
+ void setDepthEnd(const double & arg) {camera().depth_end = arg;}
void setLinearFiltering(const bool & arg) {linearFiltering_ = arg;}
void setAnisotropicLevel(const int & arg) {anisotropicLevel_ = arg;}
void setAmbientColor(const QColor & arg) {ambientColor_ = arg;}
diff --git a/qglview/renderer_deferred_shading.cpp b/qglview/renderer_deferred_shading.cpp
index e3540a3..9c8ee8d 100644
--- a/qglview/renderer_deferred_shading.cpp
+++ b/qglview/renderer_deferred_shading.cpp
@@ -45,6 +45,12 @@ void RendererDeferredShading::renderScene() {
glBindTexture(GL_TEXTURE_2D, white_image_id);
glActiveTextureChannel(0);
}
+ if (violent_image_id == 0) {
+ glActiveTextureChannel(7);
+ violent_image_id = ((GLTextureManagerBase*)currentGLTextureManager)->loadTexture(violent_image, false);
+ glBindTexture(GL_TEXTURE_2D, violent_image_id);
+ glActiveTextureChannel(0);
+ }
glClearFramebuffer(QColor(0, 0, 0, 0));
//glEnable(GL_TEXTURE_2D);
glEnableDepth();
@@ -127,12 +133,14 @@ void RendererDeferredShading::reloadShaders() {
void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) {
shader_ds_0->setUniformValue("has_diffuse", object.material().map_diffuse.bitmap_id != 0);
- shader_ds_0->setUniformValue("has_bump", object.material().map_bump.bitmap_id != 0);
+ shader_ds_0->setUniformValue("has_bump", object.material().map_normal.bitmap_id != 0);
shader_ds_0->setUniformValue("has_height", object.material().map_relief.bitmap_id != 0);
- shader_ds_0->setUniformValue("bump_scale", object.material().map_bump.color_amount);
+ shader_ds_0->setUniformValue("bump_scale", object.material().map_normal.color_amount);
shader_ds_0->setUniformValue("height_scale", object.material().map_relief.color_amount);
glActiveTextureChannel(6);
glBindTexture(GL_TEXTURE_2D, white_image_id);
+ glActiveTextureChannel(7);
+ glBindTexture(GL_TEXTURE_2D, violent_image_id);
}
@@ -144,7 +152,7 @@ void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const
amb_light.intensity = (pass == 0 ? 1. : 0.);
amb_light.setColor(pass == 0 ? view.ambientColor() : Qt::black);
amb_light.setName("ambient");
- setUniformLight(shader_ds_1, &amb_light, "qgl_AmbientLight", QMatrix4x4());
+ setUniformLight(shader_ds_1, &amb_light, "qgl_AmbientLight");
amb_light.intensity = 0.;
QVector lv;
for (int i = light_start; i < light_end; ++i)
@@ -152,7 +160,7 @@ void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const
amb_light.setName("null");
for (int i = light_end; i < lmax; ++i)
lv << &amb_light;
- setUniformLights(shader_ds_1, lv, view_matrix);
+ setUniformLights(shader_ds_1, lv, view_matrix, view.camera().pos());
}
diff --git a/qglview/shaders/dsl_pass_0.frag b/qglview/shaders/dsl_pass_0.frag
index 8bbe69c..70d68b4 100644
--- a/qglview/shaders/dsl_pass_0.frag
+++ b/qglview/shaders/dsl_pass_0.frag
@@ -3,6 +3,7 @@
in vec3 src_normal, normal;//, et;
in vec4 pos;
in float fogCoord;
+in mat3 TBN;
uniform bool acc_fog;
uniform vec2 dt;
@@ -18,10 +19,14 @@ void main(void) {
//if (acc_fog) dc.xyz = mix(dc.rgb, gl_Fog.color.rgb, fogCoord);
vec3 n, dn;
- dn = (texture2D(qgl_Material.map_bump.map, tc).rgb - vec3(0.5, 0.5, 1.)) * qgl_Material.map_bump.amount + qgl_Material.map_bump.offset;
- dn.x = -dn.x;
- dn = dn * mat3(qgl_ModelViewMatrixInverse);
- n = normalize(normal - dn);
+ dn = (texture2D(qgl_Material.map_normal.map, tc).rgb - vec3(0.5, 0.5, 1.)) * qgl_Material.map_normal.amount + qgl_Material.map_normal.offset;
+ //float tx = dn.x;
+ dn.y = -dn.y;
+ //dn.y = tx;
+ dn = TBN * dn;
+ //dn = dn * mat3(qgl_ModelViewMatrix)*10;//*(mat3(qgl_NormalMatrix));
+ n = normalize(qgl_NormalMatrix*(normal+dn));//normalize(qgl_NormalMatrix * (normal - dn));
+ //n = dn;
/*vec2 dpm = normalize(gl_FragCoord.xy * dt * 2. - vec2(1., 1.)), ntc;
ntc = gl_FragCoord.xy * dt * 2. - vec2(1., 1.) + dpm * hei;
@@ -32,16 +37,15 @@ void main(void) {
dc *= texture2D(qgl_Material.map_diffuse.map, tc) * qgl_Material.map_diffuse.amount + qgl_Material.map_diffuse.offset;
vec4 spec = texture2D(qgl_Material.map_specular.map, tc) * qgl_Material.map_specular.amount + qgl_Material.map_specular.offset;
- spec *= qgl_Material.color_specular * qgl_Material.specular;
- vec4 rough = texture2D(qgl_Material.map_roughness.map, tc) * qgl_Material.map_roughness.amount + qgl_Material.map_roughness.offset;
- rough *= qgl_Material.roughness;
+ spec *= qgl_Material.color_specular;
+ vec4 specularity = texture2D(qgl_Material.map_specularity.map, tc) * qgl_Material.map_specularity.amount + qgl_Material.map_specularity.offset;
vec4 self = texture2D(qgl_Material.map_self_illumination.map, tc) * qgl_Material.map_self_illumination.amount + qgl_Material.map_self_illumination.offset;
self *= qgl_Material.color_self_illumination;
qgl_FragData[0] = vec4(dc.rgb, z);
- qgl_FragData[1] = vec4(n.xyz / 2. + vec3(0.5), rough);
+ qgl_FragData[1] = vec4(n.xyz / 2. + vec3(0.5), specularity);
qgl_FragData[2] = vec4(spec.rgb, hei);
- qgl_FragData[3] = vec4(pos.xyz, pos.z);
+ qgl_FragData[3] = vec4(self.rgb, pos.w);
//gl_FragData[0] = vec4(et.xyz, pos.w);
//gl_FragDepth = gl_FragCoord.z - clamp(hei / pos.z / pos.z / (abs(n.z) + 1), -0.01, 0.01);
diff --git a/qglview/shaders/dsl_pass_0.vert b/qglview/shaders/dsl_pass_0.vert
index 055a73c..6877795 100644
--- a/qglview/shaders/dsl_pass_0.vert
+++ b/qglview/shaders/dsl_pass_0.vert
@@ -3,14 +3,16 @@
out vec3 src_normal, normal;//, et;
out vec4 pos;
out float fogCoord, fs_gid;
+out mat3 TBN;
uniform bool acc_fog;
uniform vec2 dt;
uniform vec3 eye;
void main(void) {
- normal = (qgl_NormalMatrix * qgl_Normal);
- pos.xyz = vec3(qgl_ModelViewMatrix * qgl_Vertex);
+ normal = qgl_Normal;//(qgl_NormalMatrix * qgl_Normal);
+ pos.xyzw = vec4(qgl_ModelViewMatrix * qgl_Vertex);
+ TBN = (mat3(qgl_Tangent, qgl_Bitangent, qgl_Normal));
/*if (acc_fog) {
fogCoord = (gl_Fog.end - length(pos.xyz) * 0.85) / (gl_Fog.end - gl_Fog.start);
fogCoord = 1. - clamp(fogCoord, 0., 1.);
diff --git a/qglview/shaders/dsl_pass_1.frag b/qglview/shaders/dsl_pass_1.frag
index a217907..0b5eabb 100644
--- a/qglview/shaders/dsl_pass_1.frag
+++ b/qglview/shaders/dsl_pass_1.frag
@@ -1,8 +1,7 @@
#version 150
//#extension GL_EXT_gpu_shader4 : enable
-in vec4 view_dir;
-in vec3 view_pos;
+in vec4 view_dir, view_pos;
uniform vec3 ambient;
uniform sampler2D t0, t1, t2, t3, tb;
@@ -15,19 +14,21 @@ uniform vec4 back_color;
uniform mat4 mat_proji;
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));}
+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_pow, sh_mul, dist, NdotL, spot, ldist, diff;
+float sh_pow, sh_mul, dist, NdotL, NdotH, spot, ldist, diff;
void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
lpos = qgl_Light[index].position;
ldir = lpos.xyz - (pos.xyz * lpos.w);
ldist = length(ldir);
ldir = normalize(ldir);
+ halfV = normalize(ldir + v);
NdotL = max(dot(n, ldir), 0.);
- spot = step(0., NdotL);
+ NdotH = max(dot(n, halfV), 0.);
+ spot = step(0., NdotL) * qgl_Light[index].intensity;
if (NdotL > 0.) {
/*if (gl_LightSource[index].spotCutoff < 180.) {
spot = max(dot(-ldir, gl_LightSource[index].spotDirection.xyz), 0.);
@@ -35,15 +36,18 @@ void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
spot = pow(spot, (gl_LightSource[index].spotExponent + 0.001));
}*/
spot /= (qgl_Light[index].constantAttenuation + ldist * (qgl_Light[index].linearAttenuation + ldist * qgl_Light[index].quadraticAttenuation));
- halfV = normalize(ldir + v);
///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);
+ //si += spot * qgl_Light[index].color.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
float NdotLs = NdotL*NdotL;
+ float NdotHs = NdotH*NdotH;
float ndlc = (1. - NdotLs) / NdotLs;
float der = NdotLs * (sh_mul + ndlc);
diff = 2. / (1. + sqrt(1. + (1. - sh_mul) * ndlc));
li += spot * qgl_Light[index].color.rgb * diff;// * light_diffuse(0, ldir, n);
+ ndlc = (1. - NdotHs) / NdotHs;
+ der = NdotHs * (sh_mul + ndlc);
si += spot * qgl_Light[index].color.rgb * (sh_mul / (der*der) / 3.1416);
+ //si += der;//dot(n, halfV);
}
}
@@ -63,14 +67,22 @@ void main(void) {
//li = vec3(0.);
si = vec3(0.);
- pos = vec4(sp, 0, 1)*mat_proji;
- pos.xyz *= v0.w;
+ float posz = z_near * z_far / (texture2D(td, tc).r * (z_far - z_near) - z_far);
+ pos = vec4(sp, 0., 1) * mat_proji;
+ pos.xy *= v3.w;
+ pos.z = posz;
+ pos.xyz += n * height;
+ //pos = v3;
+ //pos = vec4(sp, 0, 1.) * mat_proji;
+ //pos *= v0.w;
+ //pos.z += 1;
//pos.xy *= 10.;
//pos.z = v0.w;
vec3 v = normalize(-pos.xyz);
sh_pow = 1. / max((1. - v1.w), 0.0001);
sh_mul = max(1. - v1.w, 0.0001);
- //calcLight(0, n, v, v2);
+ for (int i = 0; i < 16; ++i)
+ calcLight(i, n, v, v2);
/*if (lightsCount > 0) {
calcLight(0, n, v, v2);
if (lightsCount > 1) {
@@ -95,14 +107,9 @@ void main(void) {
}
}
}*/
- //qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb;// + texture2D(tb, tc).rgb;
- //vec4 lp = mat*qgl_Light[0].position;
- lpos = qgl_Light[0].position;
- ldir = lpos.xyz - pos.xyz;
- ldist = length(ldir);
- float d = texture2D(td, tc).r;
- //float z = ((z_near / (z_near-z_far)) * z_far) / (d - (z_far / (z_far-z_near)));
- float z = z_near * z_far / (d * (z_far - z_near) - z_far);
- //qgl_FragData[0].rgb = vec3(abs((v0.w)+(v3.z))-0.5);
- qgl_FragData[0].rgb = vec3((-z*view_pos));
+ qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb;// + texture2D(tb, tc).rgb;
+ //qgl_FragData[0].rgb = vec3(abs(lpos.xyz - pos.xyz)/10);
+ //qgl_FragData[0].rgb = vec3(li.xyz);
+ //qgl_FragData[0].rgb = vec3(v1.xyz);
+ //qgl_FragData[0].a = 0.;
}
diff --git a/qglview/shaders/dsl_pass_1.vert b/qglview/shaders/dsl_pass_1.vert
index 30b8182..e06345c 100644
--- a/qglview/shaders/dsl_pass_1.vert
+++ b/qglview/shaders/dsl_pass_1.vert
@@ -2,11 +2,12 @@
in vec4 view_corner;
out vec4 view_dir;
-out vec3 view_pos;
+out vec4 view_pos;
void main(void) {
view_dir = view_corner;
- view_pos = vec3(qgl_ModelViewMatrix * vec4(qgl_Vertex.xy, 1, 1));
+ view_pos = vec4(qgl_ModelViewMatrix * vec4(qgl_Vertex.xy, 1, 1));
+ view_pos /= view_pos.w;
qgl_FragTexture = qgl_Texture;
qgl_FragColor = qgl_Color;
gl_Position = qgl_ftransform();