# Invert Maxtrix ??

Hi, it’s me again :o

Could you tell me, how to invert a 4x4 matrix ?
I dind’t find a method that I could use for OpenGL.

``````uniform mat4 g_ViewProjectionInverseMatrix;
uniform mat4 g_previousViewProjectionMatrix;
``````

Main Programm:

``````GLfloat MATRIX[16];
glGetFloatv( GL_PROJECTION_MATRIX, MATRIX );
int matrix=glGetUniformLocation(my_program, "g_ViewProjectionInverseMatrix");
int matrixPre=glGetUniformLocation(my_program, "g_previousViewProjectionMatrix");

glUniformMatrix4fvARB(matrix,1,true,MATRIX);
glUniformMatrix4fvARB(matrixPre,1,true,MATRIXPRE);
``````

And should I use “transpose” ?

I think my screen is only white because of the wrong (not inverted) matrices… :eek:

GLSL added inverse() in 1.40. No idea what the cost is – never used it. Short of that, probably better to grab an existing CPU math library (google opengl math library) or roll your own.

``````glUniformMatrix4fvARB(matrix,1,true,MATRIX);
``````

And should I use “transpose” ?

I assume you mean the “transpose” argument to glUniformMatrix4fv. If you mean as a substitute for the inverse, then you need to know that the inverse does not always equal the transpose. It can, but only for orthonormal matrices (e.g. rotation matrices). However, parallel and perspective projection transforms are generally not orthonormal.

That said, the OpenGL red book has closed-form definitions for the parallel and perspective projection transforms in the appendices – I’d just use them and save yourself the trouble. For instance: here.

if the matrix is the same for all vertices, it seems better to upload the inverse as a uniform instead of recomputing the inverse for each vertex. (regardless of the speed of .inverse in GLSL)

The compiler doesn’t find .inverse, but that doesn’t matter.
Now that is my motion-blur shader:

``````#version 140
uniform sampler2DRect depthTexture;
uniform sampler2DRect colorTexture;
const int g_width=640;
const int g_height=480;
//uniform mat4 g_ViewProjectionInverseMatrix;
////uniform mat4 g_previousViewProjectionMatrix;
mat4 g_ViewProjectionInverseMatrix;
//mat4 g_previousViewProjectionMatrix;

out vec4 gl_FragColor;
void main()
{
vec2 texCoord;
float zOverW;
vec4 tmp1;
vec4 tmp2;
vec4 H;
vec4 worldPos;
vec4 previousPos;
vec2 velocity;
vec4 color;
int i;

g_ViewProjectionInverseMatrix=gl_ProjectionMatrixInverse;
mat4 g_previousViewProjectionMatrix=gl_ProjectionMatrix;
//g_previousViewProjectionMatrix=

// Shader Code That Extracts the Per-Pixel World-Space Positions of the Objects That Were Rendered to the Depth Buffer
// Get the depth buffer value at this pixel.
zOverW = texture2DRect(depthTexture, gl_FragCoord.xy).x;

// H is the viewport position at this pixel in the range -1 to 1.
H = vec4((gl_FragCoord.x/float(g_width))*2.0 - 1.0, (1.0 - (gl_FragCoord.y/float(g_height)))*2.0 - 1.0, zOverW, 1.0);

// Transform by the view-projection inverse.
tmp1 = H * g_ViewProjectionInverseMatrix;
// Divide by w to get world position.
worldPos = tmp1/tmp1.w;

// Shader Code That Computes the Per-Pixel Velocity Vectors That Determine the Direction to Blur the Image
// Use the world position, and transform by the previous view-projection matrix.
tmp2 = worldPos * g_previousViewProjectionMatrix;
// Convert to nonhomogenous points [-1,1] by dividing by w.
previousPos = tmp2/tmp2.w;

// Use this frame's position and last frame's to compute the pixel velocity.
velocity = ((H - previousPos)/2.0).xy;
velocity.x *= float(g_width);
velocity.y *= float(g_height);

// Shader Code That Uses the Velocity Vector at the Current Pixel to Sample the Color Buffer Multiple Times to Achieve the Motion Blur Effect
// Get the initial color at this pixel.
color = texture2DRect(colorTexture, gl_FragCoord.xy);

texCoord = gl_FragCoord.xy + velocity;
// i had to unroll because my glsl driver doesn't even like loops!
color += texture2DRect(colorTexture, texCoord);
texCoord += velocity;
color += texture2DRect(colorTexture, texCoord);

// Average all of the samples to get the final blur color.
gl_FragColor = color/3.0;
gl_FragDepth = zOverW;
}

