diff --git a/QtMeshViewer/Header/OglViewerWidget.h b/QtMeshViewer/Header/OglViewerWidget.h index 7327253..c4cd9b5 100644 --- a/QtMeshViewer/Header/OglViewerWidget.h +++ b/QtMeshViewer/Header/OglViewerWidget.h @@ -38,7 +38,7 @@ private: } m_rotDirections; struct { - QVector3D position = { 10,10,10 }; + QVector3D position = { 1,1,1 }; QVector3D intensities = { 1,0.25,0.25 }; } m_light; @@ -50,7 +50,7 @@ private: QQuaternion m_rotation; bool m_wireframe = false; - bool m_lightOn = true; + bool m_lightOn = false; protected: void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; @@ -68,6 +68,7 @@ protected: private: void initShaders(); void setConnections(); + void updateLightPosition(); private slots: void resetView(); @@ -75,5 +76,6 @@ private slots: public slots: void changeDirection(int direction); void toggleWireframe(); + void toggleLight(); }; diff --git a/QtMeshViewer/Resources/Resources.qrc b/QtMeshViewer/Resources/Resources.qrc index 02ae3fc..ee43df8 100644 --- a/QtMeshViewer/Resources/Resources.qrc +++ b/QtMeshViewer/Resources/Resources.qrc @@ -19,5 +19,6 @@ Z.png screenshot.png wireframe.png + light.png diff --git a/QtMeshViewer/Resources/about.txt b/QtMeshViewer/Resources/about.txt index 51047a0..4ff3b5a 100644 --- a/QtMeshViewer/Resources/about.txt +++ b/QtMeshViewer/Resources/about.txt @@ -8,6 +8,7 @@ left mouse - rotate right mouse - move scroll - zoom space - reset view +L - set light to current position esc - close using the X, Y, Z Button you can activate/deactivate the rotating directions diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl index 19b12fc..f8a9fce 100644 --- a/QtMeshViewer/Resources/fshader.glsl +++ b/QtMeshViewer/Resources/fshader.glsl @@ -15,40 +15,41 @@ uniform struct Light { uniform bool b_transparent; uniform bool b_light; -varying vec2 v_texcoord; -varying vec3 v_position; -varying vec3 v_normal; +varying vec2 v_surfaceUV; +varying vec3 v_surfacePosition; +varying vec3 v_surfaceNormal; void main() { // variables - float brightness; - - if(b_light == true) - { - // calculate normals in worldspace - vec3 normal = normalize(n_matrix * v_normal); - - //get the surface - light vector (cause this is a candel) - vec3 surfaceToLight = light.position - v_position; - - // calculate the brightness depending on the angle - brightness = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal)); - brightness = clamp(brightness, 0, 1); - } - else - { - brightness = 1; - light.intensities = vec3(1,1,1); - } + vec3 diffuse; // get fragment color from texture - vec4 surfaceColor = vec4(texture2D(texture, v_texcoord)); + vec4 surfaceColor = vec4(texture2D(texture, v_surfaceUV)); // if not transparent, ignore alpha value and set it to 1 if(!b_transparent) surfaceColor.a = 1.0f; - // pass the data to ogl - gl_FragColor = vec4(brightness * light.intensities * surfaceColor.rgb, surfaceColor.a); + if(b_light) + { + // calculate normals in worldspace + vec3 normalWorld = normalize(n_matrix * v_surfaceNormal); + + //get the surface - light vector (cause this is a point light) + vec3 surfaceToLight = normalize(light.position - v_surfacePosition); + + // calculate the brightness depending on the angle + float diffuseCoefficient = max(0.0, dot(normalWorld, surfaceToLight)); + + // result diffuse color + diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities; + } + else + { + diffuse = surfaceColor.rgb; + } + + // put all together + gl_FragColor = vec4(diffuse, surfaceColor.a); } diff --git a/QtMeshViewer/Resources/light.png b/QtMeshViewer/Resources/light.png new file mode 100644 index 0000000..16f93e6 Binary files /dev/null and b/QtMeshViewer/Resources/light.png differ diff --git a/QtMeshViewer/Resources/vshader.glsl b/QtMeshViewer/Resources/vshader.glsl index 5282e7a..19b792c 100644 --- a/QtMeshViewer/Resources/vshader.glsl +++ b/QtMeshViewer/Resources/vshader.glsl @@ -12,9 +12,9 @@ attribute vec4 a_position; attribute vec2 a_texcoord; attribute vec3 a_normal; -varying vec2 v_texcoord; -varying vec3 v_position; -varying vec3 v_normal; +varying vec2 v_surfaceUV; +varying vec3 v_surfacePosition; +varying vec3 v_surfaceNormal; void main() { @@ -23,7 +23,7 @@ void main() // Pass data to fragment shader // Value will be automatically interpolated to fragments inside polygon faces - v_texcoord = a_texcoord; - v_position = vec3(norm_matrix * m_matrix * a_position); - v_normal = a_normal; + v_surfaceUV = a_texcoord; + v_surfacePosition = vec3(norm_matrix * m_matrix * a_position); + v_surfaceNormal = a_normal; } diff --git a/QtMeshViewer/Resources/wireframe.png b/QtMeshViewer/Resources/wireframe.png new file mode 100644 index 0000000..191b7fe Binary files /dev/null and b/QtMeshViewer/Resources/wireframe.png differ diff --git a/QtMeshViewer/Source/MainWindow.cpp b/QtMeshViewer/Source/MainWindow.cpp index 250a5c9..c8e0f13 100644 --- a/QtMeshViewer/Source/MainWindow.cpp +++ b/QtMeshViewer/Source/MainWindow.cpp @@ -101,6 +101,12 @@ void MainWindow::setupWidgets() connect(wireframe, &QAction::triggered, viewer, &OglViewerWidget::toggleWireframe); ui->mainToolBar->addAction(wireframe); + QAction *light = new QAction(QIcon(":/images/toolbar/light.png"), "Light", this); + light->setCheckable(true); + light->setChecked(false); + connect(light, &QAction::triggered, viewer, &OglViewerWidget::toggleLight); + ui->mainToolBar->addAction(light); + ui->mainToolBar->addSeparator(); QAction *fileInfo = new QAction(QIcon(":/images/toolbar/info.png"), "File info", this); diff --git a/QtMeshViewer/Source/OglViewerWidget.cpp b/QtMeshViewer/Source/OglViewerWidget.cpp index 2ddd44f..3413548 100644 --- a/QtMeshViewer/Source/OglViewerWidget.cpp +++ b/QtMeshViewer/Source/OglViewerWidget.cpp @@ -173,14 +173,18 @@ void OglViewerWidget::keyPressEvent(QKeyEvent *e) { parentWidget()->close(); } + else if (e->key() == Qt::Key_L) + { + updateLightPosition(); + update(); + } } void OglViewerWidget::initializeGL() { initializeOpenGLFunctions(); - //glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f); - glClearColor(0.02f, 0.01f, 0.01f, 0.0000f); + glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f); initShaders(); @@ -269,6 +273,13 @@ void OglViewerWidget::setConnections() } +void OglViewerWidget::updateLightPosition() +{ + QMatrix4x4 rotateBack; + rotateBack.rotate(m_rotation.inverted()); + m_light.position = rotateBack * (-m_translation); +} + ///////////////////////////////////////////////////////////////////////// // private slots @@ -305,3 +316,21 @@ void OglViewerWidget::toggleWireframe() m_wireframe = 1 - m_wireframe; update(); } + +void OglViewerWidget::toggleLight() +{ + m_lightOn = 1 - m_lightOn; + + if (m_lightOn) + { + glClearColor(m_light.intensities.x() / 100, m_light.intensities.y() / 100, m_light.intensities.z() / 100, 0.0000f); + + updateLightPosition(); + } + else + { + glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f); + } + + update(); +}