moved a few Extras projects into Extras/obsolete.
This commit is contained in:
949
Extras/obsolete/GPUphysics/GPU_physics_demo.cpp
Normal file
949
Extras/obsolete/GPUphysics/GPU_physics_demo.cpp
Normal file
@@ -0,0 +1,949 @@
|
||||
#include "GPU_physics.h"
|
||||
#include "fboSupport.h"
|
||||
#include "shaderSupport.h"
|
||||
#include "clock.h"
|
||||
|
||||
#define TIMESTEP 0.016f
|
||||
|
||||
enum DebugOptions
|
||||
{
|
||||
DRAW_WITHOUT_SHADERS,
|
||||
DRAW_WITHOUT_PHYSICS,
|
||||
DRAW_ALL
|
||||
} ;
|
||||
|
||||
|
||||
static float *positionData = NULL ;
|
||||
static float *rotationData = NULL ;
|
||||
static float *collisionData = 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 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int irand ( int max )
|
||||
{
|
||||
return rand() % max ;
|
||||
}
|
||||
|
||||
|
||||
float frand ( float max )
|
||||
{
|
||||
return (float)(rand() % 32767) * max / 32767.0f ;
|
||||
}
|
||||
|
||||
|
||||
static GLSL_ShaderPair *velocityGenerator ;
|
||||
static GLSL_ShaderPair *positionGenerator ;
|
||||
static GLSL_ShaderPair *grndCollisionGenerator ;
|
||||
static GLSL_ShaderPair *collisionGenerator ;
|
||||
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 *new_force ;
|
||||
static FrameBufferObject *massSizeX ;
|
||||
static FrameBufferObject *old ;
|
||||
static FrameBufferObject *collisions ;
|
||||
|
||||
#define TEX_SIZE 16
|
||||
|
||||
#define NUM_CUBES ( TEX_SIZE * TEX_SIZE )
|
||||
#define STRIPS_PER_CUBE 2
|
||||
#define VERTS_PER_STRIP 8
|
||||
#define NUM_VERTS ( NUM_CUBES * STRIPS_PER_CUBE * VERTS_PER_STRIP )
|
||||
|
||||
static GLuint vbo_vx = 0 ;
|
||||
static GLuint vbo_tx = 0 ;
|
||||
static GLuint vbo_co = 0 ;
|
||||
static float vertices [ NUM_VERTS * 3 ] ;
|
||||
static float texcoords [ NUM_VERTS * 2 ] ;
|
||||
static float colours [ NUM_VERTS * 4 ] ;
|
||||
static int starts [ NUM_CUBES * STRIPS_PER_CUBE ] ;
|
||||
static int lengths [ NUM_CUBES * STRIPS_PER_CUBE ] ;
|
||||
|
||||
static GLuint vbo_collvx = 0 ;
|
||||
static GLuint vbo_collt0 = 0 ;
|
||||
static GLuint vbo_collt1 = 0 ;
|
||||
static float collvertices [ NUM_CUBES * 4 * 3 ] ;
|
||||
static float colltexcoords0 [ NUM_CUBES * 4 * 2 ] ;
|
||||
static float colltexcoords1 [ NUM_CUBES * 4 * 2 ] ;
|
||||
static int collstart ;
|
||||
static int colllength ;
|
||||
|
||||
static int win_width = 640 ;
|
||||
static int win_height = 480 ;
|
||||
|
||||
inline int idToIndex ( int x, int y )
|
||||
{
|
||||
/*
|
||||
Convert a coordinate pair within the texture to an integer
|
||||
1D array index (eg to index into the data array for that texture)
|
||||
by multiplying the Y coordinate by the width of the texture and
|
||||
adding the X coordinate.
|
||||
*/
|
||||
return y * TEX_SIZE + x ;
|
||||
}
|
||||
|
||||
inline float idToFloat ( int x, int y )
|
||||
{
|
||||
/*
|
||||
Convert a coordinate pair within the texture to a float
|
||||
by putting one coordinate into the integer part and the
|
||||
other into the fraction so we can retrieve Y using floor()
|
||||
and X using fract() to recover them later on inside the shader.
|
||||
*/
|
||||
return ((float) idToIndex ( x, y )) / (float)TEX_SIZE ;
|
||||
}
|
||||
|
||||
|
||||
void keybd ( unsigned char, int, int )
|
||||
{
|
||||
exit ( 0 ) ;
|
||||
}
|
||||
|
||||
|
||||
void reshape ( int wid, int ht )
|
||||
{
|
||||
win_width = wid ;
|
||||
win_height = ht ;
|
||||
}
|
||||
|
||||
|
||||
void initGLcontext ( int argc, char **argv,
|
||||
void (*display)(void),
|
||||
bool disableVertexTextureSupport )
|
||||
{
|
||||
glutInit ( &argc, argv ) ;
|
||||
glutInitDisplayMode ( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ) ;
|
||||
glutInitWindowSize ( win_width, win_height ) ;
|
||||
glutCreateWindow ( "Shader Math Demo" ) ;
|
||||
glutDisplayFunc ( display ) ;
|
||||
glutKeyboardFunc ( keybd ) ;
|
||||
glutReshapeFunc ( reshape ) ;
|
||||
|
||||
#if defined(GPUP_MAC_OSX) && !defined (VMDMESA)
|
||||
#else
|
||||
glewInit () ;
|
||||
#endif
|
||||
|
||||
checkVertexTextureSupport ( disableVertexTextureSupport ) ;
|
||||
}
|
||||
|
||||
|
||||
void initMotionTextures ()
|
||||
{
|
||||
if ( debugOpt == DRAW_WITHOUT_SHADERS ) return ;
|
||||
|
||||
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 )
|
||||
{
|
||||
velocity = NULL ;
|
||||
rotvelocity = NULL ;
|
||||
force = NULL ;
|
||||
new_force = 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 ) ;
|
||||
force = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
|
||||
new_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, 3, FBO_FLOAT ) ;
|
||||
}
|
||||
|
||||
positionData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||
rotationData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||
|
||||
float *velocityData ;
|
||||
float *rotvelocityData ;
|
||||
float *forceData ;
|
||||
float *massSizeXData ;
|
||||
|
||||
if ( debugOpt == DRAW_WITHOUT_PHYSICS )
|
||||
{
|
||||
velocityData = NULL ;
|
||||
rotvelocityData = NULL ;
|
||||
forceData = NULL ;
|
||||
massSizeXData = NULL ;
|
||||
collisionData = NULL ;
|
||||
}
|
||||
else
|
||||
{
|
||||
velocityData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||
rotvelocityData = 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 * 3 ] ;
|
||||
}
|
||||
|
||||
/* Give the objects some initial position, rotation, mass, force, etc */
|
||||
|
||||
for ( int y = 0 ; y < TEX_SIZE ; y++ )
|
||||
for ( int x = 0 ; x < TEX_SIZE ; x++ )
|
||||
{
|
||||
/*
|
||||
Start the cubes on a nice, regular 5m grid, 10m above the ground
|
||||
centered around the origin
|
||||
*/
|
||||
|
||||
positionData [ idToIndex(x,y) * 3 + 0 ] = 5.0f * (float) (x - TEX_SIZE/2) ;
|
||||
positionData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ; // 10.0f ;
|
||||
positionData [ idToIndex(x,y) * 3 + 2 ] = 5.0f * (float) (y - TEX_SIZE/2) ;
|
||||
|
||||
/* Zero their rotations */
|
||||
rotationData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ;
|
||||
rotationData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ;
|
||||
rotationData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ;
|
||||
|
||||
if ( debugOpt != DRAW_WITHOUT_PHYSICS )
|
||||
{
|
||||
/* Random (but predominantly upwards) velocities. */
|
||||
if(irand(2)==0)
|
||||
{
|
||||
velocityData [ idToIndex(x,y) * 3 + 0 ] = frand ( 1.0f ) ;
|
||||
velocityData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ;
|
||||
velocityData [ idToIndex(x,y) * 3 + 2 ] = frand ( 1.0f ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
velocityData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ; //frand ( 10.0f ) - 5.0f;
|
||||
velocityData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ; //frand ( 100.0f ) ;
|
||||
velocityData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ; //frand ( 10.0f ) - 5.0f;
|
||||
}
|
||||
|
||||
/* Random rotational velocities */
|
||||
rotvelocityData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ; //frand ( 3.0f ) ;
|
||||
rotvelocityData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ; //frand ( 3.0f ) ;
|
||||
rotvelocityData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ; //frand ( 3.0f ) ;
|
||||
|
||||
/* Zero forces */
|
||||
forceData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ;
|
||||
forceData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ;
|
||||
forceData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ;
|
||||
|
||||
/* One kg each */
|
||||
massSizeXData [ idToIndex(x,y) * 3 + 0 ] = 0.05f ; /* Mass */
|
||||
massSizeXData [ idToIndex(x,y) * 3 + 1 ] = 1.0f ; /* Radius */
|
||||
massSizeXData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ; /* Unused */
|
||||
|
||||
/* Zero out collision data */
|
||||
collisionData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ;
|
||||
collisionData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ;
|
||||
collisionData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ;
|
||||
}
|
||||
}
|
||||
|
||||
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 ] = 1000000000.0f ;
|
||||
positionData [ 1 ] = 1000000000.0f ;
|
||||
positionData [ 2 ] = 1000000000.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 ] = 0.0f ;
|
||||
collisionData [ 1 ] = 0.0f ;
|
||||
collisionData [ 2 ] = 0.0f ;
|
||||
}
|
||||
|
||||
/* Initialise the textures */
|
||||
|
||||
position -> fillTexture ( positionData ) ;
|
||||
rotation -> fillTexture ( rotationData ) ;
|
||||
old -> fillTexture ( positionData ) ; // Doesn't really need it...
|
||||
|
||||
if ( debugOpt != DRAW_WITHOUT_PHYSICS )
|
||||
{
|
||||
velocity -> fillTexture ( velocityData ) ;
|
||||
rotvelocity -> fillTexture ( rotvelocityData ) ;
|
||||
force -> fillTexture ( forceData ) ;
|
||||
new_force -> fillTexture ( forceData ) ;
|
||||
massSizeX -> fillTexture ( massSizeXData ) ;
|
||||
collisions -> fillTexture ( collisionData ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initPhysicsShaders ()
|
||||
{
|
||||
if ( debugOpt == DRAW_WITHOUT_SHADERS ||
|
||||
debugOpt == DRAW_WITHOUT_PHYSICS )
|
||||
return ;
|
||||
|
||||
/*
|
||||
The velocity generator shader calculates:
|
||||
|
||||
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 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:
|
||||
|
||||
position = old_position + delta_T * velocity ;
|
||||
|
||||
It's also used to update the rotational velocity.
|
||||
*/
|
||||
|
||||
positionGenerator = new GLSL_ShaderPair (
|
||||
"PositionGenerator",
|
||||
NULL, NULL,
|
||||
"uniform float delta_T ;"
|
||||
"uniform sampler2D old_position ;"
|
||||
"uniform sampler2D velocity ;"
|
||||
"void main() {"
|
||||
" gl_FragColor = vec4 ("
|
||||
" texture2D ( old_position, gl_TexCoord[0].st ).xyz +"
|
||||
" texture2D ( velocity , gl_TexCoord[0].st ).xyz *"
|
||||
" delta_T,"
|
||||
" 1.0 ) ; }",
|
||||
"PositionGenerator Frag Shader" ) ;
|
||||
assert ( positionGenerator -> compiledOK () ) ;
|
||||
|
||||
|
||||
collisionGenerator = new GLSL_ShaderPair (
|
||||
"CollisionGenerator",
|
||||
NULL,
|
||||
"collisionShader.frag" ) ;
|
||||
assert ( collisionGenerator -> compiledOK () ) ;
|
||||
|
||||
|
||||
forceGenerator = new GLSL_ShaderPair (
|
||||
"ForceGenerator",
|
||||
NULL, NULL,
|
||||
"uniform sampler2D force ;"
|
||||
"uniform sampler2D position ;"
|
||||
"uniform sampler2D collisions ;"
|
||||
"void main() {"
|
||||
" vec3 last_force = texture2D ( force , gl_TexCoord[0].st ).xyz ;"
|
||||
" vec2 id = texture2D ( collisions, gl_TexCoord[0].st ).xy ;"
|
||||
" vec3 pos = texture2D ( position , gl_TexCoord[0].st ).xyz ;"
|
||||
" vec3 rel = pos - texture2D ( position, id ).xyz ;"
|
||||
" float lrel = max ( length ( rel ), 0.001 ) ;"
|
||||
" gl_FragColor = vec4 ( last_force + (rel / lrel) / lrel, 1.0 ) ;"
|
||||
"}",
|
||||
"ForceGenerator 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.y = abs(vel.y) ;"
|
||||
" gl_FragColor = vec4 ( vel, 1.0 ) ; }",
|
||||
"GroundCollisionGenerator Frag Shader" ) ;
|
||||
assert ( grndCollisionGenerator -> compiledOK () ) ;
|
||||
}
|
||||
|
||||
|
||||
void initCollideVBO ()
|
||||
{
|
||||
float *p = collvertices ;
|
||||
float *t0 = colltexcoords0 ;
|
||||
float *t1 = colltexcoords1 ;
|
||||
|
||||
collstart = 0 ;
|
||||
colllength = NUM_CUBES * 4 ;
|
||||
|
||||
for ( int y = 0 ; y < TEX_SIZE ; y++ )
|
||||
for ( int x = 0 ; x < TEX_SIZE ; x++ )
|
||||
{
|
||||
/* Texcoord 0 data sets which corner of the texture this is. */
|
||||
|
||||
*t0++ = 0.5f /(float)TEX_SIZE ;
|
||||
*t0++ = 0.5f /(float)TEX_SIZE ;
|
||||
|
||||
*t0++ = ((float)TEX_SIZE-0.5f)/(float)TEX_SIZE ;
|
||||
*t0++ = 0.5f /(float)TEX_SIZE ;
|
||||
|
||||
*t0++ = ((float)TEX_SIZE-0.5f)/(float)TEX_SIZE ;
|
||||
*t0++ = ((float)TEX_SIZE-0.5f)/(float)TEX_SIZE ;
|
||||
|
||||
*t0++ = 0.5f /(float)TEX_SIZE ;
|
||||
*t0++ =((float)TEX_SIZE-0.5f)/(float)TEX_SIZE ;
|
||||
|
||||
/* Texcoord 1 sets which cube is which. */
|
||||
|
||||
*t1++ = ((float)x+0.5f)/(float)TEX_SIZE ;
|
||||
*t1++ = ((float)y+0.5f)/(float)TEX_SIZE ;
|
||||
|
||||
*t1++ = ((float)x+0.5f)/(float)TEX_SIZE ;
|
||||
*t1++ = ((float)y+0.5f)/(float)TEX_SIZE ;
|
||||
|
||||
*t1++ = ((float)x+0.5f)/(float)TEX_SIZE ;
|
||||
*t1++ = ((float)y+0.5f)/(float)TEX_SIZE ;
|
||||
|
||||
*t1++ = ((float)x+0.5f)/(float)TEX_SIZE ;
|
||||
*t1++ = ((float)y+0.5f)/(float)TEX_SIZE ;
|
||||
|
||||
*p++ = -1 ; *p++ = -1 ; *p++ = 0.0f ;
|
||||
*p++ = +1 ; *p++ = -1 ; *p++ = 0.0f ;
|
||||
*p++ = +1 ; *p++ = +1 ; *p++ = 0.0f ;
|
||||
*p++ = -1 ; *p++ = +1 ; *p++ = 0.0f ;
|
||||
}
|
||||
|
||||
glGenBuffersARB ( 1, & vbo_collvx ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_collvx ) ;
|
||||
glBufferDataARB ( GL_ARRAY_BUFFER_ARB, colllength * 3 * sizeof(float),
|
||||
collvertices, GL_STATIC_DRAW_ARB ) ;
|
||||
|
||||
glGenBuffersARB ( 1, & vbo_collt0 ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_collt0 ) ;
|
||||
glBufferDataARB ( GL_ARRAY_BUFFER_ARB, colllength * 2 * sizeof(float),
|
||||
colltexcoords0, GL_STATIC_DRAW_ARB ) ;
|
||||
|
||||
glGenBuffersARB ( 1, & vbo_collt1 ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_collt1 ) ;
|
||||
glBufferDataARB ( GL_ARRAY_BUFFER_ARB, colllength * 2 * sizeof(float),
|
||||
colltexcoords1, GL_STATIC_DRAW_ARB ) ;
|
||||
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0 ) ;
|
||||
}
|
||||
|
||||
|
||||
void initCubeVBO ()
|
||||
{
|
||||
float *p = vertices ;
|
||||
float *t = texcoords ;
|
||||
float *c = colours ;
|
||||
int nverts = 0 ;
|
||||
|
||||
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 y = 0 ; y < (noVertexTextureSupport ? 1 : TEX_SIZE) ; y++ )
|
||||
for ( int x = 0 ; x < (noVertexTextureSupport ? 1 : TEX_SIZE) ; x++ )
|
||||
{
|
||||
/*
|
||||
I use the colour data to set which cube is which in
|
||||
the physics textures.
|
||||
*/
|
||||
|
||||
for ( int k = 0 ; k < STRIPS_PER_CUBE * VERTS_PER_STRIP ; k++ )
|
||||
{
|
||||
*t++ = ((float)x+0.5f)/(float)TEX_SIZE ;
|
||||
*t++ = ((float)y+0.5f)/(float)TEX_SIZE ;
|
||||
|
||||
if ( (x==20||x==100) && (y==20||y==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 ;
|
||||
|
||||
if ( debugOpt == DRAW_WITHOUT_SHADERS )
|
||||
{
|
||||
dx = 5.0f * (float) (TEX_SIZE/2 - x) ;
|
||||
dy = 10.0f ;
|
||||
dz = 5.0f * (float) (TEX_SIZE/2 - y) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = 0.0f ;
|
||||
dy = 0.0f ;
|
||||
dz = 0.0f ;
|
||||
}
|
||||
|
||||
*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 ;
|
||||
*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 ;
|
||||
*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 ;
|
||||
*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 ;
|
||||
*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 ;
|
||||
*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, 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, 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, nverts * 4 * sizeof(float),
|
||||
colours, GL_STATIC_DRAW_ARB ) ;
|
||||
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0 ) ;
|
||||
|
||||
if ( debugOpt == DRAW_WITHOUT_SHADERS )
|
||||
cubeShader = NULL ;
|
||||
else
|
||||
{
|
||||
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 y = 0 ; y < TEX_SIZE ; y++ )
|
||||
for ( int x = 0 ; x < TEX_SIZE ; x++ )
|
||||
{
|
||||
float *pos = & positionData [ idToIndex ( x, y ) * 3 ] ;
|
||||
float *rot = & rotationData [ idToIndex ( x, y ) * 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 ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_tx ) ;
|
||||
glTexCoordPointer ( 2, GL_FLOAT, 0, vbo_tx ? NULL : texcoords ) ;
|
||||
|
||||
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 ) ;
|
||||
|
||||
glMultiDrawArraysEXT ( GL_TRIANGLE_STRIP, (GLint*)starts, (GLint*)lengths,
|
||||
NUM_CUBES * STRIPS_PER_CUBE ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0 ) ;
|
||||
glPopClientAttrib () ;
|
||||
}
|
||||
|
||||
|
||||
void drawCubes ()
|
||||
{
|
||||
glMatrixMode ( GL_PROJECTION ) ;
|
||||
glLoadIdentity () ;
|
||||
glFrustum ( -1.0f, 1.0f,
|
||||
-1.0f / ((float)win_width/(float)win_height),
|
||||
1.0f / ((float)win_width/(float)win_height),
|
||||
1.0f, 1000000.0f) ;
|
||||
|
||||
/* Set up camera position */
|
||||
|
||||
glMatrixMode ( GL_MODELVIEW ) ;
|
||||
glLoadIdentity () ;
|
||||
glTranslatef ( 10.0f * (float)TEX_SIZE/128.0f,
|
||||
-100.0f * (float)TEX_SIZE/128.0f,
|
||||
-500.0f * (float)TEX_SIZE/128.0f ) ;
|
||||
glRotatef ( 20.0, 1.0, 0.0, 0.0 ) ;
|
||||
|
||||
glEnable ( GL_DEPTH_TEST ) ;
|
||||
glEnable ( GL_CULL_FACE ) ;
|
||||
glCullFace ( GL_FRONT ) ;
|
||||
|
||||
glClearColor ( 0.7f, 0.7f, 0.7f, 1.0f ) ;
|
||||
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
|
||||
|
||||
if ( noVertexTextureSupport )
|
||||
drawCubesTheHardWay () ;
|
||||
else
|
||||
drawCubeVBO () ;
|
||||
}
|
||||
|
||||
|
||||
void runCollisionDetection ()
|
||||
{
|
||||
static Clock ck ;
|
||||
ck.update () ;
|
||||
double tall=ck.getDeltaTime () ;
|
||||
static int firsttime = true ;
|
||||
static unsigned int query = 0 ;
|
||||
|
||||
FrameBufferObject *tmp ;
|
||||
FrameBufferObject *SCM = old ;
|
||||
FrameBufferObject *DCM = collisions ;
|
||||
unsigned int numHits ;
|
||||
|
||||
if ( firsttime )
|
||||
{
|
||||
glGenQueriesARB ( 1, (GLuint*) & query ) ;
|
||||
firsttime = false ;
|
||||
}
|
||||
|
||||
/* Fill SCM with big numbers */
|
||||
|
||||
glClearColor ( 1.0f, 1.0f, 1.0f, 1.0f ) ;
|
||||
SCM -> prepare ( true ) ;
|
||||
|
||||
glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ) ;
|
||||
force -> prepare ( true ) ; /* Zero out all of the forces. */
|
||||
|
||||
int numPasses = 0 ;
|
||||
|
||||
glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ) ;
|
||||
|
||||
glClientActiveTexture( GL_TEXTURE1 ) ;
|
||||
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_collt1 ) ;
|
||||
glTexCoordPointer ( 2, GL_FLOAT, 0, vbo_collt1 ? NULL : colltexcoords1 ) ;
|
||||
|
||||
glClientActiveTexture( GL_TEXTURE0 ) ;
|
||||
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_collt0 ) ;
|
||||
glTexCoordPointer ( 2, GL_FLOAT, 0, vbo_collt0 ? NULL : colltexcoords0 ) ;
|
||||
|
||||
glEnableClientState ( GL_VERTEX_ARRAY ) ;
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_collvx ) ;
|
||||
glVertexPointer ( 3, GL_FLOAT, 0, vbo_collvx ? NULL : collvertices ) ;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
collisionGenerator -> use () ;
|
||||
collisionGenerator -> applyTexture ( "position" , position, 0 ) ;
|
||||
collisionGenerator -> applyTexture ( "old_collisions", SCM , 1 ) ;
|
||||
|
||||
/* Fill DCM with zeroes */
|
||||
DCM -> prepare ( true ) ;
|
||||
|
||||
glBeginQueryARB ( GL_SAMPLES_PASSED_ARB, query ) ;
|
||||
|
||||
glMultiDrawArraysEXT ( GL_QUADS, (GLint*)& collstart, (GLint*)& colllength,
|
||||
1 ) ;
|
||||
numPasses++ ;
|
||||
|
||||
glEndQueryARB ( GL_SAMPLES_PASSED_ARB ) ;
|
||||
|
||||
forceGenerator -> use () ;
|
||||
forceGenerator -> applyTexture ( "position" , position , 0 ) ;
|
||||
forceGenerator -> applyTexture ( "force" , force , 1 ) ;
|
||||
forceGenerator -> applyTexture ( "collisions", DCM , 2 ) ;
|
||||
|
||||
GLuint sampleCount ;
|
||||
|
||||
glGetQueryObjectuivARB ( query, GL_QUERY_RESULT_ARB, &sampleCount ) ;
|
||||
|
||||
//fprintf ( stderr, "%d ", sampleCount ) ;
|
||||
|
||||
if ( sampleCount == 0 )
|
||||
break ;
|
||||
|
||||
new_force -> paint () ;
|
||||
|
||||
tmp = new_force ;
|
||||
new_force = force ;
|
||||
force = tmp ;
|
||||
|
||||
tmp = DCM ;
|
||||
DCM = SCM ;
|
||||
SCM = tmp ;
|
||||
}
|
||||
|
||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0 ) ;
|
||||
glPopClientAttrib () ;
|
||||
|
||||
ck.update () ;
|
||||
double tdone=ck.getDeltaTime () ;
|
||||
static int ii = 0 ;
|
||||
ii++;
|
||||
if (ii%100==0)
|
||||
fprintf ( stderr, "Performance: %d passes %d cubes: other=%fms collisions=%fms\n", numPasses, NUM_CUBES, tall*1000.0, tdone*1000.0 ) ;
|
||||
}
|
||||
|
||||
|
||||
void runPhysics ()
|
||||
{
|
||||
FrameBufferObject *tmp ;
|
||||
|
||||
/* Do some simple physics calculations in four stages */
|
||||
|
||||
/* 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, 0.0f, TIMESTEP ) ;
|
||||
velocity -> paint () ;
|
||||
|
||||
/* Copy old position into old. */
|
||||
tmp = old ;
|
||||
old = position ;
|
||||
position = tmp ;
|
||||
|
||||
positionGenerator -> use () ;
|
||||
positionGenerator -> applyTexture ( "old_position", old , 0 ) ;
|
||||
positionGenerator -> applyTexture ( "velocity" , velocity, 1 ) ;
|
||||
positionGenerator -> setUniform1f ( "delta_T", TIMESTEP ) ;
|
||||
position -> paint () ;
|
||||
|
||||
/* Copy old velocity into old. */
|
||||
|
||||
tmp = old ;
|
||||
old = velocity ;
|
||||
velocity = tmp ;
|
||||
|
||||
grndCollisionGenerator -> use () ;
|
||||
grndCollisionGenerator -> applyTexture ( "position" , position, 0 ) ;
|
||||
grndCollisionGenerator -> applyTexture ( "old_velocity", old , 1 ) ;
|
||||
velocity -> paint () ;
|
||||
|
||||
/* Copy old rotation into old. */
|
||||
tmp = old ;
|
||||
old = rotation ;
|
||||
rotation = tmp ;
|
||||
|
||||
positionGenerator -> use () ;
|
||||
positionGenerator -> applyTexture ( "old_position", old , 0 ) ;
|
||||
positionGenerator -> applyTexture ( "velocity" , rotvelocity, 1 ) ;
|
||||
positionGenerator -> setUniform1f ( "delta_T", TIMESTEP ) ;
|
||||
rotation -> paint () ;
|
||||
|
||||
restoreFrameBuffer () ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void display ( void )
|
||||
{
|
||||
if ( debugOpt != DRAW_WITHOUT_SHADERS &&
|
||||
debugOpt != DRAW_WITHOUT_PHYSICS )
|
||||
{
|
||||
runCollisionDetection () ;
|
||||
runPhysics () ;
|
||||
}
|
||||
|
||||
/* Now render the scene using the results */
|
||||
|
||||
glViewport ( 0, 0, win_width, win_height ) ;
|
||||
|
||||
drawCubes () ;
|
||||
|
||||
/* All done! */
|
||||
|
||||
glutSwapBuffers () ;
|
||||
glutPostRedisplay () ;
|
||||
}
|
||||
|
||||
|
||||
void help ()
|
||||
{
|
||||
fprintf ( stderr, "GPUphysics: Usage -\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, " -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 )
|
||||
{
|
||||
#ifdef WIN32
|
||||
//until there is a first GPU that works under VertexTextureSupport under WIN32, disable it
|
||||
bool disableVertexTextureSupport = true;
|
||||
#else
|
||||
bool disableVertexTextureSupport = false ;
|
||||
#endif
|
||||
debugOpt = DRAW_ALL ;
|
||||
|
||||
for ( int i = 1 ; i < argc ; i++ )
|
||||
{
|
||||
if ( argv [ i ][ 0 ] == '-' || argv [ i ][ 0 ] == '+' )
|
||||
for ( int j = 1 ; argv[i][j] != '\0' ; j++ )
|
||||
switch ( argv [ i ][ j ] )
|
||||
{
|
||||
case 's' : debugOpt = DRAW_WITHOUT_SHADERS ; break ;
|
||||
case 'p' : debugOpt = DRAW_WITHOUT_PHYSICS ; break ;
|
||||
case 'a' : debugOpt = DRAW_ALL ; break ;
|
||||
|
||||
case 'v' : disableVertexTextureSupport = true ; break ;
|
||||
default : help () ; exit ( 0 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
help () ;
|
||||
exit ( 0 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
initGLcontext ( argc, argv, display, disableVertexTextureSupport ) ;
|
||||
initMotionTextures () ;
|
||||
initPhysicsShaders () ;
|
||||
initCubeVBO () ;
|
||||
initCollideVBO () ;
|
||||
glutMainLoop () ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user