radblur.pp 14 KB

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