``````

Her is the whole code (from the NEHE sample :)).
I use “my_program” with the shader on top; the uniforms are not used here (except textures).
Do you see any significant errors ?

``````/**************************************
*                                     *
*   Jeff Molofee's Basecode Example   *
*          nehe.gamedev.net           *
*                2001                 *
*                                     *
*    All Code / Tutorial Commenting   *
*       by Jeff Molofee ( NeHe )      *
*                                     *
**************************************/

bool use=true;

#include <windows.h>		// Header File For Windows
#include <gl/glew.h>
#include <gl\gl.h>												// Header File For The OpenGL32 Library
#include <gl\glu.h>												// Header File For The GLu32 Library
#include <gl\glaux.h>											// Header File For The GLaux Library
#include "NeHeGL.h"												// Header File For NeHeGL
#include <math.h>												// We'll Need Some Math
#include <stdio.h>

#pragma comment( lib, "opengl32.lib" )							// Search For OpenGL32.lib While Linking
#pragma comment( lib, "glu32.lib" )								// Search For GLu32.lib While Linking
#pragma comment( lib, "glaux.lib" )								// Search For GLaux.lib While Linking
#pragma comment(lib,"glew32.lib")

#ifndef CDS_FULLSCREEN											// CDS_FULLSCREEN Is Not Defined By Some
#define CDS_FULLSCREEN 4										// Compilers. By Defining It This Way,
#endif															// We Can Avoid Errors

GL_Window*	g_window;
Keys*		g_keys;

// User Defined Variables
float		vertexes[4][3];										// Holds Float Info For 4 Sets Of Vertices
float		normal[3];											// An Array To Store The Normal Data
GLuint		BlurTexture;										// An Unsigned Int To Store The Texture Number
GLuint		DepthTexture;
GLhandleARB ProgramObject;

void CheckError(GLhandleARB glObject) ;
GLhandleARB my_program;
GLhandleARB my_program_pre;

GLuint EmptyTexture()											// Create An Empty Texture
{
GLuint txtnumber;											// Texture ID
unsigned int* data;											// Stored Data

// Create Storage Space For Texture Data (128x128x4)
data = (unsigned int*)new GLuint[((640 * 480)* 4 * sizeof(unsigned int))];
ZeroMemory(data,((640 * 480)* 4 * sizeof(unsigned int)));	// Clear Storage Memory

glGenTextures(1, &txtnumber);								// Create 1 Texture
glBindTexture(GL_SAMPLER_2D_RECT_ARB, txtnumber);					// Bind The Texture
glTexImage2D(GL_SAMPLER_2D_RECT_ARB, 0, 4, 640, 480, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data);						// Build Texture Using Information In data
glTexParameteri(GL_SAMPLER_2D_RECT_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_SAMPLER_2D_RECT_ARB,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

delete [] data;												// Release data

return txtnumber;											// Return The Texture ID
}

void ReduceToUnit(float vector[3])								// Reduces A Normal Vector (3 Coordinates)
{																// To A Unit Normal Vector With A Length Of One.
float length;												// Holds Unit Length
// Calculates The Length Of The Vector
length = (float)sqrt((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2]));

if(length == 0.0f)											// Prevents Divide By 0 Error By Providing
length = 1.0f;											// An Acceptable Value For Vectors To Close To 0.

vector[0] /= length;										// Dividing Each Element By
vector[1] /= length;										// The Length Results In A
vector[2] /= length;										// Unit Normal Vector.
}

