From 6cbb2d44bfbfa37c71a3c6b0fcfbe069c5c69315 Mon Sep 17 00:00:00 2001 From: David Williams Date: Fri, 23 May 2014 22:44:58 +0200 Subject: [PATCH] Work on making OpenGLExample work with common example framework. --- examples/OpenGL/main.cpp | 56 +++++++++++++++++++++++++++----- examples/common/OpenGLWidget.cpp | 39 ++++++++++------------ examples/common/OpenGLWidget.h | 11 ++++++- 3 files changed, 74 insertions(+), 32 deletions(-) diff --git a/examples/OpenGL/main.cpp b/examples/OpenGL/main.cpp index e27987db..962079f4 100644 --- a/examples/OpenGL/main.cpp +++ b/examples/OpenGL/main.cpp @@ -81,15 +81,6 @@ int main(int argc, char *argv[]) createCubeInVolume(volData, Vector3DInt32(midPos-10, 1, midPos-10), Vector3DInt32(midPos+10, maxPos-1, midPos+10), MaterialDensityPair44::getMaxDensity()); createCubeInVolume(volData, Vector3DInt32(midPos-10, midPos-10 ,1), Vector3DInt32(midPos+10, midPos+10, maxPos-1), MaterialDensityPair44::getMaxDensity()); - //I've removed this smoothing because it doesn't really make sense to apply a low pass filter to a volume with material values. - //I could implement the mathematical operators for MaterialDensityPair in such a way that they ignores the materials but this - //seems to be setting a bad example. Users can add this operators in their own classes if they want smoothing. - //RawVolume tempVolume(PolyVox::Region(0,0,0,128, 128, 128)); - //LowPassFilter< LargeVolume, RawVolume > pass1(&volData, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), &tempVolume, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), 3); - //pass1.executeSAT(); - //LowPassFilter< RawVolume, LargeVolume > pass2(&tempVolume, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), &volData, PolyVox::Region(Vector3DInt32(62, 62, 62), Vector3DInt32(126, 126, 126)), 3); - //pass2.executeSAT(); - QApplication app(argc, argv); OpenGLWidget openGLWidget(0); @@ -97,6 +88,53 @@ int main(int argc, char *argv[]) openGLWidget.show(); + QGLShaderProgram* shader = new QGLShaderProgram; + + if (!shader->addShaderFromSourceCode(QGLShader::Vertex, R"( + #version 140 + + in vec4 position; //This will be the position of the vertex in model-space + + uniform mat4 cameraToClipMatrix; + uniform mat4 worldToCameraMatrix; + uniform mat4 modelToWorldMatrix; + + out vec4 worldPosition; //This is being passed to the fragment shader to calculate the normals + + void main() + { + worldPosition = modelToWorldMatrix * position; + vec4 cameraPosition = worldToCameraMatrix * worldPosition; + gl_Position = cameraToClipMatrix * cameraPosition; + } + )")) + { + std::cerr << shader->log().toStdString() << std::endl; + exit(EXIT_FAILURE); + } + + if (!shader->addShaderFromSourceCode(QGLShader::Fragment, R"( + #version 130 + + in vec4 worldPosition; //Passed in from the vertex shader + + out vec4 outputColor; + + void main() + { + vec3 normal = normalize(cross(dFdy(worldPosition.xyz), dFdx(worldPosition.xyz))); + + float color = clamp(abs(dot(normalize(normal.xyz), vec3(0.9,0.1,0.5))), 0, 1); + outputColor = vec4(1.0, 1.0, 1.0, 1.0); + } + )")) + { + std::cerr << shader->log().toStdString() << std::endl; + exit(EXIT_FAILURE); + } + + openGLWidget.setShader(shader); + QTime time; time.start(); //openGLWidget.setVolume(&volData); diff --git a/examples/common/OpenGLWidget.cpp b/examples/common/OpenGLWidget.cpp index 78dbff0c..1088d9fe 100644 --- a/examples/common/OpenGLWidget.cpp +++ b/examples/common/OpenGLWidget.cpp @@ -50,8 +50,10 @@ void OpenGLWidget::initializeGL() glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glDepthRange(0.0, 1.0); + + shader = new QGLShaderProgram; - if (!shader.addShaderFromSourceCode(QGLShader::Vertex, R"( + if (!shader->addShaderFromSourceCode(QGLShader::Vertex, R"( #version 140 in vec4 position; //This will be the position of the vertex in model-space @@ -70,11 +72,11 @@ void OpenGLWidget::initializeGL() } )")) { - std::cerr << shader.log().toStdString() << std::endl; + std::cerr << shader->log().toStdString() << std::endl; exit(EXIT_FAILURE); } - if (!shader.addShaderFromSourceCode(QGLShader::Fragment, R"( + if (!shader->addShaderFromSourceCode(QGLShader::Fragment, R"( #version 130 in vec4 worldPosition; //Passed in from the vertex shader @@ -90,15 +92,15 @@ void OpenGLWidget::initializeGL() } )")) { - std::cerr << shader.log().toStdString() << std::endl; + std::cerr << shader->log().toStdString() << std::endl; exit(EXIT_FAILURE); } - shader.bindAttributeLocation("position", 0); + shader->bindAttributeLocation("position", 0); - if(!shader.link()) + if (!shader->link()) { - std::cerr << shader.log().toStdString() << std::endl; + std::cerr << shader->log().toStdString() << std::endl; exit(EXIT_FAILURE); } @@ -114,12 +116,8 @@ void OpenGLWidget::resizeGL(int w, int h) float zNear = 1.0; float zFar = 1000.0; - QMatrix4x4 cameraToClipMatrix{}; + cameraToClipMatrix.setToIdentity(); cameraToClipMatrix.frustum(-aspectRatio, aspectRatio, -1, 1, zNear, zFar); - - shader.bind(); - shader.setUniformValue("cameraToClipMatrix", cameraToClipMatrix); - shader.release(); } void OpenGLWidget::paintGL() @@ -127,13 +125,16 @@ void OpenGLWidget::paintGL() //Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - shader.bind(); + shader->bind(); + + shader->setUniformValue("worldToCameraMatrix", worldToCameraMatrix); + shader->setUniformValue("cameraToClipMatrix", cameraToClipMatrix); for (OpenGLMeshData meshData : mMeshData) { QMatrix4x4 modelToWorldMatrix{}; modelToWorldMatrix.translate(meshData.translation.getX(), meshData.translation.getY(), meshData.translation.getZ()); // Centre the model on the origin - shader.setUniformValue("modelToWorldMatrix", modelToWorldMatrix); // Update to the latest camera matrix + shader->setUniformValue("modelToWorldMatrix", modelToWorldMatrix); // Update to the latest camera matrix glBindVertexArray(meshData.vertexArrayObject); @@ -142,7 +143,7 @@ void OpenGLWidget::paintGL() glBindVertexArray(0); } - shader.release(); + shader->release(); GLenum errCode = glGetError(); if(errCode != GL_NO_ERROR) @@ -174,21 +175,15 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event) void OpenGLWidget::setupWorldToCameraMatrix() { - shader.bind(); - QVector3D lowerCorner(m_viewableRegion.getLowerX(), m_viewableRegion.getLowerY(), m_viewableRegion.getLowerZ()); QVector3D upperCorner(m_viewableRegion.getUpperX(), m_viewableRegion.getUpperY(), m_viewableRegion.getUpperZ()); QVector3D centerPoint = (lowerCorner + upperCorner) * 0.5; float fDiagonalLength = (upperCorner - lowerCorner).length(); - QMatrix4x4 worldToCameraMatrix{}; + worldToCameraMatrix.setToIdentity(); worldToCameraMatrix.translate(0, 0, -fDiagonalLength / 2.0f); //Move the camera back by the required amount worldToCameraMatrix.rotate(m_xRotation, 0, 1, 0); //rotate around y-axis worldToCameraMatrix.rotate(m_yRotation, 1, 0, 0); //rotate around x-axis worldToCameraMatrix.translate(-centerPoint); //centre the model on the origin - - shader.setUniformValue("worldToCameraMatrix", worldToCameraMatrix); - - shader.release(); } \ No newline at end of file diff --git a/examples/common/OpenGLWidget.h b/examples/common/OpenGLWidget.h index 2d9cc6d6..d80b7a70 100644 --- a/examples/common/OpenGLWidget.h +++ b/examples/common/OpenGLWidget.h @@ -53,6 +53,11 @@ public: // The viewable region can be adjusted so that this example framework can be use for different volume sizes. void setViewableRegion(PolyVox::Region viewableRegion); + void setShader(QGLShaderProgram* shader) + { + this->shader = shader; + } + // Convert a SurfaceMesh to OpenGL index/vertex buffers. Inlined because it's templatised. template void addMesh(const MeshType& surfaceMesh) @@ -107,7 +112,11 @@ private: // Index/vertex buffer data std::vector mMeshData; - QGLShaderProgram shader; + QGLShaderProgram* shader; + + // Matrices + QMatrix4x4 worldToCameraMatrix; + QMatrix4x4 cameraToClipMatrix; // Mouse data QPoint m_LastFrameMousePos;