* 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.
* Eliminated 1-component FBO that caused grief for FBO completeness test.
* Added back missing cubeShaderNoTexture.vert
This commit is contained in:
sjbaker
2006-09-20 00:44:41 +00:00
parent 22fdf584b8
commit dad2cb634e
12 changed files with 884 additions and 803 deletions

View File

@@ -1,5 +1,10 @@
(Add new stuff at the top!)
* 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.
* Eliminated 1-component FBO that caused grief for FBO completeness test.
* Added back missing cubeShaderNoTexture.vert
------------------- FIRST ADDITION TO SUBVERSION ---------------------
GPUphysics-0.4

View File

@@ -1,63 +1,63 @@
I have added some command line options to hopefully
help with our debugging problems.
1) Run without any shaders at all:
GPU_physics_demo -s
This should produce a grey screen with a neat grid of randomly
coloured cubes that are sitting completely motionless. If this
doesn't work then render-to-texture and shaders are not the
problem and we have some very basic OpenGL problem to worry
about.
2) Run with just one shader - but no render-to-texture:
GPU_physics_demo -p
Just like '-s', this should produce a grey screen with a neat
grid of randomly coloured cubes that are sitting completely
motionless. This time, the vertex shader is reading the
positioning information from a texturemap. If this
doesn't work then render-to-texture isn't the problem but
something is amiss in shader-land.
There are several possibilities - the nastiest of which might
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:
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:
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.
I have added some command line options to hopefully
help with our debugging problems.
1) Run without any shaders at all:
GPU_physics_demo -s
This should produce a grey screen with a neat grid of randomly
coloured cubes that are sitting completely motionless. If this
doesn't work then render-to-texture and shaders are not the
problem and we have some very basic OpenGL problem to worry
about.
2) Run with just one shader - but no render-to-texture:
GPU_physics_demo -p
Just like '-s', this should produce a grey screen with a neat
grid of randomly coloured cubes that are sitting completely
motionless. This time, the vertex shader is reading the
positioning information from a texturemap. If this
doesn't work then render-to-texture isn't the problem but
something is amiss in shader-land.
There are several possibilities - the nastiest of which might
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:
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:
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.

View File

@@ -1,101 +1,113 @@
/**********************\
* *
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
Add specialised includes/defines...
*/
#ifdef GPUP_WIN32
#include <windows.h>
#include <mmsystem.h>
#include <regstr.h>
#define GPUP_WGL 1
#endif
#ifdef GPUP_CYGWIN
#include <unistd.h>
#define GPUP_WGL 1
#endif
#ifdef GPUP_BEOS
#include <be/kernel/image.h>
#define GPUP_GLX 1
#endif
#ifdef GPUP_MACINTOSH
#include <CodeFragments.h>
#include <unistd.h>
#define GPUP_AGL 1
#endif
#ifdef GPUP_MAC_OSX
#include <unistd.h>
#define GPUP_CGL 1
#endif
#if defined(GPUP_LINUX) || defined(GPUP_BSD) || defined(GPUP_IRIX) || defined(GPUP_SOLARIS) || defined(GPUP_AIX)
#include <unistd.h>
#include <dlfcn.h>
#include <fcntl.h>
#define GPUP_GLX 1
#endif
#if defined(GPUP_BSD)
#include <sys/param.h>
#define GPUP_GLX 1
#endif
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <float.h>
#include <errno.h>
#include <GL/glew.h>
#if defined(GPUP_MAC_OSX) && !defined (VMDMESA)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#endif
/**********************\
* *
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
Add specialised includes/defines...
*/
#ifdef GPUP_WIN32
#include <windows.h>
#include <mmsystem.h>
#include <regstr.h>
#define GPUP_WGL 1
#endif
#ifdef GPUP_CYGWIN
#include <unistd.h>
#define GPUP_WGL 1
#endif
#ifdef GPUP_BEOS
#include <be/kernel/image.h>
#define GPUP_GLX 1
#endif
#ifdef GPUP_MACINTOSH
#include <CodeFragments.h>
#include <unistd.h>
#define GPUP_AGL 1
#endif
#ifdef GPUP_MAC_OSX
#include <unistd.h>
#define GPUP_CGL 1
#endif
#if defined(GPUP_LINUX) || defined(GPUP_BSD) || defined(GPUP_IRIX) || defined(GPUP_SOLARIS) || defined(GPUP_AIX)
#include <unistd.h>
#include <dlfcn.h>
#include <fcntl.h>
#define GPUP_GLX 1
#endif
#if defined(GPUP_BSD)
#include <sys/param.h>
#define GPUP_GLX 1
#endif
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <float.h>
#include <errno.h>
#include <GL/glew.h>
#if defined(GPUP_MAC_OSX) && !defined (VMDMESA)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#endif
#ifdef DISABLE_GL_ERROR_CHECKS
inline void showGLerror ( const char * ) {}
#else
inline void showGLerror ( const char *msg )
{
GLenum err ;
while ( (err = glGetError()) != GL_NO_ERROR )
fprintf ( stderr, "%s: OpenGL Error - %s\n", msg, gluErrorString ( err ) ) ;
}
#endif