void calcNormal(float v[3][3], float out[3])					// Calculates Normal For A Quad Using 3 Points
{
float v1[3],v2[3];											// Vector 1 (x,y,z) & Vector 2 (x,y,z)
static const int x = 0;										// Define X Coord
static const int y = 1;										// Define Y Coord
static const int z = 2;										// Define Z Coord

// Finds The Vector Between 2 Points By Subtracting
// The x,y,z Coordinates From One Point To Another.

// Calculate The Vector From Point 1 To Point 0
v1[x] = v[0][x] - v[1][x];									// Vector 1.x=Vertex[0].x-Vertex[1].x
v1[y] = v[0][y] - v[1][y];									// Vector 1.y=Vertex[0].y-Vertex[1].y
v1[z] = v[0][z] - v[1][z];									// Vector 1.z=Vertex[0].y-Vertex[1].z
// Calculate The Vector From Point 2 To Point 1
v2[x] = v[1][x] - v[2][x];									// Vector 2.x=Vertex[0].x-Vertex[1].x
v2[y] = v[1][y] - v[2][y];									// Vector 2.y=Vertex[0].y-Vertex[1].y
v2[z] = v[1][z] - v[2][z];									// Vector 2.z=Vertex[0].z-Vertex[1].z
// Compute The Cross Product To Give Us A Surface Normal
out[x] = v1[y]*v2[z] - v1[z]*v2[y];							// Cross Product For Y - Z
out[y] = v1[z]*v2[x] - v1[x]*v2[z];							// Cross Product For X - Z
out[z] = v1[x]*v2[y] - v1[y]*v2[x];							// Cross Product For X - Y

ReduceToUnit(out);											// Normalize The Vectors
}

float right=0,up=0,zzz=0,angle=0;

void ProcessHelix()												// Draws A Helix
{
GLfloat x;													// Helix x Coordinate
GLfloat y;													// Helix y Coordinate
GLfloat z;													// Helix z Coordinate
GLfloat phi;												// Angle
GLfloat theta;												// Angle
GLfloat v,u;												// Angles
GLfloat r;													// Radius Of Twist
int twists = 5;												// 5 Twists

//GLfloat glfMaterialColor[]={0.4f,0.2f,0.8f,1.0f};			// Set The Material Color
//GLfloat specular[]={1.0f,1.0f,1.0f,1.0f};					// Sets Up Specular Lighting

glLoadIdentity();											// Reset The Modelview Matrix
gluLookAt(0, 5, 50, 0, 0, 0, 0, 1, 0);						// Eye Position (0,5,50) Center Of Scene (0,0,0), Up On Y Axis

glPushMatrix();												// Push The Modelview Matrix

glTranslatef(right,angle,-50);										// Translate 50 Units Into The Screen
glRotatef(up/2.0f,1,0,0);								// Rotate By angle/2 On The X-Axis
glRotatef(zzz/3.0f,0,1,0);								// Rotate By angle/3 On The Y-Axis

// glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,glfMaterialColor);
//	glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);

for(phi=0; phi <= 360; phi+=20.0)							// 360 Degrees In Steps Of 20
{
for(theta=0; theta<=360*twists; theta+=20.0)			// 360 Degrees * Number Of Twists In Steps Of 20
{
v=(phi/180.0f*3.142f);								// Calculate Angle Of First Point	(  0 )
u=(theta/180.0f*3.142f);							// Calculate Angle Of First Point	(  0 )

x=float(cos(u)*(2.0f+cos(v) ))*r;					// Calculate x Position (1st Point)
y=float(sin(u)*(2.0f+cos(v) ))*r;					// Calculate y Position (1st Point)
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);		// Calculate z Position (1st Point)

vertexes[0][0]=x;									// Set x Value Of First Vertex
vertexes[0][1]=y;									// Set y Value Of First Vertex
vertexes[0][2]=z;									// Set z Value Of First Vertex

v=(phi/180.0f*3.142f);								// Calculate Angle Of Second Point	(  0 )
u=((theta+20)/180.0f*3.142f);						// Calculate Angle Of Second Point	( 20 )

x=float(cos(u)*(2.0f+cos(v) ))*r;					// Calculate x Position (2nd Point)
y=float(sin(u)*(2.0f+cos(v) ))*r;					// Calculate y Position (2nd Point)
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);		// Calculate z Position (2nd Point)

vertexes[1][0]=x;									// Set x Value Of Second Vertex
vertexes[1][1]=y;									// Set y Value Of Second Vertex
vertexes[1][2]=z;									// Set z Value Of Second Vertex

v=((phi+20)/180.0f*3.142f);							// Calculate Angle Of Third Point	( 20 )
u=((theta+20)/180.0f*3.142f);						// Calculate Angle Of Third Point	( 20 )

x=float(cos(u)*(2.0f+cos(v) ))*r;					// Calculate x Position (3rd Point)
y=float(sin(u)*(2.0f+cos(v) ))*r;					// Calculate y Position (3rd Point)
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);		// Calculate z Position (3rd Point)

