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

This commit is contained in:
2019-12-01 16:52:10 +00:00
parent 09298fadcd
commit 385070f70f
33 changed files with 226 additions and 83 deletions

View File

@@ -22,11 +22,13 @@ if (MINGW)
find_package(MinGW REQUIRED) find_package(MinGW REQUIRED)
endif() endif()
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
include_directories(${QAD_INCLUDES} {CMAKE_CURRENT_SOURCE_DIR}) include_directories(${QAD_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/core")
find_qt(Qt5 Core Gui OpenGL Xml) find_qt(Qt5 Core Gui OpenGL Xml)
qt_sources(SRC) qt_sources(SRC)
qt_sources(FSRC DIR "formats") qt_sources(FSRC DIR "formats")
list(APPEND SRC ${FSRC}) list(APPEND SRC ${FSRC})
qt_sources(FSRC DIR "core")
list(APPEND SRC ${FSRC})
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM) qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
qt_add_library(qglengine_core SHARED out_CPP) qt_add_library(qglengine_core SHARED out_CPP)
qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES}) qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES})

View File

@@ -24,8 +24,8 @@
Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum _target): f(f_), Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum _target): f(f_),
pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) { pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) {
is_depth = withDepth; is_depth = withDepth;
color_format = colorFormat_;
target_ = _target; target_ = _target;
color_formats.fill(colorFormat_, colorAttachments_);
colors.fill(0, colorAttachments_); colors.fill(0, colorAttachments_);
fbo = drbo = 0; fbo = drbo = 0;
tex_d = 0; tex_d = 0;
@@ -35,6 +35,20 @@ Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments_, bool
} }
Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, QVector<GLenum> colors_, bool withDepth, GLenum _target): f(f_),
pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) {
is_depth = withDepth;
target_ = _target;
color_formats = colors_;
colors.fill(0, colors_.size());
fbo = drbo = 0;
tex_d = 0;
wid = hei = 0;
pbo_queried = 0;
is_changed = false;
}
Framebuffer::~Framebuffer() { Framebuffer::~Framebuffer() {
deleteGLFramebuffer(fbo); deleteGLFramebuffer(fbo);
deleteGLRenderbuffer(drbo); deleteGLRenderbuffer(drbo);
@@ -53,7 +67,7 @@ void Framebuffer::resize(int width, int height, bool force) {
f->glBindFramebuffer(GL_FRAMEBUFFER, fbo); f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
for (int i = 0; i < colors.size(); ++i) { for (int i = 0; i < colors.size(); ++i) {
deleteGLTexture(f, colors[i]); deleteGLTexture(f, colors[i]);
createGLTexture(f, colors[i], width, height, color_format, target_); createGLTexture(f, colors[i], width, height, color_formats[i], target_);
f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST); f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST); f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@@ -26,11 +26,12 @@ class Framebuffer
{ {
public: public:
Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum _target = GL_TEXTURE_2D); Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum _target = GL_TEXTURE_2D);
Framebuffer(QOpenGLExtraFunctions * f_, QVector<GLenum> colors_, bool withDepth = true, GLenum _target = GL_TEXTURE_2D);
virtual ~Framebuffer(); virtual ~Framebuffer();
GLuint id() const {return fbo;} GLuint id() const {return fbo;}
GLuint colorTexture(int index = 0) const {return colors[index];} GLuint colorTexture(int index = 0) const {return colors[index];}
GLenum colorFormat() const {return color_format;} //GLenum colorFormat() const {return color_format;}
GLuint depthTexture() const {return tex_d;} GLuint depthTexture() const {return tex_d;}
GLenum target() const {return target_;} GLenum target() const {return target_;}
int width() const {return wid;} int width() const {return wid;}
@@ -55,7 +56,7 @@ public:
void setWriteBuffer(int index); void setWriteBuffer(int index);
void setWriteBuffers(int * indeces, int count); void setWriteBuffers(int * indeces, int count);
void setWriteBuffers(); void setWriteBuffers();
void setColorFormat(GLenum format) {color_format = format; is_changed = true;} //void setColorFormat(GLenum format) {color_format = format; is_changed = true;}
void enablePixelBuffer(); void enablePixelBuffer();
void copyDepthFrom(GLuint tex) {;} void copyDepthFrom(GLuint tex) {;}
@@ -72,7 +73,8 @@ private:
QOpenGLExtraFunctions * f; QOpenGLExtraFunctions * f;
mutable Buffer pbo; mutable Buffer pbo;
QVector<GLuint> colors; QVector<GLuint> colors;
GLenum color_format, target_; QVector<GLenum> color_formats;
GLenum target_;
GLuint fbo, drbo, tex_d; GLuint fbo, drbo, tex_d;
GLint prev_view[4], wid, hei; GLint prev_view[4], wid, hei;

View File

@@ -153,7 +153,7 @@ void QGLEngineShaders::setUniformLight(QOpenGLShaderProgram * prog, Light * ligh
if (!prog) return; if (!prog) return;
if (!prog->isLinked()) return; if (!prog->isLinked()) return;
QMatrix4x4 m = mat * light->worldTransform(); QMatrix4x4 m = mat * light->worldTransform();
QVector4D pos(0, 0, 0, 1.), dir(light->direction, 1);//, dir0(light->dir0), dir1(light->dir1); QVector4D pos(0, 0, 0, 1.), dir(light->direction(), 1);//, dir0(light->dir0), dir1(light->dir1);
pos = m * pos; pos = m * pos;
dir = ((m * dir) - pos).normalized(); dir = ((m * dir) - pos).normalized();
float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f; float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f;

View File

@@ -165,6 +165,7 @@ inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true)
class QGLView; class QGLView;
class MouseController; class MouseController;
class ObjectBase; class ObjectBase;
class AimedObject;
class Light; class Light;
class Camera; class Camera;
class Texture; class Texture;

View File

@@ -86,7 +86,7 @@ Light * assimpLight(const aiLight * l) {
Light * ret = new Light(); Light * ret = new Light();
ret->setName(l->mName.C_Str()); ret->setName(l->mName.C_Str());
ret->setPos(fromAiVector3D(l->mPosition)); ret->setPos(fromAiVector3D(l->mPosition));
ret->direction = fromAiVector3D(l->mDirection); ret->setDirection(fromAiVector3D(l->mDirection));
ret->decay_const = l->mAttenuationConstant ; ret->decay_const = l->mAttenuationConstant ;
ret->decay_linear = l->mAttenuationLinear ; ret->decay_linear = l->mAttenuationLinear ;
ret->decay_quadratic = l->mAttenuationQuadratic; ret->decay_quadratic = l->mAttenuationQuadratic;
@@ -102,14 +102,15 @@ Light * assimpLight(const aiLight * l) {
} }
ObjectBase * assimpObject(const aiNode * n, const QVector<Mesh * > & meshes, const QMap<QString, Light * > & light_by_name) { ObjectBase * assimpObject(const aiNode * n, const QVector<Mesh * > & meshes, const QMap<QString, Light * > & light_by_name, QVector<Light*> & out_lights) {
if (!n) return 0; if (!n) return 0;
ObjectBase * ret = 0; ObjectBase * ret = 0;
QString name = n->mName.C_Str(); QString name = n->mName.C_Str();
Light * light = light_by_name.value(name, 0); Light * light = light_by_name.value(name, 0);
if (light) if (light) {
ret = light->clone(); ret = light->clone();
else out_lights << (Light*)ret;
} else
ret = new ObjectBase(); ret = new ObjectBase();
ret->setName(name); ret->setName(name);
ret->setTransform(fromAiMatrix4D(n->mTransformation)); ret->setTransform(fromAiMatrix4D(n->mTransformation));
@@ -125,7 +126,7 @@ ObjectBase * assimpObject(const aiNode * n, const QVector<Mesh * > & meshes, con
} }
} }
for (uint i = 0; i < n->mNumChildren; ++i) { for (uint i = 0; i < n->mNumChildren; ++i) {
ObjectBase * co = assimpObject(n->mChildren[i], meshes, light_by_name); ObjectBase * co = assimpObject(n->mChildren[i], meshes, light_by_name, out_lights);
if (co) ret->addChild(co); if (co) ret->addChild(co);
} }
@@ -138,9 +139,9 @@ Scene * loadScene(const QString & filepath) {
qDebug() << "[Loader Assimp] Import" << filepath << "..."; qDebug() << "[Loader Assimp] Import" << filepath << "...";
Assimp::Importer importer; Assimp::Importer importer;
const aiScene * ais = importer.ReadFile(filepath.toUtf8(), aiProcess_Triangulate | const aiScene * ais = importer.ReadFile(filepath.toUtf8(), aiProcess_Triangulate |
aiProcess_SortByPType | aiProcess_SortByPType |
aiProcess_GenUVCoords | aiProcess_GenUVCoords |
aiProcess_TransformUVCoords); aiProcess_TransformUVCoords);
if (!ais) { if (!ais) {
qDebug() << "[Loader Assimp] Error: \"" + QString(importer.GetErrorString()) + "\""; qDebug() << "[Loader Assimp] Error: \"" + QString(importer.GetErrorString()) + "\"";
return 0; return 0;
@@ -156,15 +157,25 @@ Scene * loadScene(const QString & filepath) {
foreach (Light * l, lights) foreach (Light * l, lights)
light_by_name[l->name()] = l; light_by_name[l->name()] = l;
ObjectBase * root = assimpObject(ais->mRootNode, meshes, light_by_name); QVector<Light*> out_lights;
ObjectBase * root = assimpObject(ais->mRootNode, meshes, light_by_name, out_lights);
if (!root) return 0; if (!root) return 0;
QList<ObjectBase*> rcl = root->children(true);
foreach (ObjectBase * c, rcl) {
foreach (Light * l, out_lights) {
if (c->name() == (l->name() + ".Target")) {
l->setAim((l->worldTransform().inverted() * QVector4D(c->worldPos(), 1)).toVector3D());
delete c;
break;
}
}
}
Scene * scene = new Scene(); Scene * scene = new Scene();
scene->setName(root->name()); scene->setName(root->name());
foreach (ObjectBase * o, root->children()) foreach (ObjectBase * o, root->children())
scene->addObject(o); scene->addObject(o);
//foreach (ObjectBase * o, lights)
// scene->addObject(o);
qDeleteAll(lights); qDeleteAll(lights);
return scene; return scene;

View File

@@ -24,7 +24,7 @@
//extern QMatrix4x4 globCameraMatrix; //extern QMatrix4x4 globCameraMatrix;
//extern Camera * currentCamera; //extern Camera * currentCamera;
class Camera: public ObjectBase class Camera: public AimedObject
{ {
friend class QGLView; friend class QGLView;
friend class GLParticlesSystem; friend class GLParticlesSystem;
@@ -34,7 +34,7 @@ public:
Camera(); Camera();
void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); buildTransform();} void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); buildTransform();}
void setAim(const QVector3D & p) {aim_ = p; anglesFromPoints(); buildTransform();} void setAim(const QVector3D & p) {AimedObject::setAim(p); anglesFromPoints(); buildTransform();}
void move(const QVector3D & p) {pos_ += p; aim_ += p; buildTransform();} void move(const QVector3D & p) {pos_ += p; aim_ += p; buildTransform();}
void move(const float & x, const float & y = 0., const float & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z); buildTransform();} void move(const float & x, const float & y = 0., const float & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z); buildTransform();}
void moveForward(const float & x, bool withZ = true); void moveForward(const float & x, bool withZ = true);
@@ -66,7 +66,6 @@ public:
void flyFarer(const float & s); void flyFarer(const float & s);
void flyToDistance(const float & d); void flyToDistance(const float & d);
QVector3D aim() const {return aim_;}
QVector3D angles() const {return rotation();} QVector3D angles() const {return rotation();}
QVector3D direction() const {return (aim_ - pos_).normalized();} QVector3D direction() const {return (aim_ - pos_).normalized();}
QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();} QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();}
@@ -94,7 +93,6 @@ public:
QMatrix4x4 fullViewMatrix() const {return viewMatrix() * offsetMatrix();} QMatrix4x4 fullViewMatrix() const {return viewMatrix() * offsetMatrix();}
private: private:
QVector3D aim_;
mutable QVector3D offset_; mutable QVector3D offset_;
GLfloat fov_; GLfloat fov_;
GLfloat depth_start; GLfloat depth_start;

