From 541a975624f181d3ebe3e07faec6081429929700 Mon Sep 17 00:00:00 2001 From: Anakin Date: Sun, 5 Feb 2017 20:10:05 +0100 Subject: [PATCH] added preview imange, passed data to shader, need to process data in shader --- QtMeshViewer/Resources/fshader.glsl | 16 +++++++++++++--- QtMeshViewer/Source/GeometryEngine.cpp | 19 ++++++++++++++++--- preview.jpg | Bin 0 -> 44438 bytes 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 preview.jpg diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl index b66d1ed..d78d02a 100644 --- a/QtMeshViewer/Resources/fshader.glsl +++ b/QtMeshViewer/Resources/fshader.glsl @@ -8,11 +8,13 @@ uniform mat3 n_matrix; uniform vec3 cameraPosition; uniform sampler2D texture; +uniform sampler2D secondTexture; uniform float materialShininess; uniform vec3 materialSpecularColor; uniform bool b_transparent; uniform bool b_specular; +uniform bool b_normalmap; uniform bool b_light; uniform struct Light { @@ -35,7 +37,15 @@ void main() if(b_light) { // some values - vec3 normalWorld = normalize(n_matrix * v_surfaceNormal); + 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)); surfaceColor.rgb = pow(surfaceColor.rgb, vec3(2.2)); @@ -62,13 +72,13 @@ void main() vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities; // diffuse - float diffuseCoefficient = max(0.0, dot(normalWorld, surfaceToLight)); + float diffuseCoefficient = max(0.0, dot(finalNormal, surfaceToLight)); vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities; // specular float specularCoefficient = 0.0; if(diffuseCoefficient > 0.0) - specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normalWorld))), materialShininess); + specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, finalNormal))), materialShininess); vec3 specColor; if(b_specular) specColor = vec3(surfaceColor.a); diff --git a/QtMeshViewer/Source/GeometryEngine.cpp b/QtMeshViewer/Source/GeometryEngine.cpp index da2a798..570e55c 100644 --- a/QtMeshViewer/Source/GeometryEngine.cpp +++ b/QtMeshViewer/Source/GeometryEngine.cpp @@ -121,8 +121,9 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) normMatrix.translate(-m_boundings.center[0], -m_boundings.center[1], -m_boundings.center[2]); program->setUniformValue("norm_matrix", normMatrix); - // Allways use texture unit 0 + // Allways use texture unit 0 and 1 program->setUniformValue("texture", 0); + program->setUniformValue("secondTexture", 1); //setup the pipeline setupPipeline(program); @@ -133,23 +134,34 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) { bool tmp_transparent(false); bool tmp_specular(false); + bool tmp_normalmap(false); float shininess(0.0); QVector3D specularColor; // bind the correct texture if (it.textureIndex < (unsigned)m_materials->size() && m_materials->at(it.textureIndex).texture0 != Q_NULLPTR) { - m_materials->at(it.textureIndex).texture0->bind(); + m_materials->at(it.textureIndex).texture0->bind(0); tmp_transparent = m_materials->at(it.textureIndex).transparent; tmp_specular = m_materials->at(it.textureIndex).flags[7]; shininess = m_materials->at(it.textureIndex).shininess; specularColor = m_materials->at(it.textureIndex).specularColor.toVector3D(); + + if (m_materials->at(it.textureIndex).rendertype == 27 || m_materials->at(it.textureIndex).rendertype == 28) + { + if (m_materials->at(it.textureIndex).texture1 != Q_NULLPTR) + { + tmp_normalmap = true; + m_materials->at(it.textureIndex).texture1->bind(1); + } + } } else { - m_defaultMaterial->texture0->bind(); + m_defaultMaterial->texture0->bind(0); tmp_transparent = m_defaultMaterial->transparent; } + // Set model matrix program->setUniformValue("m_matrix", it.modelMatrix); @@ -159,6 +171,7 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) // set some more values program->setUniformValue("b_transparent", tmp_transparent); program->setUniformValue("b_specular", tmp_specular); + program->setUniformValue("b_normalmap", tmp_normalmap); // set some material attributes program->setUniformValue("materialShininess", shininess); diff --git a/preview.jpg b/preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d250f71df00a3778001294af9a32accd7d47821 GIT binary patch literal 44438 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 HY<>6#W=B`% literal 0 HcmV?d00001