Added simple collision detection.
This commit is contained in:
1 parent
2aaab1ab1a
commit
9ebc440ee5
5 files changed
+277
-101
No files matched your search
@@ -11,14 +11,10 @@ enum DebugOptions
|
|||||||
DRAW_ALL
|
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 *positionData = NULL ;
|
||||||
static float *rotationData = NULL ;
|
static float *rotationData = NULL ;
|
||||||
|
static float *collisionData = NULL ;
|
||||||
static bool noVertexTextureSupport = false ;
|
static bool noVertexTextureSupport = false ;
|
||||||
static DebugOptions debugOpt = DRAW_ALL ;
|
static DebugOptions debugOpt = DRAW_ALL ;
|
||||||
|
|
||||||
@@ -62,6 +58,12 @@ void checkVertexTextureSupport ( bool disableVertexTextureSupport )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int irand ( int max )
|
||||||
|
{
|
||||||
|
return rand() % max ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float frand ( float max )
|
float frand ( float max )
|
||||||
{
|
{
|
||||||
return (float)(rand() % 32767) * max / 32767.0f ;
|
return (float)(rand() % 32767) * max / 32767.0f ;
|
||||||
@@ -71,6 +73,7 @@ float frand ( float max )
|
|||||||
static GLSL_ShaderPair *velocityGenerator ;
|
static GLSL_ShaderPair *velocityGenerator ;
|
||||||
static GLSL_ShaderPair *positionGenerator ;
|
static GLSL_ShaderPair *positionGenerator ;
|
||||||
static GLSL_ShaderPair *grndCollisionGenerator ;
|
static GLSL_ShaderPair *grndCollisionGenerator ;
|
||||||
|
static GLSL_ShaderPair *collisionGenerator ;
|
||||||
static GLSL_ShaderPair *forceGenerator ;
|
static GLSL_ShaderPair *forceGenerator ;
|
||||||
static GLSL_ShaderPair *cubeShader ;
|
static GLSL_ShaderPair *cubeShader ;
|
||||||
|
|
||||||
@@ -79,16 +82,20 @@ static FrameBufferObject *rotation ;
|
|||||||
static FrameBufferObject *velocity ;
|
static FrameBufferObject *velocity ;
|
||||||
static FrameBufferObject *rotvelocity ;
|
static FrameBufferObject *rotvelocity ;
|
||||||
static FrameBufferObject *force ;
|
static FrameBufferObject *force ;
|
||||||
|
static FrameBufferObject *new_force ;
|
||||||
static FrameBufferObject *massSizeX ;
|
static FrameBufferObject *massSizeX ;
|
||||||
static FrameBufferObject *old ;
|
static FrameBufferObject *old ;
|
||||||
static FrameBufferObject *collisions ;
|
static FrameBufferObject *collisions ;
|
||||||
|
|
||||||
#define TEX_SIZE 128
|
#define TEX_SIZE 16
|
||||||
|
|
||||||
#define NUM_CUBES ( TEX_SIZE * TEX_SIZE )
|
#define NUM_CUBES ( TEX_SIZE * TEX_SIZE )
|
||||||
#define STRIPS_PER_CUBE 2
|
#define STRIPS_PER_CUBE 2
|
||||||
#define VERTS_PER_STRIP 8
|
#define VERTS_PER_STRIP 8
|
||||||
#define NUM_VERTS ( NUM_CUBES * STRIPS_PER_CUBE * VERTS_PER_STRIP )
|
#define NUM_VERTS ( NUM_CUBES * STRIPS_PER_CUBE * VERTS_PER_STRIP )
|
||||||
|
|
||||||
|
GLuint queries [ NUM_CUBES ] ;
|
||||||
|
|
||||||
static GLuint vbo_vx = 0 ;
|
static GLuint vbo_vx = 0 ;
|
||||||
static GLuint vbo_tx = 0 ;
|
static GLuint vbo_tx = 0 ;
|
||||||
static GLuint vbo_co = 0 ;
|
static GLuint vbo_co = 0 ;
|
||||||
@@ -101,6 +108,28 @@ static int lengths [ NUM_CUBES * STRIPS_PER_CUBE ] ;
|
|||||||
static int win_width = 640 ;
|
static int win_width = 640 ;
|
||||||
static int win_height = 480 ;
|
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 )
|
void keybd ( unsigned char, int, int )
|
||||||
{
|
{
|
||||||
@@ -122,7 +151,7 @@ void initGLcontext ( int argc, char **argv,
|
|||||||
glutInit ( &argc, argv ) ;
|
glutInit ( &argc, argv ) ;
|
||||||
glutInitDisplayMode ( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ) ;
|
glutInitDisplayMode ( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ) ;
|
||||||
glutInitWindowSize ( win_width, win_height ) ;
|
glutInitWindowSize ( win_width, win_height ) ;
|
||||||
glutCreateWindow ( "Bullet GPU Physics Demo. http://bullet.sf.net" ) ;
|
glutCreateWindow ( "Shader Math Demo" ) ;
|
||||||
glutDisplayFunc ( display ) ;
|
glutDisplayFunc ( display ) ;
|
||||||
glutKeyboardFunc ( keybd ) ;
|
glutKeyboardFunc ( keybd ) ;
|
||||||
glutReshapeFunc ( reshape ) ;
|
glutReshapeFunc ( reshape ) ;
|
||||||
@@ -146,6 +175,7 @@ void initMotionTextures ()
|
|||||||
velocity = NULL ;
|
velocity = NULL ;
|
||||||
rotvelocity = NULL ;
|
rotvelocity = NULL ;
|
||||||
force = NULL ;
|
force = NULL ;
|
||||||
|
new_force = NULL ;
|
||||||
massSizeX = NULL ;
|
massSizeX = NULL ;
|
||||||
collisions = NULL ;
|
collisions = NULL ;
|
||||||
}
|
}
|
||||||
@@ -154,8 +184,9 @@ void initMotionTextures ()
|
|||||||
velocity = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
|
velocity = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
|
||||||
rotvelocity = 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 ) ;
|
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 ) ;
|
massSizeX = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
|
||||||
collisions = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 4, FBO_FLOAT ) ;
|
collisions = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
positionData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
positionData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||||
@@ -165,7 +196,6 @@ void initMotionTextures ()
|
|||||||
float *rotvelocityData ;
|
float *rotvelocityData ;
|
||||||
float *forceData ;
|
float *forceData ;
|
||||||
float *massSizeXData ;
|
float *massSizeXData ;
|
||||||
float *collisionData ;
|
|
||||||
|
|
||||||
if ( debugOpt == DRAW_WITHOUT_PHYSICS )
|
if ( debugOpt == DRAW_WITHOUT_PHYSICS )
|
||||||
{
|
{
|
||||||
@@ -181,56 +211,63 @@ void initMotionTextures ()
|
|||||||
rotvelocityData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
rotvelocityData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||||
forceData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
forceData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||||
massSizeXData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
massSizeXData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||||
collisionData = new float [ TEX_SIZE * TEX_SIZE * 4 ] ;
|
collisionData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Give the objects some initial position, rotation, mass, force, etc */
|
/* Give the objects some initial position, rotation, mass, force, etc */
|
||||||
|
|
||||||
for ( int i = 0 ; i < TEX_SIZE ; i++ )
|
for ( int y = 0 ; y < TEX_SIZE ; y++ )
|
||||||
for ( int j = 0 ; j < TEX_SIZE ; j++ )
|
for ( int x = 0 ; x < TEX_SIZE ; x++ )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Start the cubes on a nice, regular 5m grid, 10m above the ground
|
Start the cubes on a nice, regular 5m grid, 10m above the ground
|
||||||
centered around the origin
|
centered around the origin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
positionData [ (i*TEX_SIZE + j) * 3 + 0 ] = 5.0f * (float) (TEX_SIZE/2 - i) ;
|
positionData [ idToIndex(x,y) * 3 + 0 ] = 5.0f * (float) (x - TEX_SIZE/2) ;
|
||||||
positionData [ (i*TEX_SIZE + j) * 3 + 1 ] = 10.0f ;
|
positionData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ; // 10.0f ;
|
||||||
positionData [ (i*TEX_SIZE + j) * 3 + 2 ] = 5.0f * (float) (TEX_SIZE/2 - j) ;
|
positionData [ idToIndex(x,y) * 3 + 2 ] = 5.0f * (float) (y - TEX_SIZE/2) ;
|
||||||
|
|
||||||
/* Zero their rotations */
|
/* Zero their rotations */
|
||||||
rotationData [ (i*TEX_SIZE + j) * 3 + 0 ] = 0.0f ;
|
rotationData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ;
|
||||||
rotationData [ (i*TEX_SIZE + j) * 3 + 1 ] = 0.0f ;
|
rotationData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ;
|
||||||
rotationData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ;
|
rotationData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ;
|
||||||
|
|
||||||
if ( debugOpt != DRAW_WITHOUT_PHYSICS )
|
if ( debugOpt != DRAW_WITHOUT_PHYSICS )
|
||||||
{
|
{
|
||||||
/* Random (but predominantly upwards) velocities. */
|
/* Random (but predominantly upwards) velocities. */
|
||||||
velocityData [ (i*TEX_SIZE + j) * 3 + 0 ] = frand ( 10.0f ) - 5.0f;
|
if(irand(8)==0)
|
||||||
velocityData [ (i*TEX_SIZE + j) * 3 + 1 ] = frand ( 100.0f ) ;
|
{
|
||||||
velocityData [ (i*TEX_SIZE + j) * 3 + 2 ] = frand ( 10.0f ) - 5.0f;
|
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 */
|
/* Random rotational velocities */
|
||||||
rotvelocityData [ (i*TEX_SIZE + j) * 3 + 0 ] = frand ( 3.0f ) ;
|
rotvelocityData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ; //frand ( 3.0f ) ;
|
||||||
rotvelocityData [ (i*TEX_SIZE + j) * 3 + 1 ] = frand ( 3.0f ) ;
|
rotvelocityData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ; //frand ( 3.0f ) ;
|
||||||
rotvelocityData [ (i*TEX_SIZE + j) * 3 + 2 ] = frand ( 3.0f ) ;
|
rotvelocityData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ; //frand ( 3.0f ) ;
|
||||||
|
|
||||||
/* Zero forces (just gravity) */
|
/* Zero forces */
|
||||||
forceData [ (i*TEX_SIZE + j) * 3 + 0 ] = 0.0f ;
|
forceData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ;
|
||||||
forceData [ (i*TEX_SIZE + j) * 3 + 1 ] = 0.0f ;
|
forceData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ;
|
||||||
forceData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ;
|
forceData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ;
|
||||||
|
|
||||||
/* One kg in weight each */
|
/* One kg each */
|
||||||
massSizeXData [ (i*TEX_SIZE + j) * 3 + 0 ] = 0.0005f ; /* Mass */
|
massSizeXData [ idToIndex(x,y) * 3 + 0 ] = 0.05f ; /* Mass */
|
||||||
massSizeXData [ (i*TEX_SIZE + j) * 3 + 1 ] = 1.0f ; /* Radius */
|
massSizeXData [ idToIndex(x,y) * 3 + 1 ] = 1.0f ; /* Radius */
|
||||||
massSizeXData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ; /* Unused */
|
massSizeXData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ; /* Unused */
|
||||||
|
|
||||||
/* Everyone collides with object 0, 1 and 2 */
|
/* Zero out collision data */
|
||||||
/*SJB*/
|
collisionData [ idToIndex(x,y) * 3 + 0 ] = 0.0f ;
|
||||||
collisionData [ (i*TEX_SIZE + j) * 3 + 0 ] = idToFloat ( 20, 20 ) ;
|
collisionData [ idToIndex(x,y) * 3 + 1 ] = 0.0f ;
|
||||||
collisionData [ (i*TEX_SIZE + j) * 3 + 1 ] = idToFloat ( 20, 100 ) ;
|
collisionData [ idToIndex(x,y) * 3 + 2 ] = 0.0f ;
|
||||||
collisionData [ (i*TEX_SIZE + j) * 3 + 2 ] = idToFloat ( 100, 20 ) ;
|
|
||||||
collisionData [ (i*TEX_SIZE + j) * 3 + 3 ] = idToFloat ( 100, 100 ) ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,19 +278,18 @@ void initMotionTextures ()
|
|||||||
so put it far away and stop it from moving around.
|
so put it far away and stop it from moving around.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
positionData [ 0 ] = 10.0f ;
|
positionData [ 0 ] = 1000000000.0f ;
|
||||||
positionData [ 1 ] = 10.0f ;
|
positionData [ 1 ] = 1000000000.0f ;
|
||||||
positionData [ 2 ] = 10.0f ;
|
positionData [ 2 ] = 1000000000.0f ;
|
||||||
velocityData [ 0 ] = 0.0f ;
|
velocityData [ 0 ] = 0.0f ;
|
||||||
velocityData [ 1 ] = 0.0f ;
|
velocityData [ 1 ] = 0.0f ;
|
||||||
velocityData [ 2 ] = 0.0f ;
|
velocityData [ 2 ] = 0.0f ;
|
||||||
massSizeXData [ 0 ] = 10000000.0f ; /* Mass */
|
massSizeXData [ 0 ] = 10000000.0f ; /* Mass */
|
||||||
massSizeXData [ 1 ] = 0.00000001f ; /* Radius */
|
massSizeXData [ 1 ] = 0.00000001f ; /* Radius */
|
||||||
massSizeXData [ 2 ] = 0.0f ; /* Unused */
|
massSizeXData [ 2 ] = 0.0f ; /* Unused */
|
||||||
collisionData [ 0 ] = 128.5 ; /* Not collide with self! */
|
collisionData [ 0 ] = 0.0f ;
|
||||||
collisionData [ 1 ] = 128.5 ;
|
collisionData [ 1 ] = 0.0f ;
|
||||||
collisionData [ 2 ] = 128.5 ;
|
collisionData [ 2 ] = 0.0f ;
|
||||||
collisionData [ 3 ] = 128.5 ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise the textures */
|
/* Initialise the textures */
|
||||||
@@ -267,9 +303,12 @@ void initMotionTextures ()
|
|||||||
velocity -> fillTexture ( velocityData ) ;
|
velocity -> fillTexture ( velocityData ) ;
|
||||||
rotvelocity -> fillTexture ( rotvelocityData ) ;
|
rotvelocity -> fillTexture ( rotvelocityData ) ;
|
||||||
force -> fillTexture ( forceData ) ;
|
force -> fillTexture ( forceData ) ;
|
||||||
|
new_force -> fillTexture ( forceData ) ;
|
||||||
massSizeX -> fillTexture ( massSizeXData ) ;
|
massSizeX -> fillTexture ( massSizeXData ) ;
|
||||||
collisions -> fillTexture ( collisionData ) ;
|
collisions -> fillTexture ( collisionData ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glGenQueriesARB ( NUM_CUBES, queries ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -325,44 +364,32 @@ void initPhysicsShaders ()
|
|||||||
"PositionGenerator Frag Shader" ) ;
|
"PositionGenerator Frag Shader" ) ;
|
||||||
assert ( positionGenerator -> compiledOK () ) ;
|
assert ( positionGenerator -> compiledOK () ) ;
|
||||||
|
|
||||||
|
|
||||||
|
collisionGenerator = new GLSL_ShaderPair (
|
||||||
|
"CollisionGenerator",
|
||||||
|
NULL,
|
||||||
|
"collisionShader.frag" ) ;
|
||||||
|
assert ( collisionGenerator -> compiledOK () ) ;
|
||||||
|
|
||||||
|
|
||||||
forceGenerator = new GLSL_ShaderPair (
|
forceGenerator = new GLSL_ShaderPair (
|
||||||
"ForceGenerator",
|
"ForceGenerator",
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
|
"uniform sampler2D force ;"
|
||||||
"uniform sampler2D position ;"
|
"uniform sampler2D position ;"
|
||||||
"uniform sampler2D collisions ;"
|
"uniform sampler2D collisions ;"
|
||||||
"void main() {"
|
"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 pos = texture2D ( position , gl_TexCoord[0].st ).xyz ;"
|
||||||
" vec4 coll = texture2D ( collisions, gl_TexCoord[0].st ).xyzw ;"
|
" vec3 rel = pos - texture2D ( position, id ).xyz ;"
|
||||||
" vec2 ctc ;"
|
" float lrel = max ( length ( rel ), 0.001 ) ;"
|
||||||
" vec3 rel ;"
|
" gl_FragColor = vec4 ( last_force + (rel / lrel) / lrel, 1.0 ) ;"
|
||||||
" 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" ) ;
|
"ForceGenerator Frag Shader" ) ;
|
||||||
assert ( forceGenerator -> compiledOK () ) ;
|
assert ( forceGenerator -> compiledOK () ) ;
|
||||||
|
|
||||||
|
|
||||||
grndCollisionGenerator = new GLSL_ShaderPair (
|
grndCollisionGenerator = new GLSL_ShaderPair (
|
||||||
"GroundCollisionGenerator",
|
"GroundCollisionGenerator",
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
@@ -371,7 +398,7 @@ void initPhysicsShaders ()
|
|||||||
"void main() {"
|
"void main() {"
|
||||||
" vec3 pos = texture2D ( position , gl_TexCoord[0].st ).xyz ;"
|
" vec3 pos = texture2D ( position , gl_TexCoord[0].st ).xyz ;"
|
||||||
" vec3 vel = texture2D ( old_velocity, 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) ;"
|
" if ( pos [ 1 ] < 0.0 ) vel.y = abs(vel.y) ;"
|
||||||
" gl_FragColor = vec4 ( vel, 1.0 ) ; }",
|
" gl_FragColor = vec4 ( vel, 1.0 ) ; }",
|
||||||
"GroundCollisionGenerator Frag Shader" ) ;
|
"GroundCollisionGenerator Frag Shader" ) ;
|
||||||
assert ( grndCollisionGenerator -> compiledOK () ) ;
|
assert ( grndCollisionGenerator -> compiledOK () ) ;
|
||||||
@@ -392,8 +419,8 @@ void initCubeVBO ()
|
|||||||
lengths [ k ] = VERTS_PER_STRIP ;
|
lengths [ k ] = VERTS_PER_STRIP ;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int i = 0 ; i < (noVertexTextureSupport ? 1 : TEX_SIZE) ; i++ )
|
for ( int y = 0 ; y < (noVertexTextureSupport ? 1 : TEX_SIZE) ; y++ )
|
||||||
for ( int j = 0 ; j < (noVertexTextureSupport ? 1 : TEX_SIZE) ; j++ )
|
for ( int x = 0 ; x < (noVertexTextureSupport ? 1 : TEX_SIZE) ; x++ )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
I use the colour data to set which cube is which in
|
I use the colour data to set which cube is which in
|
||||||
@@ -402,10 +429,10 @@ void initCubeVBO ()
|
|||||||
|
|
||||||
for ( int k = 0 ; k < STRIPS_PER_CUBE * VERTS_PER_STRIP ; k++ )
|
for ( int k = 0 ; k < STRIPS_PER_CUBE * VERTS_PER_STRIP ; k++ )
|
||||||
{
|
{
|
||||||
*t++ = ((float)i+0.5f)/(float)TEX_SIZE ;
|
*t++ = ((float)x+0.5f)/(float)TEX_SIZE ;
|
||||||
*t++ = ((float)j+0.5f)/(float)TEX_SIZE ;
|
*t++ = ((float)y+0.5f)/(float)TEX_SIZE ;
|
||||||
|
|
||||||
if ( (i==20||i==100) && (j==20||j==100) )
|
if ( (x==20||x==100) && (y==20||y==100) )
|
||||||
{
|
{
|
||||||
*c++ = 1.0f ;
|
*c++ = 1.0f ;
|
||||||
*c++ = 0.0f ;
|
*c++ = 0.0f ;
|
||||||
@@ -425,9 +452,9 @@ void initCubeVBO ()
|
|||||||
|
|
||||||
if ( debugOpt == DRAW_WITHOUT_SHADERS )
|
if ( debugOpt == DRAW_WITHOUT_SHADERS )
|
||||||
{
|
{
|
||||||
dx = 5.0f * (float) (TEX_SIZE/2 - i) ;
|
dx = 5.0f * (float) (TEX_SIZE/2 - x) ;
|
||||||
dy = 10.0f ;
|
dy = 10.0f ;
|
||||||
dz = 5.0f * (float) (TEX_SIZE/2 - j) ;
|
dz = 5.0f * (float) (TEX_SIZE/2 - y) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -478,9 +505,9 @@ void initCubeVBO ()
|
|||||||
cubeShader = NULL ;
|
cubeShader = NULL ;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//the filenames have additional path to make it easier for some platforms
|
|
||||||
if ( noVertexTextureSupport )
|
if ( noVertexTextureSupport )
|
||||||
cubeShader = new GLSL_ShaderPair ( "CubeShader", "cubeShaderNoTexture.vert",
|
cubeShader = new GLSL_ShaderPair ( "CubeShader",
|
||||||
|
"cubeShaderNoTexture.vert",
|
||||||
"cubeShader.frag" ) ;
|
"cubeShader.frag" ) ;
|
||||||
else
|
else
|
||||||
cubeShader = new GLSL_ShaderPair ( "CubeShader", "cubeShader.vert",
|
cubeShader = new GLSL_ShaderPair ( "CubeShader", "cubeShader.vert",
|
||||||
@@ -501,6 +528,8 @@ void drawCubesTheHardWay ()
|
|||||||
float p1 = positionData [ 1 ] ;
|
float p1 = positionData [ 1 ] ;
|
||||||
float p2 = positionData [ 2 ] ;
|
float p2 = positionData [ 2 ] ;
|
||||||
|
|
||||||
|
glFlush();
|
||||||
|
restoreFrameBuffer () ;
|
||||||
position -> fetchTexture ( positionData ) ;
|
position -> fetchTexture ( positionData ) ;
|
||||||
rotation -> fetchTexture ( rotationData ) ;
|
rotation -> fetchTexture ( rotationData ) ;
|
||||||
|
|
||||||
@@ -527,18 +556,19 @@ void drawCubesTheHardWay ()
|
|||||||
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_vx ) ;
|
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, vbo_vx ) ;
|
||||||
glVertexPointer ( 3, GL_FLOAT, 0, vbo_vx ? NULL : vertices ) ;
|
glVertexPointer ( 3, GL_FLOAT, 0, vbo_vx ? NULL : vertices ) ;
|
||||||
|
|
||||||
for ( int i = 0 ; i < TEX_SIZE ; i++ )
|
for ( int y = 0 ; y < TEX_SIZE ; y++ )
|
||||||
for ( int j = 0 ; j < TEX_SIZE ; j++ )
|
for ( int x = 0 ; x < TEX_SIZE ; x++ )
|
||||||
{
|
{
|
||||||
float *pos = & positionData [ (i*TEX_SIZE + j) * 3 ] ;
|
float *pos = & positionData [ idToIndex ( x, y ) * 3 ] ;
|
||||||
float *rot = & rotationData [ (i*TEX_SIZE + j) * 3 ] ;
|
float *rot = & rotationData [ idToIndex ( x, y ) * 3 ] ;
|
||||||
|
|
||||||
glPushMatrix () ;
|
glPushMatrix () ;
|
||||||
glTranslatef ( pos [ 0 ], pos [ 1 ], pos [ 2 ] ) ;
|
glTranslatef ( pos [ 0 ], pos [ 1 ], pos [ 2 ] ) ;
|
||||||
glRotatef ( rot [ 0 ] * 180.0f / 3.14159f, 0, 1, 0 ) ;
|
glRotatef ( rot [ 0 ] * 180.0f / 3.14159f, 0, 1, 0 ) ;
|
||||||
glRotatef ( rot [ 1 ] * 180.0f / 3.14159f, 1, 0, 0 ) ;
|
glRotatef ( rot [ 1 ] * 180.0f / 3.14159f, 1, 0, 0 ) ;
|
||||||
glRotatef ( rot [ 2 ] * 180.0f / 3.14159f, 0, 0, 1 ) ;
|
glRotatef ( rot [ 2 ] * 180.0f / 3.14159f, 0, 0, 1 ) ;
|
||||||
glMultiDrawArraysEXT ( GL_TRIANGLE_STRIP, (GLint*)starts, (GLint*)lengths,
|
glMultiDrawArraysEXT ( GL_TRIANGLE_STRIP, (GLint*)starts,
|
||||||
|
(GLint*)lengths,
|
||||||
STRIPS_PER_CUBE ) ;
|
STRIPS_PER_CUBE ) ;
|
||||||
glPopMatrix () ;
|
glPopMatrix () ;
|
||||||
}
|
}
|
||||||
@@ -592,9 +622,11 @@ void drawCubes ()
|
|||||||
1.0f / ((float)win_width/(float)win_height),
|
1.0f / ((float)win_width/(float)win_height),
|
||||||
1.0f, 1000000.0f) ;
|
1.0f, 1000000.0f) ;
|
||||||
|
|
||||||
|
/* Set up camera position */
|
||||||
|
|
||||||
glMatrixMode ( GL_MODELVIEW ) ;
|
glMatrixMode ( GL_MODELVIEW ) ;
|
||||||
glLoadIdentity () ;
|
glLoadIdentity () ;
|
||||||
glTranslatef ( 10.0, -100.0, -500.0 ) ;
|
glTranslatef ( 1.25f, -12.5f, -60.0f ) ; // 10.0, -100.0, -500.0 ) ;
|
||||||
glRotatef ( 20.0, 1.0, 0.0, 0.0 ) ;
|
glRotatef ( 20.0, 1.0, 0.0, 0.0 ) ;
|
||||||
|
|
||||||
glEnable ( GL_DEPTH_TEST ) ;
|
glEnable ( GL_DEPTH_TEST ) ;
|
||||||
@@ -611,19 +643,112 @@ void drawCubes ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void display ( void )
|
void runCollisionDetection ()
|
||||||
{
|
{
|
||||||
FrameBufferObject *tmp ;
|
FrameBufferObject *tmp ;
|
||||||
|
FrameBufferObject *SCM = old ;
|
||||||
|
FrameBufferObject *DCM = collisions ;
|
||||||
|
|
||||||
if ( debugOpt != DRAW_WITHOUT_SHADERS &&
|
static unsigned int numHits [ NUM_CUBES ] ;
|
||||||
debugOpt != DRAW_WITHOUT_PHYSICS )
|
static float texCoordIdent [ NUM_CUBES * 2 ] ;
|
||||||
|
static int firsttime = true ;
|
||||||
|
|
||||||
|
if ( firsttime )
|
||||||
{
|
{
|
||||||
/* Do some simple physics calculations in four stages */
|
firsttime = false ;
|
||||||
|
|
||||||
|
for ( int y = 0 ; y < TEX_SIZE ; y++ )
|
||||||
|
for ( int x = 0 ; x < TEX_SIZE ; x++ )
|
||||||
|
{
|
||||||
|
texCoordIdent [ idToIndex ( x, y ) * 2 + 0 ] =
|
||||||
|
(((float) x) + 0.5 )/(float)TEX_SIZE ;
|
||||||
|
texCoordIdent [ idToIndex ( x, y ) * 2 + 1 ] =
|
||||||
|
(((float) y) + 0.5 )/(float)TEX_SIZE ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark all polygons 'needed' */
|
||||||
|
memset ( numHits, 0xFF, NUM_CUBES * sizeof(unsigned int) ) ;
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
bool allDone ;
|
||||||
|
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
collisionGenerator -> use () ;
|
||||||
|
collisionGenerator -> applyTexture ( "position" , position, 0 ) ;
|
||||||
|
collisionGenerator -> applyTexture ( "old_collisions", SCM , 1 ) ;
|
||||||
|
|
||||||
|
/* Fill DCM with zeroes */
|
||||||
|
DCM -> prepare ( true ) ;
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < NUM_CUBES ; i++ )
|
||||||
|
{
|
||||||
|
if ( numHits [ i ] != 0 )
|
||||||
|
{
|
||||||
|
glMultiTexCoord2fv ( GL_TEXTURE0 + 1, & ( texCoordIdent [ i * 2 ] )) ;
|
||||||
|
|
||||||
|
glBeginQueryARB ( GL_SAMPLES_PASSED_ARB, queries [ i ] ) ;
|
||||||
|
DCM -> fill () ;
|
||||||
|
glEndQueryARB ( GL_SAMPLES_PASSED_ARB ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allDone = true ;
|
||||||
|
|
||||||
|
int numCollisionPairs = 0 ;
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < NUM_CUBES ; i++ )
|
||||||
|
{
|
||||||
|
if ( numHits [ i ] == 0 ) continue ;
|
||||||
|
|
||||||
|
GLuint sampleCount ;
|
||||||
|
|
||||||
|
glGetQueryObjectuivARB ( queries[i], GL_QUERY_RESULT_ARB,
|
||||||
|
&sampleCount ) ;
|
||||||
|
|
||||||
|
numHits [ i ] = sampleCount ;
|
||||||
|
numCollisionPairs += sampleCount ;
|
||||||
|
|
||||||
|
if ( sampleCount != 0 )
|
||||||
|
allDone = false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numCollisionPairs > 0 )
|
||||||
|
fprintf ( stderr, "%d ", numCollisionPairs ) ;
|
||||||
|
|
||||||
|
if ( allDone )
|
||||||
|
break ;
|
||||||
|
|
||||||
forceGenerator -> use () ;
|
forceGenerator -> use () ;
|
||||||
forceGenerator -> applyTexture ( "position" , position , 0 ) ;
|
forceGenerator -> applyTexture ( "position" , position , 0 ) ;
|
||||||
forceGenerator -> applyTexture ( "collisions", collisions, 1 ) ;
|
forceGenerator -> applyTexture ( "force" , force , 1 ) ;
|
||||||
force -> paint () ;
|
forceGenerator -> applyTexture ( "collisions", DCM , 2 ) ;
|
||||||
|
new_force -> paint () ;
|
||||||
|
|
||||||
|
tmp = new_force ;
|
||||||
|
new_force = force ;
|
||||||
|
force = tmp ;
|
||||||
|
|
||||||
|
tmp = DCM ;
|
||||||
|
DCM = SCM ;
|
||||||
|
SCM = tmp ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void runPhysics ()
|
||||||
|
{
|
||||||
|
FrameBufferObject *tmp ;
|
||||||
|
|
||||||
|
/* Do some simple physics calculations in four stages */
|
||||||
|
|
||||||
/* Copy old velocity into old. */
|
/* Copy old velocity into old. */
|
||||||
tmp = old ;
|
tmp = old ;
|
||||||
@@ -634,7 +759,7 @@ void display ( void )
|
|||||||
velocityGenerator -> applyTexture ( "old_velocity", old , 0 ) ;
|
velocityGenerator -> applyTexture ( "old_velocity", old , 0 ) ;
|
||||||
velocityGenerator -> applyTexture ( "force" , force , 1 ) ;
|
velocityGenerator -> applyTexture ( "force" , force , 1 ) ;
|
||||||
velocityGenerator -> applyTexture ( "massSizeX" , massSizeX, 2 ) ;
|
velocityGenerator -> applyTexture ( "massSizeX" , massSizeX, 2 ) ;
|
||||||
velocityGenerator -> setUniform4f ( "g_dt", 0.0f, -9.8f, 0.0f, TIMESTEP ) ;
|
velocityGenerator -> setUniform4f ( "g_dt", 0.0f, /*-9.8f */ 0.0f, 0.0f, TIMESTEP ) ;
|
||||||
velocity -> paint () ;
|
velocity -> paint () ;
|
||||||
|
|
||||||
/* Copy old position into old. */
|
/* Copy old position into old. */
|
||||||
@@ -649,6 +774,7 @@ void display ( void )
|
|||||||
position -> paint () ;
|
position -> paint () ;
|
||||||
|
|
||||||
/* Copy old velocity into old. */
|
/* Copy old velocity into old. */
|
||||||
|
|
||||||
tmp = old ;
|
tmp = old ;
|
||||||
old = velocity ;
|
old = velocity ;
|
||||||
velocity = tmp ;
|
velocity = tmp ;
|
||||||
@@ -669,11 +795,22 @@ void display ( void )
|
|||||||
positionGenerator -> setUniform1f ( "delta_T", TIMESTEP ) ;
|
positionGenerator -> setUniform1f ( "delta_T", TIMESTEP ) ;
|
||||||
rotation -> paint () ;
|
rotation -> paint () ;
|
||||||
|
|
||||||
/* Now render the scene using the results */
|
|
||||||
|
|
||||||
restoreFrameBuffer () ;
|
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 ) ;
|
glViewport ( 0, 0, win_width, win_height ) ;
|
||||||
|
|
||||||
drawCubes () ;
|
drawCubes () ;
|
||||||
@@ -701,7 +838,7 @@ void help ()
|
|||||||
|
|
||||||
int main ( int argc, char **argv )
|
int main ( int argc, char **argv )
|
||||||
{
|
{
|
||||||
bool disableVertexTextureSupport = true ;
|
bool disableVertexTextureSupport = false ;
|
||||||
debugOpt = DRAW_ALL ;
|
debugOpt = DRAW_ALL ;
|
||||||
|
|
||||||
for ( int i = 1 ; i < argc ; i++ )
|
for ( int i = 1 ; i < argc ; i++ )
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
uniform sampler2D position ;
|
||||||
|
uniform sampler2D old_collisions ;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 my_id = gl_TexCoord[0].st ;
|
||||||
|
vec2 pr_id = gl_TexCoord[1].st ;
|
||||||
|
|
||||||
|
/* Object colliding with itself */
|
||||||
|
|
||||||
|
if ( length ( my_id - pr_id ) < 0.05) discard ;
|
||||||
|
|
||||||
|
vec2 last_id = texture2D ( old_collisions, my_id ).xy ;
|
||||||
|
|
||||||
|
/* Object collision that will already have been dealt with */
|
||||||
|
|
||||||
|
if ( pr_id.y >= last_id.y ) discard ;
|
||||||
|
if ( pr_id.y == last_id.y && pr_id.x >= last_id.y) discard ;
|
||||||
|
|
||||||
|
vec3 my_pos = texture2D ( position, my_id ).xyz ;
|
||||||
|
vec3 pr_pos = texture2D ( position, pr_id ).xyz ;
|
||||||
|
|
||||||
|
/* Objects that don't actually collide */
|
||||||
|
|
||||||
|
if ( length ( my_pos - pr_pos ) >= 2.0 ) discard ;
|
||||||
|
|
||||||
|
gl_FragColor = vec4 ( pr_id, 0, 1 ) ;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -335,12 +335,14 @@ void FrameBufferObject::fillTexture ( float *data )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FrameBufferObject::paint ()
|
void FrameBufferObject::prepare ( bool clear )
|
||||||
{
|
{
|
||||||
makeDestination () ;
|
makeDestination () ;
|
||||||
|
|
||||||
glViewport ( 0, 0, width, height ) ;
|
glViewport ( 0, 0, width, height ) ;
|
||||||
|
|
||||||
|
if ( clear ) glClear ( GL_COLOR_BUFFER_BIT ) ;
|
||||||
|
|
||||||
glMatrixMode ( GL_PROJECTION ) ;
|
glMatrixMode ( GL_PROJECTION ) ;
|
||||||
glLoadIdentity () ;
|
glLoadIdentity () ;
|
||||||
glOrtho ( -1, 1, -1, 1, -1, 1 ) ;
|
glOrtho ( -1, 1, -1, 1, -1, 1 ) ;
|
||||||
@@ -351,8 +353,11 @@ void FrameBufferObject::paint ()
|
|||||||
glDisable ( GL_DEPTH_TEST ) ;
|
glDisable ( GL_DEPTH_TEST ) ;
|
||||||
glDisable ( GL_CULL_FACE ) ;
|
glDisable ( GL_CULL_FACE ) ;
|
||||||
glDisable ( GL_BLEND ) ;
|
glDisable ( GL_BLEND ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FrameBufferObject::fill ()
|
||||||
|
{
|
||||||
float s_min = 0.5f / (float) width ;
|
float s_min = 0.5f / (float) width ;
|
||||||
float s_max = (((float) width) - 0.5f) / (float) width ;
|
float s_max = (((float) width) - 0.5f) / (float) width ;
|
||||||
float t_min = 0.5f / (float) height ;
|
float t_min = 0.5f / (float) height ;
|
||||||
|
|||||||
@@ -73,7 +73,10 @@ public:
|
|||||||
glBindTexture ( GL_TEXTURE_2D, textureHandle ) ;
|
glBindTexture ( GL_TEXTURE_2D, textureHandle ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint () ;
|
void prepare ( bool clear = false ) ;
|
||||||
|
void fill () ;
|
||||||
|
|
||||||
|
void paint ( bool clear = false ) { prepare ( clear ) ; fill () ; }
|
||||||
|
|
||||||
void fillTexture ( float *data ) ;
|
void fillTexture ( float *data ) ;
|
||||||
void fillTexture ( unsigned short *data ) ;
|
void fillTexture ( unsigned short *data ) ;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"void main()" \
|
"void main()" \
|
||||||
"{" \
|
"{" \
|
||||||
" gl_TexCoord[0] = gl_MultiTexCoord0 ;" \
|
" gl_TexCoord[0] = gl_MultiTexCoord0 ;" \
|
||||||
|
" gl_TexCoord[1] = gl_MultiTexCoord1 ;" \
|
||||||
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex ;" \
|
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex ;" \
|
||||||
"}"
|
"}"
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user