View File

@@ -73,7 +73,7 @@ static FrameBufferObject *rotation ;
static FrameBufferObject *velocity ;
static FrameBufferObject *rotvelocity ;
static FrameBufferObject *force ;
static FrameBufferObject *mass ;
static FrameBufferObject *massXX ;
static FrameBufferObject *old ;
#define TEX_SIZE 128
@@ -139,7 +139,7 @@ void initMotionTextures ()
velocity = NULL ;
rotvelocity = NULL ;
force = NULL ;
mass = NULL ;
massXX = NULL ;
}
else
{
@@ -148,13 +148,13 @@ void initMotionTextures ()
if ( debugOpt == DRAW_WITHOUT_FORCES )
{
force = NULL ;
mass = NULL ;
force = NULL ;
massXX = NULL ;
}
else
{
force = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
mass = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 1, FBO_FLOAT ) ;
force = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
massXX = new FrameBufferObject ( TEX_SIZE, TEX_SIZE, 3, FBO_FLOAT ) ;
}
}
@@ -164,14 +164,14 @@ void initMotionTextures ()
float *velocityData ;
float *rotvelocityData ;
float *forceData ;
float *massData ;
float *massXXData ;
if ( debugOpt == DRAW_WITHOUT_PHYSICS )
{
velocityData = NULL ;
rotvelocityData = NULL ;
forceData = NULL ;
massData = NULL ;
massXXData = NULL ;
}
else
{
@@ -181,12 +181,12 @@ void initMotionTextures ()
if ( debugOpt == DRAW_WITHOUT_FORCES )
{
forceData = NULL ;
massData = NULL ;
massXXData= NULL ;
}
else
{
forceData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
massData = new float [ TEX_SIZE * TEX_SIZE ] ;
forceData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
massXXData = new float [ TEX_SIZE * TEX_SIZE * 3 ] ;
}
}
@@ -229,7 +229,9 @@ void initMotionTextures ()
forceData [ (i*TEX_SIZE + j) * 3 + 2 ] = 0.0f ;
/* One kg in weight each */
massData [ i*TEX_SIZE + j ] = 1.0f ;
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 */
}
}
}
@@ -248,7 +250,7 @@ void initMotionTextures ()
if ( debugOpt != DRAW_WITHOUT_FORCES )
{
force -> fillTexture ( forceData ) ;
mass -> fillTexture ( massData ) ;
massXX -> fillTexture ( massXXData ) ;
}
}
}
@@ -278,13 +280,13 @@ void initPhysicsShaders ()
"uniform vec4 g_dt ;"
"uniform sampler2D old_velocity ;"
"uniform sampler2D force ;"
"uniform sampler2D mass ;"
"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 ( mass , gl_TexCoord[0].st ).x),"
" texture2D ( massXX , gl_TexCoord[0].st ).x),"
" 1.0 ) ; }",
"VelocityGenerator Frag Shader" ) ;
assert ( velocityGenerator -> compiledOK () ) ;
@@ -578,7 +580,7 @@ void display ( void )
velocityGenerator -> use () ;
velocityGenerator -> applyTexture ( "old_velocity", old , 0 ) ;
velocityGenerator -> applyTexture ( "force" , force , 1 ) ;
velocityGenerator -> applyTexture ( "mass" , mass , 2 ) ;
velocityGenerator -> applyTexture ( "massXX" , massXX , 2 ) ;
velocityGenerator -> setUniform4f ( "g_dt", 0.0f, -9.8f, 0.0f, 0.016f ) ;
velocity -> paint () ;
}

View File

@@ -1,25 +1,25 @@
/* GPUphysics -- A library and demo program to assist in running physics
simulations on a GPU.
Copyright (C) 2006 Stephen J. Baker
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Steve Baker sjbaker1@airmail.net
*/
/* GPUphysics -- A library and demo program to assist in running physics
simulations on a GPU.
Copyright (C) 2006 Stephen J. Baker
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Steve Baker sjbaker1@airmail.net
*/

View File

@@ -1,106 +1,106 @@
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
cubeShaderNoVertexTexture.vert
cubeShader.frag
----------------------------------------------------------
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!
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
cubeShaderNoVertexTexture.vert
cubeShader.frag
----------------------------------------------------------
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!

View File

@@ -1,6 +1,6 @@
void main()
{
gl_FragColor = gl_Color ;
}
void main()
{
gl_FragColor = gl_Color ;
}

View File

