Files
bullet3/Extras/GPUphysics



Author     : Steve Baker (sjbaker1@airmail.net)

Build using: 'make'

Run   using: 'GPU_physics_demo'

Requires   : A pretty modern graphics card - nVidia 6800 or better.

             Not tested on ATI hardware.

License    : zLib - see file: 'LICENSE'



----------------------------------------------------------

Demonstrates 16,384 cubes moving under the influence of

gravity and one other force - all with potentially different

masses, velocities, applied forces, etc.  The CPU is not

involved in any of the calculations - or even in applying

those calculations to the graphics when rendering the cubes.

----------------------------------------------------------

C++ Sources:



shaderSupport.cxx -- A wrapper layer for OpenGL/GLSL shaders.



fboSupport.cxx -- A wrapper layer for render-to-texture tricks.



GPU_physics_demo.cxx -- The application code.



----------------------------------------------------------

GLSLShader Sources used in the Demo:



cubeShader.vert

cubeShader.frag  -- Used to render the cubes.



----------------------------------------------------------

The objective of this library is to provide a basis for the

the Bullet physics engine to:



* Compile shader source code into a 'class GLSL_ShaderPair' object.

* Allocate an NxM texture that you can render into. (class FrameBufferObject)

* Populate a specified texture with floating point data.

* Run a specified shader on a specified set of textures - leaving the

  results in another specified texture.

* Demonstrate that this texture can be applied directly into the

  graphics code without any CPU intervention whatever.



-------------------------------------------------------------

Step 1: In initialisation code:



* Declare some number of FrameBufferObjects.  These are texture

  maps that you can render to that represent the 'variables'

  in the massively parallel calculations:



  eg:



  position = new FrameBufferObject ( 512, 512, 4, FBO_FLOAT ) ;



* Declare some number of GLSL_ShaderPair objects:



  /* GLSL code read from disk */



  teapotShaders = new GLSL_ShaderPair (

        "TeapotShader", "shader.vert", "shader.frag" ) ;



  /* ...or...Inline GLSL code */



  textureShaders = new GLSL_ShaderPair (

    "TextureShader",

    "void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }",

    "Render2Texture Vert Shader",

    "void main() { gl_FragColor = vec4 ( 1, 1, 0, 1 ) ; }",

    "Render2Texture Frag Shader" ) )



* Check that they compiled OK:



  assert ( textureShaders -> compiledOK () ) ;

  assert ( teapotShaders  -> compiledOK () ) ;



Step 2: In the main loop:



* Select one shader pair to use to do the calculations:



  teapotShaders -> use () ;



* Set any 'uniform' parameters that the shader might need to be

  the same for all of the objects being calculated:



  teapotShaders -> setUniform3f ( "gravity", 0, -9.8f,0 ) ; 

  teapotShaders -> setUniform1f ( "delta_T", 0.016f ) ; 



* Assign slot numbers to any FBO/Textures that the shader uses as inputs

  and bind them to uniforms in the shader code:



  /* Texture 'slots' 0 up to about 15 */

  teapotShaders -> applyTexture ( "velocity" , velocityFBO, 0 ) ;

  teapotShaders -> applyTexture ( "accelleration", accnFBO, 1 ) ;



* Choose a target FBO/Texture as the place to store the results and

  render a polygon of suitable size to perform the calculations:



  position -> paint () ;



* Restore the frame buffer to normal so we can go back to using the GPU

  to do graphics:



  restoreFrameBuffer () ;



Step 3: Draw stuff!