diff --git a/qglview/glcamera.cpp b/qglview/glcamera.cpp index 8bd5ef9..cd298af 100644 --- a/qglview/glcamera.cpp +++ b/qglview/glcamera.cpp @@ -25,8 +25,9 @@ QMatrix4x4 globCameraMatrix; Camera::Camera() { fov_ = 60.; - angle_limit_lower_xy = -180.; - angle_limit_upper_xy = 180.; + angle_limit_lower_xy = 0.; + angle_limit_upper_xy = 360.; + angles_.setY(270.); depth_start = 0.1; depth_end = 1000.; mirror_x = mirror_y = false; @@ -37,7 +38,7 @@ void Camera::anglesFromPoints() { QVector3D dv = aim_ - pos_, tv; tv = QVector3D(dv.x(), dv.y(), 0.); angles_.setZ(atan2(tv.x(), tv.y()) * rad2deg); - angles_.setY(piClamp(atan2(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy)); + angles_.setY(piClamp(atan2(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy) + 180.); } @@ -60,6 +61,7 @@ void Camera::apply(const GLdouble & aspect) { if (parent_) pm *= parent_->worldTransform().inverted(); setGLMatrix(pm); + //qDebug() << angles_; } /* diff --git a/qglview/glframebuffer.cpp b/qglview/glframebuffer.cpp index 6409bad..210ff83 100644 --- a/qglview/glframebuffer.cpp +++ b/qglview/glframebuffer.cpp @@ -103,6 +103,13 @@ void GLFramebuffer::release() { } +void GLFramebuffer::setWriteBuffer(int index) { + //QVector buffers; buffers << GL_COLOR_ATTACHMENT0 + index; + glDrawBuffer(GL_COLOR_ATTACHMENT0 + index); + //glDrawBuffers(buffers.size(), buffers.constData()); +} + + void GLFramebuffer::setWriteBuffers(int indeces[]) { QVector buffers; for (uint i = 0; i < sizeof(indeces); ++i) { diff --git a/qglview/glframebuffer.h b/qglview/glframebuffer.h index a048114..3b1df80 100644 --- a/qglview/glframebuffer.h +++ b/qglview/glframebuffer.h @@ -40,7 +40,7 @@ public: void bind(); void release(); void setReadBuffer(int index) {glReadBuffer(GL_COLOR_ATTACHMENT0 + index);} - void setWriteBuffer(int index) {glDrawBuffer(GL_COLOR_ATTACHMENT0 + index);} + void setWriteBuffer(int index); void setWriteBuffers(int indeces[]); void setWriteBuffers(int * indeces, int count); void setColorFormat(GLenum format) {color_format = format; is_changed = true;} diff --git a/qglview/glmaterial.cpp b/qglview/glmaterial.cpp index bb273c9..e336f51 100644 --- a/qglview/glmaterial.cpp +++ b/qglview/glmaterial.cpp @@ -197,20 +197,21 @@ void Material::apply(QGLShaderProgram * prog) { GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat mat_specular[4] = {0.9f, 0.9f, 0.9f, 1.0f}; GLfloat mat_emission[4] = {0.f, 0.f, 0.f, 1.0f}; - mat_diffuse[0] = color_diffuse.redF(); - mat_diffuse[1] = color_diffuse.greenF(); - mat_diffuse[2] = color_diffuse.blueF(); - mat_diffuse[3] = color_diffuse.alphaF() * (1.f - transparency); + mat_diffuse[0] = map_diffuse.color_amount * color_diffuse.redF(); + mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF(); + mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF(); + mat_diffuse[3] = map_diffuse.color_amount * color_diffuse.alphaF() * (1.f - transparency); 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(); + mat_emission[0] = map_self_illumination.color_amount * color_self_illumination.redF(); + mat_emission[1] = map_self_illumination.color_amount * color_self_illumination.greenF(); + mat_emission[2] = map_self_illumination.color_amount * 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. - map_specularity.color_amount)*100.); + //qDebug() << (map_specularity.color_amount)*128.; + glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount)*128.); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse); } diff --git a/qglview/glrendererbase.cpp b/qglview/glrendererbase.cpp index a2235a5..b06f243 100644 --- a/qglview/glrendererbase.cpp +++ b/qglview/glrendererbase.cpp @@ -153,41 +153,41 @@ void GLRendererBase::applyFilteringParameters() { void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) { - RenderingParameters rp; - rp.pass = pass; - rp.light_pass = light_pass; - rp.shaders = shaders; - rp.textures = textures; - rp.light = rp.prev_light = light; - rp.fog = rp.prev_fog = fog; - rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); - rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); + RenderingParameters rpl; + rpl.pass = pass; + rpl.light_pass = light_pass; + rpl.shaders = shaders; + rpl.textures = textures; + rpl.light = rpl.prev_light = light; + rpl.fog = rpl.prev_fog = fog; + rpl.view_matrix = rp.view_matrix; + rpl.proj_matrix = rp.proj_matrix; //qDebug() << "view:" << rp.view_matrix; - for (int i = 0; i < 32; ++i) rp.prev_tex[i] = 0; - setupTextures(view.objects_, rp, true); - glSetLightEnabled(rp.prev_light); - glSetFogEnabled(rp.prev_fog); - glSetCapEnabled(GL_TEXTURE_2D, rp.textures); + for (int i = 0; i < 32; ++i) rpl.prev_tex[i] = 0; + setupTextures(view.objects_, rpl, true); + glSetLightEnabled(rpl.prev_light); + glSetFogEnabled(rpl.prev_fog); + glSetCapEnabled(GL_TEXTURE_2D, rpl.textures); glSetCapEnabled(GL_BLEND, pass == GLObjectBase::Transparent); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_CUBE_MAP); glPushMatrix(); - renderSingleObject(view.objects_, rp); + renderSingleObject(view.objects_, rpl); glPopMatrix(); } -void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rp) { +void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rpl) { if (!o.isInit()) o.init(); if (!o.isTexturesLoaded()) o.loadTextures(); if (!o.visible_) return; - if (rp.pass == o.pass_) { + if (rpl.pass == o.pass_) { Material & mat(o.material_); - QMatrix4x4 curview = rp.view_matrix * o.itransform_; - setupTextures(o, rp, false); - mat.apply((QGLShaderProgram*)rp.shaders); + QMatrix4x4 curview = rpl.view_matrix * o.itransform_; + setupTextures(o, rpl, false); + mat.apply((QGLShaderProgram*)rpl.shaders); glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL)); glLineWidth(o.line_width > 0. ? o.line_width : view.lineWidth_); glPointSize(o.line_width > 0. ? o.line_width : view.lineWidth_); @@ -199,7 +199,7 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & if (!mat.map_reflection.isEmpty()) mat.map_reflection.bind(); else glDisable(GL_TEXTURE_CUBE_MAP); } else glDisable(GL_TEXTURE_CUBE_MAP); - if (rp.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP); + if (rpl.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP); GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity}; glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); @@ -213,15 +213,46 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & glMatrixMode(GL_MODELVIEW); glActiveTextureChannel(0); } - if (rp.shaders) { + if (rpl.shaders) { //qDebug() << o.name() << curview << curview.determinant(); - setUniformMatrices((QGLShaderProgram*)rp.shaders, rp.proj_matrix, curview); + setUniformMatrices((QGLShaderProgram*)rpl.shaders, rpl.proj_matrix, curview); } else { glMatrixMode(GL_MODELVIEW); setGLMatrix(curview); } - o.draw((QGLShaderProgram*)rp.shaders); + o.draw((QGLShaderProgram*)rpl.shaders); } foreach (GLObjectBase * i, o.children_) - renderSingleObject(*i, rp); + renderSingleObject(*i, rpl); +} + + + + +void GLRendererBase::RenderingParameters::prepare() { + proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); + view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); + viewproj_matrix = proj_matrix * view_matrix; + normal_matrix = view_matrix.normalMatrix(); + proj_matrix_i = proj_matrix.inverted(); + view_matrix_i = view_matrix.inverted(); + viewproj_matrix_i = viewproj_matrix.inverted(); +} + + +void GLRendererBase::RenderingParameters::setUniform(QGLShaderProgram * prog) { + if (!prog) return; + prog->setUniformValue("qgl_ModelViewMatrix", view_matrix); + prog->setUniformValue("qgl_ProjectionMatrix", proj_matrix); + prog->setUniformValue("qgl_ModelViewProjectionMatrix", viewproj_matrix); + prog->setUniformValue("qgl_NormalMatrix", normal_matrix); + prog->setUniformValue("qgl_ModelViewMatrixInverse", view_matrix_i); + prog->setUniformValue("qgl_ProjectionMatrixInverse", proj_matrix_i); + prog->setUniformValue("qgl_ModelViewProjectionMatrixInverse", viewproj_matrix_i); + prog->setUniformValue("qgl_ModelViewMatrixTranspose", view_matrix.transposed()); + prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj_matrix.transposed()); + prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", viewproj_matrix.transposed()); + prog->setUniformValue("qgl_ModelViewMatrixInverseTranspose", view_matrix_i.transposed()); + prog->setUniformValue("qgl_ProjectionMatrixInverseTranspose", proj_matrix_i.transposed()); + prog->setUniformValue("qgl_ModelViewProjectionMatrixInverseTranspose", viewproj_matrix_i.transposed()); } diff --git a/qglview/glrendererbase.h b/qglview/glrendererbase.h index 09b4583..b94630c 100644 --- a/qglview/glrendererbase.h +++ b/qglview/glrendererbase.h @@ -28,10 +28,13 @@ class GLRendererBase: public QObject Q_OBJECT public: GLRendererBase(QGLView * view_); + virtual void prepareScene() {;} virtual void renderScene() = 0; protected: struct RenderingParameters { + void prepare(); + void setUniform(QGLShaderProgram * prog); int pass; int light_pass; bool light; @@ -41,8 +44,10 @@ protected: bool prev_fog; GLuint prev_tex[32]; void * shaders; - QMatrix4x4 view_matrix; - QMatrix4x4 proj_matrix; + QMatrix4x4 view_matrix, view_matrix_i; + QMatrix4x4 proj_matrix, proj_matrix_i; + QMatrix4x4 viewproj_matrix, viewproj_matrix_i; + QMatrix3x3 normal_matrix; QGLShaderProgram * cur_shader; }; @@ -58,8 +63,9 @@ protected: void setupLights(int pass, int lights_per_pass); inline void applyFilteringParameters(); void renderObjects(int pass, int light_pass, void * shaders = 0, bool textures = true, bool light = true, bool fog = true); - void renderSingleObject(GLObjectBase & o, RenderingParameters & rp); + void renderSingleObject(GLObjectBase & o, RenderingParameters & rpl); + RenderingParameters rp; QGLView & view; QImage white_image, violent_image; GLuint white_image_id, violent_image_id; diff --git a/qglview/glshaders.cpp b/qglview/glshaders.cpp index dbba681..18b1d83 100644 --- a/qglview/glshaders.cpp +++ b/qglview/glshaders.cpp @@ -133,7 +133,7 @@ bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & loadShaderFile(prog, QGLShader::Fragment, i.absoluteFilePath()); } if (!prog->link()) { - //qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log(); + qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log(); return false; } return true; diff --git a/qglview/gltypes.cpp b/qglview/gltypes.cpp index c1dc954..2b61fb2 100644 --- a/qglview/gltypes.cpp +++ b/qglview/gltypes.cpp @@ -51,15 +51,19 @@ QString findFile(const QString & file, const QStringList & pathes) { } -void glDrawQuad(GLfloat x, GLfloat y, GLfloat w, GLfloat h) { +void glDrawQuad(QGLShaderProgram * prog, GLfloat x, GLfloat y, GLfloat w, GLfloat h) { glResetAllTransforms(); glSetPolygonMode(GL_FILL); + int loc = prog ? prog->attributeLocation("qgl_Color") : 0, + locv = prog ? prog->attributeLocation("qgl_Vertex") : 0, + loct = prog ? prog->attributeLocation("qgl_Texture") : 0; + //locc = prog ? prog->attributeLocation("view_corner") : 0; glBegin(GL_QUADS); - glColor3f(1.f, 1.f, 1.f); - glTexCoord2f(0.f, 0.f); glVertex2f(x, y); - glTexCoord2f(1.f, 0.f); glVertex2f(x + w, y); - glTexCoord2f(1.f, 1.f); glVertex2f(x + w, y + h); - glTexCoord2f(0.f, 1.f); glVertex2f(x, y + h); + if (prog) glVertexAttrib3f(loc, 1.f, 1.f, 1.f); glColor3f(1.f, 1.f, 1.f); + if (prog) {/*prog->setAttributeValue(locc, corner_dirs[0]);*/ glVertexAttrib2f(loct, 0.f, 0.f); glVertexAttrib2f(locv, x, y);} glTexCoord2f(0.f, 0.f); glVertex2f(x, y); + if (prog) {/*prog->setAttributeValue(locc, corner_dirs[1]);*/ glVertexAttrib2f(loct, 1.f, 0.f); glVertexAttrib2f(locv, x + w, y);} glTexCoord2f(1.f, 0.f); glVertex2f(x + w, y); + if (prog) {/*prog->setAttributeValue(locc, corner_dirs[2]);*/ glVertexAttrib2f(loct, 1.f, 1.f); glVertexAttrib2f(locv, x + w, y + h);} glTexCoord2f(1.f, 1.f); glVertex2f(x + w, y + h); + if (prog) {/*prog->setAttributeValue(locc, corner_dirs[3]);*/ glVertexAttrib2f(loct, 0.f, 1.f); glVertexAttrib2f(locv, x, y + h);} glTexCoord2f(0.f, 1.f); glVertex2f(x, y + h); glEnd(); } diff --git a/qglview/gltypes.h b/qglview/gltypes.h index 8e8e60a..16a25af 100644 --- a/qglview/gltypes.h +++ b/qglview/gltypes.h @@ -155,7 +155,7 @@ inline void glSetCapEnabled(GLenum cap, bool on = true) {if (on) glEnable(cap); inline void glSetLightEnabled(bool on) {if (on) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);} inline void glSetFogEnabled(bool on) {if (on) glEnable(GL_FOG); else glDisable(GL_FOG);} inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);} -void glDrawQuad(GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f); +void glDrawQuad(QGLShaderProgram * prog = 0, GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f); QMatrix4x4 getGLMatrix(GLenum matrix); void setGLMatrix(QMatrix4x4 matrix); inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;} diff --git a/qglview/glvbo.cpp b/qglview/glvbo.cpp index 35032c9..ce35e6b 100644 --- a/qglview/glvbo.cpp +++ b/qglview/glvbo.cpp @@ -184,17 +184,15 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) { if (!simplest) { if (has_normals) { glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, offset); - offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat)); + glNormalPointer(GL_FLOAT, 0, offsets[0]); } else glDisableClientState(GL_NORMAL_ARRAY); if (has_texcoords) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, offset); - offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat)); + glTexCoordPointer(2, GL_FLOAT, 0, offsets[1]); } else glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (has_colors) { glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, 0, offset); + glColorPointer(4, GL_FLOAT, 0, offsets[2]); } else glDisableClientState(GL_COLOR_ARRAY); } } diff --git a/qglview/mainwindow.cpp b/qglview/mainwindow.cpp index b8cff43..9abc689 100644 --- a/qglview/mainwindow.cpp +++ b/qglview/mainwindow.cpp @@ -30,14 +30,19 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow() colorHalo->setColor(view->selectionHaloColor()); sel_obj = 0; - treeProperties->assignObject(view); //spinSliderShine->setDecimals(2); view->setFrameShape(QFrame::NoFrame); //view->setRenderer(new RendererDeferredShading(view)); - view->setRenderer(new RendererDeferredShading(view)); - view->setMouseSelectionEnabled(false); + view->setRenderer(new RendererSimple(view)); view->setMouseRotateEnabled(true); + view->setMouseSelectionEnabled(true); + view->setSelectionHaloEnabled(true); + view->setHoverHaloEnabled(true); + view->setHoverHaloFillAlpha(0.); + view->setSelectionHaloFillAlpha(0.); view->setBackColor(Qt::lightGray); + view->setDepthStart(1.); + view->setDepthEnd(10000.); //view->setLightingMode(QGLView::PerPixel); /*MaterialEditor * o = new MaterialEditor(); o->setWindowOpacity(.666); @@ -65,12 +70,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/earth.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube(); + obj = loadFromDAEFile("data/lights_r.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube(); obj->setScale(0.1); + //obj->child("Plane001")->material().map_specularity.color_amount = 0.95; //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.; + if (obj->child(i)->type() == GLObjectBase::Light) { + ((Light*)obj->child(i))->intensity = 1.5; + ((Light*)obj->child(i))->decay_linear = .5; + } view->addObject(obj); //obj->child("Box001")->addChild(&(view->camera())); //view->camera().flyToDistance(30); @@ -94,11 +102,9 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow() view->camera().setAim(QVector3D()); 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.5; + l->decay_linear = 0.2; l->setName("camera"); view->addObject(l); view->start(-1); @@ -147,6 +153,7 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow() startTimer(1000/60); //connect(view, SIGNAL(hoverChanged(GLObjectBase*,GLObjectBase*)), this, SLOT(hoverChanged(GLObjectBase*,GLObjectBase*))); + treeProperties->assignObject(view); connect(view, SIGNAL(selectionChanged(GLObjectBase*,GLObjectBase*)), this, SLOT(selectionChanged(GLObjectBase*,GLObjectBase*))); connect(view, SIGNAL(glInitializeDone()), this, SLOT(glInit())); connect(matEditor, SIGNAL(changed()), this, SLOT(materialChanged())); diff --git a/qglview/propertyeditor.cpp b/qglview/propertyeditor.cpp index 22c7917..f51c63f 100644 --- a/qglview/propertyeditor.cpp +++ b/qglview/propertyeditor.cpp @@ -12,7 +12,7 @@ QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & inde //QMetaProperty prop = index.parent().data(Qt::UserRole + 1).value(); w = new QCheckBox(parent); type = 14; ((QCheckBox*)w)->setChecked(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0)); ((QCheckBox*)w)->setText("0x" + QString::number(key, 16).toUpper()); - connect((QCheckBox*)w, SIGNAL(toggled(bool)), this, SLOT(changedFlag())); + connect((QCheckBox*)w, SIGNAL(clicked(bool)), this, SLOT(changedFlag())); //qDebug() << prop.enumerator().name(); } else { if (value.canConvert()) { @@ -273,6 +273,7 @@ void Delegate::changedFlag() { PropertyEditor::PropertyEditor(QWidget * parent): QTreeWidget(parent) { object = 0; + active_ = false; configTree(); connect(this, SIGNAL(itemClicked(QTreeWidgetItem * , int)), this, SLOT(itemClicked(QTreeWidgetItem * , int))); connect(this, SIGNAL(itemChanged(QTreeWidgetItem * , int)), this, SLOT(itemChanged(QTreeWidgetItem * , int))); @@ -319,6 +320,7 @@ void PropertyEditor::itemClicked(QTreeWidgetItem * item, int column) { void PropertyEditor::itemChanged(QTreeWidgetItem * item, int column) { + if (!active_) return; if (column != 1) return; QVariant value = item->data(1, Qt::UserRole); if (value.canConvert()) { @@ -332,6 +334,7 @@ void PropertyEditor::rebuild() { clear(); configTree(); if (object == 0) return; + active_ = false; const QMetaObject * mo = object->metaObject(); QList mol; while (mo != 0) { @@ -396,6 +399,7 @@ void PropertyEditor::rebuild() { chue += 60; chue %= 360; } + active_ = true; } diff --git a/qglview/propertyeditor.h b/qglview/propertyeditor.h index d3491d6..6b26b2c 100644 --- a/qglview/propertyeditor.h +++ b/qglview/propertyeditor.h @@ -66,6 +66,7 @@ private: QObject * object; QFont font_b; QList props; + bool active_; private slots: void itemClicked(QTreeWidgetItem * item, int column); diff --git a/qglview/qglview.cpp b/qglview/qglview.cpp index 7d4624e..a0e9ba4 100644 --- a/qglview/qglview.cpp +++ b/qglview/qglview.cpp @@ -242,14 +242,14 @@ void QGLView::paintGL() { } //if (so != 0) qDebug() << sel_obj->name() << cgid[3]; } - if (hoverHalo_) { - fbo_selection.setWriteBuffer(1); - renderHalo(so, iid, hoverHaloColor_, hoverHaloFill_); - } - if (selectionHalo_) { + if (selectionHalo_ && sel_obj) { fbo_selection.setWriteBuffer(2); renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_); } + if (hoverHalo_ && hov_obj) { + fbo_selection.setWriteBuffer(1); + renderHalo(hov_obj, iid, hoverHaloColor_, hoverHaloFill_); + } fbo_selection.release(); glEnableDepth(); glEnableClientState(GL_NORMAL_ARRAY); @@ -269,7 +269,11 @@ void QGLView::paintGL() { } } emit glBeginPaint(); - if (renderer_ != 0) renderer_->renderScene(); + if (renderer_ != 0) { + renderer_->rp.prepare(); + renderer_->prepareScene(); + renderer_->renderScene(); + } if (selectionHalo_ || hoverHalo_) { glReleaseTextures(); glReleaseShaders(); @@ -281,12 +285,14 @@ void QGLView::paintGL() { glDisable(GL_LIGHTING); glDisableDepth(); glBlendFunc(GL_SRC_ALPHA, GL_ONE); - if (selectionHalo_) { + if (selectionHalo_ && sel_obj) { glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2)); + //qDebug() << "draw sel"; glDrawQuad(); } - if (hoverHalo_) { + if (hoverHalo_ && hov_obj) { glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(1)); + //qDebug() << "draw hover"; glDrawQuad(); } } @@ -346,12 +352,11 @@ void QGLView::paintGL() { void QGLView::renderHalo(const GLObjectBase * obj, const int iid, const QColor & color, const double & fill) { if (!shaders_supported) return; - if (obj == 0) { - glClearFramebuffer(Qt::black, false); - } else { + if (obj) { + shader_halo->bind(); + shader_halo->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4()); glActiveTextureChannel(0); glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture()); - shader_halo->bind(); shader_halo->setUniformValue("t0", 0); shader_halo->setUniformValue("dt", QVector2D(1. / viewport()->width(), 1. / viewport()->height())); shader_halo->setUniformValue("selected", QVector4D(float((iid >> 24) & 0xFF) / 255.f, @@ -360,11 +365,14 @@ void QGLView::renderHalo(const GLObjectBase * obj, const int iid, const QColor & float(iid & 0xFF) / 255.f)); shader_halo->setUniformValue("color", color); shader_halo->setUniformValue("fill", GLfloat(fill)); - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glDrawQuad(); + //qDebug() << "render halo" << iid << shader_halo->log() << shader_halo->programId(); + glDisableDepth(); + glDrawQuad(shader_halo); glDepthMask(GL_TRUE); + //glFlush(); shader_halo->release(); + } else { + glClearFramebuffer(Qt::black, false); } } @@ -609,6 +617,12 @@ void QGLView::wheelEvent(QWheelEvent * e) { } +void QGLView::leaveEvent(QEvent * ) { + lastPos = QPoint(-1, -1); + //qDebug() << lastPos; +} + + void QGLView::processKeys() { if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return; Qt::KeyboardModifiers km = QApplication::keyboardModifiers(); diff --git a/qglview/qglview.h b/qglview/qglview.h index 6a9c4cc..1bfc562 100644 --- a/qglview/qglview.h +++ b/qglview/qglview.h @@ -205,6 +205,7 @@ protected: virtual void mouseMoveEvent(QMouseEvent * e); virtual void mouseReleaseEvent(QMouseEvent * e); virtual void wheelEvent(QWheelEvent * e); + virtual void leaveEvent(QEvent * ); virtual void keyPressEvent(QKeyEvent * e) {emit glKeyPressEvent(e); if (e->key() > 0) keys_.insert(e->key());} virtual void keyReleaseEvent(QKeyEvent * e) {emit glKeyReleaseEvent(e); keys_.remove(e->key());} virtual void focusOutEvent(QFocusEvent *) {keys_.clear();} diff --git a/qglview/renderer_deferred_shading.cpp b/qglview/renderer_deferred_shading.cpp index 9c8ee8d..e8be085 100644 --- a/qglview/renderer_deferred_shading.cpp +++ b/qglview/renderer_deferred_shading.cpp @@ -19,26 +19,22 @@ #include "renderer_deferred_shading.h" -RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo(6, true, GL_RGBA16F) { +RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo_g(4, true, GL_RGBA16F), fbo_out(2, GL_RGBA16F) { shader_fxaa = shader_ds_0 = shader_ds_1 = 0; } void RendererDeferredShading::renderScene() { - prepareUniform(); - QMatrix4x4 view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); - QMatrix4x4 proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); - QMatrix4x4 viewprojinv = (proj_matrix * view_matrix).inverted(); - corner_dirs[0] = (QVector4D(-1, -1, 1, 1) * viewprojinv).normalized(); - corner_dirs[1] = (QVector4D( 1, -1, 1, 1) * viewprojinv).normalized(); - corner_dirs[2] = (QVector4D( 1, 1, 1, 1) * viewprojinv).normalized(); - corner_dirs[3] = (QVector4D(-1, 1, 1, 1) * viewprojinv).normalized(); + QMatrix4x4 mproji = rp.proj_matrix_i; + QMatrix4x4 mview = rp.view_matrix; + corner_dirs[0] = (QVector4D(-1, -1, 1, 1) * rp.viewproj_matrix).normalized(); + corner_dirs[1] = (QVector4D( 1, -1, 1, 1) * rp.viewproj_matrix).normalized(); + corner_dirs[2] = (QVector4D( 1, 1, 1, 1) * rp.viewproj_matrix).normalized(); + corner_dirs[3] = (QVector4D(-1, 1, 1, 1) * rp.viewproj_matrix).normalized(); //qDebug() << corner_dirs[0] << corner_dirs[1] << corner_dirs[2] << corner_dirs[3]; - int passes = (view.lightsCount() - 1) / 8 + 1; - if (passes < 1) passes = 1; - fbo.bind(); + fbo_g.bind(); int buffs[] = {0, 1, 2, 3}; - fbo.setWriteBuffers(buffs); + fbo_g.setWriteBuffers(buffs); if (white_image_id == 0) { glActiveTextureChannel(6); white_image_id = ((GLTextureManagerBase*)currentGLTextureManager)->loadTexture(white_image, false); @@ -55,7 +51,7 @@ void RendererDeferredShading::renderScene() { //glEnable(GL_TEXTURE_2D); glEnableDepth(); shader_ds_0->bind(); - setUniform(shader_ds_0); + rp.setUniform(shader_ds_0); shader_ds_0->setUniformValue("z_far", GLfloat(view.depthEnd())); shader_ds_0->setUniformValue("z_near", GLfloat(view.depthStart())); shader_ds_0->setUniformValue("t0", 0); @@ -68,13 +64,14 @@ void RendererDeferredShading::renderScene() { //fbo.release(); glResetAllTransforms(); - prepareUniform(); + rp.prepare(); glSetLightEnabled(false); glDisable(GL_BLEND); //glBlendFunc(GL_ONE, GL_ONE); glDisableDepth(); shader_ds_1->bind(); - setUniform(shader_ds_1); + rp.setUniform(shader_ds_1); + //qDebug() << rp.view_matrix; shader_ds_1->setUniformValue("z_far", GLfloat(view.depthEnd())); shader_ds_1->setUniformValue("z_near", GLfloat(view.depthStart())); shader_ds_1->setUniformValue("t0", 0); @@ -83,28 +80,37 @@ void RendererDeferredShading::renderScene() { shader_ds_1->setUniformValue("t3", 3); shader_ds_1->setUniformValue("td", 4); shader_ds_1->setUniformValue("back_color", view.backColor()); - shader_ds_1->setUniformValue("mat_proji", proj_matrix.inverted()); + shader_ds_1->setUniformValue("mat_proji", mproji); shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height())); - fbo.setWriteBuffer(4); - fbo.bindColorTextures(); - fbo.bindDepthTexture(4); + fbo_g.bindColorTextures(); + fbo_g.bindDepthTexture(4); + fbo_out.bind(); + fbo_out.setWriteBuffer(0); glClearFramebuffer(Qt::black, false); //QVector lpos; //qDebug() << view_matrix; + int passes = (view.lightsCount() - 1) / 16 + 1; + if (passes < 1) passes = 1; + shader_ds_1->setUniformValue("t_pp", 5); + //qDebug() << "render in" << passes << "passes"; for (int l = 0; l < passes; ++l) { - fbo.setWriteBuffer(5 - l % 2); - shader_ds_1->setUniformValue("tb", 4 + l % 2); - setupDSLights(l, 16, view_matrix); + int wi = 1 - l % 2, ri = l % 2; + //qDebug() << " pass" << l << "read from" << ri << "write to" << wi; + glActiveTextureChannel(5); + glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri)); + fbo_out.setWriteBuffer(wi); + setupDSLights(l, 16, mview); //shader_ds_1->setUniformValue("lightsCount", cplc); - drawFB(shader_ds_1); + glDrawQuad(shader_ds_1); //renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled()); //renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled()); - glFlush(); + glFinish(); + //break; } - fbo.release(); + fbo_out.release(); glReleaseShaders(); glActiveTextureChannel(0); - glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(4 + passes % 2)); + glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(passes % 2)); if (view.isFXAAEnabled()) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -120,6 +126,18 @@ void RendererDeferredShading::renderScene() { } +void RendererDeferredShading::init(int width, int height) { + fbo_g.resize(width, height); + fbo_out.resize(width, height); +} + + +void RendererDeferredShading::resize(int width, int height) { + fbo_g.resize(width, height); + fbo_out.resize(width, height); +} + + void RendererDeferredShading::reloadShaders() { if (shader_fxaa == 0) shader_fxaa = new QGLShaderProgram(view.context()); if (shader_ds_0 == 0) shader_ds_0 = new QGLShaderProgram(view.context()); @@ -148,7 +166,7 @@ void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const int light_start, light_end, lmax; light_start = pass * lights_per_pass; light_end = qMin((pass + 1) * lights_per_pass, view.lights().size()); - lmax = light_start + 8; + lmax = light_start + lights_per_pass; amb_light.intensity = (pass == 0 ? 1. : 0.); amb_light.setColor(pass == 0 ? view.ambientColor() : Qt::black); amb_light.setName("ambient"); @@ -160,6 +178,8 @@ 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; + //QStringList lnl; foreach (Light * l, lv) lnl << l->name(); + //qDebug() << " lights" << light_start << "->" << light_end << ", inactive" << (lmax - light_end) << lnl; setUniformLights(shader_ds_1, lv, view_matrix, view.camera().pos()); } @@ -167,49 +187,3 @@ void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const void RendererDeferredShading::setupAmbientLight(const QColor & a, bool first_pass) { } - - -void RendererDeferredShading::prepareUniform() { - pm = getGLMatrix(GL_PROJECTION_MATRIX); - mvm = getGLMatrix(GL_MODELVIEW_MATRIX); - mvpm = pm * mvm; - pim = pm.inverted(); - mvim = mvm.inverted(); - mvpim = mvpm.inverted(); - nm = mvm.normalMatrix(); -} - - -void RendererDeferredShading::setUniform(QGLShaderProgram * prog) { - //qDebug() << mvm; - prog->setUniformValue("qgl_ModelViewMatrix", mvm); - prog->setUniformValue("qgl_ProjectionMatrix", pm); - prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm); - prog->setUniformValue("qgl_NormalMatrix", nm); - prog->setUniformValue("qgl_ModelViewMatrixInverse", mvim); - prog->setUniformValue("qgl_ProjectionMatrixInverse", pim); - prog->setUniformValue("qgl_ModelViewProjectionMatrixInverse", mvpim); - prog->setUniformValue("qgl_ModelViewMatrixTranspose", mvm.transposed()); - prog->setUniformValue("qgl_ProjectionMatrixTranspose", pm.transposed()); - prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed()); - prog->setUniformValue("qgl_ModelViewMatrixInverseTranspose", mvim.transposed()); - prog->setUniformValue("qgl_ProjectionMatrixInverseTranspose", pim.transposed()); - prog->setUniformValue("qgl_ModelViewProjectionMatrixInverseTranspose", mvpim.transposed()); -} - - -void RendererDeferredShading::drawFB(QGLShaderProgram * prog) { - glSetPolygonMode(GL_FILL); - int loc = prog->attributeLocation("qgl_Color"); - glVertexAttrib3f(loc, 1.f, 1.f, 1.f); - int locv = prog->attributeLocation("qgl_Vertex"), - loct = prog->attributeLocation("qgl_Texture"), - locc = prog->attributeLocation("view_corner"); - glBegin(GL_QUADS); - glColor3f(1.f, 1.f, 1.f); - prog->setAttributeValue(locc, corner_dirs[0]); glVertexAttrib2f(loct, 0.f, 0.f); glTexCoord2f(0.f, 0.f); glVertexAttrib2f(locv, -1.f, -1.f); glVertex2f(-1.f, -1.f); - prog->setAttributeValue(locc, corner_dirs[1]); glVertexAttrib2f(loct, 1.f, 0.f); glTexCoord2f(1.f, 0.f); glVertexAttrib2f(locv, 1.f, -1.f); glVertex2f(1.f, -1.f); - prog->setAttributeValue(locc, corner_dirs[2]); glVertexAttrib2f(loct, 1.f, 1.f); glTexCoord2f(1.f, 1.f); glVertexAttrib2f(locv, 1.f, 1.f); glVertex2f(1.f, 1.f); - prog->setAttributeValue(locc, corner_dirs[3]); glVertexAttrib2f(loct, 0.f, 1.f); glTexCoord2f(0.f, 1.f); glVertexAttrib2f(locv, -1.f, 1.f); glVertex2f(-1.f, 1.f); - glEnd(); -} diff --git a/qglview/renderer_deferred_shading.h b/qglview/renderer_deferred_shading.h index 2b98c0d..59d407a 100644 --- a/qglview/renderer_deferred_shading.h +++ b/qglview/renderer_deferred_shading.h @@ -30,21 +30,17 @@ public: virtual void renderScene(); protected: - void init(int width, int height) {fbo.resize(width, height);} - void resize(int width, int height) {fbo.resize(width, height);} + void init(int width, int height); + void resize(int width, int height); void reloadShaders(); void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp); void setupShadersLights(int lights_count) {cplc = lights_count;} void setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix); void setupAmbientLight(const QColor & a, bool first_pass); - void prepareUniform(); - void setUniform(QGLShaderProgram * prog); - void drawFB(QGLShaderProgram * prog); - private: int cplc; - GLFramebuffer fbo; + GLFramebuffer fbo_g, fbo_out; QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1; QMatrix4x4 pm, mvm, mvpm, pim, mvim, mvpim; diff --git a/qglview/renderer_simple.cpp b/qglview/renderer_simple.cpp index 5b026df..4b87925 100644 --- a/qglview/renderer_simple.cpp +++ b/qglview/renderer_simple.cpp @@ -70,10 +70,11 @@ void RendererSimple::renderScene() { glDepthFunc(GL_EQUAL); } view.camera().apply(view.aspect); + rp.prepare(); setupLights(l, 8); - fbo_c.bind(); + /*fbo_c.bind(); glClearFramebuffer(); //shader->bind(); /// WARNING renderObjects(GLObjectBase::Solid, l, 0, true, view.isLightEnabled(), view.isFogEnabled()); @@ -84,7 +85,8 @@ void RendererSimple::renderScene() { glReadPixels(mpos.x(), fbo_c.height() - mpos.y(), 1, 1, GL_RGBA, GL_FLOAT, data); //qDebug() << QVector3D(data[0], data[1], data[2]); } - fbo_c.release(); + fbo_c.release();*/ + //qDebug() << rp.viewproj_matrix << (getGLMatrix(GL_PROJECTION_MATRIX)*getGLMatrix(GL_MODELVIEW_MATRIX)); renderObjects(GLObjectBase::Solid, l, 0, true, view.isLightEnabled(), view.isFogEnabled()); diff --git a/qglview/shaders/dsl_pass_1.frag b/qglview/shaders/dsl_pass_1.frag index 0b5eabb..70d2473 100644 --- a/qglview/shaders/dsl_pass_1.frag +++ b/qglview/shaders/dsl_pass_1.frag @@ -4,7 +4,7 @@ in vec4 view_dir, view_pos; uniform vec3 ambient; -uniform sampler2D t0, t1, t2, t3, tb; +uniform sampler2D t0, t1, t2, t3, t_pp; uniform sampler2D td; uniform int gid, lightsCount; uniform float z_near, z_far; @@ -81,8 +81,8 @@ void main(void) { vec3 v = normalize(-pos.xyz); sh_pow = 1. / max((1. - v1.w), 0.0001); sh_mul = max(1. - v1.w, 0.0001); - for (int i = 0; i < 16; ++i) - calcLight(i, n, v, v2); + //for (int i = 0; i < 16; ++i) + calcLight(7, n, v, v2); /*if (lightsCount > 0) { calcLight(0, n, v, v2); if (lightsCount > 1) { @@ -107,9 +107,9 @@ void main(void) { } } }*/ - qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb;// + texture2D(tb, tc).rgb; + qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb + texture2D(t_pp, 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].rgb = texture2D(t_pp, tc).rgb; + //qgl_FragData[0].rgb = vec3(pow(NdotH,100)*2); //qgl_FragData[0].a = 0.; } diff --git a/qglview/shaders/selection_halo.frag b/qglview/shaders/selection_halo.frag index 74d81f7..9ae4416 100644 --- a/qglview/shaders/selection_halo.frag +++ b/qglview/shaders/selection_halo.frag @@ -15,5 +15,6 @@ void main(void) { float vs = step(1e-6, d0 + d1 + d2 + d3); float vm = step(1e-3, (d0 * 255.) * (d1 * 255.) * (d2 * 255.) * (d3 * 255.)); float v = mix(vs - vm, vs - vm - vm + 1, fill); + //qgl_FragData[0] = vec4(1,0,0,0.5);//vec4(color.rgb, v * color.a); qgl_FragData[0] = vec4(color.rgb, v * color.a); }