@@ -1,42 +1,42 @@
/* Use this for rendering the little cubes. */
/* Translation & rotation passed in texture maps */
uniform sampler2D position ;
uniform sampler2D rotation ;
/* gl_Color is just the vertex colour */
/* gl_MultiTexCoord0 selects where within the texture we
find this cubes location */
void main()
{
vec4 pos = vec4 ( texture2D ( position, gl_MultiTexCoord0.st ).xyz, 1.0 ) ;
vec3 rot = texture2D ( rotation, gl_MultiTexCoord0.st ).xyz ;
/* Build a rotation matrix */
float sh = sin ( rot.x ) ; float ch = cos ( rot.x ) ;
float sp = sin ( rot.y ) ; float cp = cos ( rot.y ) ;
float sr = sin ( rot.z ) ; float cr = cos ( rot.z ) ;
mat4 mat = mat4 ( ch * cr - sh * sr * sp,
-sh * cp,
sr * ch + sh * cr * sp,
0,
cr * sh + sr * sp * ch,
ch * cp,
sr * sh - cr * sp * ch,
0,
-sr * cp,
sp,
cr * cp,
0,
0.0, 0.0, 0.0, 1.0 ) ;
gl_FrontColor = gl_Color ;
pos.xyz += (mat * gl_Vertex).xyz ;
gl_Position = gl_ModelViewProjectionMatrix * pos ;
}
/* Use this for rendering the little cubes. */
/* Translation & rotation passed in texture maps */
uniform sampler2D position ;
uniform sampler2D rotation ;
/* gl_Color is just the vertex colour */
/* gl_MultiTexCoord0 selects where within the texture we
find this cubes location */
void main()
{
vec4 pos = vec4 ( texture2D ( position, gl_MultiTexCoord0.st ).xyz, 1.0 ) ;
vec3 rot = texture2D ( rotation, gl_MultiTexCoord0.st ).xyz ;
/* Build a rotation matrix */
float sh = sin ( rot.x ) ; float ch = cos ( rot.x ) ;
float sp = sin ( rot.y ) ; float cp = cos ( rot.y ) ;
float sr = sin ( rot.z ) ; float cr = cos ( rot.z ) ;
mat4 mat = mat4 ( ch * cr - sh * sr * sp,
-sh * cp,
sr * ch + sh * cr * sp,
0,
cr * sh + sr * sp * ch,
ch * cp,
sr * sh - cr * sp * ch,
0,
-sr * cp,
sp,
cr * cp,
0,
0.0, 0.0, 0.0, 1.0 ) ;
gl_FrontColor = gl_Color ;
pos.xyz += (mat * gl_Vertex).xyz ;
gl_Position = gl_ModelViewProjectionMatrix * pos ;
}

View File

@@ -0,0 +1,12 @@
/*
Use this for rendering the little cubes when
there is no vertex shader texture support.
*/
void main()
{
gl_FrontColor = gl_Color ;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex ;
}

View File

@@ -46,8 +46,34 @@ static void checkFrameBufferStatus ()
fprintf ( stderr, "ERROR: Unsupported FBO setup.\n" ) ;
exit ( 1 ) ;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT :
fprintf ( stderr, "WARNING: Incomplete FBO setup.\n" ) ;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT :
fprintf ( stderr, "WARNING: Incomplete FBO attachment.\n" ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT :
fprintf ( stderr, "WARNING: Incomplete FBO - missing attachment.\n" ) ;
break ;
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
fprintf ( stderr, "WARNING: Incomplete FBO - duplicate attachment.\n" ) ;
break ;
#endif
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT :
fprintf ( stderr, "WARNING: Incomplete FBO - improper dimensions.\n" ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT :
fprintf ( stderr, "WARNING: Incomplete FBO - improper formats.\n" ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT :
fprintf ( stderr, "WARNING: Incomplete FBO draw buffer.\n" ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT :
fprintf ( stderr, "WARNING: Incomplete FBO read buffer.\n" ) ;
break ;
default :
@@ -145,38 +171,61 @@ FrameBufferObject::FrameBufferObject ( int _width ,
}
glGenTextures ( 1, & textureHandle ) ;
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 ) ;
fillTexture ( (void *) NULL ) ;
glGenFramebuffersEXT ( 1, & fboHandle ) ;
glGenRenderbuffersEXT ( 1, & depth_rb ) ;
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT, fboHandle ) ;
glFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, textureHandle, 0 ) ;
// initialize depth renderbuffer
#ifdef NEED_DEPTH_BUFFER
static GLuint depth_rb = 0 ;
glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT, depth_rb ) ;
glRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,
width, height ) ;
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depth_rb ) ;
if ( depth_rb == 0 )
{
glGenRenderbuffersEXT ( 1, & depth_rb ) ;
glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT, depth_rb ) ;
glRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,
width, height ) ;
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depth_rb ) ;
}
else
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depth_rb ) ;
#else
glDisable ( GL_DEPTH_TEST ) ;
glDepthMask ( 0 ) ;
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, 0 ) ;
#endif
#ifdef NEED_STENCIL_BUFFER
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 ) ;
static GLuint stencil_rb = 0 ;
if ( stencil_rb == 0 )
{
glGenRenderbuffersEXT ( 1, & stencil_rb ) ;
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
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, stencil_rb ) ;
#else
glDisable ( GL_STENCIL_TEST ) ;
glStencilMask ( 0 ) ;
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, 0 ) ;
#endif
// Check framebuffer completeness at the end of initialization.
@@ -278,6 +327,7 @@ void FrameBufferObject::paint ()
glDisable ( GL_CULL_FACE ) ;
glDisable ( GL_BLEND ) ;
float s_min = 0.5f / (float) width ;
float s_max = (((float) width) - 0.5f) / (float) width ;
float t_min = 0.5f / (float) height ;