vertexes[2][0]=x;									// Set x Value Of Third Vertex
vertexes[2][1]=y;									// Set y Value Of Third Vertex
vertexes[2][2]=z;									// Set z Value Of Third Vertex

v=((phi+20)/180.0f*3.142f);							// Calculate Angle Of Fourth Point	( 20 )
u=((theta)/180.0f*3.142f);							// Calculate Angle Of Fourth Point	(  0 )

x=float(cos(u)*(2.0f+cos(v) ))*r;					// Calculate x Position (4th Point)
y=float(sin(u)*(2.0f+cos(v) ))*r;					// Calculate y Position (4th Point)
z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);		// Calculate z Position (4th Point)

vertexes[3][0]=x;									// Set x Value Of Fourth Vertex
vertexes[3][1]=y;									// Set y Value Of Fourth Vertex
vertexes[3][2]=z;									// Set z Value Of Fourth Vertex

calcNormal(vertexes,normal);						// Calculate The Quad Normal

glNormal3f(normal[0],normal[1],normal[2]);			// Set The Normal

glColor3f(1,0,1);
glVertex3f(vertexes[0][0],vertexes[0][1],vertexes[0][2]);
glVertex3f(vertexes[1][0],vertexes[1][1],vertexes[1][2]);
glVertex3f(vertexes[2][0],vertexes[2][1],vertexes[2][2]);
glVertex3f(vertexes[3][0],vertexes[3][1],vertexes[3][2]);
}
}

glPopMatrix();												// Pop The Matrix
}

void ViewOrtho()												// Set Up An Ortho View
{
glMatrixMode(GL_PROJECTION);								// Select Projection
glPushMatrix();												// Push The Matrix
glOrtho( 0, 640 , 480 , 0, -1, 1 );							// Select Ortho Mode (640x480)
glMatrixMode(GL_MODELVIEW);									// Select Modelview Matrix
glPushMatrix();												// Push The Matrix
}

void ViewPerspective()											// Set Up A Perspective View
{
glMatrixMode( GL_PROJECTION );								// Select Projection
glPopMatrix();												// Pop The Matrix
glMatrixMode( GL_MODELVIEW );								// Select Modelview
glPopMatrix();												// Pop The Matrix
}

