From 64eee9e60751d07cdcf619f0dfc022276721a5d7 Mon Sep 17 00:00:00 2001 From: peri4 Date: Thu, 2 Mar 2023 11:46:52 +0300 Subject: [PATCH] relief map support, small refactoring, shadow bias now based on geometry normal --- shaders/ds_geom.glsl | 34 +++-- shaders/ds_light.glsl | 25 ++-- shaders/ds_tonemap.glsl | 4 +- shaders/shadow.glsl | 5 +- src/core/CMakeLists.txt | 3 +- src/core/core/glframebuffer.cpp | 8 ++ src/core/core/glframebuffer.h | 1 + src/core/core/glmaterial.cpp | 12 +- src/core/core/glmaterial.h | 1 + src/core/core/glprimitives.cpp | 24 +++- src/core/core/glprimitives.h | 5 +- src/core/core/glshaders.cpp | 27 +++- src/core/core/glshaders.h | 14 +- src/core/core/glshaders_headers.h | 118 +++++++-------- src/core/core/glshaders_types.cpp | 1 + src/core/core/glshaders_types.h | 14 +- src/core/render/renderer.cpp | 44 ++++-- src/core/render/renderer.h | 3 +- src/core/render/renderer_base.cpp | 6 +- src/core/render/renderer_material.cpp | 20 ++- src/core/view/openglwindow.cpp | 2 +- src/core/view/qglview.cpp | 6 +- src/qglview_test/qglview_window.cpp | 4 + src/widgets/primitiveeditor.cpp | 56 +++++--- src/widgets/primitiveeditor.h | 2 + src/widgets/primitiveeditor.ui | 200 +++++++++++++++++++++++--- 26 files changed, 465 insertions(+), 174 deletions(-) diff --git a/shaders/ds_geom.glsl b/shaders/ds_geom.glsl index 180cefd..93d8cf6 100644 --- a/shaders/ds_geom.glsl +++ b/shaders/ds_geom.glsl @@ -5,15 +5,19 @@ out mat3 TBN; out vec4 object_color; out float object_flags; +const vec3 luma = vec3(0.299, 0.587, 0.114); + void main(void) { qgl_MaterialIndex = qgl_Material; qgl_FragTexture = qgl_getFragTexture(); - gl_Position = qgl_ftransform(); geom_normal = normalize(qgl_Normal * qgl_getNormalMatrix()); TBN = qgl_getTangentMatrix() * mat3(qgl_Tangent, qgl_Bitangent, qgl_Normal); object_color = qgl_ObjectColor; object_flags = qgl_ObjectFlags; + + float height = dot(qgl_materialTexture(QGL_MAP_RELIEF, qgl_FragTexture, vec4(0.)).rgb, luma); + gl_Position = qgl_ViewProjMatrix * (qgl_ModelMatrix * (vec4(qgl_Vertex + qgl_Normal * height, 1.)));//qgl_ftransform(); } @@ -26,6 +30,7 @@ in float object_flags; uniform vec2 dt; uniform float z_near; +uniform int out_index_normal = dbrNormalZ, out_index_metal = dbrMetalRoughReflectFlags; const vec3 luma = vec3(0.299, 0.587, 0.114); const float _pe = 2.4e-7; @@ -33,13 +38,13 @@ const float _pe = 2.4e-7; void main(void) { vec2 tc = qgl_FragTexture.xy; - vec4 diffuse = qgl_materialTexture(QGL_MAP_DIFFUSE, tc, vec4(0)) * object_color; + 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); + diffuse.a *= (1. - qgl_material[qgl_MaterialIndex].transparency); vec3 normal, dn; dn = qgl_materialTexture(QGL_MAP_NORMAL, tc, -vec4(0.5, 0.5, 1., 0.)).xyz; @@ -49,28 +54,27 @@ void main(void) { dn *= dn_sl / (length(dn) + 1E-6); normal = normalize(geom_normal + dn); - float metalness = dot(qgl_materialTexture(QGL_MAP_METALNESS, tc, vec4(0)).rgb, luma); + float metalness = dot(qgl_materialTexture(QGL_MAP_METALNESS, tc, vec4(0.)).rgb, luma); metalness = clamp(metalness, 0, 1); - float roughness = dot(qgl_materialTexture(QGL_MAP_ROUGHNESS, tc, vec4(0)).rgb, luma); + float roughness = dot(qgl_materialTexture(QGL_MAP_ROUGHNESS, tc, vec4(0.)).rgb, luma); roughness = clamp(roughness, 0.0001, 0.9999); float reflectivity = clamp(qgl_material[qgl_MaterialIndex].reflectivity, 0., 1.); - vec4 emission = qgl_materialTexture(QGL_MAP_EMISSION, tc, vec4(0)); + vec4 emission = qgl_materialTexture(QGL_MAP_EMISSION, tc, vec4(0.)); emission *= qgl_material[qgl_MaterialIndex].color_emission; - float height = dot(qgl_materialTexture(QGL_MAP_RELIEF, tc, vec4(0)).rgb, luma); - float z = gl_FragCoord.z; - z = z + z - 1; + z = z + z - 1.; z = ((_pe - 2.) * z_near) / (z + _pe - 1.); // infinite depth - - qgl_FragData[0] = vec4(diffuse .rgba); - qgl_FragData[1] = vec4(normal .xyz, z); - qgl_FragData[2] = vec4(metalness, roughness, reflectivity, object_flags); - qgl_FragData[3] = vec4(emission.rgb, 0/*bn.x*/); - //qgl_FragData[4] = vec4(speed.xy, bn.yz); + + qgl_FragData[dbrDiffuse ] = vec4(diffuse .rgba); + qgl_FragData[out_index_normal] = vec4(normal .xyz, z); + qgl_FragData[out_index_metal ] = vec4(metalness, roughness, reflectivity, object_flags); + qgl_FragData[dbrEmission ] = vec4(emission.rgb, 0./*bn.x*/); + //qgl_FragData[dbrSpeedBitangXY] = vec4(speed.xy, bn.yz); + qgl_FragData[dbrGeoNormal ] = vec4(normalize(geom_normal), 1.); //ivec2 itc = ivec2(gl_FragCoord.xy); //qgl_FragData[0].rgb = vec3(dot(n,vec3(0,0,1))); diff --git a/shaders/ds_light.glsl b/shaders/ds_light.glsl index ea33cd7..ffb0eba 100644 --- a/shaders/ds_light.glsl +++ b/shaders/ds_light.glsl @@ -18,8 +18,8 @@ in vec3 view_dir, world_dir; uniform vec2 dt, shadow_size; uniform float z_near; -uniform sampler2D tex_coeffs[2], tex_noise; -uniform sampler2D tex_0, tex_1, tex_2, tex_3, tex_4, tex_sh; +uniform sampler2D tex_coeff_brdf, tex_noise; +uniform sampler2D tex_0, tex_1, tex_2, tex_3, tex_4, tex_5, tex_sh; //uniform sampler2DShadow tex_shadow[16]; uniform sampler2DArrayShadow tex_shadows_cone; uniform sampler2DArray tex_depths_cone; @@ -42,7 +42,7 @@ const float PI = 3.1416; ivec2 tc; vec4 pos, lpos, shp; vec3 li, si, ldir, halfV, bn, bn2, lwdir; -vec3 normal, vds, vds2; +vec3 normal, geom_normal, vds, vds2; float rough_diff, rough_spec, dist, NdotL, NdotH, spot, ldist, diff, spec, sdist, shadow, shadow_dz; uint flags; @@ -67,7 +67,7 @@ float getShadowCone(in vec3 uvz, in int layer) { uvv[3] = iuvp.x * iuvp.y; shadow_dz = max(max(uvz.z - gt[0], uvz.z - gt[1]), max(uvz.z - gt[2], uvz.z - gt[3])); return clamp(dot(step(vec4(uvz.z), gt), uvv), 0, 1);*/ - float z = 1 - 1 / (uvz.z - z_near + 1); + float z = 1. - 1. / (uvz.z - z_near + 1.); return texture(tex_shadows_cone, vec4(uvz.xy, layer, z)); } @@ -83,7 +83,7 @@ float getShadowOmni(in vec4 uvwz, in int layer) { uvv[2] = uvp.y * iuvp.z; uvv[3] = iuvp.y * iuvp.z; return clamp(dot(step(vec4(uvwz.w), gt), uvv), 0, 1);*/ - float d = 1 - 1 / (uvwz.w - z_near + 1); + float d = 1. - 1. / (uvwz.w - z_near + 1.); return texture(tex_shadows_omni, vec4(uvwz.xyz, layer), d); //return step(uvwz.w, gt[3]); } @@ -110,7 +110,7 @@ float floatConstruct( uint m ) { m |= ieeeOne; // Add fractional part to 1.0 float f = uintBitsToFloat( m ); // Range [1:2] - return f - 1.0; // Range [0:1] + return f - 1.; // Range [0:1] } float random( float x ) { return floatConstruct(hash(floatBitsToUint(x))); } float random( vec2 v ) { return floatConstruct(hash(floatBitsToUint(v))); } @@ -174,11 +174,13 @@ void calcLight(in int index, in vec3 n, in vec3 v) { #endif if (int(round(qgl_light_parameter[index].flags)) == 1 && bitfieldExtract(flags, 3, 1) == 1 && (spot > 1E-4)) { +#ifndef SPOT vec3 odir = -(view_mat * ldir); +#endif int layer = index - lights_start; float shadow = 0.; //float bias = abs(tan(PI/2.*(1 - abs(dot(normal, ldir)))) + 1) * z_near * 1; - float bias = (1. + 1. / abs(dot(normal, ldir))) * z_near * 2.; + float bias = (1. + 1. / abs(dot(geom_normal, ldir))) * z_near * 2.; //bias = bias * bias + z_near; if (soft_shadows_enabled) { @@ -291,10 +293,12 @@ void main(void) { vec4 v0 = texelFetch(tex_0, tc, 0), v2 = texelFetch(tex_2, tc, 0), v3 = texelFetch(tex_3, tc, 0), - v4 = texelFetch(tex_4, tc, 0); + v4 = texelFetch(tex_4, tc, 0), + v5 = texelFetch(tex_5, tc, 0); vec3 diffuse = v0.rgb; normal = v1.xyz; + geom_normal = v5.xyz; vec3 emission = v3.rgb; float alpha = v0.a; float metalness = v2.r; @@ -324,7 +328,7 @@ void main(void) { li *= (1. - shlick); alpha = min(1., alpha * (1. + shlick)); - vec2 brdf = texture(tex_coeffs[0], vec2(NdotV*0.99, roughness*0.995)).rg; + vec2 brdf = texture(tex_coeff_brdf, vec2(NdotV*0.99, roughness*0.995)).rg; float env_spec = shlick * brdf.x + brdf.y; vec3 spec_col = mix(vec3(1.), diffuse, metalness); vec3 env_dir = view_mat * reflect(-v, normal); @@ -341,8 +345,9 @@ void main(void) { } qgl_FragColor = vec4(res_col, alpha); + //qgl_FragColor = vec4(diffuse.rgb, 0.25); //qgl_FragColor.a = alpha; - //qgl_FragColor.rgb = vec3(bn.z); + //qgl_FragColor.rgb = vec3(geom_normal.rgb); //qgl_FragColor.rgba = vec4(vec3(0), 0.5); #ifdef SPOT diff --git a/shaders/ds_tonemap.glsl b/shaders/ds_tonemap.glsl index 6b3aedc..1b6a3c3 100644 --- a/shaders/ds_tonemap.glsl +++ b/shaders/ds_tonemap.glsl @@ -19,7 +19,7 @@ void main(void) { float l = dot(res, luma) * 0.75; float g = gamma / frame_max; res /= l; - l = 1 - exp(-l*g); - res = max(vec3(0.f), res * l); + l = 1. - exp(-l*g); + res = max(vec3(0.), res * l); qgl_FragColor = vec4(res, dot(res, luma)); } diff --git a/shaders/shadow.glsl b/shaders/shadow.glsl index 31d95fa..47ae603 100644 --- a/shaders/shadow.glsl +++ b/shaders/shadow.glsl @@ -4,13 +4,16 @@ flat out uint object_flags; out float distance; out vec4 pos; +const vec3 luma = vec3(0.299, 0.587, 0.114); + void main(void) { object_flags = qgl_ObjectFlags; if (bitfieldExtract(object_flags, 2, 1) == 0) return; qgl_MaterialIndex = qgl_Material; qgl_FragTexture = qgl_getFragTexture(); - pos = qgl_ftransform(); + float height = dot(qgl_materialTexture(QGL_MAP_RELIEF, qgl_FragTexture, vec4(0.)).rgb, luma); + pos = qgl_ViewProjMatrix * (qgl_ModelMatrix * (vec4(qgl_Vertex + qgl_Normal * height, 1.)));//qgl_ftransform(); gl_Position = pos; } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9570beb..326be5c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -22,7 +22,8 @@ set_deploy_property(${PROJECT_NAME} ${QGLEngine_LIB_TYPE} COMPANY "${QGLEngine_COMPANY}" INFO "QGLEngine core library") make_rc(${PROJECT_NAME} _RC) -qad_add_library(${PROJECT_NAME} ${QGLEngine_LIB_TYPE} out_CPP ${_RC}) +pip_code_model(CCM "render/renderer.h" OPTIONS "-DQGLENGINE_CORE_EXPORT" "-Es") +qad_add_library(${PROJECT_NAME} ${QGLEngine_LIB_TYPE} out_CPP ${_RC} ${CCM}) qad_generate_export_header(${PROJECT_NAME}) list(APPEND out_HDR "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_export.h") qad_target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" ${_includes}) diff --git a/src/core/core/glframebuffer.cpp b/src/core/core/glframebuffer.cpp index 77e46a7..4824d9e 100644 --- a/src/core/core/glframebuffer.cpp +++ b/src/core/core/glframebuffer.cpp @@ -297,6 +297,14 @@ void Framebuffer::bindColorTexture(int index, int channel) { } +void Framebuffer::bindColorTextures(const QVector & indeces) { + for (int i = indeces.size() - 1; i >= 0; --i) { + f->glActiveTexture(GL_TEXTURE0 + i); + f->glBindTexture(GL_TEXTURE_2D, colors[indeces[i]]); + } +} + + void Framebuffer::bindColorTextures() { for (int i = colors.size() - 1; i >= 0; --i) { f->glActiveTexture(GL_TEXTURE0 + i); diff --git a/src/core/core/glframebuffer.h b/src/core/core/glframebuffer.h index 12cca60..424f728 100644 --- a/src/core/core/glframebuffer.h +++ b/src/core/core/glframebuffer.h @@ -77,6 +77,7 @@ public: void copyDepthFrom(GLuint tex) { ; } void bindColorTexture(int index, int channel = 0); + void bindColorTextures(const QVector & indeces); void bindColorTextures(); void bindDepthTexture(int channel); diff --git a/src/core/core/glmaterial.cpp b/src/core/core/glmaterial.cpp index 1ec5523..95d5c8d 100644 --- a/src/core/core/glmaterial.cpp +++ b/src/core/core/glmaterial.cpp @@ -64,11 +64,21 @@ void Map::copyToQGLMap(QGLMap & m) const { m.map_index = _layer; } else { m.array_index = 0; - m.map_index = (_type == mtNormal ? emrBlue : emrWhite); + m.map_index = emptyMapIndex(_type); } } +GLuint Map::emptyMapIndex(int type) { + switch (type) { + case mtNormal: return emrBlue; + case mtRelief: return emrBlack; + default: return emrWhite; + } + return 0; +} + + Material::Material(const QString _name) { setTypes(); name = _name; diff --git a/src/core/core/glmaterial.h b/src/core/core/glmaterial.h index 28915f7..2ddaf76 100644 --- a/src/core/core/glmaterial.h +++ b/src/core/core/glmaterial.h @@ -42,6 +42,7 @@ public: void load(TextureManager * tm); void setMapLayer(TextureManager * tm); void copyToQGLMap(QGLEngineShaders::QGLMap & m) const; + static GLuint emptyMapIndex(int type); QString bitmap_path; GLuint bitmap_id; QPointF bitmap_offset; diff --git a/src/core/core/glprimitives.cpp b/src/core/core/glprimitives.cpp index 6c7e302..abd5888 100644 --- a/src/core/core/glprimitives.cpp +++ b/src/core/core/glprimitives.cpp @@ -21,23 +21,33 @@ #include "glmesh.h" -Mesh * Primitive::plane(float width, float length) { +Mesh * Primitive::plane(float width, float length, int width_segments, int length_segments) { Mesh * ret = new Mesh(); QVector & v(ret->vertices()); QVector & n(ret->normals()); QVector & t(ret->texcoords()); QVector & i(ret->indicesTriangles()); float hw = width / 2.f, hl = length / 2.f; - for (int j = 0; j < 4; ++j) - n << QVector3D(0., 0., 1.); - t << QVector2D(0., 0.) << QVector2D(0., 1.) << QVector2D(1., 1.) << QVector2D(1., 0.); - v << QVector3D(-hw, -hl, 0.) << QVector3D(-hw, hl, 0.) << QVector3D(hw, hl, 0.) << QVector3D(hw, -hl, 0.); - i << Vector3i(0, 2, 1) << Vector3i(0, 3, 2); + float w1 = 1.f / width_segments, l1 = 1.f / length_segments; + int sind = 0; + for (int wi = 0; wi < width_segments; ++wi) { + for (int li = 0; li < length_segments; ++li) { + for (int j = 0; j < 4; ++j) + n << QVector3D(0., 0., 1.); + float ws = (float)wi / width_segments; + float ls = (float)li / length_segments; + t << QVector2D(ws, ls) << QVector2D(ws, ls + l1) << QVector2D(ws + w1, ls + l1) << QVector2D(ws + w1, ls); + v << QVector3D(ws * width - hw, ls * length - hl, 0.) << QVector3D(ws * width - hw, (ls + l1) * length - hl, 0.) + << QVector3D((ws + w1) * width - hw, (ls + l1) * length - hl, 0.) << QVector3D((ws + w1) * width - hw, ls * length - hl, 0.); + i << Vector3i(sind + 0, sind + 2, sind + 1) << Vector3i(sind + 0, sind + 3, sind + 2); + sind += 4; + } + } return ret; } -Mesh * Primitive::cube(float width, float length, float height) { +Mesh * Primitive::cube(float width, float length, float height, int width_segments, int length_segments, int height_segments) { Mesh * ret = new Mesh(); QVector3D scale(width, length, height); QVector & v(ret->vertices()); diff --git a/src/core/core/glprimitives.h b/src/core/core/glprimitives.h index 176cf7d..ea46c3e 100644 --- a/src/core/core/glprimitives.h +++ b/src/core/core/glprimitives.h @@ -25,9 +25,10 @@ namespace Primitive { -QGLENGINE_CORE_EXPORT Mesh * plane(float width = 1., float length = 1.); +QGLENGINE_CORE_EXPORT Mesh * plane(float width = 1., float length = 1., int width_segments = 1, int length_segments = 1); -QGLENGINE_CORE_EXPORT Mesh * cube(float width = 1., float length = 1., float height = 1.); +QGLENGINE_CORE_EXPORT Mesh * +cube(float width = 1., float length = 1., float height = 1., int width_segments = 1, int length_segments = 1, int height_segments = 1); QGLENGINE_CORE_EXPORT Mesh * ellipsoid(int segments_wl, int segments_h, float radius = 1., float end_angle = 360.); diff --git a/src/core/core/glshaders.cpp b/src/core/core/glshaders.cpp index 78e249f..e70d99d 100644 --- a/src/core/core/glshaders.cpp +++ b/src/core/core/glshaders.cpp @@ -39,11 +39,18 @@ bool addShader(QOpenGLShaderProgram * prog, if (add_qgl) { switch (type) { case QOpenGLShader::Fragment: + content.prepend(qgl_material_head); content.prepend(qgl_fragment_head); - content.prepend(qgl_uniform); + content.prepend(qgl_uniform_light); + content.prepend(qgl_uniform_material); + content.prepend(qgl_structs); + break; + case QOpenGLShader::Vertex: + content.prepend(qgl_material_head); + content.prepend(qgl_vertex_head); + content.prepend(qgl_uniform_material); content.prepend(qgl_structs); break; - case QOpenGLShader::Vertex: content.prepend(qgl_vertex_head); break; case QOpenGLShader::Geometry: content.prepend(qgl_geometry_head); break; } } @@ -65,7 +72,11 @@ QString prepareDefines(const QStringList & defines) { } -bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl, const QStringList & defines) { +bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, + const QString & file, + bool add_qgl, + const QStringList & defines, + const QString & custom_header) { if (!prog) prog = new QOpenGLShaderProgram(); prog->removeAllShaders(); QFile f(file); @@ -74,7 +85,7 @@ bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QStr return false; } QTextStream ts(&f); - QString cur_shader, line, pl, defs = prepareDefines(defines); + QString cur_shader, line, pl, defs = prepareDefines(defines) + "\n" + custom_header; QOpenGLShader::ShaderType type = QOpenGLShader::ShaderType(); while (!ts.atEnd()) { line = ts.readLine(); @@ -118,10 +129,14 @@ bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QStr } -bool QGLEngineShaders::loadShaders(QOpenGLShaderProgram *& prog, const QStringList & files, bool add_qgl, const QStringList & defines) { +bool QGLEngineShaders::loadShaders(QOpenGLShaderProgram *& prog, + const QStringList & files, + bool add_qgl, + const QStringList & defines, + const QString & custom_header) { if (!prog) prog = new QOpenGLShaderProgram(); prog->removeAllShaders(); - QString cur_shader, defs = prepareDefines(defines); + QString cur_shader, defs = prepareDefines(defines) + "\n" + custom_header; foreach(QString f, files) { QFileInfo fi(f); QOpenGLShader::ShaderType type = QOpenGLShader::ShaderType(); diff --git a/src/core/core/glshaders.h b/src/core/core/glshaders.h index ce94acd..83b8036 100644 --- a/src/core/core/glshaders.h +++ b/src/core/core/glshaders.h @@ -23,10 +23,16 @@ namespace QGLEngineShaders { -QGLENGINE_CORE_EXPORT bool -loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl = true, const QStringList & defines = QStringList()); -QGLENGINE_CORE_EXPORT bool -loadShaders(QOpenGLShaderProgram *& prog, const QStringList & files, bool add_qgl = true, const QStringList & defines = QStringList()); +QGLENGINE_CORE_EXPORT bool loadShadersMulti(QOpenGLShaderProgram *& prog, + const QString & file, + bool add_qgl = true, + const QStringList & defines = QStringList(), + const QString & custom_header = QString()); +QGLENGINE_CORE_EXPORT bool loadShaders(QOpenGLShaderProgram *& prog, + const QStringList & files, + bool add_qgl = true, + const QStringList & defines = QStringList(), + const QString & custom_header = QString()); } // namespace QGLEngineShaders diff --git a/src/core/core/glshaders_headers.h b/src/core/core/glshaders_headers.h index 1a991cf..4ebae2f 100644 --- a/src/core/core/glshaders_headers.h +++ b/src/core/core/glshaders_headers.h @@ -50,11 +50,7 @@ const char qgl_vertex_head[] = "layout(location = 1 ) in vec3 qgl_Vertex "#define qgl_ObjectFlags qgl_ObjectIntegers[2]\n" ""; -const char qgl_fragment_head[] = - "in vec2 qgl_FragTexture;\n" - "flat in uint qgl_MaterialIndex;\n" - "out vec4 qgl_FragData[gl_MaxDrawBuffers];\n" - "uniform vec2 qgl_ViewSize;\n" +const char qgl_material_head[] = "vec4 qgl_materialTexture(uint type, vec2 coord, vec4 tex_shift) {\n" " coord *= qgl_material[qgl_MaterialIndex].map[type].scale;\n" " vec4 t = texture(qgl_texture_array[qgl_material[qgl_MaterialIndex].map[type].array_index],\n" @@ -63,62 +59,70 @@ const char qgl_fragment_head[] = " t.rgb = t.rgb * qgl_material[qgl_MaterialIndex].map[type].amount + qgl_material[qgl_MaterialIndex].map[type].offset;\n" " return t;\n" "}\n" - "#define qgl_FragColor qgl_FragData[0]\n" ""; -const char qgl_geometry_head[] = ""; +const char qgl_fragment_head[] = "in vec2 qgl_FragTexture;\n" + "flat in uint qgl_MaterialIndex;\n" + "out vec4 qgl_FragData[gl_MaxDrawBuffers];\n" + "uniform vec2 qgl_ViewSize;\n" + "#define qgl_FragColor qgl_FragData[0]\n" + ""; -const char qgl_structs[] = "#define QGL_MAPS_COUNT 6\n" - "#define QGL_MAP_DIFFUSE 0\n" - "#define QGL_MAP_NORMAL 1\n" - "#define QGL_MAP_METALNESS 2\n" - "#define QGL_MAP_ROUGHNESS 3\n" - "#define QGL_MAP_EMISSION 4\n" - "#define QGL_MAP_RELIEF 5\n" - "#define QGL_TEXTURE_ARRAY_EMPTY 0\n" - "#define QGL_TEXTURE_ARRAY_MAPS 1\n" - "struct QGLMap {\n" - " float offset;\n" - " float amount;\n" - " vec2 scale;\n" - " uint array_index;\n" - " uint map_index;\n" - "};\n" - "struct QGLMaterial {\n" - " vec4 color_diffuse;\n" - " vec4 color_emission;\n" - " float transparency;\n" - " float reflectivity;\n" - " float iof;\n" - " float dispersion;\n" - " QGLMap map[QGL_MAPS_COUNT];\n" - "};\n" - "struct QGLLightParameter {\n" - " vec4 color;\n" - " vec4 decay_intensity;\n" - " vec4 angles;\n" - " float size;\n" - " float flags;\n" - " QGLMap map;\n" - "};\n" - "struct QGLLightPosition {\n" - " vec4 position;\n" - " vec4 direction;\n" - " mat4 shadow_matrix;\n" - "};\n" - ""; +const char qgl_geometry_head[] = ""; -const char qgl_uniform[] = "layout (std140) uniform QGLMaterialData {\n" - " QGLMaterial qgl_material[128];\n" - "};\n" - "layout (std140) uniform QGLLightParameterData {\n" - " QGLLightParameter qgl_light_parameter[256];\n" - "};\n" - "layout (std140) uniform QGLLightPositionData {\n" - " QGLLightPosition qgl_light_position[256];\n" - "};\n" - "uniform sampler2DArray qgl_texture_array[2];\n" - ""; +const char qgl_structs[] = "#define QGL_MAPS_COUNT 6\n" + "#define QGL_MAP_DIFFUSE 0\n" + "#define QGL_MAP_NORMAL 1\n" + "#define QGL_MAP_METALNESS 2\n" + "#define QGL_MAP_ROUGHNESS 3\n" + "#define QGL_MAP_EMISSION 4\n" + "#define QGL_MAP_RELIEF 5\n" + "#define QGL_TEXTURE_ARRAY_EMPTY 0\n" + "#define QGL_TEXTURE_ARRAY_MAPS 1\n" + "struct QGLMap {\n" + " float offset;\n" + " float amount;\n" + " vec2 scale;\n" + " uint array_index;\n" + " uint map_index;\n" + "};\n" + "struct QGLMaterial {\n" + " vec4 color_diffuse;\n" + " vec4 color_emission;\n" + " float transparency;\n" + " float reflectivity;\n" + " float iof;\n" + " float dispersion;\n" + " QGLMap map[QGL_MAPS_COUNT];\n" + "};\n" + "struct QGLLightParameter {\n" + " vec4 color;\n" + " vec4 decay_intensity;\n" + " vec4 angles;\n" + " float size;\n" + " float flags;\n" + " QGLMap map;\n" + "};\n" + "struct QGLLightPosition {\n" + " vec4 position;\n" + " vec4 direction;\n" + " mat4 shadow_matrix;\n" + "};\n" + ""; + +const char qgl_uniform_material[] = "layout (std140) uniform QGLMaterialData {\n" + " QGLMaterial qgl_material[128];\n" + "};\n" + "uniform sampler2DArray qgl_texture_array[2];\n" + ""; + +const char qgl_uniform_light[] = "layout (std140) uniform QGLLightParameterData {\n" + " QGLLightParameter qgl_light_parameter[256];\n" + "};\n" + "layout (std140) uniform QGLLightPositionData {\n" + " QGLLightPosition qgl_light_position[256];\n" + "};\n" + ""; } // namespace QGLEngineShaders diff --git a/src/core/core/glshaders_types.cpp b/src/core/core/glshaders_types.cpp index 04e9304..3fce3e2 100644 --- a/src/core/core/glshaders_types.cpp +++ b/src/core/core/glshaders_types.cpp @@ -35,6 +35,7 @@ QGLEngineShaders::QGLMaterial::QGLMaterial() { iof = 0.; dispersion = 0.; map[mtNormal].map_index = emrBlue; + map[mtRelief].map_index = emrBlack; map[mtRoughness].amount = 0.75; map[mtMetalness].amount = 0.25; } diff --git a/src/core/core/glshaders_types.h b/src/core/core/glshaders_types.h index 8b9040f..a282c8b 100644 --- a/src/core/core/glshaders_types.h +++ b/src/core/core/glshaders_types.h @@ -104,17 +104,23 @@ enum MapType { mtEmission = 4, mtRelief = 5, }; +enum TextureRole { + trCoeffBRDF = 10, + trEnvironment = 11, +}; enum TextureArrayRole { - tarEmpty = 10, - tarMaps = 11, + tarEmpty = 12, + tarMaps = 13, tarShadowsCone = 16, tarShadowsOmni = 17, tarDepthsCone = 18, tarDepthsOmni = 19, }; enum EmptyMapRole { - emrWhite = 0, - emrBlue = 1, + emrWhite, + emrBlue, + emrBlack, + emrCount, }; #define QGL_MAPS_COUNT 6 #pragma pack(push, 1) diff --git a/src/core/render/renderer.cpp b/src/core/render/renderer.cpp index 6976d70..decc031 100644 --- a/src/core/render/renderer.cpp +++ b/src/core/render/renderer.cpp @@ -19,12 +19,16 @@ #define GL_GLEXT_PROTOTYPES #include "renderer.h" +#include "ccm_qglengine_core.h" #include "glmesh.h" #include "glshaders.h" #include "gltexture_manager.h" #include "qglview.h" #include +#include +#include +#include #include @@ -33,7 +37,9 @@ using namespace QGLEngineShaders; Renderer::Renderer(QGLView * view_) : RendererBase(view_) - , fbo_ds(view_, QVector() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F) + , fbo_ds(view_, + QVector() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F << GL_RGBA32F + << GL_RGBA16F) , fbo_out(view_, obrBuffersCount, false, GL_RGBA16F) , rend_mat(this) , rend_service(this) @@ -94,6 +100,13 @@ Renderer::Renderer(QGLView * view_) shader_defines[srLightSpotPass] << "SPOT"; shader_defines[srShadowOmniPass] << "OMNI"; + PICodeInfo::EnumInfo * obre = PICodeInfo::enumsInfo->value("Renderer::DeferredBufferRole"); + if (obre) { + for (auto e: obre->members) { + obr_defines += "#define " + PI2QString(e.name) + " " + QString::number(e.value) + "\n"; + } + } + edit_mode = need_init_shaders = true; camera_light_mode = QGLView::clmAuto; } @@ -157,7 +170,7 @@ void Renderer::reloadShaders() { QString dir = ":/shaders/"; while (it.hasNext()) { it.next(); - loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key())); + loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()), obr_defines); } loadShadersMulti(tone_proc.shader_sum, dir + "sum.glsl", false); QStringList fxaa_defs; @@ -203,11 +216,10 @@ void Renderer::initShaders() { initUniformBuffer(prog, &buffer_materials, bpMaterials, "QGLMaterialData"); initUniformBuffer(prog, &buffer_lights, bpLightParameters, "QGLLightParameterData"); initUniformBuffer(prog, &buffer_lights_pos, bpLightPositions, "QGLLightPositionData"); - for (int i = 0; i < 5; ++i) + for (int i = 0; i <= 5; ++i) prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i); - prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount); - prog->setUniformValue("tex_env", (int)Renderer::dbrBuffersCount + 1); - prog->setUniformValue("tex_noise", (int)Renderer::dbrBuffersCount + 2); + prog->setUniformValue("tex_coeff_brdf", trCoeffBRDF); + prog->setUniformValue("tex_env", trEnvironment); setUniformMaps(prog); } if (bindShader(srFinalPass, &prog)) { @@ -311,12 +323,8 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) { void Renderer::renderLight(int first_wr_buff, bool clear_only) { QOpenGLShaderProgram * prog = 0; Camera * cam = view->camera(); - for (int i = 0; i < 3; ++i) { - view->glActiveTexture(GL_TEXTURE0 + Renderer::dbrBuffersCount + i); - view->glBindTexture(GL_TEXTURE_2D, tex_coeff[i]); - } - fbo_ds.bindColorTextures(); - fbo_out.bind(); + view->glActiveTexture(GL_TEXTURE0 + trCoeffBRDF); + view->glBindTexture(GL_TEXTURE_2D, tex_coeff[0]); // tex_env.bind((int)Renderer::dbrBuffersCount + 1); typedef QPair PassPair; QVector passes; @@ -558,17 +566,21 @@ void Renderer::renderScene() { setUniformCamera(prog, cam); textures_empty.bind(f, tarEmpty); textures_maps.bind(f, tarMaps); + prog->setUniformValue("out_index_normal", dbrNormalZSolid); + prog->setUniformValue("out_index_metal", dbrMetalRoughReflectFlagsSolid); glPolygonMode(GL_FRONT_AND_BACK, view->renderMode()); renderObjects(scene, rpSolid); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } - fbo_ds.blit(dbrNormalZ, fbo_ds.id(), dbrNormalZSolid, fbo_ds.rect(), fbo_ds.rect()); - fbo_ds.blit(dbrMetalRoughReflectFlags, fbo_ds.id(), dbrMetalRoughReflectFlagsSolid, fbo_ds.rect(), fbo_ds.rect()); + // fbo_ds.blit(dbrNormalZ, fbo_ds.id(), dbrNormalZSolid, fbo_ds.rect(), fbo_ds.rect()); + // fbo_ds.blit(dbrMetalRoughReflectFlags, fbo_ds.id(), dbrMetalRoughReflectFlagsSolid, fbo_ds.rect(), fbo_ds.rect()); fbo_ds.release(); phase.end(); /// lighting passes phase.begin("... light"); + fbo_out.bind(); + fbo_ds.bindColorTextures({dbrDiffuse, dbrNormalZSolid, dbrMetalRoughReflectFlagsSolid, dbrEmission, dbrSpeedBitangXY, dbrGeoNormal}); renderLight(obrSolidOmni, scene.geometries_used[rpSolid].isEmpty()); phase.end(); @@ -583,6 +595,8 @@ void Renderer::renderScene() { setUniformCamera(prog, cam); textures_empty.bind(f, tarEmpty); textures_maps.bind(f, tarMaps); + prog->setUniformValue("out_index_normal", dbrNormalZ); + prog->setUniformValue("out_index_metal", dbrMetalRoughReflectFlags); glPolygonMode(GL_FRONT_AND_BACK, view->renderMode()); renderObjects(scene, rpTransparent); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -592,6 +606,8 @@ void Renderer::renderScene() { /// lighting passes phase.begin("... light"); + fbo_out.bind(); + fbo_ds.bindColorTextures({dbrDiffuse, dbrNormalZ, dbrMetalRoughReflectFlags, dbrEmission, dbrSpeedBitangXY, dbrGeoNormal}); renderLight(obrTransparentOmni, scene.geometries_used[rpTransparent].isEmpty()); phase.end(); diff --git a/src/core/render/renderer.h b/src/core/render/renderer.h index a55ceda..47d0858 100644 --- a/src/core/render/renderer.h +++ b/src/core/render/renderer.h @@ -85,6 +85,7 @@ public: dbrMetalRoughReflectFlags, dbrEmission, dbrSpeedBitangXY, + dbrGeoNormal, dbrNormalZSolid, dbrMetalRoughReflectFlagsSolid, @@ -155,7 +156,7 @@ private: QMap> cur_lights; QVector fb_effects; QImage last_img; - QString timings; + QString obr_defines, timings; bool is_grabbing = false; }; diff --git a/src/core/render/renderer_base.cpp b/src/core/render/renderer_base.cpp index 146ff90..fed65b5 100644 --- a/src/core/render/renderer_base.cpp +++ b/src/core/render/renderer_base.cpp @@ -57,13 +57,15 @@ void RendererBase::initTextureArrays() { QOpenGLExtraFunctions * f = view; textures_maps.init(f); textures_empty.init(f); - textures_empty.resize(f, QSize(1, 1), 2); + textures_empty.resize(f, QSize(1, 1), emrCount); textures_empty.bind(f, tarEmpty); QImage im(1, 1, QImage::Format_RGBA8888); im.fill(0xFFFFFFFF); textures_empty.load(f, im, emrWhite); im.fill(0xFF8080); textures_empty.load(f, im, emrBlue); + im.fill(0x000000); + textures_empty.load(f, im, emrBlack); shadow_maps_cone.init(f); shadow_maps_omni.init(f); depth_maps_cone.init(f); @@ -402,7 +404,7 @@ void RendererBase::initCoeffTextures() { } } createCoeffTexture(tex_coeff[0], data.constData(), size, 2); - createNoiseTexture(tex_coeff[2]); + // createNoiseTexture(tex_coeff[2]); } diff --git a/src/core/render/renderer_material.cpp b/src/core/render/renderer_material.cpp index 55881b0..70a1a97 100644 --- a/src/core/render/renderer_material.cpp +++ b/src/core/render/renderer_material.cpp @@ -30,7 +30,7 @@ using namespace QGLEngineShaders; -RendererMaterial::RendererMaterial(Renderer * r_): r(r_), fbo_mat_thumb(r->view, 6, true, GL_RGBA16F) { +RendererMaterial::RendererMaterial(Renderer * r_): r(r_), fbo_mat_thumb(r->view, 7, true, GL_RGBA16F) { mat_sphere = Primitive::ellipsoid(16, 16); mat_camera = new Camera(); mat_camera->setPos(QVector3D(2, 2, 2)); @@ -38,6 +38,7 @@ RendererMaterial::RendererMaterial(Renderer * r_): r(r_), fbo_mat_thumb(r->view, mat_camera->setFOV(45.); mat_light = new Light(); mat_light->setPos(QVector3D(50, 100, 25)); + mat_light->setCastShadows(false); last_thumb_material = 0; } @@ -74,6 +75,8 @@ void RendererMaterial::renderMaterial(Material * m) { if (r->bindShader(role, &prog)) { r->setUniformMaps(prog); r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size()); + prog->setUniformValue("out_index_normal", Renderer::dbrNormalZ); + prog->setUniformValue("out_index_metal", Renderer::dbrMetalRoughReflectFlags); // qDebug() << mat_camera->viewMatrix(); r->textures_empty.bind(f, tarEmpty); r->textures_maps.bind(f, tarMaps); @@ -83,15 +86,18 @@ void RendererMaterial::renderMaterial(Material * m) { mat_sphere->loadObject(f, o); mat_sphere->draw(f, 1); } - fbo_mat_thumb.bindColorTextures(); - fbo_mat_thumb.bindDepthTexture(5); - fbo_mat_thumb.setWriteBuffer(5); + fbo_mat_thumb.bindColorTextures({Renderer::dbrDiffuse, + Renderer::dbrNormalZ, + Renderer::dbrMetalRoughReflectFlags, + Renderer::dbrEmission, + Renderer::dbrSpeedBitangXY, + Renderer::dbrGeoNormal}); + fbo_mat_thumb.setWriteBuffer(6); if (r->bindShader(Renderer::srLightOmniPass, &prog)) { r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size()); r->setUniformViewCorners(prog, mat_camera, fbo_mat_thumb.size()); - for (int i = 0; i < 5; ++i) + 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", 0); prog->setUniformValue("lights_count", 1); QMap> mat_l; @@ -102,7 +108,7 @@ void RendererMaterial::renderMaterial(Material * m) { r->renderQuad(prog, r->quad, mat_camera); r->view->scene()->setLightsChanged(); } - fbo_mat_thumb.queryImage(5); + fbo_mat_thumb.queryImage(6); fbo_mat_thumb.release(); } diff --git a/src/core/view/openglwindow.cpp b/src/core/view/openglwindow.cpp index 74584dc..13708dc 100644 --- a/src/core/view/openglwindow.cpp +++ b/src/core/view/openglwindow.cpp @@ -15,7 +15,7 @@ OpenGLWindow::OpenGLWindow(QWindow * parent): QWindow(parent) { format.setRenderableType(QSurfaceFormat::OpenGLES); #else if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { - format.setVersion(4, 0); + format.setVersion(4, 3); format.setProfile(QSurfaceFormat::CoreProfile); } #endif diff --git a/src/core/view/qglview.cpp b/src/core/view/qglview.cpp index 10dd864..d3aea2c 100644 --- a/src/core/view/qglview.cpp +++ b/src/core/view/qglview.cpp @@ -91,12 +91,12 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) { default_camera->setName("Camera"); emit cameraPosChanged(default_camera->pos()); - Mesh * m = Primitive::cube(10, 10, 10); - m->flipNormals(); + /*Mesh * m = Primitive::plane(10, 10, 10); + // m->flipNormals(); ObjectBase * o = new ObjectBase(m); o->setColor(Qt::cyan); scene()->addObject(o); - delete m; + delete m;*/ } diff --git a/src/qglview_test/qglview_window.cpp b/src/qglview_test/qglview_window.cpp index f6ecb8a..3a4c431 100644 --- a/src/qglview_test/qglview_window.cpp +++ b/src/qglview_test/qglview_window.cpp @@ -137,6 +137,10 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView viewEditor->assignQGLView(view->view()); widgetTextures->assignQGLView(view->view()); + auto * o = primitiveEditor->createCurrent(); + o->calculateBoundingBox(); + view->view()->focusOn(o->boundingBox()); + session.load(); diff --git a/src/widgets/primitiveeditor.cpp b/src/widgets/primitiveeditor.cpp index a6bc926..29050a7 100644 --- a/src/widgets/primitiveeditor.cpp +++ b/src/widgets/primitiveeditor.cpp @@ -36,9 +36,14 @@ PrimitiveEditor::PrimitiveEditor(QWidget * parent): QWidget(parent), ui(new Ui:: #endif editors[Plane] << ui->widgetWidth; editors[Plane] << ui->widgetLength; + editors[Plane] << ui->widgetSegmentsW; + editors[Plane] << ui->widgetSegmentsL; editors[Cube] << ui->widgetWidth; editors[Cube] << ui->widgetLength; editors[Cube] << ui->widgetHeight; + editors[Cube] << ui->widgetSegmentsW; + editors[Cube] << ui->widgetSegmentsL; + editors[Cube] << ui->widgetSegmentsH; editors[Ellipsoid] << ui->widgetRadius1; editors[Ellipsoid] << ui->widgetSegments; editors[Ellipsoid] << ui->widgetSegments2; @@ -86,18 +91,40 @@ void PrimitiveEditor::assignQGLView(QGLView * v) { } +ObjectBase * PrimitiveEditor::createCurrent() { + if (!view) return nullptr; + QVariantList params; + Mesh * m = createMesh(params); + if (!m) return nullptr; + ObjectBase * o = new ObjectBase(m); + o->setColor(ui->colorButton->color()); + o->setName(ui->comboPrimitives->currentText()); + o->setProperty("primitive", params); + view->scene()->addObject(o); + view->scene()->selectObject(o); + delete m; + return o; +} + + Mesh * PrimitiveEditor::createMesh(QVariantList & params) { Mesh * m = 0; PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex(); params << pt; switch (pt) { case Plane: - m = Primitive::plane(ui->spinWidth->value(), ui->spinLength->value()); - params << ui->spinWidth->value() << ui->spinLength->value(); + m = Primitive::plane(ui->spinWidth->value(), ui->spinLength->value(), ui->spinSegmentsW->value(), ui->spinSegmentsL->value()); + params << ui->spinWidth->value() << ui->spinLength->value() << ui->spinSegmentsW->value() << ui->spinSegmentsL->value(); break; case Cube: - m = Primitive::cube(ui->spinWidth->value(), ui->spinLength->value(), ui->spinHeight->value()); - params << ui->spinWidth->value() << ui->spinLength->value() << ui->spinHeight->value(); + m = Primitive::cube(ui->spinWidth->value(), + ui->spinLength->value(), + ui->spinHeight->value(), + ui->spinSegmentsW->value(), + ui->spinSegmentsL->value(), + ui->spinSegmentsH->value()); + params << ui->spinWidth->value() << ui->spinLength->value() << ui->spinHeight->value() << ui->spinSegmentsW->value() + << ui->spinSegmentsL->value() << ui->spinSegmentsH->value(); break; case Ellipsoid: m = Primitive::ellipsoid(ui->spinSegments->value(), ui->spinSegments2->value(), ui->spinRadius->value(), ui->spinAngle->value()); @@ -155,11 +182,16 @@ void PrimitiveEditor::selectionChanged() { case Plane: ui->spinWidth->setValue(vl.takeFirst().toDouble()); ui->spinLength->setValue(vl.takeFirst().toDouble()); + if (!vl.isEmpty()) ui->spinSegmentsW->setValue(vl.takeFirst().toInt()); + if (!vl.isEmpty()) ui->spinSegmentsL->setValue(vl.takeFirst().toInt()); break; case Cube: ui->spinWidth->setValue(vl.takeFirst().toDouble()); ui->spinLength->setValue(vl.takeFirst().toDouble()); ui->spinHeight->setValue(vl.takeFirst().toDouble()); + if (!vl.isEmpty()) ui->spinSegmentsW->setValue(vl.takeFirst().toInt()); + if (!vl.isEmpty()) ui->spinSegmentsL->setValue(vl.takeFirst().toInt()); + if (!vl.isEmpty()) ui->spinSegmentsH->setValue(vl.takeFirst().toInt()); break; case Ellipsoid: ui->spinSegments->setValue(vl.takeFirst().toDouble()); @@ -191,8 +223,8 @@ void PrimitiveEditor::selectionChanged() { ui->spinAngle->setValue(vl.takeFirst().toDouble()); break; } - ui->flipNormals->setChecked(vl.takeFirst().toBool()); - ui->colorButton->setColor(vl.takeFirst().value()); + if (!vl.isEmpty()) ui->flipNormals->setChecked(vl.takeFirst().toBool()); + if (!vl.isEmpty()) ui->colorButton->setColor(vl.takeFirst().value()); } } } @@ -215,17 +247,7 @@ void PrimitiveEditor::replaceMesh() { void PrimitiveEditor::on_buttonAdd_clicked() { - if (!view) return; - QVariantList params; - Mesh * m = createMesh(params); - if (!m) return; - ObjectBase * o = new ObjectBase(m); - o->setColor(ui->colorButton->color()); - o->setName(ui->comboPrimitives->currentText()); - o->setProperty("primitive", params); - view->scene()->addObject(o); - view->scene()->selectObject(o); - delete m; + createCurrent(); } diff --git a/src/widgets/primitiveeditor.h b/src/widgets/primitiveeditor.h index 3b8b7f9..14645d9 100644 --- a/src/widgets/primitiveeditor.h +++ b/src/widgets/primitiveeditor.h @@ -49,6 +49,8 @@ public: void assignQGLView(QGLView * v); + ObjectBase * createCurrent(); + protected: Mesh * createMesh(QVariantList & params); void showEditors(); diff --git a/src/widgets/primitiveeditor.ui b/src/widgets/primitiveeditor.ui index c5c286c..fa0bbb1 100644 --- a/src/widgets/primitiveeditor.ui +++ b/src/widgets/primitiveeditor.ui @@ -6,8 +6,8 @@ 0 0 - 360 - 536 + 499 + 697 @@ -134,6 +134,120 @@ + + + + + 0 + + + 0 + + + 0 + + + + + Segments W: + + + + + + + 1 + + + 1000 + + + 1 + + + 1 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Segments L: + + + + + + + 1 + + + 1000 + + + 1 + + + 1 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Segments H: + + + + + + + 1 + + + 1000 + + + 1 + + + 1 + + + + + + @@ -437,8 +551,8 @@ replaceMesh() - 330 - 84 + 498 + 109 369 @@ -453,8 +567,8 @@ replaceMesh() - 334 - 116 + 498 + 147 366 @@ -469,8 +583,8 @@ replaceMesh() - 332 - 144 + 498 + 299 370 @@ -485,8 +599,8 @@ replaceMesh() - 334 - 186 + 498 + 337 371 @@ -501,8 +615,8 @@ replaceMesh() - 335 - 210 + 391 + 377 372 @@ -517,8 +631,8 @@ replaceMesh() - 329 - 246 + 498 + 415 370 @@ -533,8 +647,8 @@ replaceMesh() - 336 - 284 + 498 + 453 372 @@ -550,7 +664,7 @@ 70 - 344 + 532 370 @@ -581,8 +695,8 @@ replaceMesh() - 271 - 285 + 498 + 500 179 @@ -590,6 +704,54 @@ + + spinSegmentsW + valueChanged(int) + PrimitiveEditor + replaceMesh() + + + 465 + 173 + + + 511 + 164 + + + + + spinSegmentsL + valueChanged(int) + PrimitiveEditor + replaceMesh() + + + 462 + 208 + + + 520 + 206 + + + + + spinSegmentsH + valueChanged(int) + PrimitiveEditor + replaceMesh() + + + 468 + 251 + + + 563 + 251 + + + replaceMesh()