From 385070f70f727d9d08ac39a238cd72b9f0f92882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Sun, 1 Dec 2019 16:52:10 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/libs@637 a8b55f48-bf90-11e4-a774-851b48703e85 --- qglengine/CMakeLists.txt | 4 +- qglengine/{ => core}/glbuffer.cpp | 0 qglengine/{ => core}/glbuffer.h | 0 qglengine/{ => core}/glframebuffer.cpp | 18 +++- qglengine/{ => core}/glframebuffer.h | 8 +- qglengine/{ => core}/glmaterial.cpp | 0 qglengine/{ => core}/glmaterial.h | 0 qglengine/{ => core}/glmesh.cpp | 0 qglengine/{ => core}/glmesh.h | 0 qglengine/{ => core}/glprimitives.cpp | 0 qglengine/{ => core}/glprimitives.h | 0 qglengine/{ => core}/glshaders.cpp | 2 +- qglengine/{ => core}/glshaders.h | 0 qglengine/{ => core}/glshaders_headers.h | 0 qglengine/{ => core}/glshaders_types.cpp | 0 qglengine/{ => core}/glshaders_types.h | 0 qglengine/{ => core}/gltexturearray.cpp | 0 qglengine/{ => core}/gltexturearray.h | 0 qglengine/{ => core}/gltypes.cpp | 0 qglengine/{ => core}/gltypes.h | 1 + qglengine/formats/loader_assimp.cpp | 33 ++++-- qglengine/glcamera.h | 6 +- qglengine/globject.cpp | 41 ++++++-- qglengine/globject.h | 15 ++- qglengine/glrendererbase.cpp | 8 +- qglengine/renderer.cpp | 19 ++-- qglengine/renderer_base.cpp | 2 +- qglengine/renderer_service.cpp | 128 ++++++++++++++++++----- qglengine/renderer_service.h | 5 +- qglengine/shaders/ds_geom.glsl | 4 +- qglengine/shaders/ds_light.glsl | 4 +- qglengine/shaders/service_frame.glsl | 3 +- qglengine/widgets/object_editor.cpp | 8 +- 33 files changed, 226 insertions(+), 83 deletions(-) rename qglengine/{ => core}/glbuffer.cpp (100%) rename qglengine/{ => core}/glbuffer.h (100%) rename qglengine/{ => core}/glframebuffer.cpp (94%) rename qglengine/{ => core}/glframebuffer.h (89%) rename qglengine/{ => core}/glmaterial.cpp (100%) rename qglengine/{ => core}/glmaterial.h (100%) rename qglengine/{ => core}/glmesh.cpp (100%) rename qglengine/{ => core}/glmesh.h (100%) rename qglengine/{ => core}/glprimitives.cpp (100%) rename qglengine/{ => core}/glprimitives.h (100%) rename qglengine/{ => core}/glshaders.cpp (98%) rename qglengine/{ => core}/glshaders.h (100%) rename qglengine/{ => core}/glshaders_headers.h (100%) rename qglengine/{ => core}/glshaders_types.cpp (100%) rename qglengine/{ => core}/glshaders_types.h (100%) rename qglengine/{ => core}/gltexturearray.cpp (100%) rename qglengine/{ => core}/gltexturearray.h (100%) rename qglengine/{ => core}/gltypes.cpp (100%) rename qglengine/{ => core}/gltypes.h (99%) diff --git a/qglengine/CMakeLists.txt b/qglengine/CMakeLists.txt index f161de0..45080bf 100644 --- a/qglengine/CMakeLists.txt +++ b/qglengine/CMakeLists.txt @@ -22,11 +22,13 @@ if (MINGW) find_package(MinGW REQUIRED) endif() 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) qt_sources(SRC) qt_sources(FSRC DIR "formats") 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_add_library(qglengine_core SHARED out_CPP) qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES}) diff --git a/qglengine/glbuffer.cpp b/qglengine/core/glbuffer.cpp similarity index 100% rename from qglengine/glbuffer.cpp rename to qglengine/core/glbuffer.cpp diff --git a/qglengine/glbuffer.h b/qglengine/core/glbuffer.h similarity index 100% rename from qglengine/glbuffer.h rename to qglengine/core/glbuffer.h diff --git a/qglengine/glframebuffer.cpp b/qglengine/core/glframebuffer.cpp similarity index 94% rename from qglengine/glframebuffer.cpp rename to qglengine/core/glframebuffer.cpp index 7bd3142..30e3817 100644 --- a/qglengine/glframebuffer.cpp +++ b/qglengine/core/glframebuffer.cpp @@ -24,8 +24,8 @@ Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum _target): f(f_), pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) { is_depth = withDepth; - color_format = colorFormat_; target_ = _target; + color_formats.fill(colorFormat_, colorAttachments_); colors.fill(0, colorAttachments_); fbo = drbo = 0; tex_d = 0; @@ -35,6 +35,20 @@ Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments_, bool } +Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, QVector 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() { deleteGLFramebuffer(fbo); deleteGLRenderbuffer(drbo); @@ -53,7 +67,7 @@ void Framebuffer::resize(int width, int height, bool force) { f->glBindFramebuffer(GL_FRAMEBUFFER, fbo); for (int i = 0; i < colors.size(); ++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_MAG_FILTER, GL_NEAREST); f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); diff --git a/qglengine/glframebuffer.h b/qglengine/core/glframebuffer.h similarity index 89% rename from qglengine/glframebuffer.h rename to qglengine/core/glframebuffer.h index d4704a3..f1e315d 100644 --- a/qglengine/glframebuffer.h +++ b/qglengine/core/glframebuffer.h @@ -26,11 +26,12 @@ class Framebuffer { public: Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum _target = GL_TEXTURE_2D); + Framebuffer(QOpenGLExtraFunctions * f_, QVector colors_, bool withDepth = true, GLenum _target = GL_TEXTURE_2D); virtual ~Framebuffer(); GLuint id() const {return fbo;} 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;} GLenum target() const {return target_;} int width() const {return wid;} @@ -55,7 +56,7 @@ public: void setWriteBuffer(int index); void setWriteBuffers(int * indeces, int count); 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 copyDepthFrom(GLuint tex) {;} @@ -72,7 +73,8 @@ private: QOpenGLExtraFunctions * f; mutable Buffer pbo; QVector colors; - GLenum color_format, target_; + QVector color_formats; + GLenum target_; GLuint fbo, drbo, tex_d; GLint prev_view[4], wid, hei; diff --git a/qglengine/glmaterial.cpp b/qglengine/core/glmaterial.cpp similarity index 100% rename from qglengine/glmaterial.cpp rename to qglengine/core/glmaterial.cpp diff --git a/qglengine/glmaterial.h b/qglengine/core/glmaterial.h similarity index 100% rename from qglengine/glmaterial.h rename to qglengine/core/glmaterial.h diff --git a/qglengine/glmesh.cpp b/qglengine/core/glmesh.cpp similarity index 100% rename from qglengine/glmesh.cpp rename to qglengine/core/glmesh.cpp diff --git a/qglengine/glmesh.h b/qglengine/core/glmesh.h similarity index 100% rename from qglengine/glmesh.h rename to qglengine/core/glmesh.h diff --git a/qglengine/glprimitives.cpp b/qglengine/core/glprimitives.cpp similarity index 100% rename from qglengine/glprimitives.cpp rename to qglengine/core/glprimitives.cpp diff --git a/qglengine/glprimitives.h b/qglengine/core/glprimitives.h similarity index 100% rename from qglengine/glprimitives.h rename to qglengine/core/glprimitives.h diff --git a/qglengine/glshaders.cpp b/qglengine/core/glshaders.cpp similarity index 98% rename from qglengine/glshaders.cpp rename to qglengine/core/glshaders.cpp index 1af712a..cd093ff 100644 --- a/qglengine/glshaders.cpp +++ b/qglengine/core/glshaders.cpp @@ -153,7 +153,7 @@ void QGLEngineShaders::setUniformLight(QOpenGLShaderProgram * prog, Light * ligh if (!prog) return; if (!prog->isLinked()) return; 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; dir = ((m * dir) - pos).normalized(); float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f; diff --git a/qglengine/glshaders.h b/qglengine/core/glshaders.h similarity index 100% rename from qglengine/glshaders.h rename to qglengine/core/glshaders.h diff --git a/qglengine/glshaders_headers.h b/qglengine/core/glshaders_headers.h similarity index 100% rename from qglengine/glshaders_headers.h rename to qglengine/core/glshaders_headers.h diff --git a/qglengine/glshaders_types.cpp b/qglengine/core/glshaders_types.cpp similarity index 100% rename from qglengine/glshaders_types.cpp rename to qglengine/core/glshaders_types.cpp diff --git a/qglengine/glshaders_types.h b/qglengine/core/glshaders_types.h similarity index 100% rename from qglengine/glshaders_types.h rename to qglengine/core/glshaders_types.h diff --git a/qglengine/gltexturearray.cpp b/qglengine/core/gltexturearray.cpp similarity index 100% rename from qglengine/gltexturearray.cpp rename to qglengine/core/gltexturearray.cpp diff --git a/qglengine/gltexturearray.h b/qglengine/core/gltexturearray.h similarity index 100% rename from qglengine/gltexturearray.h rename to qglengine/core/gltexturearray.h diff --git a/qglengine/gltypes.cpp b/qglengine/core/gltypes.cpp similarity index 100% rename from qglengine/gltypes.cpp rename to qglengine/core/gltypes.cpp diff --git a/qglengine/gltypes.h b/qglengine/core/gltypes.h similarity index 99% rename from qglengine/gltypes.h rename to qglengine/core/gltypes.h index f79de41..49d8376 100644 --- a/qglengine/gltypes.h +++ b/qglengine/core/gltypes.h @@ -165,6 +165,7 @@ inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true) class QGLView; class MouseController; class ObjectBase; +class AimedObject; class Light; class Camera; class Texture; diff --git a/qglengine/formats/loader_assimp.cpp b/qglengine/formats/loader_assimp.cpp index 3ab464a..d312005 100644 --- a/qglengine/formats/loader_assimp.cpp +++ b/qglengine/formats/loader_assimp.cpp @@ -86,7 +86,7 @@ Light * assimpLight(const aiLight * l) { Light * ret = new Light(); ret->setName(l->mName.C_Str()); ret->setPos(fromAiVector3D(l->mPosition)); - ret->direction = fromAiVector3D(l->mDirection); + ret->setDirection(fromAiVector3D(l->mDirection)); ret->decay_const = l->mAttenuationConstant ; ret->decay_linear = l->mAttenuationLinear ; ret->decay_quadratic = l->mAttenuationQuadratic; @@ -102,14 +102,15 @@ Light * assimpLight(const aiLight * l) { } -ObjectBase * assimpObject(const aiNode * n, const QVector & meshes, const QMap & light_by_name) { +ObjectBase * assimpObject(const aiNode * n, const QVector & meshes, const QMap & light_by_name, QVector & out_lights) { if (!n) return 0; ObjectBase * ret = 0; QString name = n->mName.C_Str(); Light * light = light_by_name.value(name, 0); - if (light) + if (light) { ret = light->clone(); - else + out_lights << (Light*)ret; + } else ret = new ObjectBase(); ret->setName(name); ret->setTransform(fromAiMatrix4D(n->mTransformation)); @@ -125,7 +126,7 @@ ObjectBase * assimpObject(const aiNode * n, const QVector & meshes, con } } 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); } @@ -138,9 +139,9 @@ Scene * loadScene(const QString & filepath) { qDebug() << "[Loader Assimp] Import" << filepath << "..."; Assimp::Importer importer; const aiScene * ais = importer.ReadFile(filepath.toUtf8(), aiProcess_Triangulate | - aiProcess_SortByPType | - aiProcess_GenUVCoords | - aiProcess_TransformUVCoords); + aiProcess_SortByPType | + aiProcess_GenUVCoords | + aiProcess_TransformUVCoords); if (!ais) { qDebug() << "[Loader Assimp] Error: \"" + QString(importer.GetErrorString()) + "\""; return 0; @@ -156,15 +157,25 @@ Scene * loadScene(const QString & filepath) { foreach (Light * l, lights) light_by_name[l->name()] = l; - ObjectBase * root = assimpObject(ais->mRootNode, meshes, light_by_name); + QVector out_lights; + ObjectBase * root = assimpObject(ais->mRootNode, meshes, light_by_name, out_lights); if (!root) return 0; + QList 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->setName(root->name()); foreach (ObjectBase * o, root->children()) scene->addObject(o); - //foreach (ObjectBase * o, lights) - // scene->addObject(o); qDeleteAll(lights); return scene; diff --git a/qglengine/glcamera.h b/qglengine/glcamera.h index 3412f6f..822a9e3 100644 --- a/qglengine/glcamera.h +++ b/qglengine/glcamera.h @@ -24,7 +24,7 @@ //extern QMatrix4x4 globCameraMatrix; //extern Camera * currentCamera; -class Camera: public ObjectBase +class Camera: public AimedObject { friend class QGLView; friend class GLParticlesSystem; @@ -34,7 +34,7 @@ public: Camera(); 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 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); @@ -66,7 +66,6 @@ public: void flyFarer(const float & s); void flyToDistance(const float & 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();} @@ -94,7 +93,6 @@ public: QMatrix4x4 fullViewMatrix() const {return viewMatrix() * offsetMatrix();} private: - QVector3D aim_; mutable QVector3D offset_; GLfloat fov_; GLfloat depth_start; diff --git a/qglengine/globject.cpp b/qglengine/globject.cpp index 968e329..334ddcf 100644 --- a/qglengine/globject.cpp +++ b/qglengine/globject.cpp @@ -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; light_type = Omni; intensity = 1.; angle_start = angle_end = 180.; decay_linear = decay_quadratic = decay_start = 0.; 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; light_type = Omni; pos_ = p; @@ -485,7 +508,7 @@ Light::Light(const QVector3D & p, const QColor & c, float i): ObjectBase(), shad angle_start = angle_end = 180.; decay_linear = decay_quadratic = decay_start = 0.; 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->light_type = light_type; - o->direction = direction; + o->pos_ = pos_; + o->aim_ = aim_; o->angle_start = angle_start; o->angle_end = angle_end; o->intensity = intensity; @@ -531,9 +555,9 @@ QDataStream & operator <<(QDataStream & s, const ObjectBase * p) { if (p->type_ == ObjectBase::glLight) { //qDebug() << "place light ..."; 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(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) { //qDebug() << "place camera ..."; @@ -592,7 +616,7 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) { case 17: if (p) p->name_ = cs.getData(); break; case 18: if (p) p->meta = cs.getData(); break; case 19: if (p) p->color_ = cs.getData(); break; - case 100: if (l) l->direction = cs.getData(); break; + case 100: if (l) l->setDirection(cs.getData());break; case 101: if (l) l->angle_start = cs.getData(); break; case 102: if (l) l->angle_end = cs.getData(); break; case 103: if (l) l->intensity = cs.getData(); break; @@ -602,6 +626,7 @@ QDataStream & operator >>(QDataStream & s, ObjectBase *& p) { case 107: if (l) l->decay_start = cs.getData(); break; case 108: if (l) l->decay_end = cs.getData(); break; case 109: if (l) l->light_type = (Light::Type)cs.getData(); break; + case 110: if (l) l->setAim(cs.getData()); if (l->aim().isNull()) l->setAim(l->direction()); break; case 200: if (c) c->setAim(cs.getData()); break; case 201: if (c) c->setFOV(cs.getData()); break; case 202: if (c) c->setDepthStart(cs.getData()); break; diff --git a/qglengine/globject.h b/qglengine/globject.h index f03c95a..189abaa 100644 --- a/qglengine/globject.h +++ b/qglengine/globject.h @@ -229,13 +229,23 @@ inline bool operator <(const ObjectBase & f, const ObjectBase & s) {return f.pos class AimedObject: public ObjectBase { friend class QGLView; friend class GLRendererBase; + friend class Light; + friend class Camera; public: 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 RendererBase; public: @@ -247,7 +257,6 @@ public: virtual void init() {shadow_map.resize(512, 512); is_init = true;} void apply(); - QVector3D direction, dir0, dir1; float angle_start; float angle_end; float intensity; diff --git a/qglengine/glrendererbase.cpp b/qglengine/glrendererbase.cpp index 77d8527..d289782 100644 --- a/qglengine/glrendererbase.cpp +++ b/qglengine/glrendererbase.cpp @@ -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 dir[] = {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[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y(); - pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z(); + 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[2] = l.light_type == Light::Directional ? -l.direction().z() : lp.z(); pos[3] = l.light_type == Light::Directional ? 0. : 1.; dir[0] = ld.x(); dir[1] = ld.y(); @@ -209,7 +209,7 @@ void GLRendererBase::renderShadow(Light * l, QOpenGLShaderProgram * prog, QMatri Camera cam; QVector3D wp = l->worldPos(); 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.setDepthEnd(view->camera()->depthEnd()); cam.setFOV(l->angle_end); diff --git a/qglengine/renderer.cpp b/qglengine/renderer.cpp index e287da5..711556c 100644 --- a/qglengine/renderer.cpp +++ b/qglengine/renderer.cpp @@ -28,7 +28,7 @@ using namespace QGLEngineShaders; Renderer::Renderer(QGLView * view_): RendererBase(view_), - fbo_ds (view_, 5, true , GL_RGBA16F), + fbo_ds (view_, QVector() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F), fbo_out (view_, 3, false, GL_RGBA16F), fbo_hsmall (view_, 1, false, GL_RGB16F ), rend_mat(this), rend_service(this), rend_selection(this) { @@ -125,13 +125,22 @@ bool Renderer::bindShader(Renderer::ShaderRole role, QOpenGLShaderProgram ** ret void Renderer::initShaders() { if (!need_init_shaders) return; 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_lights , bpLightParameters, "QGLLightParameterData"); initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" ); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_materials , bpMaterials , "QGLMaterialData" ); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights , bpLightParameters, "QGLLightParameterData"); 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(); - /// lighting pass + /// lighting passes fbo_ds.bindColorTextures(); fbo_ds.bindDepthTexture(5); fbo_out.bind(); @@ -248,12 +257,8 @@ void Renderer::renderScene() { if (bindShader(pass.first, &prog)) { setUniformCamera(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_count", ll[pass.second].size()); - prog->setUniformValue("tex_sum", 7); fbo_out.setWriteBuffer(wi); fbo_out.bindColorTexture(ri, 7); glClearFramebuffer(Qt::black, false); diff --git a/qglengine/renderer_base.cpp b/qglengine/renderer_base.cpp index a3d6b63..30ce1b0 100644 --- a/qglengine/renderer_base.cpp +++ b/qglengine/renderer_base.cpp @@ -258,7 +258,7 @@ void RendererBase::reloadLightsPositions(Camera * cam) { QGLLightPosition & so(cur_lights_pos_[i]); Light * l = current_lights[i]; 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; dir = ((m * dir) - pos).normalized(); so.position = pos; diff --git a/qglengine/renderer_service.cpp b/qglengine/renderer_service.cpp index b2ee49e..dd94ef3 100644 --- a/qglengine/renderer_service.cpp +++ b/qglengine/renderer_service.cpp @@ -54,8 +54,8 @@ RendererService::RendererService(Renderer * r_): r(r_) { axis_camera->setFOV(45.); axis_mesh = Primitive::arrow(12); size_vp_scale = size_full_scale = 1.; - box_mesh = Primitive::cube(); - box_mesh_f = Primitive::cubeFrame(); + box_mesh = Primitive::cube(0.8, 0.8, 0.8); + box_mesh_f = Primitive::cubeFrame(0.8, 0.8, 0.8); omni_mesh = Primitive::ellipsoid(2, 1); omni_mesh_f = Primitive::ellipsoidFrame(2, 1); 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_f = Primitive::coneFrame(8, 1., 1., 1.); QMatrix4x4 mat; - mat.rotate(90, 0,1,0); - mat.translate(0,0,2); + mat.translate(0,0,1); mat.rotate(180, 1,0,0); cone_mesh ->transformPoints(mat); cone_mesh_f->transformPoints(mat); + cone_mesh_f->scalePoints(1.5); box_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_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() { cur_objects.resize(3); for (int i = 0; i < 3; ++i) { @@ -166,6 +190,32 @@ void RendererService::fillOmniObjects() { } +void RendererService::fillSpotObjects() { + QList 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 & mats, const QVector & colors, QMatrix4x4 add_mat, int count) { QMatrix4x4 m = invariantSizeMatrix(center) * add_mat; cur_objects.resize(count); @@ -196,18 +246,7 @@ bool RendererService::calculateCenter() { } axis_mat = QMatrix4x4(); if ((sol.size() == 1) && (current_action != haMove)) { - ObjectBase * o = 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; + axis_mat = parentRotationMatrix(sol[0]); } return true; } @@ -259,11 +298,50 @@ void RendererService::drawCurrentHandleObjects() { void RendererService::drawLights() { + QGLView * v = r->view; + RendererSelection & rs(r->rend_selection); + fillOmniObjects(); - omni_mesh->loadObjects(r->view, cur_objects); - r->fillSelectionsBuffer(r->rend_selection.cur_selections_, light2objectList(r->view->scene_->lights_used.value(Light::Omni))); - omni_mesh->loadSelections(r->view, r->rend_selection.cur_selections_); - omni_mesh->draw(r->view, cur_objects.size()); + omni_mesh->loadObjects(v, cur_objects); + r->fillSelectionsBuffer(rs.cur_selections_, light2objectList(v->scene_->lights_used.value(Light::Omni))); + omni_mesh->loadSelections(v, rs.cur_selections_); + 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); glDisable(GL_CULL_FACE); r->setUniformCamera(prog, r->view->camera()); - fillOmniObjects(); - setObjectsColor(cur_objects, Qt::white); prog->setUniformValue("line_width", 2.f); prog->setUniformValue("z_offset", 0.f); - omni_mesh_f->loadObjects(f, cur_objects); - omni_mesh_f->draw(f, cur_objects.size()); - - setObjectsColor(cur_objects, Qt::black); + drawLightsFrame(Qt::white); prog->setUniformValue("line_width", 1.f); prog->setUniformValue("z_offset", -1.E-2f); - omni_mesh_f->loadObjects(f, cur_objects); - omni_mesh_f->draw(f, cur_objects.size()); + drawLightsFrame(Qt::black); glEnable(GL_CULL_FACE); //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); diff --git a/qglengine/renderer_service.h b/qglengine/renderer_service.h index 9165cea..9cb3d4e 100644 --- a/qglengine/renderer_service.h +++ b/qglengine/renderer_service.h @@ -66,12 +66,15 @@ public: void resize(int width, int height); QMatrix4x4 invariantSizeMatrix(QVector3D p); + QMatrix4x4 parentRotationMatrix(ObjectBase * o, bool self_rotation = true); void fillXYZObjects(); void fillOmniObjects(); + void fillSpotObjects(); void fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector & mats, const QVector & colors, QMatrix4x4 add_mat, int count = 3); bool calculateCenter(); void drawCurrentHandleObjects(); void drawLights(); + void drawLightsFrame(QColor color); void setObjectsColor(QVector & ol, QColor col); void renderService(); void setCurrentAction(HandleAction ha) {current_action = ha;} @@ -87,7 +90,7 @@ private: QVector3D selection_center; QVector mat_xyz, mat_ms2; QVector color_xyz, color_ms2; - QVector cur_objects; + QVector cur_objects, cur_aims; Camera * axis_camera; QSize axis_viewport; HandleAction current_action; diff --git a/qglengine/shaders/ds_geom.glsl b/qglengine/shaders/ds_geom.glsl index 26a122b..9d4b913 100644 --- a/qglengine/shaders/ds_geom.glsl +++ b/qglengine/shaders/ds_geom.glsl @@ -52,8 +52,8 @@ void main(void) { float height = dot(qgl_materialTexture(QGL_MAP_RELIEF, tc, vec4(0)).rgb, luma); - qgl_FragData[0] = vec4(diffuse .rgb, roughness ); - qgl_FragData[1] = vec4(normal .xyz, reflectivity); + qgl_FragData[0] = vec4(diffuse .rgb, reflectivity); + qgl_FragData[1] = vec4(normal .xyz, roughness ); qgl_FragData[2] = vec4(specular.rgb, height ); qgl_FragData[3] = vec4(emission.rgb, 0/*bn.x*/); //qgl_FragData[4] = vec4(speed.xy, bn.yz); diff --git a/qglengine/shaders/ds_light.glsl b/qglengine/shaders/ds_light.glsl index f07d71a..5601c1b 100644 --- a/qglengine/shaders/ds_light.glsl +++ b/qglengine/shaders/ds_light.glsl @@ -113,8 +113,8 @@ void main(void) { vec3 normal = v1.xyz; vec3 specular = v2.rgb; vec3 emission = v3.rgb; - float roughness = v0.w; - float reflectivity = v1.w; + float reflectivity = v0.w; + float roughness = v1.w; float height = v2.w; //bn = normalize(vec3(v3.w, v4.zw)); //bn2 = normalize(cross(n, bn)); diff --git a/qglengine/shaders/service_frame.glsl b/qglengine/shaders/service_frame.glsl index bdf8fe0..a96d2f0 100644 --- a/qglengine/shaders/service_frame.glsl +++ b/qglengine/shaders/service_frame.glsl @@ -6,7 +6,8 @@ out float mat_scale; void main(void) { gl_Position = qgl_ftransform(); 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); } diff --git a/qglengine/widgets/object_editor.cpp b/qglengine/widgets/object_editor.cpp index ded02f5..4e59825 100644 --- a/qglengine/widgets/object_editor.cpp +++ b/qglengine/widgets/object_editor.cpp @@ -86,9 +86,9 @@ void ObjectEditor::setObject(ObjectBase * o) { ui->spinLightDecayQuadratic->setValue(l->decay_quadratic); ui->spinLightAngleStart->setValue(l->angle_start); ui->spinLightAngleEnd->setValue(l->angle_end); - ui->spinLightDirectionX->setValue(l->direction.x()); - ui->spinLightDirectionY->setValue(l->direction.y()); - ui->spinLightDirectionZ->setValue(l->direction.z()); + ui->spinLightDirectionX->setValue(l->direction().x()); + ui->spinLightDirectionY->setValue(l->direction().y()); + ui->spinLightDirectionZ->setValue(l->direction().z()); } ui->groupCamera->setEnabled(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->angle_start = ui->spinLightAngleStart->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(); } if (object->type() == ObjectBase::glCamera) {