diff --git a/Extras/GPUphysics/CHANGES b/Extras/GPUphysics/CHANGES index dbc22551a..935ec323d 100644 --- a/Extras/GPUphysics/CHANGES +++ b/Extras/GPUphysics/CHANGES @@ -24,6 +24,13 @@ GPUphysics-0.3 * Use signed initial velocities so everything doesn't slide off the screen! * The 'bounce' now slows down X/Z motion as well as Y so things actually do stop moving eventually. +* Caught up with some portability issues for more recent versions of + GLSL. + +GPUphysics-0.4 +============== + +* Test for availability of vertex shader textures. +* Fixed 'status: xxxx' message. +* Added support for running the demo in the absence of vertex shader textures. -* Added to the Bullet Subversion repository at Sourceforge.net - See http://sf.net/projects/bullet diff --git a/Extras/GPUphysics/CMakeLists.txt b/Extras/GPUphysics/CMakeLists.txt index 4c453381b..e0c76c26c 100644 --- a/Extras/GPUphysics/CMakeLists.txt +++ b/Extras/GPUphysics/CMakeLists.txt @@ -1,66 +1,66 @@ -PROJECT(GPUphysics) - -# This is basically the overall name of the project in Visual Studio this is the name of the Solution File - - -# For every executable you have with a main method you should have an add_executable line below. -# For every add executable line you should list every .cpp and .h file you have associated with that executable. - - -# This is the variable for Windows. I use this to define the root of my directory structure. -SET(GLUT_ROOT ${GPUphysics_SOURCE_DIR}/Glut) - -# You shouldn't have to modify anything below this line -######################################################## - - -# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system -# This should be the case. -INCLUDE (${CMAKE_ROOT}/Modules/FindGLU.cmake) -INCLUDE (${CMAKE_ROOT}/Modules/FindGLUT.cmake) -INCLUDE (${CMAKE_ROOT}/Modules/FindOpenGL.cmake) - - - -IF (WIN32) - # This is the Windows code for which Opengl, and Glut are not properly installed - # since I can't install them I must cheat and copy libraries around - INCLUDE_DIRECTORIES(${GLUT_ROOT}) - # LINK_DIRECTORIES(${GLUT_ROOT}\\lib) - IF (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") - SET(GLUT_glut_LIBRARY ${GPUphysics_SOURCE_DIR}/Glut/glut32.lib) - # LINK_LIBRARIES(${GLUT_ROOT}\\lib\\glut32 ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) - # TARGET_LINK_LIBRARIES(table ${GLUT_ROOT}\\lib\\glut32) -# -# ADD_CUSTOM_COMMAND(TARGET table POST_BUILD COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2005\\Debug -# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2003\\Debug -# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs6\\Debug) - ELSE (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") -# LINK_LIBRARIES(${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) -# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY}) - ENDIF(${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") -# TARGET_LINK_LIBRARIES(table ${OPENGL_gl_LIBRARY}) -# TARGET_LINK_LIBRARIES(table ${OPENGL_glu_LIBRARY}) -ELSE (WIN32) - # This is the lines for linux. This should always work if everything is installed and working fine. -# SET(CMAKE_BUILD_TYPE Debug) -# SET(CMAKE_CXX_FLAGS_DEBUG "-g") - INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR}) -# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) -# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) -ENDIF (WIN32) - -INCLUDE_DIRECTORIES( -glew/include -) - -LINK_LIBRARIES( - glew/lib/glew32.lib ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY} -) - -ADD_EXECUTABLE(GPUphysics - fboSupport.cxx - GPU_physics_demo.cxx - shaderSupport.cxx -) - +PROJECT(GPUphysics) + +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${GPUphysics_SOURCE_DIR}/../../Glut) + +# You shouldn't have to modify anything below this line +######################################################## + + +# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system +# This should be the case. +INCLUDE (${CMAKE_ROOT}/Modules/FindGLU.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindGLUT.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindOpenGL.cmake) + + + +IF (WIN32) + # This is the Windows code for which Opengl, and Glut are not properly installed + # since I can't install them I must cheat and copy libraries around + INCLUDE_DIRECTORIES(${GLUT_ROOT}) + # LINK_DIRECTORIES(${GLUT_ROOT}\\lib) + IF (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") + SET(GLUT_glut_LIBRARY ${GPUphysics_SOURCE_DIR}/Glut/glut32.lib) + # LINK_LIBRARIES(${GLUT_ROOT}\\lib\\glut32 ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) + # TARGET_LINK_LIBRARIES(table ${GLUT_ROOT}\\lib\\glut32) +# +# ADD_CUSTOM_COMMAND(TARGET table POST_BUILD COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2005\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2003\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs6\\Debug) + ELSE (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# LINK_LIBRARIES(${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY}) + ENDIF(${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# TARGET_LINK_LIBRARIES(table ${OPENGL_gl_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${OPENGL_glu_LIBRARY}) +ELSE (WIN32) + # This is the lines for linux. This should always work if everything is installed and working fine. +# SET(CMAKE_BUILD_TYPE Debug) +# SET(CMAKE_CXX_FLAGS_DEBUG "-g") + INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +ENDIF (WIN32) + +INCLUDE_DIRECTORIES( +../../Glut/GL/include +) + +LINK_LIBRARIES( + ../../Glut/glew/lib/glew32.lib ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY} +) + +ADD_EXECUTABLE(GPUphysics + fboSupport.cxx + GPU_physics_demo.cxx + shaderSupport.cxx +) + diff --git a/Extras/GPUphysics/DEBUGGING_README b/Extras/GPUphysics/DEBUGGING_README index ca45b70a0..aaccf8b97 100644 --- a/Extras/GPUphysics/DEBUGGING_README +++ b/Extras/GPUphysics/DEBUGGING_README @@ -24,24 +24,10 @@ help with our debugging problems. something is amiss in shader-land. There are several possibilities - the nastiest of which might - be that either: - - a) Your graphics card/driver doesn't support floating point - textures. (This is pretty much 'Game Over' for you because - without that, doing physics in the GPU is going to be - virtually impossible). - - b) Your graphics card/driver doesn't support vertex shader - textures (or it supports them but sets the maximum number - to zero - which is the same thing). This means that we - can't move things around using GPU textures - but we can - still use the GPU to accellerate physics calculations. - In practical game scenarios, I think the CPU needs to know - where all the objects are - so this may not be the serious - issue it sounds like. What it mostly does is to clobber - the idea of running physics on particle system types of - effect where a vast number of objects are involved but - where individual objects have zero effect on game play. + be that your graphics card/driver doesn't support floating point + textures. (This is pretty much 'Game Over' for you because + without that, doing physics in the GPU is going to be + virtually impossible). 3) Run without forces being applied: @@ -63,5 +49,15 @@ help with our debugging problems. This is the most likely scenario. +4) Run without vertex texturing: + GPU_physics_demo -v + + On hardware that doesn't support vertex texturing, this flag + is turned on by default (and things run about 5x slower!) + + Use this flag to force the software to run without vertex + texturing on hardware that does actually support it. + + You can use this flag in conjunction with any of the others. diff --git a/Extras/GPUphysics/GPU_physics.h b/Extras/GPUphysics/GPU_physics.h new file mode 100644 index 000000000..5850cf5d3 --- /dev/null +++ b/Extras/GPUphysics/GPU_physics.h @@ -0,0 +1,101 @@ + +/**********************\ +* * +* Determine OS type * +* * +\**********************/ + +#if defined(__CYGWIN__) +#define GPUP_WIN32 1 +#define GPUP_CYGWIN 1 /* Windoze AND Cygwin. */ +#elif defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) +#define GPUP_WIN32 1 +#define GPUP_MSVC 1 /* Windoze AND MSVC. */ +#elif defined(__BEOS__) +#define GPUP_BEOS 1 +#elif defined( macintosh ) +#define GPUP_MACINTOSH 1 +#elif defined(__APPLE__) +#define GPUP_MAC_OSX 1 +#elif defined(__linux__) +#define GPUP_LINUX 1 +#elif defined(__sgi) +#define GPUP_IRIX 1 +#elif defined(_AIX) +#define GPUP_AIX 1 +#elif defined(SOLARIS) || defined(sun) +#define GPUP_SOLARIS 1 +#elif defined(hpux) +#define GPUP_HPUX 1 +#elif (defined(__unix__) || defined(unix)) && !defined(USG) +#define GPUP_BSD 1 +#endif +#if defined(BORLANDBUILDER) +#define GPUP_BB 1 +#endif + +#include +#include +#include + +/* + Add specialised includes/defines... +*/ + +#ifdef GPUP_WIN32 +#include +#include +#include +#define GPUP_WGL 1 +#endif + +#ifdef GPUP_CYGWIN +#include +#define GPUP_WGL 1 +#endif + +#ifdef GPUP_BEOS +#include +#define GPUP_GLX 1 +#endif + +#ifdef GPUP_MACINTOSH +#include +#include +#define GPUP_AGL 1 +#endif + +#ifdef GPUP_MAC_OSX +#include +#define GPUP_CGL 1 +#endif + +#if defined(GPUP_LINUX) || defined(GPUP_BSD) || defined(GPUP_IRIX) || defined(GPUP_SOLARIS) || defined(GPUP_AIX) +#include +#include +#include +#define GPUP_GLX 1 +#endif + +#if defined(GPUP_BSD) +#include +#define GPUP_GLX 1 +#endif + +#include +#include +#include +#include +#include + +#include + +#if defined(GPUP_MAC_OSX) && !defined (VMDMESA) +#include +#include +#include +#else +#include +#include +#endif + diff --git a/Extras/GPUphysics/GPU_physics_demo.cxx b/Extras/GPUphysics/GPU_physics_demo.cxx index 4fe54bddb..12383852d 100644 --- a/Extras/GPUphysics/GPU_physics_demo.cxx +++ b/Extras/GPUphysics/GPU_physics_demo.cxx @@ -1,17 +1,4 @@ -#ifndef WIN32 -#include -#endif -#include -#include -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#include -#endif +#include "GPU_physics.h" #include "fboSupport.h" #include "shaderSupport.h" @@ -25,7 +12,49 @@ enum DebugOptions } ; -DebugOptions debugOpt = DRAW_ALL ; +static float *positionData = NULL ; +static float *rotationData = NULL ; +static bool noVertexTextureSupport = false ; +static DebugOptions debugOpt = DRAW_ALL ; + +void checkVertexTextureSupport ( bool disableVertexTextureSupport ) +{ + GLint nVertTextures ; + GLint nFragTextures ; + GLint nCombTextures ; + + glGetIntegerv ( GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, & nVertTextures ) ; + glGetIntegerv ( GL_MAX_TEXTURE_IMAGE_UNITS, & nFragTextures ) ; + glGetIntegerv ( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, & nCombTextures ) ; + + fprintf(stderr, "INFO: This hardware supports at most:\n" + " %2d vert texture samplers\n" + " %2d frag texture samplers\n" + " %2d total texture samplers\n", + nVertTextures, nFragTextures, nCombTextures ) ; + + noVertexTextureSupport = ( nVertTextures < 2 ) ; + + if ( noVertexTextureSupport && debugOpt != DRAW_WITHOUT_SHADERS ) + { + fprintf ( stderr, "\n" + "********************************************\n" + "* *\n" + "* WARNING: This graphics card doesn't have *\n" + "* vertex shader texture support - a work- *\n" + "* around will be used - but this demo will *\n" + "* be much less impressive as a result! *\n" + "* *\n" + "********************************************\n\n" ) ; + } + + if ( ! noVertexTextureSupport && disableVertexTextureSupport ) + { + fprintf ( stderr, "WARNING: Vertex Texture Support has" + "been disabled from the command line.\n" ) ; + noVertexTextureSupport = true ; + } +} float frand ( float max ) @@ -33,6 +62,7 @@ float frand ( float max ) return (float)(rand() % 32767) * max / 32767.0f ; } + static GLSL_ShaderPair *velocityGenerator ; static GLSL_ShaderPair *positionGenerator ; static GLSL_ShaderPair *collisionGenerator ; @@ -44,6 +74,7 @@ static FrameBufferObject *velocity ; static FrameBufferObject *rotvelocity ; static FrameBufferObject *force ; static FrameBufferObject *mass ; +static FrameBufferObject *old ; #define TEX_SIZE 128 #define NUM_CUBES ( TEX_SIZE * TEX_SIZE ) @@ -77,7 +108,9 @@ void reshape ( int wid, int ht ) } -void initGLcontext ( int argc, char **argv, void (*display)(void) ) +void initGLcontext ( int argc, char **argv, + void (*display)(void), + bool disableVertexTextureSupport ) { glutInit ( &argc, argv ) ; glutInitDisplayMode ( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ) ; @@ -88,6 +121,8 @@ void initGLcontext ( int argc, char **argv, void (*display)(void) ) glutReshapeFunc ( reshape ) ; glewInit () ; + + checkVertexTextureSupport ( disableVertexTextureSupport ) ; } @@ -97,6 +132,7 @@ void initMotionTextures () position = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; rotation = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; + old = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; if ( debugOpt == DRAW_WITHOUT_PHYSICS ) { @@ -122,8 +158,9 @@ void initMotionTextures () } } - float *positionData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; - float *rotationData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; + positionData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; + rotationData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; + float *velocityData ; float *rotvelocityData ; float *forceData ; @@ -175,9 +212,9 @@ void initMotionTextures () if ( debugOpt != DRAW_WITHOUT_PHYSICS ) { /* Random (but predominantly upwards) velocities. */ - velocityData [ (i*TEX_SIZE + j) * 3 + 0 ] = frand ( 10.0f ) ; + velocityData [ (i*TEX_SIZE + j) * 3 + 0 ] = frand ( 10.0f ) - 5.0f; velocityData [ (i*TEX_SIZE + j) * 3 + 1 ] = frand ( 100.0f ) ; - velocityData [ (i*TEX_SIZE + j) * 3 + 2 ] = frand ( 10.0f ) ; + velocityData [ (i*TEX_SIZE + j) * 3 + 2 ] = frand ( 10.0f ) - 5.0f; /* Random rotational velocities */ rotvelocityData [ (i*TEX_SIZE + j) * 3 + 0 ] = frand ( 3.0f ) ; @@ -201,6 +238,7 @@ void initMotionTextures () position -> fillTexture ( positionData ) ; rotation -> fillTexture ( rotationData ) ; + old -> fillTexture ( positionData ) ; // Doesn't really need it... if ( debugOpt != DRAW_WITHOUT_PHYSICS ) { @@ -237,15 +275,14 @@ void initPhysicsShaders () velocityGenerator = new GLSL_ShaderPair ( "VelocityGenerator", NULL, NULL, - "uniform float delta_T ;" - "uniform vec3 g ;" + "uniform vec4 g_dt ;" "uniform sampler2D old_velocity ;" "uniform sampler2D force ;" "uniform sampler2D mass ;" "void main() {" " gl_FragColor = vec4 (" " texture2D ( old_velocity, gl_TexCoord[0].st ).xyz +" - " delta_T * ( g +" + " g_dt.w * ( g_dt.xyz +" " texture2D ( force , gl_TexCoord[0].st ).xyz /" " texture2D ( mass , gl_TexCoord[0].st ).x)," " 1.0 ) ; }", @@ -290,7 +327,7 @@ void initPhysicsShaders () "void main() {" " vec3 pos = texture2D ( position , gl_TexCoord[0].st ).xyz ;" " vec3 vel = texture2D ( old_velocity, gl_TexCoord[0].st ).xyz ;" - " if ( pos [ 1 ] < 0.0 ) vel [ 1 ] *= -0.90 ;" + " if ( pos [ 1 ] < 0.0 ) vel *= vec3(0.90,-0.90,0.90) ;" " gl_FragColor = vec4 ( vel, 1.0 ) ; }", "CollisionGenerator Frag Shader" ) ; assert ( collisionGenerator -> compiledOK () ) ; @@ -303,15 +340,17 @@ void initCubeVBO () float *p = vertices ; float *t = texcoords ; float *c = colours ; + int nverts = 0 ; - for ( int k = 0 ; k < NUM_CUBES * STRIPS_PER_CUBE ; k++ ) + for ( int k = 0 ; + k < (noVertexTextureSupport ? 1 : NUM_CUBES) * STRIPS_PER_CUBE ; k++ ) { starts [ k ] = k * VERTS_PER_STRIP ; lengths [ k ] = VERTS_PER_STRIP ; } - for ( int i = 0 ; i < TEX_SIZE ; i++ ) - for ( int j = 0 ; j < TEX_SIZE ; j++ ) + for ( int i = 0 ; i < (noVertexTextureSupport ? 1 : TEX_SIZE) ; i++ ) + for ( int j = 0 ; j < (noVertexTextureSupport ? 1 : TEX_SIZE) ; j++ ) { int n = i * TEX_SIZE + j ; @@ -363,21 +402,23 @@ void initCubeVBO () *p++ = +1 + dx ; *p++ = -1 + dy ; *p++ = +1 + dz ; *p++ = +1 + dx ; *p++ = +1 + dy ; *p++ = -1 + dz ; *p++ = +1 + dx ; *p++ = +1 + dy ; *p++ = +1 + dz ; + + nverts += STRIPS_PER_CUBE * VERTS_PER_STRIP ; } glGenBuffersARB ( 1, & vbo_vx ) ; glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_vx ) ; - glBufferDataARB ( GL_ARRAY_BUFFER_ARB, NUM_VERTS * 3 * sizeof(float), + glBufferDataARB ( GL_ARRAY_BUFFER_ARB, nverts * 3 * sizeof(float), vertices, GL_STATIC_DRAW_ARB ) ; glGenBuffersARB ( 1, & vbo_tx ) ; glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_tx ) ; - glBufferDataARB ( GL_ARRAY_BUFFER_ARB, NUM_VERTS * 2 * sizeof(float), + glBufferDataARB ( GL_ARRAY_BUFFER_ARB, nverts * 2 * sizeof(float), texcoords, GL_STATIC_DRAW_ARB ) ; glGenBuffersARB ( 1, & vbo_co ) ; glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_co ) ; - glBufferDataARB ( GL_ARRAY_BUFFER_ARB, NUM_VERTS * 4 * sizeof(float), + glBufferDataARB ( GL_ARRAY_BUFFER_ARB, nverts * 4 * sizeof(float), colours, GL_STATIC_DRAW_ARB ) ; glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0 ) ; @@ -386,15 +427,89 @@ void initCubeVBO () cubeShader = NULL ; else { - cubeShader = new GLSL_ShaderPair ( "CubeShader", "cubeShader.vert", - "cubeShader.frag" ) ; + if ( noVertexTextureSupport ) + cubeShader = new GLSL_ShaderPair ( "CubeShader", "cubeShaderNoTexture.vert", + "cubeShader.frag" ) ; + else + cubeShader = new GLSL_ShaderPair ( "CubeShader", "cubeShader.vert", + "cubeShader.frag" ) ; assert ( cubeShader -> compiledOK () ) ; } } +void drawCubesTheHardWay () +{ + /* + Without vertex texture support, we have to read the position/rotation + data back from the hardware every frame and render each cube individually. + */ + + float p0 = positionData [ 0 ] ; + float p1 = positionData [ 1 ] ; + float p2 = positionData [ 2 ] ; + + position -> fetchTexture ( positionData ) ; + rotation -> fetchTexture ( rotationData ) ; + + if ( positionData [ 0 ] == p0 && + positionData [ 1 ] == p1 && + positionData [ 2 ] == p2 ) + { + fprintf ( stderr, "WARNING: If nothing seems to be working, you may\n" + "have an old version of the nVidia driver.\n" + "Version 76.76 is known to be bad.\n" ) ; + } + + cubeShader -> use () ; /* Math = Cube shader */ + + glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ; + + glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ; + + glEnableClientState ( GL_COLOR_ARRAY ) ; + glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_co ) ; + glColorPointer ( 4, GL_FLOAT, 0, vbo_co ? NULL : colours ) ; + + glEnableClientState ( GL_VERTEX_ARRAY ) ; + glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_vx ) ; + glVertexPointer ( 3, GL_FLOAT, 0, vbo_vx ? NULL : vertices ) ; + + for ( int i = 0 ; i < TEX_SIZE ; i++ ) + for ( int j = 0 ; j < TEX_SIZE ; j++ ) + { + float *pos = & positionData [ (i*TEX_SIZE + j) * 3 ] ; + float *rot = & rotationData [ (i*TEX_SIZE + j) * 3 ] ; + + glPushMatrix () ; + glTranslatef ( pos [ 0 ], pos [ 1 ], pos [ 2 ] ) ; + glRotatef ( rot [ 0 ] * 180.0f / 3.14159f, 0, 1, 0 ) ; + glRotatef ( rot [ 1 ] * 180.0f / 3.14159f, 1, 0, 0 ) ; + glRotatef ( rot [ 2 ] * 180.0f / 3.14159f, 0, 0, 1 ) ; + glMultiDrawArraysEXT ( GL_TRIANGLE_STRIP, (GLint*)starts, (GLint*)lengths, + STRIPS_PER_CUBE ) ; + glPopMatrix () ; + } + + glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0 ) ; + glPopClientAttrib () ; +} + + void drawCubeVBO () { + /* + With vertex texture support, we can leave the position/rotation + data on the hardware and render all of the cubes in one big VBO! + */ + + if ( debugOpt != DRAW_WITHOUT_SHADERS ) + { + cubeShader -> use () ; /* Math = Cube shader */ + cubeShader -> applyTexture ( "position", position, 0 ) ; + cubeShader -> applyTexture ( "rotation", rotation, 1 ) ; + } + glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ; glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ; @@ -437,12 +552,17 @@ void drawCubes () glClearColor ( 0.7f, 0.7f, 0.7f, 1.0f ) ; glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ; - drawCubeVBO () ; + if ( noVertexTextureSupport ) + drawCubesTheHardWay () ; + else + drawCubeVBO () ; } void display ( void ) { + FrameBufferObject *tmp ; + if ( debugOpt != DRAW_WITHOUT_SHADERS && debugOpt != DRAW_WITHOUT_PHYSICS ) { @@ -450,31 +570,50 @@ void display ( void ) if ( debugOpt != DRAW_WITHOUT_FORCES ) { + /* Copy old velocity into old. */ + tmp = old ; + old = velocity ; + velocity = tmp ; + velocityGenerator -> use () ; - velocityGenerator -> applyTexture ( "old_velocity", velocity, 0 ) ; + velocityGenerator -> applyTexture ( "old_velocity", old , 0 ) ; velocityGenerator -> applyTexture ( "force" , force , 1 ) ; velocityGenerator -> applyTexture ( "mass" , mass , 2 ) ; - velocityGenerator -> setUniform1f ( "delta_T" , 0.016f ) ; - velocityGenerator -> setUniform3f ( "g", 0.0f, -9.8f, 0.0f ) ; + velocityGenerator -> setUniform4f ( "g_dt", 0.0f, -9.8f, 0.0f, 0.016f ) ; velocity -> paint () ; } + /* Copy old position into old. */ + tmp = old ; + old = position ; + position = tmp ; + positionGenerator -> use () ; - positionGenerator -> applyTexture ( "old_position", position, 0 ) ; + positionGenerator -> applyTexture ( "old_position", old , 0 ) ; positionGenerator -> applyTexture ( "velocity" , velocity, 1 ) ; positionGenerator -> setUniform1f ( "delta_T", 0.016f ) ; position -> paint () ; if ( debugOpt != DRAW_WITHOUT_COLLISIONS ) { + /* Copy old velocity into old. */ + tmp = old ; + old = velocity ; + velocity = tmp ; + collisionGenerator -> use () ; collisionGenerator -> applyTexture ( "position" , position, 0 ) ; - collisionGenerator -> applyTexture ( "old_velocity", velocity, 1 ) ; + collisionGenerator -> applyTexture ( "old_velocity", old , 1 ) ; velocity -> paint () ; } + /* Copy old rotation into old. */ + tmp = old ; + old = rotation ; + rotation = tmp ; + positionGenerator -> use () ; - positionGenerator -> applyTexture ( "old_position", rotation , 0 ) ; + positionGenerator -> applyTexture ( "old_position", old , 0 ) ; positionGenerator -> applyTexture ( "velocity" , rotvelocity, 1 ) ; positionGenerator -> setUniform1f ( "delta_T", 0.016f ) ; rotation -> paint () ; @@ -486,13 +625,6 @@ void display ( void ) glViewport ( 0, 0, win_width, win_height ) ; - if ( debugOpt != DRAW_WITHOUT_SHADERS ) - { - cubeShader -> use () ; /* Math = Cube shader */ - cubeShader -> applyTexture ( "position", position, 0 ) ; - cubeShader -> applyTexture ( "rotation", rotation, 1 ) ; - } - drawCubes () ; /* All done! */ @@ -505,19 +637,22 @@ void display ( void ) void help () { fprintf ( stderr, "GPUphysics: Usage -\n\n" ) ; - fprintf ( stderr, " GPUphysics_demo [-c][-p][-v][-a]\n\n" ) ; + fprintf ( stderr, " GPUphysics_demo [-c][-p][-v][-a][-v]\n\n" ) ; fprintf ( stderr, "Where:\n" ) ; fprintf ( stderr, " -s -- Draw with shaders at all\n" ) ; fprintf ( stderr, " -p -- Draw with shaders but no physics\n" ) ; fprintf ( stderr, " -c -- Draw with physics but no ground collisions\n" ) ; fprintf ( stderr, " -f -- Draw with physics but no forces\n" ) ; fprintf ( stderr, " -a -- Draw with all features enabled [default]\n" ) ; + fprintf ( stderr, " -v -- Disable vertex textures even if " + "they are supported in hardware\n" ) ; fprintf ( stderr, "\n" ) ; } int main ( int argc, char **argv ) { + bool disableVertexTextureSupport = false ; debugOpt = DRAW_ALL ; for ( int i = 1 ; i < argc ; i++ ) @@ -532,6 +667,7 @@ int main ( int argc, char **argv ) case 'f' : debugOpt = DRAW_WITHOUT_FORCES ; break ; case 'a' : debugOpt = DRAW_ALL ; break ; + case 'v' : disableVertexTextureSupport = true ; break ; default : help () ; exit ( 0 ) ; } else @@ -541,8 +677,7 @@ int main ( int argc, char **argv ) } } - initGLcontext ( argc, argv, display ) ; - + initGLcontext ( argc, argv, display, disableVertexTextureSupport ) ; initMotionTextures () ; initPhysicsShaders () ; initCubeVBO () ; diff --git a/Extras/GPUphysics/Makefile b/Extras/GPUphysics/Makefile index 8062dbd48..0745b2ddd 100644 --- a/Extras/GPUphysics/Makefile +++ b/Extras/GPUphysics/Makefile @@ -1,5 +1,5 @@ -HDRS = fboSupport.h shaderSupport.h +HDRS = fboSupport.h shaderSupport.h GPU_physics.h OBJS = GPU_physics_demo.o fboSupport.o shaderSupport.o all: ${OBJS} diff --git a/Extras/GPUphysics/README b/Extras/GPUphysics/README index 8ee76ae31..4a999c257 100644 --- a/Extras/GPUphysics/README +++ b/Extras/GPUphysics/README @@ -25,7 +25,8 @@ GPU_physics_demo.cxx -- The application code. GLSLShader Sources used in the Demo: cubeShader.vert -cubeShader.frag -- Used to render the cubes. +cubeShaderNoVertexTexture.vert +cubeShader.frag ---------------------------------------------------------- The objective of this library is to provide a basis for the diff --git a/Extras/GPUphysics/fboSupport.cxx b/Extras/GPUphysics/fboSupport.cxx index e87f2ec95..8da23de18 100644 --- a/Extras/GPUphysics/fboSupport.cxx +++ b/Extras/GPUphysics/fboSupport.cxx @@ -1,18 +1,6 @@ -#include -#include -#include +#include "GPU_physics.h" // #define FBO_USE_NVIDIA_FLOAT_TEXTURE_EXTENSION 1 -#include - -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#include -#endif #include "fboSupport.h" #ifdef FBO_USE_NVIDIA_FLOAT_TEXTURE_EXTENSION @@ -53,12 +41,18 @@ static void checkFrameBufferStatus () { case GL_FRAMEBUFFER_COMPLETE_EXT : break ; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT : - /* choose different formats */ + fprintf ( stderr, "ERROR: Unsupported FBO setup.\n" ) ; + exit ( 1 ) ; + + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT : + fprintf ( stderr, "WARNING: Incomplete FBO setup.\n" ) ; break ; + default : - printf("status : %i\n",status); - assert ( 1 ) ; /* programming error; will fail on all hardware */ + fprintf ( stderr, "WARNING: Unexpected FBO status : 0x%04x\n", status ) ; + break ; } } @@ -174,13 +168,15 @@ FrameBufferObject::FrameBufferObject ( int _width , GL_RENDERBUFFER_EXT, depth_rb ) ; #ifdef NEED_STENCIL_BUFFER - statuc GLuint stencil_rb ; + static GLuint stencil_rb ; glGenRenderbuffersEXT ( 1, & stencil_rb ) ; // initialize stencil renderbuffer glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT, stencil_rb ) ; glRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, width, height ) ; glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencil_rb ) ; +#else + glDisable ( GL_STENCIL_TEST ) ; #endif // Check framebuffer completeness at the end of initialization. @@ -191,6 +187,43 @@ FrameBufferObject::FrameBufferObject ( int _width , +void FrameBufferObject::fetchTexture ( void *data ) +{ + glBindTexture ( GL_TEXTURE_2D, textureHandle ) ; + glGetTexImage ( GL_TEXTURE_2D, 0, /* MIP level...zero */ + format, /* External format */ + type, /* Data type */ + data /* Image data */ ) ; +} + + + +void FrameBufferObject::fetchTexture ( unsigned char *data ) +{ + if ( type != FBO_UNSIGNED_BYTE ) + { + fprintf ( stderr, "FBO: Data format mismatch!" ) ; + return ; + } + + fetchTexture ( (void *)data ) ; +} + + + +void FrameBufferObject::fetchTexture ( float *data ) +{ + if ( type != FBO_FLOAT ) + { + fprintf ( stderr, "FBO: Data format mismatch!" ) ; + return ; + } + + fetchTexture ( (void *)data ) ; +} + + + void FrameBufferObject::fillTexture ( void *data ) { glBindTexture( GL_TEXTURE_2D, textureHandle ) ; diff --git a/Extras/GPUphysics/fboSupport.h b/Extras/GPUphysics/fboSupport.h index 62e870a1f..aeec27414 100644 --- a/Extras/GPUphysics/fboSupport.h +++ b/Extras/GPUphysics/fboSupport.h @@ -3,6 +3,8 @@ GLuint makeTextureTarget ( GLuint textureHandle ) ; void renderTo2DTexture ( GLuint fboHandle ) ; void renderToFrameBuffer () ; +//#define NEED_STENCIL_BUFFER 1 + enum fboDataType { #ifndef GL_BYTE @@ -44,11 +46,12 @@ class FrameBufferObject GLuint fboHandle ; GLuint depth_rb ; -#ifdef NEED_STENCIL +#ifdef NEED_STENCIL_BUFFER GLuint stencil_rb ; #endif - void fillTexture ( void *data ) ; + void fillTexture ( void *data ) ; + void fetchTexture ( void *data ) ; public: FrameBufferObject ( int _width, /* Must be a power of two! */ diff --git a/Extras/GPUphysics/shaderSupport.cxx b/Extras/GPUphysics/shaderSupport.cxx index 3e7b8b562..34c40fb96 100644 --- a/Extras/GPUphysics/shaderSupport.cxx +++ b/Extras/GPUphysics/shaderSupport.cxx @@ -1,21 +1,4 @@ -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#endif -#include -#include -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#include -#endif +#include "GPU_physics.h" #include "shaderSupport.h" #include "fboSupport.h" @@ -71,26 +54,22 @@ public: -/************************************\ -* * -* Low level File I/O junk * -* * -\************************************/ - -static int fSize ( const char *fname ) -{ - struct stat st ; - return ( stat ( fname, &st ) != -1 ) ? st . st_size : -1 ; -} - - static char *readShaderText ( const char *fname ) { - int size = fSize ( fname ) ; + + - char *shader = new char [ size + 1 ] ; + FILE *fd = fopen ( fname, "r" ) ; - FILE *fd = fopen ( fname, "r" ) ; + int size = 0; + /* File operations denied? ok, just close and return failure */ + if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) + { + printf("Error: cannot get filesize from %s\n", fname); + exit (1); + } + + char *shader = new char [ size + 1 ] ; if ( fd == NULL ) { diff --git a/Extras/GPUphysics/shaderSupport.h b/Extras/GPUphysics/shaderSupport.h index a76fcc2a2..af4000ea3 100644 --- a/Extras/GPUphysics/shaderSupport.h +++ b/Extras/GPUphysics/shaderSupport.h @@ -1,7 +1,4 @@ -#include -#include - class GLSL_Shader ; class FrameBufferObject ; diff --git a/glew32.dll b/glew32.dll new file mode 100644 index 000000000..aa55ae990 Binary files /dev/null and b/glew32.dll differ