void DrawBlur(int times, float inc)								// Draw The Blurred Image
{						// Starting Alpha Value

// Disable AutoTexture Coordinates
//	glDisable(GL_TEXTURE_GEN_S);
//	glDisable(GL_TEXTURE_GEN_T);
//glDisable(GL_TEXTURE_GEN_R);
//glDisable(GL_TEXTURE_GEN_Q);
//glEnable(GL_SAMPLER_2D_RECT_ARB);									// Enable 2D Texture Mapping
//glDisable(GL_DEPTH_TEST);									// Disable Depth Testing
//glBlendFunc(GL_SRC_ALPHA,GL_ONE);							// Set Blending Mode
//glEnable(GL_BLEND);											// Enable Blending

glActiveTexture(GL_TEXTURE0);
glEnable(GL_SAMPLER_2D_RECT_ARB);
glBindTexture(GL_SAMPLER_2D_RECT_ARB,DepthTexture);					// Bind To The Blur Texture

glActiveTexture(GL_TEXTURE1);
glEnable(GL_SAMPLER_2D_RECT_ARB);
glBindTexture(GL_SAMPLER_2D_RECT_ARB,BlurTexture);					// Bind To The Blur Texture

ViewOrtho();												// Switch To An Ortho View

//glTranslatef(right,-up,z);
//alphainc = alpha / times;									// alphainc=0.2f / Times To Render Blur

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0,1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,1);
glVertex2f(0,0);									// First Vertex		(   0,   0 )

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);
glVertex2f(0,480-1);									// Second Vertex	(   0, 480 )

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,0);
glVertex2f(640-1,480-1);								// Third Vertex		( 640, 480 )

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1,1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,1);
glVertex2f(640-1,0);									// Fourth Vertex	( 640,   0 )

//spost += inc;										// Gradually Increase spost (Zooming Closer To Texture Center)

ViewPerspective();											// Switch To A Perspective View
glActiveTexture(GL_TEXTURE0);
glEnable(GL_SAMPLER_2D_RECT_ARB);
glBindTexture(GL_SAMPLER_2D_RECT_ARB,0);					// Bind To The Blur Texture

glActiveTexture(GL_TEXTURE1);
glEnable(GL_SAMPLER_2D_RECT_ARB);
glBindTexture(GL_SAMPLER_2D_RECT_ARB,0);					// Bind To The Blur Texture
glEnable(GL_DEPTH_TEST);									// Enable Depth Testing

}

float bblur=0;

BOOL Initialize (GL_Window* window, Keys* keys)					// Any GL Init Code & User Initialiazation Goes Here
{
g_window	= window;
g_keys		= keys;

// Start Of User Initialization
angle		= 0.0f;											// Set Starting Angle To Zero

BlurTexture = EmptyTexture();								// Create Our Empty Texture
DepthTexture = EmptyTexture();								// Create Our Empty Texture
glViewport(0 , 0,window->init.width ,window->init.height);	// Set Up A Viewport
glMatrixMode(GL_PROJECTION);								// Select The Projection Matrix
glLoadIdentity();											// Reset The Projection Matrix
gluPerspective(50, (float)window->init.width/(float)window->init.height, 5,  2000); // Set Our Perspective
glMatrixMode(GL_MODELVIEW);									// Select The Modelview Matrix
glLoadIdentity();											// Reset The Modelview Matrix

glEnable(GL_DEPTH_TEST);									// Enable Depth Testing

//GLfloat global_ambient[4]={0.2f, 0.2f,  0.2f, 1.0f};		// Set Ambient Lighting To Fairly Dark (No Color)
//GLfloat light0pos[4]=     {0.0f, 5.0f, 10.0f, 1.0f};		// Set The Light Position
//GLfloat light0ambient[4]= {0.2f, 0.2f,  0.2f, 1.0f};		// More Ambient Light
//GLfloat light0diffuse[4]= {0.3f, 0.3f,  0.3f, 1.0f};		// Set The Diffuse Light A Bit Brighter
//GLfloat light0specular[4]={0.8f, 0.8f,  0.8f, 1.0f};		// Fairly Bright Specular Lighting

//GLfloat lmodel_ambient[]= {0.2f,0.2f,0.2f,1.0f};			// And More Ambient Light
//glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);		// Set The Ambient Light Model

//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);		// Set The Global Ambient Light Model
//glLightfv(GL_LIGHT0, GL_POSITION, light0pos);				// Set The Lights Position
//glLightfv(GL_LIGHT0, GL_AMBIENT, light0ambient);			// Set The Ambient Light
//glLightfv(GL_LIGHT0, GL_DIFFUSE, light0diffuse);			// Set The Diffuse Light
//glLightfv(GL_LIGHT0, GL_SPECULAR, light0specular);			// Set Up Specular Lighting
//glEnable(GL_LIGHTING);										// Enable Lighting
//glEnable(GL_LIGHT0);										// Enable Light0

glMateriali(GL_FRONT, GL_SHININESS, 128);
glClearColor(0.0f, 0.0f, 0.0f, 0.5);						// Set The Clear Color To Black

GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
//fprintf(stderr, "Error: %s
", glewGetErrorString(err));
}
//fprintf(stdout, "Status: Using GLEW %s
", glewGetString(GLEW_VERSION));

