diff --git a/cmake/FindQGLEngine.cmake b/cmake/FindQGLEngine.cmake index 7c070fc..5ad76fd 100644 --- a/cmake/FindQGLEngine.cmake +++ b/cmake/FindQGLEngine.cmake @@ -11,6 +11,7 @@ These targets include directories and dependencies cmake_policy(SET CMP0011 NEW) # don`t affect includer policies cmake_policy(SET CMP0020 NEW) # Automatically link Qt executables to qtmain target on Windows +find_package(PIP REQUIRED) find_package(QAD REQUIRED) include(QtWraps) include(SHSTKMacros) @@ -38,7 +39,7 @@ foreach (_l ${__libs}) set(__libs_${_l} "") endforeach() -set(__deps_core "QAD::Widgets") +set(__deps_core "QAD::Widgets;QAD::PIQtUtils") set(__deps_widgets "QGLEngine::Core") #message("find QGLEngine ${BUILDING_QGLEngine}") diff --git a/shaders/ds_geom.glsl b/shaders/ds_geom.glsl index 42e82c3..cfec31e 100644 --- a/shaders/ds_geom.glsl +++ b/shaders/ds_geom.glsl @@ -32,6 +32,10 @@ void main(void) { vec4 diffuse = qgl_materialTexture(QGL_MAP_DIFFUSE, tc, vec4(0)) * object_color; diffuse.rgb *= qgl_material[qgl_MaterialIndex].color_diffuse.rgb; +#ifdef SOLID + if(diffuse.a < 0.5) + discard; +#endif diffuse.a *= (1.f - qgl_material[qgl_MaterialIndex].transparency); vec3 normal, dn; diff --git a/src/core/core/glmaterial.cpp b/src/core/core/glmaterial.cpp index 8bf10e8..968aaf9 100644 --- a/src/core/core/glmaterial.cpp +++ b/src/core/core/glmaterial.cpp @@ -29,9 +29,6 @@ Map::Map() { color_offset = 0.f; bitmap_scale = QPointF(1., 1.); use_bitmap = false; - invert_R = false; - invert_G = false; - invert_B = false; _changed = true; _layer = 0; } @@ -145,3 +142,8 @@ void Material::detectMaps() { map_emission.use_bitmap = !map_emission.bitmap_path.isEmpty(); map_relief.use_bitmap = !map_relief.bitmap_path.isEmpty(); } + + +uint MapBakeOptions::hash() const { + return qHash((uint)invert_R + ((uint)invert_G << 1) + ((uint)invert_B << 2)); +} diff --git a/src/core/core/glmaterial.h b/src/core/core/glmaterial.h index 27ed4fb..b3823f9 100644 --- a/src/core/core/glmaterial.h +++ b/src/core/core/glmaterial.h @@ -23,6 +23,14 @@ #include "glshaders_types.h" +struct QGLENGINE_CORE_EXPORT MapBakeOptions { + uint hash() const; + bool invert_R = false; + bool invert_G = false; + bool invert_B = false; +}; + + class QGLENGINE_CORE_EXPORT Map { public: Map(); @@ -38,7 +46,7 @@ public: float color_amount; float color_offset; bool use_bitmap; - bool invert_R, invert_G, invert_B; + MapBakeOptions bake_options; bool _changed; int _type, _layer; @@ -74,6 +82,20 @@ public: }; +inline QDataStream & operator<<(QDataStream & s, const MapBakeOptions & m) { + ChunkStream cs; + cs.add(1, m.invert_R).add(2, m.invert_G).add(3, m.invert_B); + s << cs.data(); + return s; +} +inline QDataStream & operator>>(QDataStream & s, MapBakeOptions & m) { + ChunkStream cs(s); + cs.readAll(); + cs.get(1, m.invert_R).get(2, m.invert_G).get(3, m.invert_B); + return s; +} + + inline QDataStream & operator<<(QDataStream & s, const Map & m) { ChunkStream cs; cs.add(1, m.bitmap_path) @@ -81,9 +103,7 @@ inline QDataStream & operator<<(QDataStream & s, const Map & m) { .add(3, m.color_offset) .add(6, m.bitmap_scale) .add(7, m.use_bitmap) - .add(8, m.invert_R) - .add(9, m.invert_G) - .add(10, m.invert_B); + .add(11, m.bake_options); s << cs.data(); return s; } @@ -95,9 +115,7 @@ inline QDataStream & operator>>(QDataStream & s, Map & m) { .get(3, m.color_offset) .get(6, m.bitmap_scale) .get(7, m.use_bitmap) - .get(8, m.invert_R) - .get(9, m.invert_G) - .get(10, m.invert_B); + .get(11, m.bake_options); return s; } diff --git a/src/core/mouse_controller.cpp b/src/core/mouse_controller.cpp index f747928..c6c636f 100644 --- a/src/core/mouse_controller.cpp +++ b/src/core/mouse_controller.cpp @@ -144,7 +144,7 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) { mouse_vector[1] *= -1.; if (cur_action == RendererService::haMove) { double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length(); - mouse_vector /= QVector3D(view->width(), view->height(), 1); + mouse_vector /= QVector3D(view->pixelWidth(), view->pixelHeight(), 1); mouse_vector *= -center_screen.z() * len_scl; axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector); QMatrix4x4 pmat; @@ -168,7 +168,7 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) { o->setRotation(o->rotation() + axe_vector); } if (cur_action == RendererService::haScale) { - mouse_vector /= QVector3D(view->width(), view->height(), 1); + mouse_vector /= QVector3D(view->pixelWidth(), view->pixelHeight(), 1); mouse_vector *= 3. / app_scale; axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector); scales << axe_vector; diff --git a/src/core/openglwindow.cpp b/src/core/openglwindow.cpp index f14f804..6443fe6 100644 --- a/src/core/openglwindow.cpp +++ b/src/core/openglwindow.cpp @@ -66,6 +66,16 @@ bool OpenGLWindow::getVSync() const { } +int OpenGLWindow::pixelWidth() const { + return devicePixelRatio() * width(); +} + + +int OpenGLWindow::pixelHeight() const { + return devicePixelRatio() * height(); +} + + // void OpenGLWindow::setSamples(int samples) { // QSurfaceFormat f = requestedFormat(); // if (f.samples() != samples) { diff --git a/src/core/openglwindow.h b/src/core/openglwindow.h index 3e469e7..ce16fc8 100644 --- a/src/core/openglwindow.h +++ b/src/core/openglwindow.h @@ -27,6 +27,9 @@ public: // int getSamples() const; int getFrameCounter() const { return frame_cnt; } + int pixelWidth() const; + int pixelHeight() const; + public slots: void renderLater(); void renderNow(); diff --git a/src/core/qglview.cpp b/src/core/qglview.cpp index a04380f..7e4b639 100644 --- a/src/core/qglview.cpp +++ b/src/core/qglview.cpp @@ -148,7 +148,7 @@ void QGLView::timerEvent(QTimerEvent *) { void QGLView::render() { - resizeGL(width(), height()); + resizeGL(pixelWidth(), pixelHeight()); emit glBeginPaint(); renderer_.mouse_pos = mapFromGlobal(QCursor::pos()); renderer_.renderScene(); @@ -177,7 +177,7 @@ void QGLView::initialize() { glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); glCullFace(GL_BACK); renderer_.reloadShaders(); - renderer_.init(width(), height()); + renderer_.init(pixelWidth(), pixelHeight()); scene_->reinitAll(); is_init = true; prev_size = QSize(); diff --git a/src/core/render/gltexture_manager.cpp b/src/core/render/gltexture_manager.cpp index ef08b69..e72b1fd 100644 --- a/src/core/render/gltexture_manager.cpp +++ b/src/core/render/gltexture_manager.cpp @@ -32,6 +32,7 @@ void TextureManager::addSearchPath(const QString & path) { if (!search_pathes.contains(path)) search_pathes << path; } + QString TextureManager::findFile(const QString & path) { return ::findFile(path, search_pathes); } diff --git a/src/core/render/gltexture_manager.h b/src/core/render/gltexture_manager.h index 08afc52..e8e1025 100644 --- a/src/core/render/gltexture_manager.h +++ b/src/core/render/gltexture_manager.h @@ -33,8 +33,8 @@ public: TextureManager(QOpenGLExtraFunctions * f_): f(f_) {} virtual ~TextureManager() {} - static void addSearchPath(const QString & path) { - if (!search_pathes; { search_pathes.clear(); } + static void addSearchPath(const QString & path); + static void clearSearchPathes() { search_pathes.clear(); } static QStringList searchPathes() { return search_pathes; } static QString findFile(const QString & path); GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false); diff --git a/src/core/render/renderer.cpp b/src/core/render/renderer.cpp index cc4d3f9..47642fc 100644 --- a/src/core/render/renderer.cpp +++ b/src/core/render/renderer.cpp @@ -45,21 +45,24 @@ Renderer::Renderer(QGLView * view_) cam_light->intensity = 0.75; cam_light->setName("Camera_Light"); - shader_files[srSelectionFill] = "selection.glsl"; - shader_files[srSelectionHalo] = "selection_halo.glsl"; - shader_files[srSelectionApply] = "selection_apply.glsl"; - shader_files[srSelectionFrame] = "selection_frame.glsl"; + shader_files[srSelectionFill] = "selection.glsl"; + shader_files[srSelectionHalo] = "selection_halo.glsl"; + shader_files[srSelectionApply] = "selection_apply.glsl"; + shader_files[srSelectionFrame] = "selection_frame.glsl"; - shader_files[srServiceFill] = "service_fill.glsl"; - shader_files[srServiceFrame] = "service_frame.glsl"; - shader_files[srServiceLine] = "service_line.glsl"; + shader_files[srServiceFill] = "service_fill.glsl"; + shader_files[srServiceFrame] = "service_frame.glsl"; + shader_files[srServiceLine] = "service_line.glsl"; - shader_files[srGeometryPass] = "ds_geom.glsl"; - shader_files[srLightOmniPass] = "ds_light.glsl"; - shader_files[srLightSpotPass] = "ds_light.glsl"; + shader_files[srGeometrySolidPass] = "ds_geom.glsl"; + shader_files[srGeometryTransparentPass] = "ds_geom.glsl"; + shader_files[srLightOmniPass] = "ds_light.glsl"; + shader_files[srLightSpotPass] = "ds_light.glsl"; + shader_files[srFinalPass] = "ds_final.glsl"; + shader_files[srTonemapPass] = "ds_tonemap.glsl"; + + shader_defines[srGeometrySolidPass] << "SOLID"; shader_defines[srLightSpotPass] << "SPOT"; - shader_files[srFinalPass] = "ds_final.glsl"; - shader_files[srTonemapPass] = "ds_tonemap.glsl"; edit_mode = need_init_shaders = true; camera_light_mode = QGLView::clmAuto; @@ -116,7 +119,7 @@ void Renderer::reloadShaders() { shader_fxaa = nullptr; if (tone_proc.shader_sum) delete tone_proc.shader_sum; tone_proc.shader_sum = nullptr; - QString dir = ":shaders/"; + QString dir = ":/shaders/"; while (it.hasNext()) { it.next(); loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key())); @@ -159,7 +162,8 @@ bool Renderer::bindShader(QOpenGLShaderProgram * sp) { void Renderer::initShaders() { if (!need_init_shaders) return; need_init_shaders = false; - initUniformBuffer(shaders.value(srGeometryPass), &buffer_materials, bpMaterials, "QGLMaterialData"); + initUniformBuffer(shaders.value(srGeometrySolidPass), &buffer_materials, bpMaterials, "QGLMaterialData"); + initUniformBuffer(shaders.value(srGeometryTransparentPass), &buffer_materials, bpMaterials, "QGLMaterialData"); QOpenGLShaderProgram * prog = 0; for (ShaderRole role: {srLightOmniPass, srLightSpotPass}) { initUniformBuffer(shaders.value(role), &buffer_materials, bpMaterials, "QGLMaterialData"); @@ -178,7 +182,10 @@ void Renderer::initShaders() { prog->setUniformValue("tex_t_0", 3); prog->setUniformValue("tex_t_1", 4); } - if (bindShader(srGeometryPass, &prog)) { + if (bindShader(srGeometrySolidPass, &prog)) { + setUniformMaps(prog); + } + if (bindShader(srGeometryTransparentPass, &prog)) { setUniformMaps(prog); } if (bindShader(srTonemapPass, &prog)) { @@ -358,7 +365,7 @@ void Renderer::renderScene() { fbo_ds.bind(); glEnableDepth(); glClearFramebuffer(); - if (bindShader(srGeometryPass, &prog)) { + if (bindShader(srGeometrySolidPass, &prog)) { setUniformCamera(prog, cam); textures_empty.bind(f, tarEmpty); textures_maps.bind(f, tarMaps); @@ -381,7 +388,10 @@ void Renderer::renderScene() { fbo_ds.setWriteBuffers({0, 1, 2, 3, 4}); glClearFramebuffer(Qt::black, false); fbo_ds.setWriteBuffers(); - if (bindShader(srGeometryPass, &prog)) { + if (bindShader(srGeometryTransparentPass, &prog)) { + setUniformCamera(prog, cam); + textures_empty.bind(f, tarEmpty); + textures_maps.bind(f, tarMaps); renderObjects(scene, rpTransparent); } fbo_ds.release(); diff --git a/src/core/render/renderer.h b/src/core/render/renderer.h index c54c370..cdaeb30 100644 --- a/src/core/render/renderer.h +++ b/src/core/render/renderer.h @@ -51,7 +51,8 @@ class QGLENGINE_CORE_EXPORT Renderer: public RendererBase { srServiceLine, // Deferred shading - srGeometryPass, + srGeometrySolidPass, + srGeometryTransparentPass, srLightOmniPass, srLightSpotPass, srFinalPass, diff --git a/src/core/render/renderer_base.cpp b/src/core/render/renderer_base.cpp index 3aa8700..95cf508 100644 --- a/src/core/render/renderer_base.cpp +++ b/src/core/render/renderer_base.cpp @@ -89,7 +89,7 @@ void RendererBase::setUniformMaps(QOpenGLShaderProgram * prog) { void RendererBase::setUniformCamera(QOpenGLShaderProgram * prog, Camera * cam, bool matrices, QSize viewport) { - double w = view->width(), h = view->height(); + double w = view->pixelWidth(), h = view->pixelHeight(); if (viewport.isValid()) { w = viewport.width(); h = viewport.height(); diff --git a/src/core/render/renderer_material.cpp b/src/core/render/renderer_material.cpp index 56be0c9..44bb27a 100644 --- a/src/core/render/renderer_material.cpp +++ b/src/core/render/renderer_material.cpp @@ -70,7 +70,8 @@ void RendererMaterial::renderMaterial(Material * m) { fbo_mat_thumb.bind(); glEnableDepth(); glClearFramebuffer(QColor(0, 0, 0, 0)); - if (r->bindShader(Renderer::srGeometryPass, &prog)) { + auto role = m->hasTransparency() ? Renderer::srGeometryTransparentPass : Renderer::srGeometrySolidPass; + if (r->bindShader(role, &prog)) { r->setUniformMaps(prog); r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size()); // qDebug() << mat_camera->viewMatrix(); diff --git a/src/core/render/renderer_selection.cpp b/src/core/render/renderer_selection.cpp index 95bb8b2..1f36b11 100644 --- a/src/core/render/renderer_selection.cpp +++ b/src/core/render/renderer_selection.cpp @@ -184,8 +184,8 @@ void RendererSelection::renderSelectionFrame() { QOpenGLShaderProgram * prog = 0; if (r->bindShader(Renderer::srSelectionFrame, &prog)) { QMatrix4x4 mat; - double mrx = r->mouse_rect.x(), mrw = r->mouse_rect.width(), vw = r->view->width(); - double mry = r->mouse_rect.y(), mrh = r->mouse_rect.height(), vh = r->view->height(); + double mrx = r->mouse_rect.x(), mrw = r->mouse_rect.width(), vw = r->view->pixelWidth(); + double mry = r->mouse_rect.y(), mrh = r->mouse_rect.height(), vh = r->view->pixelHeight(); mat.translate(-1. + (mrw + mrx * 2) / vw, 1. - (mrh + mry * 2) / vh, 0.); mat.scale(mrw / vw, mrh / vh, 0.); r->initQuad(sel_frame, mat); diff --git a/src/core/render/renderer_service.cpp b/src/core/render/renderer_service.cpp index ee0915f..ba455c8 100644 --- a/src/core/render/renderer_service.cpp +++ b/src/core/render/renderer_service.cpp @@ -511,7 +511,7 @@ void RendererService::renderService() { axis_camera->setRotation(r->view->camera()->rotation()); r->setUniformCamera(prog, axis_camera, true, axis_viewport); axis_mesh->draw(f, 3); - f->glViewport(0, 0, r->view->width(), r->view->height()); + f->glViewport(0, 0, r->view->pixelWidth(), r->view->pixelHeight()); } f->glDisable(GL_MULTISAMPLE); } diff --git a/src/widgets/material_map_editor.cpp b/src/widgets/material_map_editor.cpp index 5914fc2..14144df 100644 --- a/src/widgets/material_map_editor.cpp +++ b/src/widgets/material_map_editor.cpp @@ -68,10 +68,10 @@ void MaterialMapEditor::mapChanged() { } map->bitmap_scale.setX(ui->spinScaleX->value()); map->bitmap_scale.setY(ui->spinScaleY->value()); - map->invert_R = ui->actionInvert_R->isChecked(); - map->invert_G = ui->actionInvert_G->isChecked(); - map->invert_B = ui->actionInvert_B->isChecked(); - active = true; + map->bake_options.invert_R = ui->actionInvert_R->isChecked(); + map->bake_options.invert_G = ui->actionInvert_G->isChecked(); + map->bake_options.invert_B = ui->actionInvert_B->isChecked(); + active = true; emit changed(); } @@ -90,9 +90,9 @@ void MaterialMapEditor::setMap(Map * m) { ui->spinScaleY->setValue(map->bitmap_scale.y()); ui->linePath->setProperty("GLpath", map->bitmap_path); ui->linePath->setText(QFileInfo(map->bitmap_path).fileName()); - ui->actionInvert_R->setChecked(map->invert_R); - ui->actionInvert_G->setChecked(map->invert_G); - ui->actionInvert_B->setChecked(map->invert_B); + ui->actionInvert_R->setChecked(map->bake_options.invert_R); + ui->actionInvert_G->setChecked(map->bake_options.invert_G); + ui->actionInvert_B->setChecked(map->bake_options.invert_B); updateIcon(); active = true; }