radblur.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. //------------------------------------------------------------------------
  2. //
  3. // Author : Dario Corno (rIo) / Jeff Molofee (NeHe)
  4. // Converted to Delphi : Jan Horn
  5. // Email : [email protected]
  6. // Website : http://www.sulaco.co.za
  7. // Authors Web Site : http://www.spinningkids.org/rio
  8. // Date : 14 October 2001
  9. // Version : 1.0
  10. // Description : Radial Blur
  11. //
  12. // Adapted to FPC : Sebastian Guenther ([email protected]) 2001-11-21
  13. //
  14. //------------------------------------------------------------------------
  15. program RadialBlur;
  16. {$mode objfpc}
  17. uses GL, GLU, GLUT;
  18. const
  19. WND_TITLE = 'Radial Blur';
  20. type TVector = Array[0..2] of glFloat;
  21. var
  22. ElapsedTime : Integer; // Elapsed time between frames
  23. // Textures
  24. BlurTexture : glUint; // An Unsigned Int To Store The Texture Number
  25. // User vaiables
  26. Angle : glFloat;
  27. Vertexes : Array[0..3] of TVector;
  28. normal : TVector;
  29. const
  30. FPSCount : Integer = 0; // Counter for FPS
  31. // Lights and Materials
  32. globalAmbient : Array[0..3] of glFloat = (0.2, 0.2, 0.2, 1.0); // Set Ambient Lighting To Fairly Dark Light (No Color)
  33. Light0Pos : Array[0..3] of glFloat = (0.0, 5.0, 10.0, 1.0); // Set The Light Position
  34. Light0Ambient : Array[0..3] of glFloat = (0.2, 0.2, 0.2, 1.0); // More Ambient Light
  35. Light0Diffuse : Array[0..3] of glFloat = (0.3, 0.3, 0.3, 1.0); // Set The Diffuse Light A Bit Brighter
  36. Light0Specular : Array[0..3] of glFloat = (0.8, 0.8, 0.8, 1.0); // Fairly Bright Specular Lighting
  37. LmodelAmbient : Array[0..3] of glFloat = (0.2, 0.2, 0.2, 1.0); // And More Ambient Light
  38. function EmptyTexture : glUint;
  39. var txtnumber : glUint;
  40. pData : Pointer;
  41. begin
  42. // Create Storage Space For Texture Data (128x128x4)
  43. GetMem(pData, 128*128*4);
  44. glGenTextures(1, @txtnumber); // Create 1 Texture
  45. glBindTexture(GL_TEXTURE_2D, txtnumber); // Bind The Texture
  46. glTexImage2D(GL_TEXTURE_2D, 0, 4, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, pData);
  47. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  48. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  49. result :=txtNumber;
  50. end;
  51. procedure ReduceToUnit(var vector : Array of glFloat);
  52. var length : glFLoat;
  53. begin
  54. // Calculates The Length Of The Vector
  55. length := sqrt((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2]));
  56. if Length = 0 then
  57. Length :=1;
  58. vector[0] :=vector[0] / length;
  59. vector[1] :=vector[1] / length;
  60. vector[2] :=vector[2] / length;
  61. end;
  62. procedure calcNormal(const v : Array of TVector; var cross : Array of glFloat);
  63. var v1, v2 : Array[0..2] of glFloat;
  64. begin
  65. // Finds The Vector Between 2 Points By Subtracting
  66. // The x,y,z Coordinates From One Point To Another.
  67. // Calculate The Vector From Point 1 To Point 0
  68. v1[0] := v[0][0] - v[1][0]; // Vector 1.x=Vertex[0].x-Vertex[1].x
  69. v1[1] := v[0][1] - v[1][1]; // Vector 1.y=Vertex[0].y-Vertex[1].y
  70. v1[2] := v[0][2] - v[1][2]; // Vector 1.z=Vertex[0].y-Vertex[1].z
  71. // Calculate The Vector From Point 2 To Point 1
  72. v2[0] := v[1][0] - v[2][0]; // Vector 2.x=Vertex[0].x-Vertex[1].x
  73. v2[1] := v[1][1] - v[2][1]; // Vector 2.y=Vertex[0].y-Vertex[1].y
  74. v2[2] := v[1][2] - v[2][2]; // Vector 2.z=Vertex[0].z-Vertex[1].z
  75. // Compute The Cross Product To Give Us A Surface Normal
  76. cross[0] := v1[1]*v2[2] - v1[2]*v2[1]; // Cross Product For Y - Z
  77. cross[1] := v1[2]*v2[0] - v1[0]*v2[2]; // Cross Product For X - Z
  78. cross[2] := v1[0]*v2[1] - v1[1]*v2[0]; // Cross Product For X - Y
  79. ReduceToUnit(cross); // Normalize The Vectors
  80. end;
  81. // Draws A Helix
  82. procedure ProcessHelix;
  83. const Twists = 5;
  84. MaterialColor : Array[1..4] of glFloat = (0.4, 0.2, 0.8, 1.0);
  85. Specular : Array[1..4] of glFloat = (1, 1, 1, 1);
  86. var x, y, z : glFLoat;
  87. phi, theta : Integer;
  88. r, u, v : glFLoat;
  89. begin
  90. glLoadIdentity(); // Reset The Modelview Matrix
  91. 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
  92. glPushMatrix(); // Push The Modelview Matrix
  93. glTranslatef(0,0,-50); // Translate 50 Units Into The Screen
  94. glRotatef(angle/2.0, 1, 0, 0); // Rotate By angle/2 On The X-Axis
  95. glRotatef(angle/3.0, 0, 1, 0); // Rotate By angle/3 On The Y-Axis
  96. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, @MaterialColor);
  97. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @specular);
  98. r :=1.5; // Radius
  99. glBegin(GL_QUADS); // Begin Drawing Quads
  100. phi :=0;
  101. while phi < 360 do
  102. begin
  103. theta :=0;
  104. while theta < 360*twists do
  105. begin
  106. v := phi / 180.0 * pi; // Calculate Angle Of First Point ( 0 )
  107. u := theta / 180.0 * pi; // Calculate Angle Of First Point ( 0 )
  108. x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (1st Point)
  109. y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (1st Point)
  110. z :=(u-(2*pi) + sin(v))*r; // Calculate z Position (1st Point)
  111. vertexes[0][0] :=x; // Set x Value Of First Vertex
  112. vertexes[0][1] :=y; // Set y Value Of First Vertex
  113. vertexes[0][2] :=z; // Set z Value Of First Vertex
  114. v :=(phi/180.0 * pi); // Calculate Angle Of Second Point ( 0 )
  115. u :=((theta+20)/180.0 * pi); // Calculate Angle Of Second Point ( 20 )
  116. x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (2nd Point)
  117. y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (2nd Point)
  118. z :=(u-(2*pi) + sin(v))*r; // Calculate z Position (2nd Point)
  119. vertexes[1][0] :=x; // Set x Value Of Second Vertex
  120. vertexes[1][1] :=y; // Set y Value Of Second Vertex
  121. vertexes[1][2] :=z; // Set z Value Of Second Vertex
  122. v :=(phi+20)/180.0*pi; // Calculate Angle Of Third Point ( 20 )
  123. u :=(theta+20)/180.0*pi; // Calculate Angle Of Third Point ( 20 )
  124. x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (3rd Point)
  125. y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (3rd Point)
  126. z :=(u-(2*pi) + sin(v))*r; // Calculate z Position (3rd Point)
  127. vertexes[2][0] :=x; // Set x Value Of Third Vertex
  128. vertexes[2][1] :=y; // Set y Value Of Third Vertex
  129. vertexes[2][2] :=z; // Set z Value Of Third Vertex
  130. v :=(phi+20)/180.0*pi; // Calculate Angle Of Fourth Point ( 20 )
  131. u :=theta / 180.0*pi; // Calculate Angle Of Fourth Point ( 0 )
  132. x :=cos(u)*(2 + cos(v))*r; // Calculate x Position (4th Point)
  133. y :=sin(u)*(2 + cos(v))*r; // Calculate y Position (4th Point)
  134. z :=(u-(2*pi) + sin(v))*r; // Calculate z Position (4th Point)
  135. vertexes[3][0] :=x; // Set x Value Of Fourth Vertex
  136. vertexes[3][1] :=y; // Set y Value Of Fourth Vertex
  137. vertexes[3][2] :=z; // Set z Value Of Fourth Vertex
  138. calcNormal(vertexes, normal); // Calculate The Quad Normal
  139. glNormal3f(normal[0],normal[1],normal[2]); // Set The Normal
  140. // Render The Quad
  141. glVertex3f(vertexes[0][0],vertexes[0][1],vertexes[0][2]);
  142. glVertex3f(vertexes[1][0],vertexes[1][1],vertexes[1][2]);
  143. glVertex3f(vertexes[2][0],vertexes[2][1],vertexes[2][2]);
  144. glVertex3f(vertexes[3][0],vertexes[3][1],vertexes[3][2]);
  145. theta := theta + 20;
  146. end;
  147. phi :=phi + 20;
  148. end;
  149. glEnd(); // Done Rendering Quads
  150. glPopMatrix(); // Pop The Matrix
  151. end;
  152. // Set Up An Ortho View
  153. procedure ViewOrtho;
  154. begin
  155. glMatrixMode(GL_PROJECTION); // Select Projection
  156. glPushMatrix(); // Push The Matrix
  157. glLoadIdentity(); // Reset The Matrix
  158. glOrtho( 0, 640 , 480 , 0, -1, 1 ); // Select Ortho Mode (640x480)
  159. glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
  160. glPushMatrix(); // Push The Matrix
  161. glLoadIdentity(); // Reset The Matrix
  162. end;
  163. // Set Up A Perspective View
  164. procedure ViewPerspective;
  165. begin
  166. glMatrixMode( GL_PROJECTION ); // Select Projection
  167. glPopMatrix(); // Pop The Matrix
  168. glMatrixMode( GL_MODELVIEW ); // Select Modelview
  169. glPopMatrix(); // Pop The Matrix
  170. end;
  171. // Renders To A Texture
  172. procedure RenderToTexture;
  173. begin
  174. glViewport(0, 0, 128, 128); // Set Our Viewport (Match Texture Size)
  175. ProcessHelix(); // Render The Helix
  176. glBindTexture(GL_TEXTURE_2D,BlurTexture); // Bind To The Blur Texture
  177. // Copy Our ViewPort To The Blur Texture (From 0,0 To 128,128... No Border)
  178. glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 0, 0, 128, 128, 0);
  179. glClearColor(0.0, 0.0, 0.5, 0.5); // Set The Clear Color To Medium Blue
  180. glClear(GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT); // Clear The Screen And Depth Buffer
  181. glViewport(0, 0, 640 ,480); // Set Viewport (0,0 to 640x480)
  182. end;
  183. // Draw The Blurred Image
  184. procedure DrawBlur(const times : Integer; const inc : glFloat);
  185. var spost, alpha, alphainc : glFloat;
  186. I : Integer;
  187. begin
  188. alpha := 0.2;
  189. spost := 0.0;
  190. glEnable(GL_TEXTURE_2D); // Enable 2D Texture Mapping
  191. glDisable(GL_DEPTH_TEST); // Disable Depth Testing
  192. glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set Blending Mode
  193. glEnable(GL_BLEND); // Enable Blending
  194. glBindTexture(GL_TEXTURE_2D,BlurTexture); // Bind To The Blur Texture
  195. ViewOrtho(); // Switch To An Ortho View
  196. alphainc := alpha / times; // alphainc=0.2f / Times To Render Blur
  197. glBegin(GL_QUADS); // Begin Drawing Quads
  198. // Number Of Times To Render Blur
  199. For I :=0 to times-1 do
  200. begin
  201. glColor4f(1.0, 1.0, 1.0, alpha); // Set The Alpha Value (Starts At 0.2)
  202. glTexCoord2f(0+spost,1-spost); // Texture Coordinate ( 0, 1 )
  203. glVertex2f(0,0); // First Vertex ( 0, 0 )
  204. glTexCoord2f(0+spost,0+spost); // Texture Coordinate ( 0, 0 )
  205. glVertex2f(0,480); // Second Vertex ( 0, 480 )
  206. glTexCoord2f(1-spost,0+spost); // Texture Coordinate ( 1, 0 )
  207. glVertex2f(640,480); // Third Vertex ( 640, 480 )
  208. glTexCoord2f(1-spost,1-spost); // Texture Coordinate ( 1, 1 )
  209. glVertex2f(640,0); // Fourth Vertex ( 640, 0 )
  210. spost := spost + inc; // Gradually Increase spost (Zooming Closer To Texture Center)
  211. alpha := alpha - alphainc; // Gradually Decrease alpha (Gradually Fading Image Out)
  212. end;
  213. glEnd(); // Done Drawing Quads
  214. ViewPerspective(); // Switch To A Perspective View
  215. glEnable(GL_DEPTH_TEST); // Enable Depth Testing
  216. glDisable(GL_TEXTURE_2D); // Disable 2D Texture Mapping
  217. glDisable(GL_BLEND); // Disable Blending
  218. glBindTexture(GL_TEXTURE_2D,0); // Unbind The Blur Texture
  219. end;
  220. {------------------------------------------------------------------}
  221. { Function to draw the actual scene }
  222. {------------------------------------------------------------------}
  223. procedure glDraw;
  224. begin
  225. glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
  226. glLoadIdentity(); // Reset The View
  227. RenderToTexture; // Render To A Texture
  228. ProcessHelix; // Draw Our Helix
  229. DrawBlur(25, 0.02); // Draw The Blur Effect
  230. angle :=ElapsedTime / 5.0; // Update angle Based On The Clock
  231. end;
  232. {------------------------------------------------------------------}
  233. { Initialise OpenGL }
  234. {------------------------------------------------------------------}
  235. procedure glInit;
  236. begin
  237. glClearColor(0.0, 0.0, 0.0, 0.5); // Black Background
  238. glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
  239. glClearDepth(1.0); // Depth Buffer Setup
  240. glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
  241. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Realy Nice perspective calculations
  242. glEnable(GL_DEPTH_TEST); // Enable Depth Buffer
  243. glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
  244. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @LmodelAmbient); // Set The Ambient Light Model
  245. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @GlobalAmbient); // Set The Global Ambient Light Model
  246. glLightfv(GL_LIGHT0, GL_POSITION, @light0Pos); // Set The Lights Position
  247. glLightfv(GL_LIGHT0, GL_AMBIENT, @light0Ambient); // Set The Ambient Light
  248. glLightfv(GL_LIGHT0, GL_DIFFUSE, @light0Diffuse); // Set The Diffuse Light
  249. glLightfv(GL_LIGHT0, GL_SPECULAR, @light0Specular); // Set Up Specular Lighting
  250. glEnable(GL_LIGHTING); // Enable Lighting
  251. glEnable(GL_LIGHT0); // Enable Light0
  252. BlurTexture := EmptyTexture(); // Create Our Empty Texture
  253. glShadeModel(GL_SMOOTH); // Select Smooth Shading
  254. glMateriali(GL_FRONT, GL_SHININESS, 128);
  255. end;
  256. {------------------------------------------------------------------}
  257. { Handle window resize }
  258. {------------------------------------------------------------------}
  259. procedure glResizeWnd(Width, Height : Integer);
  260. begin
  261. if (Height = 0) then // prevent divide by zero exception
  262. Height := 1;
  263. glViewport(0, 0, Width, Height); // Set the viewport for the OpenGL window
  264. glMatrixMode(GL_PROJECTION); // Change Matrix Mode to Projection
  265. glLoadIdentity(); // Reset View
  266. gluPerspective(45.0, Width/glFloat(Height), 2.0, 200.0); // Do the perspective calculations. Last value = max clipping depth
  267. glMatrixMode(GL_MODELVIEW); // Return to the modelview matrix
  268. glLoadIdentity(); // Reset View
  269. end;
  270. var
  271. DemoStart, LastTime : LongWord;
  272. procedure DisplayWindow; cdecl;
  273. begin
  274. Inc(FPSCount); // Increment FPS Counter
  275. LastTime :=ElapsedTime;
  276. ElapsedTime := glutGet(GLUT_ELAPSED_TIME) - DemoStart; // Calculate Elapsed Time
  277. ElapsedTime :=(LastTime + ElapsedTime) DIV 2; // Average it out for smoother movement
  278. glDraw;
  279. glutSwapBuffers;
  280. Inc(ElapsedTime, 10);
  281. glutPostRedisplay;
  282. end;
  283. procedure OnReshape(width, height: Integer); cdecl;
  284. begin
  285. glResizeWnd(width, height);
  286. end;
  287. begin
  288. glutInit(@argc, argv);
  289. glutInitDisplayMode(GLUT_RGB or GLUT_DOUBLE or GLUT_DEPTH);
  290. glutCreateWindow(WND_TITLE);
  291. glutDisplayFunc(@DisplayWindow);
  292. glutReshapeFunc(@OnReshape);
  293. glutInitWindowSize(640, 480);
  294. glInit;
  295. DemoStart := glutGet(GLUT_ELAPSED_TIME);
  296. glutMainLoop;
  297. end.