diff --git a/Extras/GPUphysics/CHANGES b/Extras/GPUphysics/CHANGES index 7978db416..bdffff2d7 100644 --- a/Extras/GPUphysics/CHANGES +++ b/Extras/GPUphysics/CHANGES @@ -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 diff --git a/Extras/GPUphysics/DEBUGGING_README b/Extras/GPUphysics/DEBUGGING_README index aaccf8b97..f1b87021b 100644 --- a/Extras/GPUphysics/DEBUGGING_README +++ b/Extras/GPUphysics/DEBUGGING_README @@ -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. + diff --git a/Extras/GPUphysics/GPU_physics.h b/Extras/GPUphysics/GPU_physics.h index 5850cf5d3..02c2439fa 100644 --- a/Extras/GPUphysics/GPU_physics.h +++ b/Extras/GPUphysics/GPU_physics.h @@ -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 -#include -#include - -/* - Add specialised includes/defines... -*/ - -#ifdef GPUP_WIN32 -#include -#include -#include -#define GPUP_WGL 1 -#endif - -#ifdef GPUP_CYGWIN -#include -#define GPUP_WGL 1 -#endif - -#ifdef GPUP_BEOS -#include -#define GPUP_GLX 1 -#endif - -#ifdef GPUP_MACINTOSH -#include -#include -#define GPUP_AGL 1 -#endif - -#ifdef GPUP_MAC_OSX -#include -#define GPUP_CGL 1 -#endif - -#if defined(GPUP_LINUX) || defined(GPUP_BSD) || defined(GPUP_IRIX) || defined(GPUP_SOLARIS) || defined(GPUP_AIX) -#include -#include -#include -#define GPUP_GLX 1 -#endif - -#if defined(GPUP_BSD) -#include -#define GPUP_GLX 1 -#endif - -#include -#include -#include -#include -#include - -#include - -#if defined(GPUP_MAC_OSX) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#include -#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 +#include +#include + +/* + Add specialised includes/defines... +*/ + +#ifdef GPUP_WIN32 +#include +#include +#include +#define GPUP_WGL 1 +#endif + +#ifdef GPUP_CYGWIN +#include +#define GPUP_WGL 1 +#endif + +#ifdef GPUP_BEOS +#include +#define GPUP_GLX 1 +#endif + +#ifdef GPUP_MACINTOSH +#include +#include +#define GPUP_AGL 1 +#endif + +#ifdef GPUP_MAC_OSX +#include +#define GPUP_CGL 1 +#endif + +#if defined(GPUP_LINUX) || defined(GPUP_BSD) || defined(GPUP_IRIX) || defined(GPUP_SOLARIS) || defined(GPUP_AIX) +#include +#include +#include +#define GPUP_GLX 1 +#endif + +#if defined(GPUP_BSD) +#include +#define GPUP_GLX 1 +#endif + +#include +#include +#include +#include +#include + +#include + +#if defined(GPUP_MAC_OSX) && !defined (VMDMESA) +#include +#include +#include +#else +#include +#include +#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 + diff --git a/Extras/GPUphysics/GPU_physics_demo.cxx b/Extras/GPUphysics/GPU_physics_demo.cxx index 12383852d..debf0d120 100644 --- a/Extras/GPUphysics/GPU_physics_demo.cxx +++ b/Extras/GPUphysics/GPU_physics_demo.cxx @@ -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 () ; } diff --git a/Extras/GPUphysics/LICENSE b/Extras/GPUphysics/LICENSE index ecc1a1005..93ba7debb 100644 --- a/Extras/GPUphysics/LICENSE +++ b/Extras/GPUphysics/LICENSE @@ -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 +*/ + diff --git a/Extras/GPUphysics/README b/Extras/GPUphysics/README index 4a999c257..d05450503 100644 --- a/Extras/GPUphysics/README +++ b/Extras/GPUphysics/README @@ -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! + + diff --git a/Extras/GPUphysics/cubeShader.frag b/Extras/GPUphysics/cubeShader.frag index 17a11a76c..a9fb8ac02 100644 --- a/Extras/GPUphysics/cubeShader.frag +++ b/Extras/GPUphysics/cubeShader.frag @@ -1,6 +1,6 @@ - -void main() -{ - gl_FragColor = gl_Color ; -} - + +void main() +{ + gl_FragColor = gl_Color ; +} + diff --git a/Extras/GPUphysics/cubeShader.vert b/Extras/GPUphysics/cubeShader.vert index f6b10dff4..b41b7e898 100644 --- a/Extras/GPUphysics/cubeShader.vert +++ b/Extras/GPUphysics/cubeShader.vert @@ -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 ; +} + diff --git a/Extras/GPUphysics/cubeShaderNoTexture.vert b/Extras/GPUphysics/cubeShaderNoTexture.vert new file mode 100644 index 000000000..47fef79df --- /dev/null +++ b/Extras/GPUphysics/cubeShaderNoTexture.vert @@ -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 ; +} + diff --git a/Extras/GPUphysics/fboSupport.cxx b/Extras/GPUphysics/fboSupport.cxx index 8da23de18..b0e2429fa 100644 --- a/Extras/GPUphysics/fboSupport.cxx +++ b/Extras/GPUphysics/fboSupport.cxx @@ -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 ; diff --git a/Extras/GPUphysics/fboSupport.h b/Extras/GPUphysics/fboSupport.h index aeec27414..d7f27f9f9 100644 --- a/Extras/GPUphysics/fboSupport.h +++ b/Extras/GPUphysics/fboSupport.h @@ -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 } diff --git a/Extras/GPUphysics/shaderSupport.cxx b/Extras/GPUphysics/shaderSupport.cxx index 34c40fb96..083095a11 100644 --- a/Extras/GPUphysics/shaderSupport.cxx +++ b/Extras/GPUphysics/shaderSupport.cxx @@ -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 ) ; +} + +