From 2b286e4748fc76fff4596e7610df39031ec218aa Mon Sep 17 00:00:00 2001 From: sjbaker Date: Wed, 27 Sep 2006 19:18:52 +0000 Subject: [PATCH] Added new GPU physics demo into both trunk and branch. --- Extras/GPUphysics/CHANGES | 10 + Extras/GPUphysics/DEBUGGING_README | 22 +- Extras/GPUphysics/GPU_physics_demo.cpp | 306 ++++++++++++++----------- Extras/GPUphysics/fboSupport.cpp | 29 ++- Extras/GPUphysics/fboSupport.h | 10 +- 5 files changed, 220 insertions(+), 157 deletions(-) diff --git a/Extras/GPUphysics/CHANGES b/Extras/GPUphysics/CHANGES index bdffff2d7..27ed81b63 100644 --- a/Extras/GPUphysics/CHANGES +++ b/Extras/GPUphysics/CHANGES @@ -1,5 +1,15 @@ (Add new stuff at the top!) +Sept 27th: +========== +* Added a 'collisionMap' and pre-populated it with the handles of + four of the cubes (which are coloured RED so you can see them). +* Non-red cubes are painted in shades of blue/green. +* Every cube (including the red ones) is gravitationally attracted + to all four red cubes in inverse proportion to their ranges. + +Sept 9th: +========= * Merged in my latest changes into SVN repository. * Arranged to avoid reading/writing textures at same time. * Removed depth and stencil buffers from FBO's. diff --git a/Extras/GPUphysics/DEBUGGING_README b/Extras/GPUphysics/DEBUGGING_README index f1b87021b..18fbd1bab 100644 --- a/Extras/GPUphysics/DEBUGGING_README +++ b/Extras/GPUphysics/DEBUGGING_README @@ -29,27 +29,7 @@ help with our debugging problems. without that, doing physics in the GPU is going to be virtually impossible). -3) Run without forces being applied: - - GPU_physics -f - - This sets the cubes off moving at constant speed (each cube - going at a different speed and spinning). - - Run without collision against the ground: - - GPU_physics -c - - The cubes move under gravity - but don't interact with the - notional ground plane so the eventually fall off the bottom - of the screen.. - - If either (3) or (4) fails but (1) and (2) worked then the - problem is probably something to do with render-to-texture. - - This is the most likely scenario. - -4) Run without vertex texturing: +3) Run without vertex texturing: GPU_physics_demo -v diff --git a/Extras/GPUphysics/GPU_physics_demo.cpp b/Extras/GPUphysics/GPU_physics_demo.cpp index 7fd766eac..6650b3c92 100644 --- a/Extras/GPUphysics/GPU_physics_demo.cpp +++ b/Extras/GPUphysics/GPU_physics_demo.cpp @@ -2,18 +2,23 @@ #include "fboSupport.h" #include "shaderSupport.h" +#define TIMESTEP 0.016f + enum DebugOptions { DRAW_WITHOUT_SHADERS, DRAW_WITHOUT_PHYSICS, - DRAW_WITHOUT_COLLISIONS, - DRAW_WITHOUT_FORCES, DRAW_ALL } ; +inline float idToFloat ( int i, int j ) +{ + return float ( (i*2) & 255 ) + float ( (j*2) & 255 ) / 256.0f ; +} -static float *positionData = NULL ; -static float *rotationData = NULL ; + +static float *positionData = NULL ; +static float *rotationData = NULL ; static bool noVertexTextureSupport = false ; static DebugOptions debugOpt = DRAW_ALL ; @@ -63,18 +68,20 @@ float frand ( float max ) } -static GLSL_ShaderPair *velocityGenerator ; -static GLSL_ShaderPair *positionGenerator ; -static GLSL_ShaderPair *collisionGenerator ; -static GLSL_ShaderPair *cubeShader ; +static GLSL_ShaderPair *velocityGenerator ; +static GLSL_ShaderPair *positionGenerator ; +static GLSL_ShaderPair *grndCollisionGenerator ; +static GLSL_ShaderPair *forceGenerator ; +static GLSL_ShaderPair *cubeShader ; static FrameBufferObject *position ; static FrameBufferObject *rotation ; static FrameBufferObject *velocity ; static FrameBufferObject *rotvelocity ; static FrameBufferObject *force ; -static FrameBufferObject *massXX ; +static FrameBufferObject *massSizeX ; static FrameBufferObject *old ; +static FrameBufferObject *collisions ; #define TEX_SIZE 128 #define NUM_CUBES ( TEX_SIZE * TEX_SIZE ) @@ -139,23 +146,16 @@ void initMotionTextures () velocity = NULL ; rotvelocity = NULL ; force = NULL ; - massXX = NULL ; + massSizeX = NULL ; + collisions = NULL ; } else { velocity = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; rotvelocity = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; - - if ( debugOpt == DRAW_WITHOUT_FORCES ) - { - force = NULL ; - massXX = NULL ; - } - else - { - force = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; - massXX = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; - } + force = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; + massSizeX = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ; + collisions = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 4, FBO_FLOAT ) ; } positionData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; @@ -164,30 +164,24 @@ void initMotionTextures () float *velocityData ; float *rotvelocityData ; float *forceData ; - float *massXXData ; + float *massSizeXData ; + float *collisionData ; if ( debugOpt == DRAW_WITHOUT_PHYSICS ) { velocityData = NULL ; rotvelocityData = NULL ; forceData = NULL ; - massXXData = NULL ; + massSizeXData = NULL ; + collisionData = NULL ; } else { velocityData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; rotvelocityData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; - - if ( debugOpt == DRAW_WITHOUT_FORCES ) - { - forceData = NULL ; - massXXData= NULL ; - } - else - { - forceData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; - massXXData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; - } + forceData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; + massSizeXData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ; + collisionData = new float [ TEX_SIZE * TEX_SIZE * 4 ] ; } /* Give the objects some initial position, rotation, mass, force, etc */ @@ -221,21 +215,47 @@ void initMotionTextures () rotvelocityData [ (i*TEX_SIZE + j) * 3 + 1 ] = frand ( 3.0f ) ; rotvelocityData [ (i*TEX_SIZE + j) * 3 + 2 ] = frand ( 3.0f ) ; - if ( debugOpt != DRAW_WITHOUT_FORCES ) - { - /* Zero forces (just gravity) */ - forceData [ (i*TEX_SIZE + j) * 3 + 0 ] = 0.0f ; - forceData [ (i*TEX_SIZE + j) * 3 + 1 ] = 0.0f ; - forceData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ; + /* Zero forces (just gravity) */ + forceData [ (i*TEX_SIZE + j) * 3 + 0 ] = 0.0f ; + forceData [ (i*TEX_SIZE + j) * 3 + 1 ] = 0.0f ; + forceData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ; - /* One kg in weight each */ - massXXData [ (i*TEX_SIZE + j) * 3 + 0 ] = 1.0f ; - massXXData [ (i*TEX_SIZE + j) * 3 + 1 ] = 0.0f ; /* Unused */ - massXXData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ; /* Unused */ - } + /* One kg in weight each */ + massSizeXData [ (i*TEX_SIZE + j) * 3 + 0 ] = 0.0005f ; /* Mass */ + massSizeXData [ (i*TEX_SIZE + j) * 3 + 1 ] = 1.0f ; /* Radius */ + massSizeXData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ; /* Unused */ + + /* Everyone collides with object 0, 1 and 2 */ +/*SJB*/ + collisionData [ (i*TEX_SIZE + j) * 3 + 0 ] = idToFloat ( 20, 20 ) ; + collisionData [ (i*TEX_SIZE + j) * 3 + 1 ] = idToFloat ( 20, 100 ) ; + collisionData [ (i*TEX_SIZE + j) * 3 + 2 ] = idToFloat ( 100, 20 ) ; + collisionData [ (i*TEX_SIZE + j) * 3 + 3 ] = idToFloat ( 100, 100 ) ; } } + if ( debugOpt != DRAW_WITHOUT_PHYSICS ) + { + /* + Object zero is the 'null' object for collision detection + so put it far away and stop it from moving around. + */ + + positionData [ 0 ] = 10.0f ; + positionData [ 1 ] = 10.0f ; + positionData [ 2 ] = 10.0f ; + velocityData [ 0 ] = 0.0f ; + velocityData [ 1 ] = 0.0f ; + velocityData [ 2 ] = 0.0f ; + massSizeXData [ 0 ] = 10000000.0f ; /* Mass */ + massSizeXData [ 1 ] = 0.00000001f ; /* Radius */ + massSizeXData [ 2 ] = 0.0f ; /* Unused */ + collisionData [ 0 ] = 128.5 ; /* Not collide with self! */ + collisionData [ 1 ] = 128.5 ; + collisionData [ 2 ] = 128.5 ; + collisionData [ 3 ] = 128.5 ; + } + /* Initialise the textures */ position -> fillTexture ( positionData ) ; @@ -246,12 +266,9 @@ void initMotionTextures () { velocity -> fillTexture ( velocityData ) ; rotvelocity -> fillTexture ( rotvelocityData ) ; - - if ( debugOpt != DRAW_WITHOUT_FORCES ) - { - force -> fillTexture ( forceData ) ; - massXX -> fillTexture ( massXXData ) ; - } + force -> fillTexture ( forceData ) ; + massSizeX -> fillTexture ( massSizeXData ) ; + collisions -> fillTexture ( collisionData ) ; } } @@ -262,35 +279,28 @@ void initPhysicsShaders () debugOpt == DRAW_WITHOUT_PHYSICS ) return ; - if ( debugOpt == DRAW_WITHOUT_FORCES ) - { - velocityGenerator = NULL ; - } - else - { - /* - The velocity generator shader calculates: + /* + The velocity generator shader calculates: - velocity = old_velocity + delta_T * ( F / m ) ; - */ + velocity = old_velocity + delta_T * ( F / m ) ; + */ - velocityGenerator = new GLSL_ShaderPair ( - "VelocityGenerator", - NULL, NULL, - "uniform vec4 g_dt ;" - "uniform sampler2D old_velocity ;" - "uniform sampler2D force ;" - "uniform sampler2D massXX ;" - "void main() {" - " gl_FragColor = vec4 (" - " texture2D ( old_velocity, gl_TexCoord[0].st ).xyz +" - " g_dt.w * ( g_dt.xyz +" - " texture2D ( force , gl_TexCoord[0].st ).xyz /" - " texture2D ( massXX , gl_TexCoord[0].st ).x)," - " 1.0 ) ; }", - "VelocityGenerator Frag Shader" ) ; + velocityGenerator = new GLSL_ShaderPair ( + "VelocityGenerator", + NULL, NULL, + "uniform vec4 g_dt ;" + "uniform sampler2D old_velocity ;" + "uniform sampler2D force ;" + "uniform sampler2D massSizeX ;" + "void main() {" + " gl_FragColor = vec4 (" + " texture2D ( old_velocity, gl_TexCoord[0].st ).xyz +" + " g_dt.w * ( g_dt.xyz +" + " texture2D ( force , gl_TexCoord[0].st ).xyz /" + " texture2D ( massSizeX , gl_TexCoord[0].st ).x)," + " 1.0 ) ; }", + "VelocityGenerator Frag Shader" ) ; assert ( velocityGenerator -> compiledOK () ) ; - } /* The position generater shader calculates: @@ -315,25 +325,56 @@ void initPhysicsShaders () "PositionGenerator Frag Shader" ) ; assert ( positionGenerator -> compiledOK () ) ; - if ( debugOpt == DRAW_WITHOUT_COLLISIONS ) - { - collisionGenerator = NULL ; - } - else - { - collisionGenerator = new GLSL_ShaderPair ( - "CollisionGenerator", - NULL, NULL, - "uniform sampler2D position ;" - "uniform sampler2D old_velocity ;" - "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 *= vec3(0.90,-0.90,0.90) ;" - " gl_FragColor = vec4 ( vel, 1.0 ) ; }", - "CollisionGenerator Frag Shader" ) ; - assert ( collisionGenerator -> compiledOK () ) ; - } + forceGenerator = new GLSL_ShaderPair ( + "ForceGenerator", + NULL, NULL, + "uniform sampler2D position ;" + "uniform sampler2D collisions ;" + "void main() {" + " vec3 pos = texture2D ( position , gl_TexCoord[0].st ).xyz ;" + " vec4 coll = texture2D ( collisions, gl_TexCoord[0].st ).xyzw ;" + " vec2 ctc ;" + " vec3 rel ;" + " float lrel ;" + " vec3 force = vec3 ( 0.0, 0.0, 0.0 ) ;" + /* First 'collision' */ + " ctc = vec2 ( coll.x / 256.0, coll.x ) ;" + " rel = pos - texture2D ( position, ctc ).xyz ;" + " lrel = max ( length ( rel ), 0.001 ) ;" + " force += (rel/lrel) * -1.0 / (lrel) ;" + /* Second 'collision' */ + " ctc = vec2 ( coll.y / 256.0, coll.y ) ;" + " rel = pos - texture2D ( position, ctc ).xyz ;" + " lrel = max ( length ( rel ), 0.001 ) ;" + " force += (rel/lrel) * -1.0 / (lrel) ;" + /* Third 'collision' */ + " ctc = vec2 ( coll.z / 256.0, coll.z ) ;" + " rel = pos - texture2D ( position, ctc ).xyz ;" + " lrel = max ( length ( rel ), 0.001 ) ;" + " force += (rel/lrel) * -1.0 / (lrel) ;" + /* Fourth 'collision' */ + " ctc = vec2 ( coll.w / 256.0, coll.w ) ;" + " rel = pos - texture2D ( position, ctc ).xyz ;" + " lrel = max ( length ( rel ), 0.001 ) ;" + " force += (rel/lrel) * -1.0 / (lrel) ;" + /* Write out results */ + " gl_FragColor = vec4 ( force, 1.0 ) ;" + "}", + "ForceCollisionGenerator Frag Shader" ) ; + assert ( forceGenerator -> compiledOK () ) ; + + grndCollisionGenerator = new GLSL_ShaderPair ( + "GroundCollisionGenerator", + NULL, NULL, + "uniform sampler2D position ;" + "uniform sampler2D old_velocity ;" + "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 *= vec3(0.90,-0.90,0.90) ;" + " gl_FragColor = vec4 ( vel, 1.0 ) ; }", + "GroundCollisionGenerator Frag Shader" ) ; + assert ( grndCollisionGenerator -> compiledOK () ) ; } @@ -366,10 +407,20 @@ void initCubeVBO () *t++ = ((float)i+0.5f)/(float)TEX_SIZE ; *t++ = ((float)j+0.5f)/(float)TEX_SIZE ; - *c++ = frand ( 1.0f ) ; - *c++ = frand ( 1.0f ) ; - *c++ = frand ( 1.0f ) ; - *c++ = 1.0f ; + if ( (i==20||i==100) && (j==20||j==100) ) + { + *c++ = 1.0f ; + *c++ = 0.0f ; + *c++ = 0.0f ; + *c++ = 1.0f ; + } + else + { + *c++ = 0.0f ; + *c++ = frand ( 1.0f ) ; + *c++ = frand ( 1.0f ) ; + *c++ = 1.0f ; + } } float dx, dy, dz ; @@ -571,20 +622,22 @@ void display ( void ) { /* Do some simple physics calculations in four stages */ - if ( debugOpt != DRAW_WITHOUT_FORCES ) - { - /* Copy old velocity into old. */ - tmp = old ; - old = velocity ; - velocity = tmp ; + forceGenerator -> use () ; + forceGenerator -> applyTexture ( "position" , position , 0 ) ; + forceGenerator -> applyTexture ( "collisions", collisions, 1 ) ; + force -> paint () ; - velocityGenerator -> use () ; - velocityGenerator -> applyTexture ( "old_velocity", old , 0 ) ; - velocityGenerator -> applyTexture ( "force" , force , 1 ) ; - velocityGenerator -> applyTexture ( "massXX" , massXX , 2 ) ; - velocityGenerator -> setUniform4f ( "g_dt", 0.0f, -9.8f, 0.0f, 0.016f ) ; - velocity -> paint () ; - } + /* Copy old velocity into old. */ + tmp = old ; + old = velocity ; + velocity = tmp ; + + velocityGenerator -> use () ; + velocityGenerator -> applyTexture ( "old_velocity", old , 0 ) ; + velocityGenerator -> applyTexture ( "force" , force , 1 ) ; + velocityGenerator -> applyTexture ( "massSizeX" , massSizeX, 2 ) ; + velocityGenerator -> setUniform4f ( "g_dt", 0.0f, -9.8f, 0.0f, TIMESTEP ) ; + velocity -> paint () ; /* Copy old position into old. */ tmp = old ; @@ -594,21 +647,18 @@ void display ( void ) positionGenerator -> use () ; positionGenerator -> applyTexture ( "old_position", old , 0 ) ; positionGenerator -> applyTexture ( "velocity" , velocity, 1 ) ; - positionGenerator -> setUniform1f ( "delta_T", 0.016f ) ; + positionGenerator -> setUniform1f ( "delta_T", TIMESTEP ) ; position -> paint () ; - if ( debugOpt != DRAW_WITHOUT_COLLISIONS ) - { - /* Copy old velocity into old. */ - tmp = old ; - old = velocity ; - velocity = tmp ; + /* Copy old velocity into old. */ + tmp = old ; + old = velocity ; + velocity = tmp ; - collisionGenerator -> use () ; - collisionGenerator -> applyTexture ( "position" , position, 0 ) ; - collisionGenerator -> applyTexture ( "old_velocity", old , 1 ) ; - velocity -> paint () ; - } + grndCollisionGenerator -> use () ; + grndCollisionGenerator -> applyTexture ( "position" , position, 0 ) ; + grndCollisionGenerator -> applyTexture ( "old_velocity", old , 1 ) ; + velocity -> paint () ; /* Copy old rotation into old. */ tmp = old ; @@ -618,7 +668,7 @@ void display ( void ) positionGenerator -> use () ; positionGenerator -> applyTexture ( "old_position", old , 0 ) ; positionGenerator -> applyTexture ( "velocity" , rotvelocity, 1 ) ; - positionGenerator -> setUniform1f ( "delta_T", 0.016f ) ; + positionGenerator -> setUniform1f ( "delta_T", TIMESTEP ) ; rotation -> paint () ; /* Now render the scene using the results */ @@ -644,8 +694,6 @@ void help () 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" ) ; @@ -666,8 +714,6 @@ int main ( int argc, char **argv ) { case 's' : debugOpt = DRAW_WITHOUT_SHADERS ; break ; case 'p' : debugOpt = DRAW_WITHOUT_PHYSICS ; break ; - case 'c' : debugOpt = DRAW_WITHOUT_COLLISIONS ; break ; - case 'f' : debugOpt = DRAW_WITHOUT_FORCES ; break ; case 'a' : debugOpt = DRAW_ALL ; break ; case 'v' : disableVertexTextureSupport = true ; break ; diff --git a/Extras/GPUphysics/fboSupport.cpp b/Extras/GPUphysics/fboSupport.cpp index b0e2429fa..d49d676f3 100644 --- a/Extras/GPUphysics/fboSupport.cpp +++ b/Extras/GPUphysics/fboSupport.cpp @@ -174,8 +174,8 @@ FrameBufferObject::FrameBufferObject ( int _width , glBindTexture ( GL_TEXTURE_2D, textureHandle ) ; glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ) ; glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ) ; - glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ) ; - glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ) ; + //glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ) ; + //glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ) ; fillTexture ( (void *) NULL ) ; glGenFramebuffersEXT ( 1, & fboHandle ) ; @@ -260,6 +260,19 @@ void FrameBufferObject::fetchTexture ( unsigned char *data ) +void FrameBufferObject::fetchTexture ( unsigned short *data ) +{ + if ( type != FBO_UNSIGNED_SHORT ) + { + fprintf ( stderr, "FBO: Data format mismatch!" ) ; + return ; + } + + fetchTexture ( (void *)data ) ; +} + + + void FrameBufferObject::fetchTexture ( float *data ) { if ( type != FBO_FLOAT ) @@ -298,6 +311,18 @@ void FrameBufferObject::fillTexture ( unsigned char *data ) fillTexture ( (void *)data ) ; } +void FrameBufferObject::fillTexture ( unsigned short *data ) +{ + if ( type != FBO_UNSIGNED_SHORT ) + { + fprintf ( stderr, "FBO: Data format mismatch!" ) ; + return ; + } + + fillTexture ( (void *)data ) ; +} + + void FrameBufferObject::fillTexture ( float *data ) { if ( type != FBO_FLOAT ) diff --git a/Extras/GPUphysics/fboSupport.h b/Extras/GPUphysics/fboSupport.h index d7f27f9f9..be622f12f 100644 --- a/Extras/GPUphysics/fboSupport.h +++ b/Extras/GPUphysics/fboSupport.h @@ -75,11 +75,13 @@ public: void paint () ; - void fillTexture ( float *data ) ; - void fillTexture ( unsigned char *data ) ; + void fillTexture ( float *data ) ; + void fillTexture ( unsigned short *data ) ; + void fillTexture ( unsigned char *data ) ; - void fetchTexture ( float *data ) ; - void fetchTexture ( unsigned char *data ) ; + void fetchTexture ( float *data ) ; + void fetchTexture ( unsigned short *data ) ; + void fetchTexture ( unsigned char *data ) ; } ;