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

This commit is contained in:
2015-11-23 17:07:25 +00:00
parent 104a7f99ad
commit 48addec20f
32 changed files with 738 additions and 541 deletions

255
qglview/glcamera.cpp Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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<GLdouble>(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<GLdouble>(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<GLdouble>(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<GLdouble>(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);
}
*/

108
qglview/glcamera.h Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

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

View File

@@ -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

View File

@@ -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;

View File

@@ -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<int, GLObjectBase * > * ids = 0, int sh_id_loc = 0);
void checkPass();
virtual void localTransform(QMatrix4x4 & m);
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
int pass_; // Pass

View File

@@ -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;

View File

@@ -22,6 +22,7 @@
#include <QMutex>
#include "gltexture_manager.h"
#include "globject.h"
#include "glcamera.h"
class GLParticlesSystem: public GLObjectBase
{

View File

@@ -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);
}

View File

@@ -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;
};

View File

@@ -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<Light*> & lights, const QMatrix4x4 & mat) {
void setUniformLights(QGLShaderProgram * prog, const QVector<Light*> & 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<Light*> & 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));

View File

@@ -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<Light*> & lights, const QMatrix4x4 & mat);
void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat);
void setUniformLights(QGLShaderProgram * prog, const QVector<Light*> & 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

View File

@@ -16,12 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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<GLdouble>(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<GLdouble>(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<GLdouble>(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<GLdouble>(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;
}

View File

@@ -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

View File

@@ -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<GLfloat> 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);

View File

@@ -50,11 +50,13 @@ public:
bool loadFromFile(const QString & filename);
private:
QVector<GLfloat> vertices_, normals_, texcoords_, colors_;
void calculateBinormals();
QVector<GLfloat> 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;
};

View File

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

View File

@@ -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;

View File

@@ -140,7 +140,7 @@ QVector<Material> 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<Material> 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;
/*

View File

@@ -156,7 +156,7 @@ QVector<Material> 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<Material> 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<Material> 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;
}

View File

@@ -65,10 +65,15 @@ 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));
@@ -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"));

View File

@@ -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

View File

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

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>470</width>
<height>692</height>
<height>737</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@@ -25,12 +25,18 @@
</property>
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Diffuse</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="text">
<string>Color:</string>
</property>
@@ -38,25 +44,38 @@
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorDiffuse">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapDiffuse" native="true"/>
<widget class="MaterialMapEditor" name="mapDiffuse" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Specular</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="text">
<string>Color:</string>
</property>
@@ -64,25 +83,38 @@
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorSpecular">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapSpecular" native="true"/>
<widget class="MaterialMapEditor" name="mapSpecular" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Self illumination</string>
</property>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="text">
<string>Color:</string>
</property>
@@ -90,37 +122,77 @@
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorSelfIllum">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapSelfIllum" native="true"/>
<widget class="MaterialMapEditor" name="mapSelfIllum" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_6">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Specularity</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="MaterialMapEditor" name="mapSpecularity" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_5">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Bump</string>
<string>Normal</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="MaterialMapEditor" name="mapBump" native="true"/>
<widget class="MaterialMapEditor" name="mapBump" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_4">
<property name="styleSheet">
<string notr="true">font:bold;</string>
</property>
<property name="title">
<string>Relief</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="MaterialMapEditor" name="mapRelief" native="true"/>
<widget class="MaterialMapEditor" name="mapRelief" native="true">
<property name="styleSheet">
<string notr="true">font:normal;</string>
</property>
</widget>
</item>
</layout>
</widget>
@@ -133,65 +205,13 @@
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Roughness</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="SpinSlider" name="spinRoughness">
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Specular</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="SpinSlider" name="spinSpecular">
<property name="maximum">
<double>64.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Transparency</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="7" column="1">
<widget class="SpinSlider" name="spinTransparent">
<property name="maximum">
<double>1.000000000000000</double>
@@ -207,14 +227,14 @@
</property>
</widget>
</item>
<item row="10" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Reflectivity</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="8" column="1">
<widget class="SpinSlider" name="spinReflect">
<property name="maximum">
<double>1.000000000000000</double>
@@ -230,14 +250,14 @@
</property>
</widget>
</item>
<item row="11" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>IOF</string>
</property>
</widget>
</item>
<item row="11" column="1">
<item row="9" column="1">
<widget class="SpinSlider" name="spinIOF">
<property name="maximum">
<double>2.000000000000000</double>
@@ -256,14 +276,14 @@
</property>
</widget>
</item>
<item row="12" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Dispersion</string>
</property>
</widget>
</item>
<item row="12" column="1">
<item row="10" column="1">
<widget class="SpinSlider" name="spinDispersion">
<property name="maximum">
<double>1.000000000000000</double>
@@ -282,14 +302,14 @@
</property>
</widget>
</item>
<item row="13" column="0">
<item row="11" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Reflection map</string>
</property>
</widget>
</item>
<item row="13" column="1">
<item row="11" column="1">
<widget class="QFrame" name="frameReflection">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
@@ -494,18 +514,6 @@
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Roughness</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="MaterialMapEditor" name="mapRoughness" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@@ -563,38 +571,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>spinRoughness</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>443</x>
<y>404</y>
</hint>
<hint type="destinationlabel">
<x>280</x>
<y>95</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinSpecular</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>443</x>
<y>426</y>
</hint>
<hint type="destinationlabel">
<x>283</x>
<y>120</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinTransparent</sender>
<signal>valueChanged(double)</signal>
@@ -772,7 +748,7 @@
</hints>
</connection>
<connection>
<sender>mapRoughness</sender>
<sender>mapSpecularity</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;}

View File

@@ -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<Light*> 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());
}

View File

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

View File

@@ -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.);

View File

@@ -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.;
}

View File

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