// Create Shader And Program Objects
my_program = glCreateProgramObjectARB();
my_program_pre = glCreateProgramObjectARB();

CheckError(my_program);

CheckError(my_program_pre);

//int uColor , uDepth;
//uColor = glGetUniformLocationARB(s2,"tex1");
//uDepth = glGetUniformLocationARB(s2,"tex2");

int u1=glGetUniformLocation(my_program, "Texture");
int u2=glGetUniformLocation(my_program, "uTexture");
int uShift=glGetUniformLocation(my_program, "uShift");

glUniform1i( u1, 0);
glUniform1i( u2, 0);

glUniform2f(uShift,1.0/640, 0.0);

return TRUE;												// Return TRUE (Initialization Successful)
}

void Deinitialize (void)										// Any User DeInitialization Goes Here
{
glDeleteTextures(1,&BlurTexture);							// Delete The Blur Texture
glDeleteTextures(1,&DepthTexture);							// Delete The Blur Texture
}

void RenderToTexture()											// Renders To A Texture
{
glViewport(0,0,640,480);									// Set Our Viewport (Match Texture Size)

ProcessHelix();												// Render The Helix

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_SAMPLER_2D_RECT_ARB,BlurTexture);					// Bind To The Blur Texture

// Copy Our ViewPort To The Blur Texture (From 0,0 To 128,128... No Border)
glCopyTexImage2D(GL_SAMPLER_2D_RECT_ARB, 0, GL_RGBA, 0, 0, 640, 480, 0);

glClearColor(0.0f, 0.0f, 0.5f, 0.5);						// Set The Clear Color To Medium Blue
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear The Screen And Depth Buffer

glViewport(0 , 0,640 ,480);									// Set Viewport (0,0 to 640x480)
}
void RenderToDepthTexture()											// Renders To A Texture
{
glViewport(0,0,640,480);									// Set Our Viewport (Match Texture Size)

ProcessHelix();												// Render The Helix

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_SAMPLER_2D_RECT_ARB,DepthTexture);					// Bind To The Blur Texture

// Copy Our ViewPort To The Blur Texture (From 0,0 To 128,128... No Border)
glCopyTexImage2D(GL_SAMPLER_2D_RECT_ARB, 0, GL_DEPTH_COMPONENT, 0, 0, 640, 480, 0);

glClearColor(0.0f, 0.0f, 0.5f, 0.5);						// Set The Clear Color To Medium Blue
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear The Screen And Depth Buffer

glViewport(0 , 0,640 ,480);									// Set Viewport (0,0 to 640x480)
}

bool _uuse_blur=false;

GLfloat MATRIXPRE[16];