View File

@@ -3,7 +3,9 @@ GLuint makeTextureTarget ( GLuint textureHandle ) ;
void renderTo2DTexture ( GLuint fboHandle ) ;
void renderToFrameBuffer () ;
//#define NEED_STENCIL_BUFFER 1
// #define NEED_STENCIL_BUFFER 1
// #define NEED_DEPTH_BUFFER 1
enum fboDataType
{
@@ -44,11 +46,6 @@ class FrameBufferObject
GLuint textureHandle ;
GLuint fboHandle ;
GLuint depth_rb ;
#ifdef NEED_STENCIL_BUFFER
GLuint stencil_rb ;
#endif
void fillTexture ( void *data ) ;
void fetchTexture ( void *data ) ;
@@ -61,6 +58,12 @@ public:
void makeDestination ()
{
#ifndef NEED_DEPTH_BUFFER
glDepthMask ( 0 ) ;
#endif
#ifndef NEED_STENCIL_BUFFER
glStencilMask ( 0 ) ;
#endif
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT, fboHandle ) ;
}
@@ -83,5 +86,11 @@ public:
inline void restoreFrameBuffer ()
{
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT, 0 ) ;
#ifndef NEED_DEPTH_BUFFER
glDepthMask ( 1 ) ;
#endif
#ifndef NEED_STENCIL_BUFFER
glStencilMask ( 1 ) ;
#endif
}

View File

