diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl index d78d02a..12256d7 100644 --- a/QtMeshViewer/Resources/fshader.glsl +++ b/QtMeshViewer/Resources/fshader.glsl @@ -1,21 +1,26 @@ +#version 450 #ifdef GL_ES // Set default precision to medium precision mediump int; precision mediump float; #endif -uniform mat3 n_matrix; +uniform mat3 normalMatrix; uniform vec3 cameraPosition; -uniform sampler2D texture; -uniform sampler2D secondTexture; -uniform float materialShininess; -uniform vec3 materialSpecularColor; +uniform sampler2D tx0; +uniform sampler2D tx1; -uniform bool b_transparent; -uniform bool b_specular; -uniform bool b_normalmap; -uniform bool b_light; +uniform struct Material { + float shininess; + vec3 specularColor; + bool isTransparent; + bool hasSpecularmap; + bool hasNormalmap; + bool isGlow; +} material; + +uniform bool useLight; uniform struct Light { vec4 position; @@ -24,82 +29,99 @@ uniform struct Light { float ambientCoefficient; } light; -attribute vec3 a_polyNorm; -attribute vec3 a_polyTan; -attribute vec3 a_polyBiTan; - varying vec2 v_surfaceUV; varying vec3 v_surfacePosition; varying vec3 v_surfaceNormal; +varying vec3 v_polyNorm; +varying vec3 v_polyTan; +varying vec3 v_polyBiTan; void main() { - if(b_light) + if(useLight && !material.isGlow) { - // some values - mat3 tbn = transpose(mat3(a_polyTan, a_polyBiTan, a_polyNorm)); - - vec3 finalNormal = normalize(n_matrix * v_surfaceNormal); - - // if(b_normalmap) - // { - // finalNormal = texture2D(secondTexture, v_surfaceUV).rgb; - // finalNormal = normalize(finalNormal * 2.0 -1.0) - // } - - vec4 surfaceColor = vec4(texture2D(texture, v_surfaceUV)); + // get the color and undo gamma correction + vec4 surfaceColor = vec4(texture2D(tx0, v_surfaceUV)); surfaceColor.rgb = pow(surfaceColor.rgb, vec3(2.2)); - - vec3 surfaceToLight; - float attenuation; - // directional light - if(light.position.w == 0.0f) - { - surfaceToLight = normalize(light.position.xyz); - } - // point light - else - { - surfaceToLight = normalize(light.position.xyz - v_surfacePosition); - } - - float distanceToLight = length(light.position.xyz - v_surfacePosition); - attenuation = 1.0 / (1.0 + light.attenuationFactor * pow(distanceToLight, 2)); + // attenutation depending on the distance to the light + float distanceToLight = length(light.position.xyz - v_surfacePosition); + float attenuation = 1.0 / (1.0 + light.attenuationFactor * pow(distanceToLight, 2)); + + // normal vector + vec3 normal = normalize(normalMatrix * v_surfaceNormal); + + // direction from surface to light depending on the light type + vec3 surfaceToLight; + if(light.position.w == 0.0) // directional light + surfaceToLight = normalize(light.position.xyz); + else // point light + surfaceToLight = normalize(light.position.xyz - v_surfacePosition); + + // direction from surface to camera vec3 surfaceToCamera = normalize(cameraPosition - v_surfacePosition); - // ambient + // adjust the values if material has normal map + if(material.hasNormalmap) + { + vec3 surfaceTangent = normalize(normalMatrix * v_polyTan); + vec3 surfaceBitangent = normalize(normalMatrix * -v_polyBiTan); + vec3 surfaceNormal = normalize(normalMatrix * v_surfaceNormal); + mat3 tbn = transpose(mat3(surfaceTangent, surfaceBitangent, surfaceNormal)); + normal = texture2D(tx1, v_surfaceUV).rgb; + normal = normalize(normal * 2.0 -1.0); + surfaceToLight = tbn * surfaceToLight; + surfaceToCamera = tbn * surfaceToCamera; + } + + + ///////////////////////////////////////////////////////////////////////////////////// + // ambient component + vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities; - // diffuse - float diffuseCoefficient = max(0.0, dot(finalNormal, surfaceToLight)); + + ///////////////////////////////////////////////////////////////////////////////////// + // diffuse component + + float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight)); vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities; - // specular + + ///////////////////////////////////////////////////////////////////////////////////// + // specular component + float specularCoefficient = 0.0; if(diffuseCoefficient > 0.0) - specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, finalNormal))), materialShininess); - vec3 specColor; - if(b_specular) - specColor = vec3(surfaceColor.a); - else - specColor = materialSpecularColor; + specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), material.shininess); + + float specularWeight = 1; + if(material.hasSpecularmap) + specularWeight = surfaceColor.a; + vec3 specColor = specularWeight * material.specularColor; + vec3 specular = specularCoefficient * specColor * light.intensities; - // linear color before gamma correction) + ///////////////////////////////////////////////////////////////////////////////////// + // linear color before gamma correction vec3 linearColor = ambient + attenuation * (diffuse + specular); - // final color after gama correction + ///////////////////////////////////////////////////////////////////////////////////// + // gama correction vec3 gamma = vec3(1.0/2.2); - if(!b_transparent) - surfaceColor.a = 1.0f; + + if(!material.isTransparent) + surfaceColor.a = 1.0; + gl_FragColor = vec4(pow(linearColor, gamma), surfaceColor.a); } + // don't use light else { - vec4 surfaceColor = vec4(texture2D(texture, v_surfaceUV)); - if(!b_transparent) - surfaceColor.a = 1.0f; + vec4 surfaceColor = vec4(texture2D(tx0, v_surfaceUV)); + + if(!material.isTransparent) + surfaceColor.a = 1.0; gl_FragColor = surfaceColor; } diff --git a/QtMeshViewer/Resources/vshader.glsl b/QtMeshViewer/Resources/vshader.glsl index 19b792c..3b75892 100644 --- a/QtMeshViewer/Resources/vshader.glsl +++ b/QtMeshViewer/Resources/vshader.glsl @@ -1,29 +1,39 @@ +#version 450 #ifdef GL_ES // Set default precision to medium precision mediump int; precision mediump float; #endif -uniform mat4 vp_matrix; -uniform mat4 norm_matrix; -uniform mat4 m_matrix; +uniform mat4 viewProjection; +uniform mat4 normalizeModel; +uniform mat4 modelMatrix; attribute vec4 a_position; attribute vec2 a_texcoord; attribute vec3 a_normal; +attribute vec3 a_polyNorm; +attribute vec3 a_polyTan; +attribute vec3 a_polyBiTan; varying vec2 v_surfaceUV; varying vec3 v_surfacePosition; varying vec3 v_surfaceNormal; +varying vec3 v_polyNorm; +varying vec3 v_polyTan; +varying vec3 v_polyBiTan; void main() { // Calculate vertex position in screen space - gl_Position = vp_matrix * norm_matrix * m_matrix * a_position; + gl_Position = viewProjection * normalizeModel * modelMatrix * a_position; // Pass data to fragment shader // Value will be automatically interpolated to fragments inside polygon faces v_surfaceUV = a_texcoord; - v_surfacePosition = vec3(norm_matrix * m_matrix * a_position); + v_surfacePosition = vec3(normalizeModel * modelMatrix * a_position); v_surfaceNormal = a_normal; + v_polyNorm = a_polyNorm; + v_polyTan = a_polyTan; + v_polyBiTan = a_polyBiTan; } diff --git a/QtMeshViewer/Source/GeometryEngine.cpp b/QtMeshViewer/Source/GeometryEngine.cpp index 570e55c..1cc1004 100644 --- a/QtMeshViewer/Source/GeometryEngine.cpp +++ b/QtMeshViewer/Source/GeometryEngine.cpp @@ -5,7 +5,6 @@ #include "..\Header\OutputDevice.h" #include -#include "..\Header\Profiler.h" ///////////////////////////////////////////////////////////////////////// // constructor/destructor @@ -119,11 +118,11 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) float maxExtent = std::max(std::max(m_boundings.extents[0], m_boundings.extents[1]), m_boundings.extents[2]); normMatrix.scale(1 / maxExtent); normMatrix.translate(-m_boundings.center[0], -m_boundings.center[1], -m_boundings.center[2]); - program->setUniformValue("norm_matrix", normMatrix); + program->setUniformValue("normalizeModel", normMatrix); // Allways use texture unit 0 and 1 - program->setUniformValue("texture", 0); - program->setUniformValue("secondTexture", 1); + program->setUniformValue("tx0", 0); + program->setUniformValue("tx1", 1); //setup the pipeline setupPipeline(program); @@ -135,6 +134,7 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) bool tmp_transparent(false); bool tmp_specular(false); bool tmp_normalmap(false); + bool tmp_glow(false); float shininess(0.0); QVector3D specularColor; @@ -155,6 +155,9 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) m_materials->at(it.textureIndex).texture1->bind(1); } } + + if (m_materials->at(it.textureIndex).flags[0] || m_materials->at(it.textureIndex).flags[1] || m_materials->at(it.textureIndex).rendertype == 1) + tmp_glow = true; } else { @@ -163,19 +166,18 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) } // Set model matrix - program->setUniformValue("m_matrix", it.modelMatrix); + program->setUniformValue("modelMatrix", it.modelMatrix); // Set normal matrix - program->setUniformValue("n_matrix", (normMatrix * it.modelMatrix).normalMatrix()); - - // set some more values - program->setUniformValue("b_transparent", tmp_transparent); - program->setUniformValue("b_specular", tmp_specular); - program->setUniformValue("b_normalmap", tmp_normalmap); + program->setUniformValue("normalMatrix", (normMatrix * it.modelMatrix).normalMatrix()); // set some material attributes - program->setUniformValue("materialShininess", shininess); - program->setUniformValue("materialSpecularColor", specularColor); + program->setUniformValue("material.shininess", shininess); + program->setUniformValue("material.specularColor", specularColor); + program->setUniformValue("material.isTransparent", tmp_transparent); + program->setUniformValue("material.hasSpecularmap", tmp_specular); + program->setUniformValue("material.hasNormalmap", tmp_normalmap); + program->setUniformValue("material.isGlow", tmp_glow); // Draw cube geometry using indices from VBO 1 glDrawElements(GL_TRIANGLES, it.size, GL_UNSIGNED_INT, (void*)(it.offset * sizeof(GLuint))); @@ -185,7 +187,6 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) void GeometryEngine::loadFile(QString filePath) { - TIC("Start"); // cleanup old stuff and recreate buffers clearData(); m_arrayBuf.create(); @@ -260,7 +261,5 @@ void GeometryEngine::loadFile(QString filePath) clearData(); OutputDevice::getInstance()->print(QString(e.what()), 2); } - - TOC("End"); } diff --git a/QtMeshViewer/Source/MshFile.cpp b/QtMeshViewer/Source/MshFile.cpp index 96676f3..3d510a9 100644 --- a/QtMeshViewer/Source/MshFile.cpp +++ b/QtMeshViewer/Source/MshFile.cpp @@ -921,7 +921,7 @@ void MshFile::loadTexture(QOpenGLTexture *& destination, QString filepath, QStri if (!loadSuccess) { OutputDevice::getInstance()->print("WARNING: texture not found or corrupted: " + filename, 1); - + //TODO: use the correct diffuse color or return with null img = QImage(1, 1, QImage::Format_RGB32); img.fill(QColor(m_materials->back().diffuseColor[0] * 255, m_materials->back().diffuseColor[1] * 255, m_materials->back().diffuseColor[2] * 255)); filename += " *"; diff --git a/QtMeshViewer/Source/OglViewerWidget.cpp b/QtMeshViewer/Source/OglViewerWidget.cpp index 62916af..9399da8 100644 --- a/QtMeshViewer/Source/OglViewerWidget.cpp +++ b/QtMeshViewer/Source/OglViewerWidget.cpp @@ -143,10 +143,10 @@ void OglViewerWidget::paintGL() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set view-projection matrix - m_program.setUniformValue("vp_matrix", m_projection * m_camera->getMatrix()); + m_program.setUniformValue("viewProjection", m_projection * m_camera->getMatrix()); // Set Light values - m_program.setUniformValue("b_light", m_lightOn); + m_program.setUniformValue("useLight", m_lightOn); m_program.setUniformValue("light.position", m_light.position); m_program.setUniformValue("light.intensities", m_light.intensities); m_program.setUniformValue("light.attenuationFactor", m_light.attenuationFactor); diff --git a/preview.jpg b/preview.jpg index 2d250f7..3dd55da 100644 Binary files a/preview.jpg and b/preview.jpg differ