From 4f7e1e68460a60cd14cc6523e77ed5ba8095706f Mon Sep 17 00:00:00 2001 From: David Williams Date: Fri, 23 May 2014 22:03:57 +0200 Subject: [PATCH] Each mesh now has it's own transform matrix applied, so that our example framework can support breaking a volume into regions. --- examples/Basic/OpenGLWidget.cpp | 11 ++--- examples/Basic/OpenGLWidget.h | 80 ++++++++++++++++----------------- examples/Basic/main.cpp | 8 ++-- 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/examples/Basic/OpenGLWidget.cpp b/examples/Basic/OpenGLWidget.cpp index edd75b55..78dbff0c 100644 --- a/examples/Basic/OpenGLWidget.cpp +++ b/examples/Basic/OpenGLWidget.cpp @@ -127,17 +127,14 @@ void OpenGLWidget::paintGL() //Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - QMatrix4x4 modelToWorldMatrix{}; - //modelToWorldMatrix.rotate(m_xRotation, 0, 1, 0); //rotate around y-axis - //modelToWorldMatrix.rotate(m_yRotation, 1, 0, 0); //rotate around x-axis - //modelToWorldMatrix.translate(-32, -32, -32); //centre the model on the origin - shader.bind(); - shader.setUniformValue("modelToWorldMatrix", modelToWorldMatrix); //Update to the latest camera matrix - 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 + glBindVertexArray(meshData.vertexArrayObject); glDrawElements(GL_TRIANGLES, meshData.noOfIndices, GL_UNSIGNED_INT, 0); diff --git a/examples/Basic/OpenGLWidget.h b/examples/Basic/OpenGLWidget.h index 7ac39928..2d9cc6d6 100644 --- a/examples/Basic/OpenGLWidget.h +++ b/examples/Basic/OpenGLWidget.h @@ -37,6 +37,7 @@ struct OpenGLMeshData GLuint indexBuffer; GLuint vertexBuffer; GLuint vertexArrayObject; + PolyVox::Vector3DInt32 translation; }; class OpenGLWidget : public QGLWidget @@ -49,13 +50,48 @@ public: void mouseMoveEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); - // Convert a SurfaceMesh to OpenGL index/vertex buffers - template - void addMesh(const MeshType& surfaceMesh); - // The viewable region can be adjusted so that this example framework can be use for different volume sizes. void setViewableRegion(PolyVox::Region viewableRegion); + // Convert a SurfaceMesh to OpenGL index/vertex buffers. Inlined because it's templatised. + template + void addMesh(const MeshType& surfaceMesh) + { + //Convienient access to the vertices and indices + const auto& vecIndices = surfaceMesh.getIndices(); + const auto& vecVertices = surfaceMesh.getVertices(); + + // This struct holds the OpenGL properties (buffer handles, etc) which will be used + // to render our mesh. We copy the data from the PolyVox mesh into this structure. + OpenGLMeshData meshData; + + //Create the VAO for the mesh + glGenVertexArrays(1, &(meshData.vertexArrayObject)); + glBindVertexArray(meshData.vertexArrayObject); + + //The GL_ARRAY_BUFFER will contain the list of vertex positions + glGenBuffers(1, &(meshData.vertexBuffer)); + glBindBuffer(GL_ARRAY_BUFFER, meshData.vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(CubicVertex), vecVertices.data(), GL_STATIC_DRAW); + + //and GL_ELEMENT_ARRAY_BUFFER will contain the indices + glGenBuffers(1, &(meshData.indexBuffer)); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshData.indexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, vecIndices.size() * sizeof(uint32_t), vecIndices.data(), GL_STATIC_DRAW); + + //We need to tell OpenGL how to understand the format of the vertex data + glEnableVertexAttribArray(0); //We're talking about shader attribute '0' + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(CubicVertex), 0); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type) + + glBindVertexArray(0); + + meshData.noOfIndices = vecIndices.size(); //Save this for the call to glDrawElements later + + meshData.translation = surfaceMesh.m_Region.getLowerCorner(); + + mMeshData.push_back(meshData); + } + protected: @@ -83,40 +119,4 @@ private: int m_yRotation; }; -template -void OpenGLWidget::addMesh(const MeshType& surfaceMesh) -{ - //Convienient access to the vertices and indices - const auto& vecIndices = surfaceMesh.getIndices(); - const auto& vecVertices = surfaceMesh.getVertices(); - - // This struct holds the OpenGL properties (buffer handles, etc) which will be used - // to render our mesh. We copy the data from the PolyVox mesh into this structure. - OpenGLMeshData meshData; - - //Create the VAO for the mesh - glGenVertexArrays(1, &(meshData.vertexArrayObject)); - glBindVertexArray(meshData.vertexArrayObject); - - //The GL_ARRAY_BUFFER will contain the list of vertex positions - glGenBuffers(1, &(meshData.vertexBuffer)); - glBindBuffer(GL_ARRAY_BUFFER, meshData.vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(CubicVertex), vecVertices.data(), GL_STATIC_DRAW); - - //and GL_ELEMENT_ARRAY_BUFFER will contain the indices - glGenBuffers(1, &(meshData.indexBuffer)); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshData.indexBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, vecIndices.size() * sizeof(uint32_t), vecIndices.data(), GL_STATIC_DRAW); - - //We need to tell OpenGL how to understand the format of the vertex data - glEnableVertexAttribArray(0); //We're talking about shader attribute '0' - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(CubicVertex), 0); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type) - - glBindVertexArray(0); - - meshData.noOfIndices = vecIndices.size(); //Save this for the call to glDrawElements later - - mMeshData.push_back(meshData); -} - #endif //__BasicExample_OpenGLWidget_H__ diff --git a/examples/Basic/main.cpp b/examples/Basic/main.cpp index b422f1c4..ee908dd7 100644 --- a/examples/Basic/main.cpp +++ b/examples/Basic/main.cpp @@ -78,16 +78,16 @@ int main(int argc, char *argv[]) createSphereInVolume(volData, 30); // Extract the surface for the specified region of the volume. Uncomment the line for the kind of surface extraction you want to see. - auto mesh = extractCubicMesh(&volData, volData.getEnclosingRegion()); + //auto mesh = extractCubicMesh(&volData, volData.getEnclosingRegion()); //auto mesh = extractMarchingCubesMesh(&volData, volData.getEnclosingRegion()); - //auto mesh = extractCubicMesh(&volData, PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(31, 31, 31))); - //auto mesh2 = extractCubicMesh(&volData, PolyVox::Region(Vector3DInt32(32, 32, 32), Vector3DInt32(63, 63, 63))); + auto mesh = extractCubicMesh(&volData, PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(31, 31, 31))); + auto mesh2 = extractCubicMesh(&volData, PolyVox::Region(Vector3DInt32(32, 32, 32), Vector3DInt32(63, 63, 63))); //Pass the surface to the OpenGL window openGLWidget.addMesh(mesh); + openGLWidget.addMesh(mesh2); openGLWidget.setViewableRegion(volData.getEnclosingRegion()); - //openGLWidget.addMesh(mesh2); //Run the message pump. return app.exec();