@@ -1,420 +1,411 @@
#include "GPU_physics.h"
#include "shaderSupport.h"
#include "fboSupport.h"
static void showGLerror ()
{
GLenum err ;
while ( (err = glGetError()) != GL_NO_ERROR )
fprintf ( stderr, "OpenGL Error: %s\n", gluErrorString ( err ) ) ;
}
#define DEFAULT_VERT_SHADER \
"void main()" \
"{" \
" gl_TexCoord[0] = gl_MultiTexCoord0 ;" \
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex ;" \
"}"
class FrameBufferObject ;
class GLSL_Shader
{
GLenum type ;
GLhandleARB handle ;
char *name ;
char *source ;
public:
GLSL_Shader ()
{
type = (GLenum) 0 ;
handle = 0 ;
name = NULL ;
source = NULL ;
}
~GLSL_Shader ()
{
delete [] name ;
delete [] source ;
}
bool compileFile ( const char *fname , GLenum type ) ;
bool compileString ( const char *source, GLenum type,
const char *name ) ;
GLenum getType () { return type ; }
GLhandleARB getHandle () { return handle ; }
} ;
static char *readShaderText ( const char *fname )
{
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 )
{
fprintf ( stderr, "Cannot read shader '%s'\n", fname ) ;
exit ( 1 ) ;
}
int count = fread ( shader, 1, size, fd ) ;
shader [ count ] = '\0' ;
fclose ( fd ) ;
return shader ;
}
/*****************************\
* *
* Error handling stuff *
* *
\*****************************/
static void showShaderInfo ( const char *which,
GLhandleARB handle, const char *name )
{
int len = 0 ;
showGLerror () ;
glGetObjectParameterivARB ( handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &len ) ;
showGLerror () ;
if ( len > 0 )
{
int trueLen ;
char *s = new char [ len ] ;
glGetInfoLogARB ( handle, len, (GLint*)&trueLen, s ) ;
if ( trueLen > 0 && s [ 0 ] != '\0' )
fprintf ( stderr, "%s:%s - \n%s\n", which, name, s ) ;
delete [] s ;
}
}
/************************************\
* *
* Single Shader Stuff *
* *
\************************************/
bool GLSL_Shader::compileFile ( const char *fname, GLenum _type )
{
return compileString ( readShaderText ( fname ), _type, fname ) ;
}
bool GLSL_Shader::compileString ( const char *_source,
GLenum _type,
const char *_name )
{
delete [] name ;
delete [] source ;
type = _type ;
name = strdup ( _name ) ;
source = strdup ( _source ) ;
GLint stat ;
handle = glCreateShaderObjectARB ( type ) ;
glShaderSourceARB ( handle, 1, (const GLcharARB **) & source, NULL);
glCompileShaderARB ( handle ) ;
glGetObjectParameterivARB ( handle, GL_OBJECT_COMPILE_STATUS_ARB, & stat ) ;
showShaderInfo ( "Compiling", handle, name ) ;
if ( ! stat )
{
fprintf ( stderr, "Failed to compile shader '%s'.\n", name ) ;
return false ;
}
return true ;
}
/************************************\
* *
* Shader Pair Stuff *
* *
\************************************/
GLint GLSL_ShaderPair::getUniformLocation ( const char *uni_name )
{
assert ( success ) ;
GLint loc = glGetUniformLocationARB ( handle, uni_name ) ;
if ( loc == -1 )
fprintf ( stderr, "No such uniform as '%s' or"
" '%s' is unused in shader pair '%s'.\n", uni_name,
uni_name,
name ) ;
else
showGLerror () ;
return loc ;
}
void GLSL_ShaderPair::showActiveUniforms ( FILE *fd )
{
GLint maxlen = 0 ;
GLint maxattrs = 0 ;
if ( fd == NULL ) fd = stderr ;
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_UNIFORMS_ARB,
&maxattrs ) ;
if ( maxattrs == 0 )
{
fprintf ( fd, "No Active Uniforms.\n" ) ;
return ;
}
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB,
&maxlen ) ;
char *name = new char [ maxlen+1 ] ;
fprintf ( fd, "Active Uniforms:\n" ) ;
for ( int i = 0 ; i < maxattrs ; i++ )
{
GLsizei len ;
GLint size ;
GLenum vartype ;
char *vartypename ;
GLint location ;
glGetActiveUniformARB ( handle, i,
maxlen+1, &len, &size, &vartype, name ) ;
location = glGetUniformLocationARB ( handle, name ) ;
switch ( vartype )
{
case GL_FLOAT : vartypename = "float " ; break ;
case GL_FLOAT_VEC2_ARB : vartypename = "vec2 " ; break ;
case GL_FLOAT_VEC3_ARB : vartypename = "vec3 " ; break ;
case GL_FLOAT_VEC4_ARB : vartypename = "vec4 " ; break ;
case GL_INT : vartypename = "int " ; break ;
case GL_INT_VEC2_ARB : vartypename = "intvec2 " ; break ;
case GL_INT_VEC3_ARB : vartypename = "intvec3 " ; break ;
case GL_INT_VEC4_ARB : vartypename = "intvec4 " ; break ;
case GL_BOOL : vartypename = "bool " ; break ;
case GL_BOOL_VEC2_ARB : vartypename = "boolvec2 " ; break ;
case GL_BOOL_VEC3_ARB : vartypename = "boolvec3 " ; break ;
case GL_BOOL_VEC4_ARB : vartypename = "boolvec4 " ; break ;
case GL_FLOAT_MAT2_ARB : vartypename = "mat2 " ; break ;
case GL_FLOAT_MAT3_ARB : vartypename = "mat3 " ; break ;
case GL_FLOAT_MAT4_ARB : vartypename = "mat4 " ; break ;
case GL_SAMPLER_1D_ARB : vartypename = "sampler1D" ; break ;
case GL_SAMPLER_2D_ARB : vartypename = "sampler2D" ; break ;
case GL_SAMPLER_3D_ARB : vartypename = "sampler3D" ; break ;
default : vartypename = "?????????" ; break ;
}
if ( size == 1 )
fprintf ( fd, "%2d) %s %s ; // @%d\n", i,
vartypename, name, location ) ;
else
fprintf ( fd, "%2d) %s %s [ %d ] ; // @%d\n", i,
vartypename, name, size, location ) ;
}
fprintf ( fd, "\n" ) ;
delete name ;
}
void GLSL_ShaderPair::showActiveAttribs ( FILE *fd )
{
if ( fd == NULL ) fd = stderr ;
GLint maxlen = 0 ;
GLint maxattrs = 0 ;
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_ATTRIBUTES_ARB,
&maxattrs ) ;
if ( maxattrs == 0 )
{
fprintf ( fd, "No Active Attributes.\n" ) ;
return ;
}
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB,
&maxlen ) ;
char *name = new char [ maxlen+1 ] ;
fprintf ( fd, "Active Attributes:\n" ) ;
for ( int i = 0 ; i < maxattrs ; i++ )
{
GLsizei len ;
GLint size ;
GLenum vartype ;
char *vartypename ;
GLint location ;
glGetActiveAttribARB ( handle, i, maxlen+1, &len, &size, &vartype, name ) ;
location = glGetAttribLocationARB ( handle, name ) ;
switch ( vartype )
{
case GL_FLOAT : vartypename = "float" ; break ;
case GL_FLOAT_VEC2_ARB : vartypename = "vec2 " ; break ;
case GL_FLOAT_VEC3_ARB : vartypename = "vec3 " ; break ;
case GL_FLOAT_VEC4_ARB : vartypename = "vec4 " ; break ;
case GL_FLOAT_MAT2_ARB : vartypename = "mat2 " ; break ;
case GL_FLOAT_MAT3_ARB : vartypename = "mat3 " ; break ;
case GL_FLOAT_MAT4_ARB : vartypename = "mat4 " ; break ;
default : vartypename = "???? " ; break ;
}
if ( size == 1 )
fprintf ( fd, "%2d) %s %s ; // @%d\n", i,
vartypename, name, location ) ;
else
fprintf ( fd, "%2d) %s %s [ %d ] ; // @%d\n", i,
vartypename, name, size, location ) ;
}
fprintf ( fd, "\n" ) ;
delete name ;
}
bool GLSL_ShaderPair::link ()
{
GLint stat ;
handle = glCreateProgramObjectARB () ;
glAttachObjectARB ( handle, vertShader -> getHandle () ) ;
glAttachObjectARB ( handle, fragShader -> getHandle () ) ;
glLinkProgramARB ( handle ) ;
glGetObjectParameterivARB ( handle, GL_OBJECT_LINK_STATUS_ARB, &stat ) ;
showShaderInfo ( "Linking", handle, name ) ;
glValidateProgramARB ( handle ) ;
showShaderInfo ( "Validate", handle, name ) ;
if ( ! stat )
{
fprintf ( stderr, "Failed to link shader.\n" ) ;
return false ;
}
return true ;
}
GLSL_ShaderPair::GLSL_ShaderPair ( const char *_name,
const char *vertFname,
const char *fragFname )
{
name = strdup ( _name ) ;
handle = 0 ;
vertShader = new GLSL_Shader () ;
fragShader = new GLSL_Shader () ;
bool res1 = ( vertFname == NULL ) ?
vertShader -> compileString ( DEFAULT_VERT_SHADER,
GL_VERTEX_SHADER_ARB,
"Default Vertex Shader" ) :
vertShader -> compileFile ( vertFname, GL_VERTEX_SHADER_ARB ) ;
bool res2 = fragShader -> compileFile ( fragFname, GL_FRAGMENT_SHADER_ARB ) ;
success = ( res1 && res2 && link () ) ;
}
GLSL_ShaderPair::GLSL_ShaderPair ( const char *_name,
const char *vertSource,
const char *vertName,
const char *fragSource,
const char *fragName )
{
name = strdup ( _name ) ;
handle = 0 ;
vertShader = new GLSL_Shader () ;
fragShader = new GLSL_Shader () ;
bool res1 = ( vertSource == NULL ) ?
vertShader -> compileString ( DEFAULT_VERT_SHADER,
GL_VERTEX_SHADER_ARB,
"Default Vertex Shader" ) :
vertShader -> compileString ( vertSource,
GL_VERTEX_SHADER_ARB,
vertName );
bool res2 = fragShader -> compileString ( fragSource,
GL_FRAGMENT_SHADER_ARB,
fragName );
success = ( res1 && res2 && link () ) ;
}
GLSL_ShaderPair::~GLSL_ShaderPair ()
{
delete [] name ;
delete vertShader ;
delete fragShader ;
}
void GLSL_ShaderPair::applyTexture ( const char *uniformName,
FrameBufferObject *fbo,
int slot )
{
fbo -> use ( slot ) ;
glUniform1iARB ( getUniformLocation ( uniformName ), slot ) ;
}
#include "GPU_physics.h"
#include "shaderSupport.h"
#include "fboSupport.h"
#define DEFAULT_VERT_SHADER \
"void main()" \
"{" \
" gl_TexCoord[0] = gl_MultiTexCoord0 ;" \
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex ;" \
"}"
class FrameBufferObject ;
class GLSL_Shader
{
GLenum type ;
GLhandleARB handle ;
char *name ;
char *source ;
public:
GLSL_Shader ()
{
type = (GLenum) 0 ;
handle = 0 ;
name = NULL ;
source = NULL ;
}
~GLSL_Shader ()
{
delete [] name ;
delete [] source ;
}
bool compileFile ( const char *fname , GLenum type ) ;
bool compileString ( const char *source, GLenum type,
const char *name ) ;
GLenum getType () { return type ; }
GLhandleARB getHandle () { return handle ; }
} ;
static char *readShaderText ( const char *fname )
{
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 )
{
fprintf ( stderr, "Cannot read shader '%s'\n", fname ) ;
exit ( 1 ) ;
}
int count = fread ( shader, 1, size, fd ) ;
shader [ count ] = '\0' ;
fclose ( fd ) ;
return shader ;
}
/*****************************\
* *
* Error handling stuff *
* *
\*****************************/
static void showShaderInfo ( const char *which,
GLhandleARB handle, const char *name )
{
int len = 0 ;
showGLerror ( "showShaderInfo_0" ) ;
glGetObjectParameterivARB ( handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &len ) ;
showGLerror ( "showShaderInfo_1" ) ;
if ( len > 0 )
{
int trueLen ;
char *s = new char [ len ] ;
glGetInfoLogARB ( handle, len, (GLint*)&trueLen, s ) ;
if ( trueLen > 0 && s [ 0 ] != '\0' )
fprintf ( stderr, "%s:%s - \n%s\n", which, name, s ) ;
delete [] s ;
}
}
/************************************\
* *
* Single Shader Stuff *
* *
\************************************/
bool GLSL_Shader::compileFile ( const char *fname, GLenum _type )
{
return compileString ( readShaderText ( fname ), _type, fname ) ;
}
bool GLSL_Shader::compileString ( const char *_source,
GLenum _type,
const char *_name )
{
delete [] name ;
delete [] source ;
type = _type ;
name = strdup ( _name ) ;
source = strdup ( _source ) ;
GLint stat ;
handle = glCreateShaderObjectARB ( type ) ;
glShaderSourceARB ( handle, 1, (const GLcharARB **) & source, NULL);
glCompileShaderARB ( handle ) ;
glGetObjectParameterivARB ( handle, GL_OBJECT_COMPILE_STATUS_ARB, & stat ) ;
showShaderInfo ( "Compiling", handle, name ) ;
if ( ! stat )
{
fprintf ( stderr, "Failed to compile shader '%s'.\n", name ) ;
return false ;
}
return true ;
}
/************************************\
* *
* Shader Pair Stuff *
* *
\************************************/
GLint GLSL_ShaderPair::getUniformLocation ( const char *uni_name )
{
assert ( success ) ;
GLint loc = glGetUniformLocationARB ( handle, uni_name ) ;
if ( loc == -1 )
fprintf ( stderr, "No such uniform as '%s' or"
" '%s' is unused in shader pair '%s'.\n", uni_name,
uni_name,
name ) ;
else
showGLerror ( "GLSL_ShaderPair::getUniformLocation" ) ;
return loc ;
}
void GLSL_ShaderPair::showActiveUniforms ( FILE *fd )
{
GLint maxlen = 0 ;
GLint maxattrs = 0 ;
if ( fd == NULL ) fd = stderr ;
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_UNIFORMS_ARB,
&maxattrs ) ;
if ( maxattrs == 0 )
{
fprintf ( fd, "No Active Uniforms.\n" ) ;
return ;
}
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB,
&maxlen ) ;
char *name = new char [ maxlen+1 ] ;
fprintf ( fd, "Active Uniforms:\n" ) ;
for ( int i = 0 ; i < maxattrs ; i++ )
{
GLsizei len ;
GLint size ;
GLenum vartype ;
char *vartypename ;
GLint location ;
glGetActiveUniformARB ( handle, i,
maxlen+1, &len, &size, &vartype, name ) ;
location = glGetUniformLocationARB ( handle, name ) ;
switch ( vartype )
{
case GL_FLOAT : vartypename = "float " ; break ;
case GL_FLOAT_VEC2_ARB : vartypename = "vec2 " ; break ;
case GL_FLOAT_VEC3_ARB : vartypename = "vec3 " ; break ;
case GL_FLOAT_VEC4_ARB : vartypename = "vec4 " ; break ;
case GL_INT : vartypename = "int " ; break ;
case GL_INT_VEC2_ARB : vartypename = "intvec2 " ; break ;
case GL_INT_VEC3_ARB : vartypename = "intvec3 " ; break ;
case GL_INT_VEC4_ARB : vartypename = "intvec4 " ; break ;
case GL_BOOL : vartypename = "bool " ; break ;
case GL_BOOL_VEC2_ARB : vartypename = "boolvec2 " ; break ;
case GL_BOOL_VEC3_ARB : vartypename = "boolvec3 " ; break ;
case GL_BOOL_VEC4_ARB : vartypename = "boolvec4 " ; break ;
case GL_FLOAT_MAT2_ARB : vartypename = "mat2 " ; break ;
case GL_FLOAT_MAT3_ARB : vartypename = "mat3 " ; break ;
case GL_FLOAT_MAT4_ARB : vartypename = "mat4 " ; break ;
case GL_SAMPLER_1D_ARB : vartypename = "sampler1D" ; break ;
case GL_SAMPLER_2D_ARB : vartypename = "sampler2D" ; break ;
case GL_SAMPLER_3D_ARB : vartypename = "sampler3D" ; break ;
default : vartypename = "?????????" ; break ;
}
if ( size == 1 )
fprintf ( fd, "%2d) %s %s ; // @%d\n", i,
vartypename, name, location ) ;
else
fprintf ( fd, "%2d) %s %s [ %d ] ; // @%d\n", i,
vartypename, name, size, location ) ;
}
fprintf ( fd, "\n" ) ;
delete name ;
}
void GLSL_ShaderPair::showActiveAttribs ( FILE *fd )
{
if ( fd == NULL ) fd = stderr ;
GLint maxlen = 0 ;
GLint maxattrs = 0 ;
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_ATTRIBUTES_ARB,
&maxattrs ) ;
if ( maxattrs == 0 )
{
fprintf ( fd, "No Active Attributes.\n" ) ;
return ;
}
glGetObjectParameterivARB ( handle,
GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB,
&maxlen ) ;
char *name = new char [ maxlen+1 ] ;
fprintf ( fd, "Active Attributes:\n" ) ;
for ( int i = 0 ; i < maxattrs ; i++ )
{
GLsizei len ;
GLint size ;
GLenum vartype ;
char *vartypename ;
GLint location ;
glGetActiveAttribARB ( handle, i, maxlen+1, &len, &size, &vartype, name ) ;
location = glGetAttribLocationARB ( handle, name ) ;
switch ( vartype )
{
case GL_FLOAT : vartypename = "float" ; break ;
case GL_FLOAT_VEC2_ARB : vartypename = "vec2 " ; break ;
case GL_FLOAT_VEC3_ARB : vartypename = "vec3 " ; break ;
case GL_FLOAT_VEC4_ARB : vartypename = "vec4 " ; break ;
case GL_FLOAT_MAT2_ARB : vartypename = "mat2 " ; break ;
case GL_FLOAT_MAT3_ARB : vartypename = "mat3 " ; break ;
case GL_FLOAT_MAT4_ARB : vartypename = "mat4 " ; break ;
default : vartypename = "???? " ; break ;
}
if ( size == 1 )
fprintf ( fd, "%2d) %s %s ; // @%d\n", i,
vartypename, name, location ) ;
else
fprintf ( fd, "%2d) %s %s [ %d ] ; // @%d\n", i,
vartypename, name, size, location ) ;
}
fprintf ( fd, "\n" ) ;
delete name ;
}
bool GLSL_ShaderPair::link ()
{
GLint stat ;
handle = glCreateProgramObjectARB () ;
glAttachObjectARB ( handle, vertShader -> getHandle () ) ;
glAttachObjectARB ( handle, fragShader -> getHandle () ) ;
glLinkProgramARB ( handle ) ;
glGetObjectParameterivARB ( handle, GL_OBJECT_LINK_STATUS_ARB, &stat ) ;
showShaderInfo ( "Linking", handle, name ) ;
glValidateProgramARB ( handle ) ;
showShaderInfo ( "Validate", handle, name ) ;
if ( ! stat )
{
fprintf ( stderr, "Failed to link shader.\n" ) ;
return false ;
}
return true ;
}
GLSL_ShaderPair::GLSL_ShaderPair ( const char *_name,
const char *vertFname,
const char *fragFname )
{
name = strdup ( _name ) ;
handle = 0 ;
vertShader = new GLSL_Shader () ;
fragShader = new GLSL_Shader () ;
bool res1 = ( vertFname == NULL ) ?
vertShader -> compileString ( DEFAULT_VERT_SHADER,
GL_VERTEX_SHADER_ARB,
"Default Vertex Shader" ) :
vertShader -> compileFile ( vertFname, GL_VERTEX_SHADER_ARB ) ;
bool res2 = fragShader -> compileFile ( fragFname, GL_FRAGMENT_SHADER_ARB ) ;
success = ( res1 && res2 && link () ) ;
}
GLSL_ShaderPair::GLSL_ShaderPair ( const char *_name,
const char *vertSource,
const char *vertName,
const char *fragSource,
const char *fragName )
{
name = strdup ( _name ) ;
handle = 0 ;
vertShader = new GLSL_Shader () ;
fragShader = new GLSL_Shader () ;
bool res1 = ( vertSource == NULL ) ?
vertShader -> compileString ( DEFAULT_VERT_SHADER,
GL_VERTEX_SHADER_ARB,
"Default Vertex Shader" ) :
vertShader -> compileString ( vertSource,
GL_VERTEX_SHADER_ARB,
vertName );
bool res2 = fragShader -> compileString ( fragSource,
GL_FRAGMENT_SHADER_ARB,
fragName );
success = ( res1 && res2 && link () ) ;
}
GLSL_ShaderPair::~GLSL_ShaderPair ()
{
delete [] name ;
delete vertShader ;
delete fragShader ;
}
void GLSL_ShaderPair::applyTexture ( const char *uniformName,
FrameBufferObject *fbo,
int slot )
{
fbo -> use ( slot ) ;
glUniform1iARB ( getUniformLocation ( uniformName ), slot ) ;
}