From d61827c365e955f8257d64e768e2a650cf24bd7c Mon Sep 17 00:00:00 2001 From: David Williams Date: Mon, 20 Apr 2009 21:00:28 +0000 Subject: [PATCH] Work on OpenGL Example. --- examples/OpenGL/OpenGLWidget.cpp | 113 +++++++------ examples/OpenGL/OpenGLWidget.h | 2 +- examples/OpenGL/main.cpp | 266 ------------------------------- 3 files changed, 62 insertions(+), 319 deletions(-) diff --git a/examples/OpenGL/OpenGLWidget.cpp b/examples/OpenGL/OpenGLWidget.cpp index e0921ca3..d532fcd9 100644 --- a/examples/OpenGL/OpenGLWidget.cpp +++ b/examples/OpenGL/OpenGLWidget.cpp @@ -12,11 +12,11 @@ using namespace std; OpenGLWidget::OpenGLWidget(QWidget *parent) :QGLWidget(parent) + ,m_volData(0) { m_xRotation = 0; m_yRotation = 0; m_uRegionSideLength = 16.0f; - m_distance = -g_uVolumeSideLength / 2.0f; timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); @@ -87,7 +87,8 @@ void OpenGLWidget::setVolume(PolyVox::Volume* volData) } } - m_distance = m_volData->getLongestSideLength() / -2.0f; + //Projection matrix is dependant on volume size, so we need to set it up again. + setupProjectionMatrix(); } } @@ -124,66 +125,64 @@ void OpenGLWidget::initializeGL() void OpenGLWidget::resizeGL(int w, int h) { - glViewport ( 0, 0, w, h ); - glMatrixMode ( GL_PROJECTION ); // Select The Projection Matrix - glLoadIdentity ( ); // Reset The Projection Matrix + //Setup the viewport based on the window size + glViewport(0, 0, w, h); - float aspect = ( float ) w / ( float ) h; - glOrtho(-m_distance*aspect, m_distance*aspect, -m_distance, m_distance, 1.0, 5000); - glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix - glLoadIdentity ( ); // Reset The Model View Matrix + //Projection matrix is also dependant on the size of the current volume. + if(m_volData) + { + setupProjectionMatrix(); + } } void OpenGLWidget::paintGL() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer - - glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix - glLoadIdentity(); // Reset The Current Modelview Matrix - - //Moves the camera back so we can see the volume - glTranslatef(0.0f, 0.0f, m_distance); - - //Rotate the volume by the required amount - //glRotatef(g_xRotation, 1.0f, 0.0f, 0.0f); - //glRotatef(g_yRotation, 0.0f, 1.0f, 0.0f); - - ; - glRotatef(m_xRotation, 1.0f, 0.0f, 0.0f); - glRotatef(m_yRotation, 0.0f, 1.0f, 0.0f); - - //Centre the volume on the origin - glTranslatef(-g_uVolumeSideLength/2,-g_uVolumeSideLength/2,-g_uVolumeSideLength/2); - - for(PolyVox::uint16_t uRegionZ = 0; uRegionZ < m_uVolumeDepthInRegions; ++uRegionZ) + if(m_volData) { - for(PolyVox::uint16_t uRegionY = 0; uRegionY < m_uVolumeHeightInRegions; ++uRegionY) - { - for(PolyVox::uint16_t uRegionX = 0; uRegionX < m_uVolumeWidthInRegions; ++uRegionX) - { - Vector3DUint8 v3dRegPos(uRegionX,uRegionY,uRegionZ); - if(m_bUseOpenGLVertexBufferObjects) - { - renderRegionVertexBufferObject(m_mapOpenGLSurfacePatches[v3dRegPos]); - } - else - { - IndexedSurfacePatch* ispCurrent = m_mapIndexedSurfacePatches[v3dRegPos]; - renderRegionImmediateMode(*ispCurrent); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer + glMatrixMode(GL_MODELVIEW); // Select The Model View Matrix + glLoadIdentity(); // Reset The Current Modelview Matrix + + //Moves the camera back so we can see the volume + glTranslatef(0.0f, 0.0f, -m_volData->getDiagonalLength()); + + glRotatef(m_xRotation, 1.0f, 0.0f, 0.0f); + glRotatef(m_yRotation, 0.0f, 1.0f, 0.0f); + + //Centre the volume on the origin + glTranslatef(-g_uVolumeSideLength/2,-g_uVolumeSideLength/2,-g_uVolumeSideLength/2); + + for(PolyVox::uint16_t uRegionZ = 0; uRegionZ < m_uVolumeDepthInRegions; ++uRegionZ) + { + for(PolyVox::uint16_t uRegionY = 0; uRegionY < m_uVolumeHeightInRegions; ++uRegionY) + { + for(PolyVox::uint16_t uRegionX = 0; uRegionX < m_uVolumeWidthInRegions; ++uRegionX) + { + Vector3DUint8 v3dRegPos(uRegionX,uRegionY,uRegionZ); + if(m_bUseOpenGLVertexBufferObjects) + { + renderRegionVertexBufferObject(m_mapOpenGLSurfacePatches[v3dRegPos]); + } + else + { + IndexedSurfacePatch* ispCurrent = m_mapIndexedSurfacePatches[v3dRegPos]; + renderRegionImmediateMode(*ispCurrent); + + } } } } + + GLenum errCode; + const GLubyte *errString; + + if ((errCode = glGetError()) != GL_NO_ERROR) + { + errString = gluErrorString(errCode); + cout << "OpenGL Error: " << errString << endl; + } } - - GLenum errCode; - const GLubyte *errString; - - if ((errCode = glGetError()) != GL_NO_ERROR) - { - errString = gluErrorString(errCode); - cout << "OpenGL Error: " << errString << endl; - } // Reset The Current Modelview Matrix } void OpenGLWidget::mousePressEvent(QMouseEvent* event) @@ -203,5 +202,15 @@ void OpenGLWidget::mouseMoveEvent(QMouseEvent* event) void OpenGLWidget::wheelEvent(QWheelEvent* event) { - m_distance += event->delta() / 120.0f; +} + +void OpenGLWidget::setupProjectionMatrix(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + float frustumSize = m_volData->getDiagonalLength() / 2.0f; + float aspect = static_cast(width()) / static_cast(height()); + + glOrtho(frustumSize*aspect, -frustumSize*aspect, frustumSize, -frustumSize, 1.0, 5000); } \ No newline at end of file diff --git a/examples/OpenGL/OpenGLWidget.h b/examples/OpenGL/OpenGLWidget.h index f72ba6ed..de5765b7 100644 --- a/examples/OpenGL/OpenGLWidget.h +++ b/examples/OpenGL/OpenGLWidget.h @@ -37,12 +37,12 @@ class OpenGLWidget : public QGLWidget void paintGL(); private: + void setupProjectionMatrix(void); QPoint m_LastFrameMousePos; QPoint m_CurrentMousePos; int m_xRotation; int m_yRotation; - float m_distance; QTimer *timer; diff --git a/examples/OpenGL/main.cpp b/examples/OpenGL/main.cpp index 926681ad..b2516766 100644 --- a/examples/OpenGL/main.cpp +++ b/examples/OpenGL/main.cpp @@ -79,269 +79,3 @@ int main(int argc, char *argv[]) return app.exec(); } - -#ifdef USING_GLUT - -#ifdef WIN32 -#include "glew/glew.h" -#else -#include // The GL Header File -#endif -#include // The GL Utility Toolkit (Glut) Header] - -#include - -//Some namespaces we need -using namespace std; -using namespace PolyVox; -using namespace std; - -//Global variables are easier for demonstration purposes, especially -//as I'm not sure how/if I can pass variables to the GLUT functions. -//Global variables are denoted by the 'g_' prefix -const uint16_t g_uVolumeSideLength = 256; -const uint16_t g_uRegionSideLength = 16; -const uint16_t g_uVolumeSideLengthInRegions = g_uVolumeSideLength / g_uRegionSideLength; - -int g_xRotation = 0.0f; -int g_yRotation = 0.0f; -int g_xOld = 0; -int g_yOld = 0; - -int g_frameCounter = 0; - -bool g_bUseOpenGLVertexBufferObjects; - -//Creates a volume 128x128x128 -Volume g_volData(g_uVolumeSideLength); - -//Rather than storing one big mesh, the volume is broken into regions and a mesh is stored for each region -OpenGLSurfacePatch g_openGLSurfacePatches[g_uVolumeSideLengthInRegions][g_uVolumeSideLengthInRegions][g_uVolumeSideLengthInRegions]; -IndexedSurfacePatch* g_indexedSurfacePatches[g_uVolumeSideLengthInRegions][g_uVolumeSideLengthInRegions][g_uVolumeSideLengthInRegions]; - -void timerFunc(int value) -{ - cout << "FPS = " << g_frameCounter << endl; - g_frameCounter = 0; - glutTimerFunc(1000, timerFunc, 0); -} - -void init ( GLvoid ) // Create Some Everyday Functions -{ - glShadeModel(GL_SMOOTH); // Enable Smooth Shading - glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background - glClearDepth(1.0f); // Depth Buffer Setup - glEnable(GL_DEPTH_TEST); // Enables Depth Testing - glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do - glEnable ( GL_COLOR_MATERIAL ); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - glEnable(GL_LIGHT0); - - glShadeModel(GL_SMOOTH); -} - -void display ( void ) // Create The Display Function -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer - - glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix - glLoadIdentity(); // Reset The Current Modelview Matrix - - //Moves the camera back so we can see the volume - glTranslatef(0.0f, 0.0f, -100.0f); - - //Rotate the volume by the required amount - glRotatef(g_xRotation, 1.0f, 0.0f, 0.0f); - glRotatef(g_yRotation, 0.0f, 1.0f, 0.0f); - - //Centre the volume on the origin - glTranslatef(-g_uVolumeSideLength/2,-g_uVolumeSideLength/2,-g_uVolumeSideLength/2); - - for(uint16_t uRegionZ = 0; uRegionZ < g_uVolumeSideLengthInRegions; ++uRegionZ) - { - for(uint16_t uRegionY = 0; uRegionY < g_uVolumeSideLengthInRegions; ++uRegionY) - { - for(uint16_t uRegionX = 0; uRegionX < g_uVolumeSideLengthInRegions; ++uRegionX) - { - if(g_bUseOpenGLVertexBufferObjects) - { - renderRegionVertexBufferObject(g_openGLSurfacePatches[uRegionX][uRegionY][uRegionZ]); - } - else - { - IndexedSurfacePatch* ispCurrent = g_indexedSurfacePatches[uRegionX][uRegionY][uRegionZ]; - renderRegionImmediateMode(*ispCurrent); - - } - } - } - } - - GLenum errCode; - const GLubyte *errString; - - if ((errCode = glGetError()) != GL_NO_ERROR) - { - errString = gluErrorString(errCode); - cout << "OpenGL Error: " << errString << endl; - } - - - - g_frameCounter++; - glutSwapBuffers ( ); - // Swap The Buffers To Not Be Left With A Clear Screen -} - -void idle() -{ - glutPostRedisplay(); -} - - -void reshape ( int w, int h ) // Create The Reshape Function (the viewport) -{ - glViewport ( 0, 0, w, h ); - glMatrixMode ( GL_PROJECTION ); // Select The Projection Matrix - glLoadIdentity ( ); // Reset The Projection Matrix - if ( h==0 ) // Calculate The Aspect Ratio Of The Window - gluPerspective ( 80, ( float ) w, 1.0, 5000.0 ); - else - gluPerspective ( 80, ( float ) w / ( float ) h, 1.0, 5000.0 ); - glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix - glLoadIdentity ( ); // Reset The Model View Matrix -} - -void keyboard ( unsigned char key, int x, int y ) // Create Keyboard Function -{ - switch ( key ) { -case 27: // When Escape Is Pressed... - exit ( 0 ); // Exit The Program - break; // Ready For Next Case -default: // Now Wrap It Up - break; - } -} - -void motion(int x, int y) -{ - glMatrixMode(GL_MODELVIEW); - int xDiff = x - g_xOld; - int yDiff = y - g_yOld; - g_xOld = x; - g_yOld = y; - g_xRotation += xDiff; - g_yRotation += yDiff; -} - - -void arrow_keys ( int a_keys, int x, int y ) // Create Special Function (required for arrow keys) -{ - switch ( a_keys ) { -case GLUT_KEY_UP: // When Up Arrow Is Pressed... - glutFullScreen ( ); // Go Into Full Screen Mode - break; -case GLUT_KEY_DOWN: // When Down Arrow Is Pressed... - glutReshapeWindow ( 500, 500 ); // Go Into A 500 By 500 Window - break; -default: - break; - } -} - -void main ( int argc, char** argv ) // Create Main Function For Bringing It All Together -{ - g_bUseOpenGLVertexBufferObjects = true; - glutInit ( &argc, argv ); // Erm Just Write It =) - glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE ); // Display Mode - glutInitWindowSize ( 500, 500 ); // If glutFullScreen wasn't called this is the window size - glutCreateWindow ( "PolyVox OpenGL Example" ); // Window Title (argv[0] for current directory as title) - glutMotionFunc(motion); - glutDisplayFunc ( display ); // Matching Earlier Functions To Their Counterparts - glutReshapeFunc ( reshape ); - glutKeyboardFunc ( keyboard ); - glutSpecialFunc ( arrow_keys ); - glutTimerFunc(1000, timerFunc, 0); - glutIdleFunc(idle); - - if(g_bUseOpenGLVertexBufferObjects) - { -#ifdef WIN32 - //If we are on Windows we will need GLEW to access recent OpenGL functionality - GLenum err = glewInit(); - if (GLEW_OK != err) - { - /* Problem: glewInit failed, something is seriously wrong. */ - cout << "Error: " << glewGetErrorString(err) << endl; - } -#endif - } - - //Make our volume contain a sphere in the center. - uint16_t minPos = 0; - uint16_t midPos = g_volData.getSideLength() / 2; - uint16_t maxPos = g_volData.getSideLength() - 1; - createCubeInVolume(g_volData, Vector3DUint16(minPos, minPos, minPos), Vector3DUint16(maxPos, maxPos, maxPos), 0); - - createSphereInVolume(g_volData, 50.0f, 5); - createSphereInVolume(g_volData, 40.0f, 4); - createSphereInVolume(g_volData, 30.0f, 3); - createSphereInVolume(g_volData, 20.0f, 2); - createSphereInVolume(g_volData, 10.0f, 1); - - createCubeInVolume(g_volData, Vector3DUint16(minPos, minPos, minPos), Vector3DUint16(midPos-1, midPos-1, midPos-1), 0); - createCubeInVolume(g_volData, Vector3DUint16(midPos+1, midPos+1, minPos), Vector3DUint16(maxPos, maxPos, midPos-1), 0); - createCubeInVolume(g_volData, Vector3DUint16(midPos+1, minPos, midPos+1), Vector3DUint16(maxPos, midPos-1, maxPos), 0); - createCubeInVolume(g_volData, Vector3DUint16(minPos, midPos+1, midPos+1), Vector3DUint16(midPos-1, maxPos, maxPos), 0); - - //Our volume is broken down into cuboid regions, and we create one mesh for each region. - //This three-level for loop iterates over each region. - for(uint16_t uRegionZ = 0; uRegionZ < g_uVolumeSideLengthInRegions; ++uRegionZ) - { - for(uint16_t uRegionY = 0; uRegionY < g_uVolumeSideLengthInRegions; ++uRegionY) - { - for(uint16_t uRegionX = 0; uRegionX < g_uVolumeSideLengthInRegions; ++uRegionX) - { - //Create a new surface patch (which is basiaclly the PolyVox term for a mesh). - IndexedSurfacePatch* ispCurrent = new IndexedSurfacePatch(); - - //Compute the extents of the current region - //FIXME - This is a little complex? PolyVox could - //provide more functions for dealing with regions? - uint16_t regionStartX = uRegionX * g_uRegionSideLength; - uint16_t regionStartY = uRegionY * g_uRegionSideLength; - uint16_t regionStartZ = uRegionZ * g_uRegionSideLength; - - uint16_t regionEndX = regionStartX + g_uRegionSideLength + 1; //Why do we need the '+1' here? - uint16_t regionEndY = regionStartY + g_uRegionSideLength + 1; //Why do we need the '+1' here? - uint16_t regionEndZ = regionStartZ + g_uRegionSideLength + 1; //Why do we need the '+1' here? - - Vector3DInt32 regLowerCorner(regionStartX, regionStartY, regionStartZ); - Vector3DInt32 regUpperCorner(regionEndX, regionEndY, regionEndZ); - - //Extract the surface for this region - extractReferenceSurface(&g_volData, Region(regLowerCorner, regUpperCorner), ispCurrent); - - - if(g_bUseOpenGLVertexBufferObjects) - { - g_openGLSurfacePatches[uRegionX][uRegionY][uRegionZ] = BuildOpenGLSurfacePatch(*ispCurrent); - } - else - { - g_indexedSurfacePatches[uRegionX][uRegionY][uRegionZ] = ispCurrent; - } - //delete ispCurrent; - } - } - } - - init (); - - glutMainLoop ( ); // Initialize The Main Loop -} - -#endif //USING_GLUT \ No newline at end of file