123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- //------------------------------------------------------------------------
- //
- // Author : Dario Corno (rIo) / Jeff Molofee (NeHe)
- // Converted to Delphi : Jan Horn
- // Email : [email protected]
- // Website : http://www.sulaco.co.za
- // Authors Web Site : http://www.spinningkids.org/rio
- // Date : 14 October 2001
- // Version : 1.0
- // Description : Radial Blur
- //
- // Adapted to FPC : Sebastian Guenther ([email protected]) 2001-11-21
- //
- //------------------------------------------------------------------------
- program RadialBlur;
- {$mode objfpc}
- uses GL, GLU, GLUT;
- const
- WND_TITLE = 'Radial Blur';
- type TVector = Array[0..2] of glFloat;
- var
- ElapsedTime : Integer; // Elapsed time between frames
- // Textures
- BlurTexture : glUint; // An Unsigned Int To Store The Texture Number
- // User vaiables
- Angle : glFloat;
- Vertexes : Array[0..3] of TVector;
- normal : TVector;
- const
- FPSCount : Integer = 0; // Counter for FPS
- // Lights and Materials
- globalAmbient : Array[0..3] of glFloat = (0.2, 0.2, 0.2, 1.0); // Set Ambient Lighting To Fairly Dark Light (No Color)
- Light0Pos : Array[0..3] of glFloat = (0.0, 5.0, 10.0, 1.0); // Set The Light Position
- Light0Ambient : Array[0..3] of glFloat = (0.2, 0.2, 0.2, 1.0); // More Ambient Light
- Light0Diffuse : Array[0..3] of glFloat = (0.3, 0.3, 0.3, 1.0); // Set The Diffuse Light A Bit Brighter
- Light0Specular : Array[0..3] of glFloat = (0.8, 0.8, 0.8, 1.0); // Fairly Bright Specular Lighting
- LmodelAmbient : Array[0..3] of glFloat = (0.2, 0.2, 0.2, 1.0); // And More Ambient Light
- function EmptyTexture : glUint;
- var txtnumber : glUint;
- pData : Pointer;
- begin
- // Create Storage Space For Texture Data (128x128x4)
- GetMem(pData, 128*128*4);
- glGenTextures(1, @txtnumber); // Create 1 Texture
- glBindTexture(GL_TEXTURE_2D, txtnumber); // Bind The Texture
- glTexImage2D(GL_TEXTURE_2D, 0, 4, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, pData);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- result :=txtNumber;
- end;
- procedure ReduceToUnit(var vector : Array of glFloat);
- var length : glFLoat;
- begin
- // Calculates The Length Of The Vector
- length := sqrt((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2]));
- if Length = 0 then
- Length :=1;
- vector[0] :=vector[0] / length;
- vector[1] :=vector[1] / length;
- vector[2] :=vector[2] / length;
- end;
- procedure calcNormal(const v : Array of TVector; var cross : Array of glFloat);
- var v1, v2 : Array[0..2] of glFloat;
- begin
- // 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[0] := v[0][0] - v[1][0]; // Vector 1.x=Vertex[0].x-Vertex[1].x
- v1[1] := v[0][1] - v[1][1]; // Vector 1.y=Vertex[0].y-Vertex[1].y
- v1[2] := v[0][2] - v[1][2]; // Vector 1.z=Vertex[0].y-Vertex[1].z
- // Calculate The Vector From Point 2 To Point 1
- v2[0] := v[1][0] - v[2][0]; // Vector 2.x=Vertex[0].x-Vertex[1].x
- v2[1] := v[1][1] - v[2][1]; // Vector 2.y=Vertex[0].y-Vertex[1].y
- v2[2] := v[1][2] - v[2][2]; // Vector 2.z=Vertex[0].z-Vertex[1].z
- // Compute The Cross Product To Give Us A Surface Normal
- cross[0] := v1[1]*v2[2] - v1[2]*v2[1]; // Cross Product For Y - Z
- cross[1] := v1[2]*v2[0] - v1[0]*v2[2]; // Cross Product For X - Z
- cross[2] := v1[0]*v2[1] - v1[1]*v2[0]; // Cross Product For X - Y
- ReduceToUnit(cross); // Normalize The Vectors
- end;
- // Draws A Helix
- procedure ProcessHelix;
- const Twists = 5;
- MaterialColor : Array[1..4] of glFloat = (0.4, 0.2, 0.8, 1.0);
- Specular : Array[1..4] of glFloat = (1, 1, 1, 1);
- var x, y, z : glFLoat;
- phi, theta : Integer;
- r, u, v : glFLoat;
- begin
- 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(0,0,-50); // Translate 50 Units Into The Screen
- glRotatef(angle/2.0, 1, 0, 0); // Rotate By angle/2 On The X-Axis
- glRotatef(angle/3.0, 0, 1, 0); // Rotate By angle/3 On The Y-Axis
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, @MaterialColor);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @specular);
- r :=1.5; // Radius
- glBegin(GL_QUADS); // Begin Drawing Quads
- phi :=0;
- while phi < 360 do
- begin
- theta :=0;
- while theta < 360*twists do
- begin
- v := phi / 180.0 * pi; // Calculate Angle Of First Point ( 0 )
- u := theta / 180.0 * pi; // Calculate Angle Of First Point ( 0 )
- x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (1st Point)
- y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (1st Point)
- z :=(u-(2*pi) + 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.0 * pi); // Calculate Angle Of Second Point ( 0 )
- u :=((theta+20)/180.0 * pi); // Calculate Angle Of Second Point ( 20 )
- x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (2nd Point)
- y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (2nd Point)
- z :=(u-(2*pi) + 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.0*pi; // Calculate Angle Of Third Point ( 20 )
- u :=(theta+20)/180.0*pi; // Calculate Angle Of Third Point ( 20 )
- x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (3rd Point)
- y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (3rd Point)
- z :=(u-(2*pi) + 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.0*pi; // Calculate Angle Of Fourth Point ( 20 )
- u :=theta / 180.0*pi; // Calculate Angle Of Fourth Point ( 0 )
- x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (4th Point)
- y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (4th Point)
- z :=(u-(2*pi) + 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
- // Render The Quad
- 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]);
- theta := theta + 20;
- end;
- phi :=phi + 20;
- end;
- glEnd(); // Done Rendering Quads
- glPopMatrix(); // Pop The Matrix
- end;
- // Set Up An Ortho View
- procedure ViewOrtho;
- begin
- glMatrixMode(GL_PROJECTION); // Select Projection
- glPushMatrix(); // Push The Matrix
- glLoadIdentity(); // Reset The Matrix
- glOrtho( 0, 640 , 480 , 0, -1, 1 ); // Select Ortho Mode (640x480)
- glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
- glPushMatrix(); // Push The Matrix
- glLoadIdentity(); // Reset The Matrix
- end;
- // Set Up A Perspective View
- procedure ViewPerspective;
- begin
- glMatrixMode( GL_PROJECTION ); // Select Projection
- glPopMatrix(); // Pop The Matrix
- glMatrixMode( GL_MODELVIEW ); // Select Modelview
- glPopMatrix(); // Pop The Matrix
- end;
- // Renders To A Texture
- procedure RenderToTexture;
- begin
- glViewport(0, 0, 128, 128); // Set Our Viewport (Match Texture Size)
- ProcessHelix(); // Render The Helix
- glBindTexture(GL_TEXTURE_2D,BlurTexture); // Bind To The Blur Texture
- // Copy Our ViewPort To The Blur Texture (From 0,0 To 128,128... No Border)
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 0, 0, 128, 128, 0);
- glClearColor(0.0, 0.0, 0.5, 0.5); // Set The Clear Color To Medium Blue
- glClear(GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT); // Clear The Screen And Depth Buffer
- glViewport(0, 0, 640 ,480); // Set Viewport (0,0 to 640x480)
- end;
- // Draw The Blurred Image
- procedure DrawBlur(const times : Integer; const inc : glFloat);
- var spost, alpha, alphainc : glFloat;
- I : Integer;
- begin
- alpha := 0.2;
- spost := 0.0;
- glEnable(GL_TEXTURE_2D); // 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
- glBindTexture(GL_TEXTURE_2D,BlurTexture); // Bind To The Blur Texture
- ViewOrtho(); // Switch To An Ortho View
- alphainc := alpha / times; // alphainc=0.2f / Times To Render Blur
- glBegin(GL_QUADS); // Begin Drawing Quads
- // Number Of Times To Render Blur
- For I :=0 to times-1 do
- begin
- glColor4f(1.0, 1.0, 1.0, alpha); // Set The Alpha Value (Starts At 0.2)
- glTexCoord2f(0+spost,1-spost); // Texture Coordinate ( 0, 1 )
- glVertex2f(0,0); // First Vertex ( 0, 0 )
- glTexCoord2f(0+spost,0+spost); // Texture Coordinate ( 0, 0 )
- glVertex2f(0,480); // Second Vertex ( 0, 480 )
- glTexCoord2f(1-spost,0+spost); // Texture Coordinate ( 1, 0 )
- glVertex2f(640,480); // Third Vertex ( 640, 480 )
- glTexCoord2f(1-spost,1-spost); // Texture Coordinate ( 1, 1 )
- glVertex2f(640,0); // Fourth Vertex ( 640, 0 )
- spost := spost + inc; // Gradually Increase spost (Zooming Closer To Texture Center)
- alpha := alpha - alphainc; // Gradually Decrease alpha (Gradually Fading Image Out)
- end;
- glEnd(); // Done Drawing Quads
- ViewPerspective(); // Switch To A Perspective View
- glEnable(GL_DEPTH_TEST); // Enable Depth Testing
- glDisable(GL_TEXTURE_2D); // Disable 2D Texture Mapping
- glDisable(GL_BLEND); // Disable Blending
- glBindTexture(GL_TEXTURE_2D,0); // Unbind The Blur Texture
- end;
- {------------------------------------------------------------------}
- { Function to draw the actual scene }
- {------------------------------------------------------------------}
- procedure glDraw;
- begin
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
- glLoadIdentity(); // Reset The View
- RenderToTexture; // Render To A Texture
- ProcessHelix; // Draw Our Helix
- DrawBlur(25, 0.02); // Draw The Blur Effect
- angle :=ElapsedTime / 5.0; // Update angle Based On The Clock
- end;
- {------------------------------------------------------------------}
- { Initialise OpenGL }
- {------------------------------------------------------------------}
- procedure glInit;
- begin
- glClearColor(0.0, 0.0, 0.0, 0.5); // Black Background
- glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
- glClearDepth(1.0); // Depth Buffer Setup
- glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Realy Nice perspective calculations
- glEnable(GL_DEPTH_TEST); // Enable Depth Buffer
- glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @LmodelAmbient); // Set The Ambient Light Model
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @GlobalAmbient); // 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
- BlurTexture := EmptyTexture(); // Create Our Empty Texture
- glShadeModel(GL_SMOOTH); // Select Smooth Shading
- glMateriali(GL_FRONT, GL_SHININESS, 128);
- end;
- {------------------------------------------------------------------}
- { Handle window resize }
- {------------------------------------------------------------------}
- procedure glResizeWnd(Width, Height : Integer);
- begin
- if (Height = 0) then // prevent divide by zero exception
- Height := 1;
- glViewport(0, 0, Width, Height); // Set the viewport for the OpenGL window
- glMatrixMode(GL_PROJECTION); // Change Matrix Mode to Projection
- glLoadIdentity(); // Reset View
- gluPerspective(45.0, Width/glFloat(Height), 2.0, 200.0); // Do the perspective calculations. Last value = max clipping depth
- glMatrixMode(GL_MODELVIEW); // Return to the modelview matrix
- glLoadIdentity(); // Reset View
- end;
- var
- DemoStart, LastTime : LongWord;
- procedure DisplayWindow; cdecl;
- begin
- Inc(FPSCount); // Increment FPS Counter
- LastTime :=ElapsedTime;
- ElapsedTime := glutGet(GLUT_ELAPSED_TIME) - DemoStart; // Calculate Elapsed Time
- ElapsedTime :=(LastTime + ElapsedTime) DIV 2; // Average it out for smoother movement
- glDraw;
- glutSwapBuffers;
- Inc(ElapsedTime, 10);
- glutPostRedisplay;
- end;
- procedure OnReshape(width, height: Integer); cdecl;
- begin
- glResizeWnd(width, height);
- end;
- begin
- glutInit(@argc, argv);
- glutInitDisplayMode(GLUT_RGB or GLUT_DOUBLE or GLUT_DEPTH);
- glutCreateWindow(WND_TITLE);
- glutDisplayFunc(@DisplayWindow);
- glutReshapeFunc(@OnReshape);
- glutInitWindowSize(640, 480);
- glInit;
- DemoStart := glutGet(GLUT_ELAPSED_TIME);
- glutMainLoop;
- end.
|