void Update (DWORD milliseconds)								// Perform Motion Updates Here
{
if (g_keys->keyDown [VK_ESCAPE] == TRUE)					// Is ESC Being Pressed?
{
TerminateApplication (g_window);						// Terminate The Program
}

if (g_keys->keyDown [VK_F1] == TRUE)						// Is F1 Being Pressed?
{
ToggleFullscreen (g_window);							// Toggle Fullscreen Mode
}

if (g_keys->keyDown [VK_RIGHT] == TRUE)						// Is F1 Being Pressed?
{
right+=5;
}

if (g_keys->keyDown [VK_LEFT] == TRUE)						// Is F1 Being Pressed?
{
right-=5;
}

if (g_keys->keyDown [VK_UP] == TRUE)						// Is F1 Being Pressed?
{
up+=5;
}

if (g_keys->keyDown [VK_DOWN] == TRUE)						// Is F1 Being Pressed?
{
up-=5;
}

if (g_keys->keyDown [VK_PRIOR] == TRUE)						// Is F1 Being Pressed?
{
zzz-=5;
}

if (g_keys->keyDown [VK_NEXT] == TRUE)						// Is F1 Being Pressed?
{
zzz+=5;
}

if (g_keys->keyDown [VK_ADD] == TRUE)						// Is F1 Being Pressed?
{
bblur+=0.005f;
}

if (g_keys->keyDown [VK_SUBTRACT] == TRUE)						// Is F1 Being Pressed?
{
bblur-=0.005f;
}

if (g_keys->keyDown ['W'] == TRUE)						// Is F1 Being Pressed?
{
angle++;
}

if (g_keys->keyDown ['S'] == TRUE)						// Is F1 Being Pressed?
{
angle--;
}

if(g_keys->keyDown ['1'] == TRUE)
{
_uuse_blur=!_uuse_blur;
g_keys->keyDown ['1'] = FALSE;
}
if(g_keys->keyDown ['2'] == TRUE)
{
g_keys->keyDown ['2'] = FALSE;
}

if(g_keys->keyDown ['O'] == TRUE)
{
g_keys->keyDown ['O'] = FALSE;
}

if(g_keys->keyDown ['P'] == TRUE)
{
g_keys->keyDown ['P'] = FALSE;
}
GLfloat MATRIX[16];
glGetFloatv( GL_PROJECTION_MATRIX, MATRIX );
int matrix=glGetUniformLocation(my_program, "g_ViewProjectionInverseMatrix");
int matrixPre=glGetUniformLocation(my_program, "g_previousViewProjectionMatrix");

glUniformMatrix4fvARB(matrix,1,true,MATRIX);
glUniformMatrix4fvARB(matrixPre,1,true,MATRIXPRE);

int hh=glGetUniformLocation(my_program, "g_width");
int ww=glGetUniformLocation(my_program, "g_height");

glUniform1i(hh,480);
glUniform1i(ww,640);

int i;
for(i=0;i<16;i++)
{
MATRIXPRE[i]=MATRIX[i];
}

//angle += (float)(milliseconds) / 5.0f;						// Update angle Based On The Clock
}

void Draw (void)												// Draw The Scene
{
glUseProgramObjectARB(NULL);

glClearColor(0.0f, 0.0f, 0.0f, 0);						// Set The Clear Color To Black
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear Screen And Depth Buffer

ProcessHelix();												// Draw Our Helix
//glUseProgramObjectARB(my_program_pre);
RenderToTexture();
RenderToDepthTexture();	// Render To A Texture (NICHT SHADER !!!)
glUseProgramObjectARB(my_program);
DrawBlur(25,0.02f);											// Draw The Blur Effect

glFlush ();													// Flush The GL Rendering Pipeline
}

char* data;

{
fseek(file, 0, SEEK_END);
int size=ftell(file);
//size=filelength(file);
data=(char*)malloc(size);

fseek(file,-size, SEEK_CUR); //zum Anfang zurück

data[size]='\0';
}

void CheckError(GLhandleARB glObject)
{
int blen,slen ;
char* InfoLog;

glGetObjectParameterivARB(glObject, GL_OBJECT_INFO_LOG_LENGTH_ARB , &blen);
if (blen > 1)
{
InfoLog=(char*)malloc( blen*sizeof(GLhandleARB));
glGetInfoLogARB(glObject, blen, &slen, InfoLog);
MessageBox(HWND_DESKTOP, InfoLog,NULL,NULL);
free(InfoLog);
}
}
{

FILE *file=fopen(name,"rb");

fclose(file);

// Attach The Shader Objects To The Program Object

}

{

FILE *file=fopen(name,"rb");

fclose(file);