View File

@@ -465,18 +465,41 @@ QMatrix4x4 ObjectBase::worldMatrix(QMatrix4x4 parent) const {
Light::Light(): ObjectBase(), shadow_map(0, true, GL_R16F) { AimedObject::AimedObject() {
}
void AimedObject::setAim(const QVector3D & p) {
aim_ = p;
}
QVector3D AimedObject::direction() const {
return (aim_ - pos_).normalized();
}
void AimedObject::setDirection(const QVector3D & d) {
double len = qMax(direction().length(), 0.001f);
aim_ = pos_ + (d.normalized() * len);
}
Light::Light(): AimedObject(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
intensity = 1.; intensity = 1.;
angle_start = angle_end = 180.; angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.; decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.; decay_const = decay_end = 1.;
direction.setZ(1.); setDirection(0, 0, -1.);
} }
Light::Light(const QVector3D & p, const QColor & c, float i): ObjectBase(), shadow_map(0, true, GL_R16F) { Light::Light(const QVector3D & p, const QColor & c, float i): AimedObject(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
pos_ = p; pos_ = p;
@@ -485,7 +508,7 @@ Light::Light(const QVector3D & p, const QColor & c, float i): ObjectBase(), shad
angle_start = angle_end = 180.; angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.; decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.; decay_const = decay_end = 1.;
direction.setZ(1.); setDirection(0, 0, -1.);
} }
@@ -502,7 +525,8 @@ ObjectBase * Light::clone(bool withChildren) {
} }
o->color_ = color_; o->color_ = color_;
o->light_type = light_type; o->light_type = light_type;
o->direction = direction; o->pos_ = pos_;
o->aim_ = aim_;
o->angle_start = angle_start; o->angle_start = angle_start;
o->angle_end = angle_end; o->angle_end = angle_end;
o->intensity = intensity; o->intensity = intensity;
@@ -531,9 +555,9 @@ QDataStream & operator <<(QDataStream & s, const ObjectBase * p) {
if (p->type_ == ObjectBase::glLight) { if (p->type_ == ObjectBase::glLight) {
//qDebug() << "place light ..."; //qDebug() << "place light ...";
const Light * l = (const Light*)p; const Light * l = (const Light*)p;
cs.add(100, l->direction).add(101, l->angle_start).add(102, l->angle_end).add(103, l->intensity) cs.add(100, l->direction()).add(101, l->angle_start).add(102, l->angle_end).add(103, l->intensity)
.add(104, l->decay_const).add(105, l->decay_linear).add(106, l->decay_quadratic) .add(104, l->decay_const).add(105, l->decay_linear).add(106, l->decay_quadratic)
.add(107, l->decay_start).add(108, l->decay_end).add(109, int(l->light_type)); .add(107, l->decay_start).add(108, l->decay_end).add(109, int(l->light_type)).add(110, l->aim());
} }
if (p->type_ == ObjectBase::glCamera) { if (p->type_ == ObjectBase::glCamera) {
//qDebug() << "place camera ..."; //qDebug() << "place camera ...";
@@ -592,7 +616,7 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) {
case 17: if (p) p->name_ = cs.getData<QString>(); break; case 17: if (p) p->name_ = cs.getData<QString>(); break;
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break; case 18: if (p) p->meta = cs.getData<QVariantMap>(); break;
case 19: if (p) p->color_ = cs.getData<QColor>(); break; case 19: if (p) p->color_ = cs.getData<QColor>(); break;
case 100: if (l) l->direction = cs.getData<QVector3D>(); break; case 100: if (l) l->setDirection(cs.getData<QVector3D>());break;
case 101: if (l) l->angle_start = cs.getData<GLfloat>(); break; case 101: if (l) l->angle_start = cs.getData<GLfloat>(); break;
case 102: if (l) l->angle_end = cs.getData<GLfloat>(); break; case 102: if (l) l->angle_end = cs.getData<GLfloat>(); break;
case 103: if (l) l->intensity = cs.getData<GLfloat>(); break; case 103: if (l) l->intensity = cs.getData<GLfloat>(); break;
@@ -602,6 +626,7 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) {
case 107: if (l) l->decay_start = cs.getData<GLfloat>(); break; case 107: if (l) l->decay_start = cs.getData<GLfloat>(); break;
case 108: if (l) l->decay_end = cs.getData<GLfloat>(); break; case 108: if (l) l->decay_end = cs.getData<GLfloat>(); break;
case 109: if (l) l->light_type = (Light::Type)cs.getData<int>(); break; case 109: if (l) l->light_type = (Light::Type)cs.getData<int>(); break;
case 110: if (l) l->setAim(cs.getData<QVector3D>()); if (l->aim().isNull()) l->setAim(l->direction()); break;
case 200: if (c) c->setAim(cs.getData<QVector3D>()); break; case 200: if (c) c->setAim(cs.getData<QVector3D>()); break;
case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break; case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break;
case 202: if (c) c->setDepthStart(cs.getData<GLfloat>()); break; case 202: if (c) c->setDepthStart(cs.getData<GLfloat>()); break;

View File

@@ -229,13 +229,23 @@ inline bool operator <(const ObjectBase & f, const ObjectBase & s) {return f.pos
class AimedObject: public ObjectBase { class AimedObject: public ObjectBase {
friend class QGLView; friend class QGLView;
friend class GLRendererBase; friend class GLRendererBase;
friend class Light;
friend class Camera;
public: public:
AimedObject(); AimedObject();
~AimedObject(); ~AimedObject() {}
QVector3D aim() const {return aim_;}
QVector3D worldAim() const {return (itransform_ * QVector4D(aim_, 1.)).toVector3D();}
void setAim(const QVector3D & p);
QVector3D direction() const;
void setDirection(const QVector3D & d);
void setDirection(double x, double y, double z) {setDirection(QVector3D(x, y, z));}
protected:
QVector3D aim_;
}; };
class Light: public ObjectBase { class Light: public AimedObject {
friend class QGLView; friend class QGLView;
friend class RendererBase; friend class RendererBase;
public: public:
@@ -247,7 +257,6 @@ public:
virtual void init() {shadow_map.resize(512, 512); is_init = true;} virtual void init() {shadow_map.resize(512, 512); is_init = true;}
void apply(); void apply();
QVector3D direction, dir0, dir1;
float angle_start; float angle_start;
float angle_end; float angle_end;
float intensity; float intensity;

View File

@@ -36,9 +36,9 @@ void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index)
GLfloat pos[] = {0.f, 0.f, 0.f, 0.f}; GLfloat pos[] = {0.f, 0.f, 0.f, 0.f};
GLfloat dir[] = {0.f, 0.f, 0.f}; GLfloat dir[] = {0.f, 0.f, 0.f};
GLfloat col[] = {0.f, 0.f, 0.f}; GLfloat col[] = {0.f, 0.f, 0.f};
pos[0] = l.light_type == Light::Directional ? -l.direction.x() : lp.x(); pos[0] = l.light_type == Light::Directional ? -l.direction().x() : lp.x();
pos[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y(); pos[1] = l.light_type == Light::Directional ? -l.direction().y() : lp.y();
pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z(); pos[2] = l.light_type == Light::Directional ? -l.direction().z() : lp.z();
pos[3] = l.light_type == Light::Directional ? 0. : 1.; pos[3] = l.light_type == Light::Directional ? 0. : 1.;
dir[0] = ld.x(); dir[0] = ld.x();
dir[1] = ld.y(); dir[1] = ld.y();
@@ -209,7 +209,7 @@ void GLRendererBase::renderShadow(Light * l, QOpenGLShaderProgram * prog, QMatri
Camera cam; Camera cam;
QVector3D wp = l->worldPos(); QVector3D wp = l->worldPos();
cam.setPos(wp); cam.setPos(wp);
cam.setAim(wp + (l->worldTransform() * QVector4D(l->direction)).toVector3D()); cam.setAim(wp + (l->worldTransform() * QVector4D(l->direction())).toVector3D());
cam.setDepthStart(view->camera()->depthStart()); cam.setDepthStart(view->camera()->depthStart());
cam.setDepthEnd(view->camera()->depthEnd()); cam.setDepthEnd(view->camera()->depthEnd());
cam.setFOV(l->angle_end); cam.setFOV(l->angle_end);

View File

@@ -28,7 +28,7 @@ using namespace QGLEngineShaders;
Renderer::Renderer(QGLView * view_): RendererBase(view_), Renderer::Renderer(QGLView * view_): RendererBase(view_),
fbo_ds (view_, 5, true , GL_RGBA16F), fbo_ds (view_, QVector<GLenum>() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F),
fbo_out (view_, 3, false, GL_RGBA16F), fbo_out (view_, 3, false, GL_RGBA16F),
fbo_hsmall (view_, 1, false, GL_RGB16F ), fbo_hsmall (view_, 1, false, GL_RGB16F ),
rend_mat(this), rend_service(this), rend_selection(this) { rend_mat(this), rend_service(this), rend_selection(this) {
@@ -125,13 +125,22 @@ bool Renderer::bindShader(Renderer::ShaderRole role, QOpenGLShaderProgram ** ret
void Renderer::initShaders() { void Renderer::initShaders() {
if (!need_init_shaders) return; if (!need_init_shaders) return;
need_init_shaders = false; need_init_shaders = false;
initUniformBuffer(shaders.value(srGeometryPass), &buffer_materials , bpMaterials , "QGLMaterialData" ); initUniformBuffer(shaders.value(srGeometryPass ), &buffer_materials , bpMaterials , "QGLMaterialData" );
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_materials , bpMaterials , "QGLMaterialData" ); initUniformBuffer(shaders.value(srLightOmniPass), &buffer_materials , bpMaterials , "QGLMaterialData" );
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights , bpLightParameters, "QGLLightParameterData"); initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights , bpLightParameters, "QGLLightParameterData");
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" ); initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" );
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_materials , bpMaterials , "QGLMaterialData" ); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_materials , bpMaterials , "QGLMaterialData" );
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights , bpLightParameters, "QGLLightParameterData"); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights , bpLightParameters, "QGLLightParameterData");
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" ); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" );
ShaderRole roles[] = {srLightOmniPass, srLightSpotPass};
for (int p = 0; p < 2; ++p) {
QOpenGLShaderProgram * prog = 0;
if (!bindShader(roles[p], &prog)) continue;
for (int i = 0; i < 5; ++i)
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
prog->setUniformValue("tex_d", 5);
prog->setUniformValue("tex_sum", 7);
}
} }
@@ -236,7 +245,7 @@ void Renderer::renderScene() {
} }
fbo_ds.release(); fbo_ds.release();
/// lighting pass /// lighting passes
fbo_ds.bindColorTextures(); fbo_ds.bindColorTextures();
fbo_ds.bindDepthTexture(5); fbo_ds.bindDepthTexture(5);
fbo_out.bind(); fbo_out.bind();
@@ -248,12 +257,8 @@ void Renderer::renderScene() {
if (bindShader(pass.first, &prog)) { if (bindShader(pass.first, &prog)) {
setUniformCamera(prog, cam); setUniformCamera(prog, cam);
setUniformViewCorners(prog, cam); setUniformViewCorners(prog, cam);
for (int i = 0; i < 5; ++i)
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
prog->setUniformValue("tex_d", 5);
prog->setUniformValue("lights_start", lights_start[pass.second]); prog->setUniformValue("lights_start", lights_start[pass.second]);
prog->setUniformValue("lights_count", ll[pass.second].size()); prog->setUniformValue("lights_count", ll[pass.second].size());
prog->setUniformValue("tex_sum", 7);
fbo_out.setWriteBuffer(wi); fbo_out.setWriteBuffer(wi);
fbo_out.bindColorTexture(ri, 7); fbo_out.bindColorTexture(ri, 7);
glClearFramebuffer(Qt::black, false); glClearFramebuffer(Qt::black, false);

View File

@@ -258,7 +258,7 @@ void RendererBase::reloadLightsPositions(Camera * cam) {
QGLLightPosition & so(cur_lights_pos_[i]); QGLLightPosition & so(cur_lights_pos_[i]);
Light * l = current_lights[i]; Light * l = current_lights[i];
QMatrix4x4 m = mat * l->worldTransform(); QMatrix4x4 m = mat * l->worldTransform();
QVector4D pos(0, 0, 0, 1.), dir(l->direction, 1);//, dir0(light->dir0), dir1(light->dir1); QVector4D pos(0, 0, 0, 1.), dir(l->direction(), 1);//, dir0(light->dir0), dir1(light->dir1);
pos = m * pos; pos = m * pos;
dir = ((m * dir) - pos).normalized(); dir = ((m * dir) - pos).normalized();
so.position = pos; so.position = pos;

View File

@@ -54,8 +54,8 @@ RendererService::RendererService(Renderer * r_): r(r_) {
axis_camera->setFOV(45.); axis_camera->setFOV(45.);
axis_mesh = Primitive::arrow(12); axis_mesh = Primitive::arrow(12);
size_vp_scale = size_full_scale = 1.; size_vp_scale = size_full_scale = 1.;
box_mesh = Primitive::cube(); box_mesh = Primitive::cube(0.8, 0.8, 0.8);
box_mesh_f = Primitive::cubeFrame(); box_mesh_f = Primitive::cubeFrame(0.8, 0.8, 0.8);
omni_mesh = Primitive::ellipsoid(2, 1); omni_mesh = Primitive::ellipsoid(2, 1);
omni_mesh_f = Primitive::ellipsoidFrame(2, 1); omni_mesh_f = Primitive::ellipsoidFrame(2, 1);
omni_mesh ->scalePoints(1.5); omni_mesh ->scalePoints(1.5);
@@ -63,14 +63,18 @@ RendererService::RendererService(Renderer * r_): r(r_) {
cone_mesh = Primitive::cone(8, 1., 1., 1.); cone_mesh = Primitive::cone(8, 1., 1., 1.);
cone_mesh_f = Primitive::coneFrame(8, 1., 1., 1.); cone_mesh_f = Primitive::coneFrame(8, 1., 1., 1.);
QMatrix4x4 mat; QMatrix4x4 mat;
mat.rotate(90, 0,1,0); mat.translate(0,0,1);
mat.translate(0,0,2);
mat.rotate(180, 1,0,0); mat.rotate(180, 1,0,0);
cone_mesh ->transformPoints(mat); cone_mesh ->transformPoints(mat);
cone_mesh_f->transformPoints(mat); cone_mesh_f->transformPoints(mat);
cone_mesh_f->scalePoints(1.5);
box_mesh ->scalePoints(1.3); box_mesh ->scalePoints(1.3);
omni_mesh ->scalePoints(1.3); omni_mesh ->scalePoints(1.3);
cone_mesh ->translatePoints(0,0,-1);
cone_mesh ->scalePoints(1.4);
cone_mesh ->translatePoints(0,0,1);
cone_mesh ->scalePoints(1.5);
handle_move_mesh = Primitive::arrow(12, 0.06); handle_move_mesh = Primitive::arrow(12, 0.06);
handle_ms_2_mesh = Primitive::torus(8, 12, 0.5, 0.02, 90); handle_ms_2_mesh = Primitive::torus(8, 12, 0.5, 0.02, 90);
@@ -144,6 +148,26 @@ QMatrix4x4 RendererService::invariantSizeMatrix(QVector3D p) {
} }
QMatrix4x4 RendererService::parentRotationMatrix(ObjectBase * o, bool self_rotation) {
QMatrix4x4 ret;
if (!o) return ret;
QMatrix4x4 pmat;
if (o->parent()) {
pmat = o->parent()->worldTransform();
pmat.setColumn(3, QVector4D(0,0,0,1));
double det = pmat.determinant();
if (det > 0.) pmat /= sqrt(det);
}
if (self_rotation) {
ret.rotate(o->angles_.z(), 0., 0., 1.);
ret.rotate(o->angles_.y(), 0., 1., 0.);
ret.rotate(o->angles_.x(), 1., 0., 0.);
}
ret = pmat * ret;
return ret;
}
void RendererService::fillXYZObjects() { void RendererService::fillXYZObjects() {
cur_objects.resize(3); cur_objects.resize(3);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
@@ -166,6 +190,32 @@ void RendererService::fillOmniObjects() {
} }
void RendererService::fillSpotObjects() {
QList<Light*> ll = r->view->scene()->lights_used.value(Light::Cone);
Object o;
cur_objects.clear();
cur_aims.clear();
foreach (Light * l, ll) {
QMatrix4x4 m, lm;
//QVector3D up = QVector3D::crossProduct(l->direction, QVector3D(0,0,1)).normalized();
//if (up.isNull())
// up = QVector3D::crossProduct(l->direction, QVector3D(0,0,1)).normalized();
//lm.lookAt(QVector3D(), l->direction, up);
//lm.lookAt(QVector3D(), l->direction, (QVector3D(0,0,1)));
lm.rotate(QQuaternion::fromDirection(l->direction(), QVector3D()));
m = invariantSizeMatrix(l->worldPos()) * parentRotationMatrix(l) * lm;
m.transposed().copyDataTo(o.modelmatrix);
o.object_id = l->id_;
cur_objects << o;
m = invariantSizeMatrix(l->worldAim());
m.transposed().copyDataTo(o.modelmatrix);
o.object_id = l->id_ + 1;
cur_aims << o;
}
}
void RendererService::fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count) { void RendererService::fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count) {
QMatrix4x4 m = invariantSizeMatrix(center) * add_mat; QMatrix4x4 m = invariantSizeMatrix(center) * add_mat;
cur_objects.resize(count); cur_objects.resize(count);
@@ -196,18 +246,7 @@ bool RendererService::calculateCenter() {
} }
axis_mat = QMatrix4x4(); axis_mat = QMatrix4x4();
if ((sol.size() == 1) && (current_action != haMove)) { if ((sol.size() == 1) && (current_action != haMove)) {
ObjectBase * o = sol[0]; axis_mat = parentRotationMatrix(sol[0]);
QMatrix4x4 pmat;
if (o->parent()) {
pmat = o->parent()->worldTransform();
pmat.setColumn(3, QVector4D(0,0,0,1));
double det = pmat.determinant();
if (det > 0.) pmat /= sqrt(det);
}
axis_mat.rotate(o->angles_.z(), 0., 0., 1.);
axis_mat.rotate(o->angles_.y(), 0., 1., 0.);
axis_mat.rotate(o->angles_.x(), 1., 0., 0.);
axis_mat = pmat * axis_mat;
} }
return true; return true;
} }
@@ -259,11 +298,50 @@ void RendererService::drawCurrentHandleObjects() {
void RendererService::drawLights() { void RendererService::drawLights() {
QGLView * v = r->view;
RendererSelection & rs(r->rend_selection);
fillOmniObjects(); fillOmniObjects();
omni_mesh->loadObjects(r->view, cur_objects); omni_mesh->loadObjects(v, cur_objects);
r->fillSelectionsBuffer(r->rend_selection.cur_selections_, light2objectList(r->view->scene_->lights_used.value(Light::Omni))); r->fillSelectionsBuffer(rs.cur_selections_, light2objectList(v->scene_->lights_used.value(Light::Omni)));
omni_mesh->loadSelections(r->view, r->rend_selection.cur_selections_); omni_mesh->loadSelections(v, rs.cur_selections_);
omni_mesh->draw(r->view, cur_objects.size()); omni_mesh->draw(v, cur_objects.size());
fillSpotObjects();
cone_mesh->loadObjects(v, cur_objects);
r->fillSelectionsBuffer(rs.cur_selections_, light2objectList(v->scene_->lights_used.value(Light::Cone)));
cone_mesh->loadSelections(v, rs.cur_selections_);
cone_mesh->draw(v, cur_objects.size());
box_mesh->loadObjects(v, cur_aims);
box_mesh->loadSelections(v, rs.cur_selections_);
box_mesh->draw(v, cur_aims.size());
}
void RendererService::drawLightsFrame(QColor color) {
QGLView * v = r->view;
RendererSelection & rs(r->rend_selection);
fillOmniObjects();
setObjectsColor(cur_objects, color);
omni_mesh_f->loadObjects(v, cur_objects);
r->fillSelectionsBuffer(rs.cur_selections_, light2objectList(v->scene_->lights_used.value(Light::Omni)));
omni_mesh_f->loadSelections(v, rs.cur_selections_);
omni_mesh_f->draw(v, cur_objects.size());
fillSpotObjects();
setObjectsColor(cur_objects, color);
cone_mesh_f->loadObjects(v, cur_objects);
r->fillSelectionsBuffer(rs.cur_selections_, light2objectList(v->scene_->lights_used.value(Light::Cone)));
cone_mesh_f->loadSelections(v, rs.cur_selections_);
cone_mesh_f->draw(v, cur_objects.size());
setObjectsColor(cur_aims, color);
box_mesh_f->loadObjects(v, cur_aims);
box_mesh_f->loadSelections(v, rs.cur_selections_);
box_mesh_f->draw(v, cur_aims.size());
setObjectsColor(cur_aims, color);
} }
@@ -289,19 +367,13 @@ void RendererService::renderService() {
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
r->setUniformCamera(prog, r->view->camera()); r->setUniformCamera(prog, r->view->camera());
fillOmniObjects();
setObjectsColor(cur_objects, Qt::white);
prog->setUniformValue("line_width", 2.f); prog->setUniformValue("line_width", 2.f);
prog->setUniformValue("z_offset", 0.f); prog->setUniformValue("z_offset", 0.f);
omni_mesh_f->loadObjects(f, cur_objects); drawLightsFrame(Qt::white);
omni_mesh_f->draw(f, cur_objects.size());
setObjectsColor(cur_objects, Qt::black);
prog->setUniformValue("line_width", 1.f); prog->setUniformValue("line_width", 1.f);
prog->setUniformValue("z_offset", -1.E-2f); prog->setUniformValue("z_offset", -1.E-2f);
omni_mesh_f->loadObjects(f, cur_objects); drawLightsFrame(Qt::black);
omni_mesh_f->draw(f, cur_objects.size());
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

View File

@@ -66,12 +66,15 @@ public:
void resize(int width, int height); void resize(int width, int height);
QMatrix4x4 invariantSizeMatrix(QVector3D p); QMatrix4x4 invariantSizeMatrix(QVector3D p);
QMatrix4x4 parentRotationMatrix(ObjectBase * o, bool self_rotation = true);
void fillXYZObjects(); void fillXYZObjects();
void fillOmniObjects(); void fillOmniObjects();
void fillSpotObjects();
void fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count = 3); void fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count = 3);
bool calculateCenter(); bool calculateCenter();
void drawCurrentHandleObjects(); void drawCurrentHandleObjects();
void drawLights(); void drawLights();
void drawLightsFrame(QColor color);
void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col); void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col);
void renderService(); void renderService();
void setCurrentAction(HandleAction ha) {current_action = ha;} void setCurrentAction(HandleAction ha) {current_action = ha;}
@@ -87,7 +90,7 @@ private:
QVector3D selection_center; QVector3D selection_center;
QVector<QMatrix4x4> mat_xyz, mat_ms2; QVector<QMatrix4x4> mat_xyz, mat_ms2;
QVector<QVector4D> color_xyz, color_ms2; QVector<QVector4D> color_xyz, color_ms2;
QVector<QGLEngineShaders::Object> cur_objects; QVector<QGLEngineShaders::Object> cur_objects, cur_aims;
Camera * axis_camera; Camera * axis_camera;
QSize axis_viewport; QSize axis_viewport;
HandleAction current_action; HandleAction current_action;

View File

@@ -52,8 +52,8 @@ void main(void) {
float height = dot(qgl_materialTexture(QGL_MAP_RELIEF, tc, vec4(0)).rgb, luma); float height = dot(qgl_materialTexture(QGL_MAP_RELIEF, tc, vec4(0)).rgb, luma);
qgl_FragData[0] = vec4(diffuse .rgb, roughness ); qgl_FragData[0] = vec4(diffuse .rgb, reflectivity);
qgl_FragData[1] = vec4(normal .xyz, reflectivity); qgl_FragData[1] = vec4(normal .xyz, roughness );
qgl_FragData[2] = vec4(specular.rgb, height ); qgl_FragData[2] = vec4(specular.rgb, height );
qgl_FragData[3] = vec4(emission.rgb, 0/*bn.x*/); qgl_FragData[3] = vec4(emission.rgb, 0/*bn.x*/);
//qgl_FragData[4] = vec4(speed.xy, bn.yz); //qgl_FragData[4] = vec4(speed.xy, bn.yz);

View File

@@ -113,8 +113,8 @@ void main(void) {
vec3 normal = v1.xyz; vec3 normal = v1.xyz;
vec3 specular = v2.rgb; vec3 specular = v2.rgb;
vec3 emission = v3.rgb; vec3 emission = v3.rgb;
float roughness = v0.w; float reflectivity = v0.w;
float reflectivity = v1.w; float roughness = v1.w;
float height = v2.w; float height = v2.w;
//bn = normalize(vec3(v3.w, v4.zw)); //bn = normalize(vec3(v3.w, v4.zw));
//bn2 = normalize(cross(n, bn)); //bn2 = normalize(cross(n, bn));

View File

@@ -6,7 +6,8 @@ out float mat_scale;
void main(void) { void main(void) {
gl_Position = qgl_ftransform(); gl_Position = qgl_ftransform();
object_color_g = qgl_ObjectColor; object_color_g = qgl_ObjectColor;
mat_scale = pow(qgl_ModelMatrix[0][0] * qgl_ModelMatrix[1][1] * qgl_ModelMatrix[2][2], 0.3333); //mat_scale = pow(qgl_ModelMatrix[0][0] * qgl_ModelMatrix[1][1] * qgl_ModelMatrix[2][2], 0.3333);
mat_scale = pow(determinant(mat3(qgl_ModelMatrix)), 0.333);
} }

View File

@@ -86,9 +86,9 @@ void ObjectEditor::setObject(ObjectBase * o) {
ui->spinLightDecayQuadratic->setValue(l->decay_quadratic); ui->spinLightDecayQuadratic->setValue(l->decay_quadratic);
ui->spinLightAngleStart->setValue(l->angle_start); ui->spinLightAngleStart->setValue(l->angle_start);
ui->spinLightAngleEnd->setValue(l->angle_end); ui->spinLightAngleEnd->setValue(l->angle_end);
ui->spinLightDirectionX->setValue(l->direction.x()); ui->spinLightDirectionX->setValue(l->direction().x());
ui->spinLightDirectionY->setValue(l->direction.y()); ui->spinLightDirectionY->setValue(l->direction().y());
ui->spinLightDirectionZ->setValue(l->direction.z()); ui->spinLightDirectionZ->setValue(l->direction().z());
} }
ui->groupCamera->setEnabled(object->type() == ObjectBase::glCamera); ui->groupCamera->setEnabled(object->type() == ObjectBase::glCamera);
ui->groupCamera->setVisible(object->type() == ObjectBase::glCamera); ui->groupCamera->setVisible(object->type() == ObjectBase::glCamera);
@@ -135,7 +135,7 @@ void ObjectEditor::objectChanged() {
l->decay_quadratic = ui->spinLightDecayQuadratic->value(); l->decay_quadratic = ui->spinLightDecayQuadratic->value();
l->angle_start = ui->spinLightAngleStart->value(); l->angle_start = ui->spinLightAngleStart->value();
l->angle_end = ui->spinLightAngleEnd->value(); l->angle_end = ui->spinLightAngleEnd->value();
l->direction = QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized(); l->setDirection(QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized());
l->apply(); l->apply();
} }
if (object->type() == ObjectBase::glCamera) { if (object->type() == ObjectBase::glCamera) {