Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

arbfslight.c 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * Use GL_ARB_fragment_shader and GL_ARB_vertex_shader to implement
  3. * simple per-pixel lighting.
  4. *
  5. * Michal Krol
  6. * 20 February 2006
  7. *
  8. * Based on the original demo by:
  9. * Brian Paul
  10. * 17 April 2003
  11. */
  12. #ifdef WIN32
  13. #include <windows.h>
  14. #endif
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <math.h>
  18. #include <GL/gl.h>
  19. #include <GL/glut.h>
  20. #include <GL/glext.h>
  21. #ifdef WIN32
  22. #define GETPROCADDRESS wglGetProcAddress
  23. #else
  24. #define GETPROCADDRESS glutGetProcAddress
  25. #endif
  26. static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
  27. static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
  28. static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f };
  29. static GLfloat delta = 1.0f;
  30. static GLhandleARB fragShader;
  31. static GLhandleARB vertShader;
  32. static GLhandleARB program;
  33. static GLint uLightPos;
  34. static GLint uDiffuse;
  35. static GLint uSpecular;
  36. static GLboolean anim = GL_TRUE;
  37. static GLboolean wire = GL_FALSE;
  38. static GLboolean pixelLight = GL_TRUE;
  39. static GLint t0 = 0;
  40. static GLint frames = 0;
  41. static GLfloat xRot = 0.0f, yRot = 0.0f;
  42. static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
  43. static PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
  44. static PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
  45. static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
  46. static PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
  47. static PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
  48. static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
  49. static PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
  50. static PFNGLUNIFORM3FVARBPROC glUniform3fvARB = NULL;
  51. static PFNGLUNIFORM3FVARBPROC glUniform4fvARB = NULL;
  52. static void normalize (GLfloat *dst, const GLfloat *src)
  53. {
  54. GLfloat len = sqrt (src[0] * src[0] + src[1] * src[1] + src[2] * src[2]);
  55. dst[0] = src[0] / len;
  56. dst[1] = src[1] / len;
  57. dst[2] = src[2] / len;
  58. }
  59. static void Redisplay (void)
  60. {
  61. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  62. if (pixelLight)
  63. {
  64. GLfloat vec[3];
  65. glUseProgramObjectARB (program);
  66. normalize (vec, lightPos);
  67. glUniform3fvARB (uLightPos, 1, vec);
  68. glDisable(GL_LIGHTING);
  69. }
  70. else
  71. {
  72. glUseProgramObjectARB (0);
  73. glLightfv (GL_LIGHT0, GL_POSITION, lightPos);
  74. glEnable(GL_LIGHTING);
  75. }
  76. glPushMatrix ();
  77. glRotatef (xRot, 1.0f, 0.0f, 0.0f);
  78. glRotatef (yRot, 0.0f, 1.0f, 0.0f);
  79. glutSolidSphere (2.0, 10, 5);
  80. glPopMatrix ();
  81. glutSwapBuffers();
  82. frames++;
  83. if (anim)
  84. {
  85. GLint t = glutGet (GLUT_ELAPSED_TIME);
  86. if (t - t0 >= 5000)
  87. {
  88. GLfloat seconds = (GLfloat) (t - t0) / 1000.0f;
  89. GLfloat fps = frames / seconds;
  90. printf ("%d frames in %6.3f seconds = %6.3f FPS\n", frames, seconds, fps);
  91. t0 = t;
  92. frames = 0;
  93. }
  94. }
  95. }
  96. static void Idle (void)
  97. {
  98. lightPos[0] += delta;
  99. if (lightPos[0] > 25.0f || lightPos[0] < -25.0f)
  100. delta = -delta;
  101. glutPostRedisplay ();
  102. }
  103. static void Reshape (int width, int height)
  104. {
  105. glViewport (0, 0, width, height);
  106. glMatrixMode (GL_PROJECTION);
  107. glLoadIdentity ();
  108. glFrustum (-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
  109. glMatrixMode (GL_MODELVIEW);
  110. glLoadIdentity ();
  111. glTranslatef (0.0f, 0.0f, -15.0f);
  112. }
  113. static void Key (unsigned char key, int x, int y)
  114. {
  115. (void) x;
  116. (void) y;
  117. switch (key)
  118. {
  119. case ' ':
  120. case 'a':
  121. anim = !anim;
  122. if (anim)
  123. glutIdleFunc (Idle);
  124. else
  125. glutIdleFunc (NULL);
  126. break;
  127. case 'x':
  128. lightPos[0] -= 1.0f;
  129. break;
  130. case 'X':
  131. lightPos[0] += 1.0f;
  132. break;
  133. case 'w':
  134. wire = !wire;
  135. if (wire)
  136. glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  137. else
  138. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  139. break;
  140. case 'p':
  141. pixelLight = !pixelLight;
  142. if (pixelLight)
  143. printf ("Per-pixel lighting\n");
  144. else
  145. printf ("Conventional lighting\n");
  146. break;
  147. case 27:
  148. exit(0);
  149. break;
  150. }
  151. glutPostRedisplay ();
  152. }
  153. static void SpecialKey (int key, int x, int y)
  154. {
  155. const GLfloat step = 3.0f;
  156. (void) x;
  157. (void) y;
  158. switch (key)
  159. {
  160. case GLUT_KEY_UP:
  161. xRot -= step;
  162. break;
  163. case GLUT_KEY_DOWN:
  164. xRot += step;
  165. break;
  166. case GLUT_KEY_LEFT:
  167. yRot -= step;
  168. break;
  169. case GLUT_KEY_RIGHT:
  170. yRot += step;
  171. break;
  172. }
  173. glutPostRedisplay ();
  174. }
  175. static void Init (void)
  176. {
  177. static const char *fragShaderText =
  178. "uniform vec3 lightPos;\n"
  179. "uniform vec4 diffuse;\n"
  180. "uniform vec4 specular;\n"
  181. "varying vec3 normal;\n"
  182. "void main () {\n"
  183. " // Compute dot product of light direction and normal vector\n"
  184. " float dotProd = max (dot (lightPos, normalize (normal)), 0.0);\n"
  185. " // Compute diffuse and specular contributions\n"
  186. " gl_FragColor = diffuse * dotProd + specular * pow (dotProd, 20.0);\n"
  187. "}\n"
  188. ;
  189. static const char *vertShaderText =
  190. "varying vec3 normal;\n"
  191. "void main () {\n"
  192. " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  193. " normal = gl_NormalMatrix * gl_Normal;\n"
  194. "}\n"
  195. ;
  196. if (!glutExtensionSupported ("GL_ARB_fragment_shader"))
  197. {
  198. printf ("Sorry, this demo requires GL_ARB_fragment_shader\n");
  199. exit(1);
  200. }
  201. if (!glutExtensionSupported ("GL_ARB_shader_objects"))
  202. {
  203. printf ("Sorry, this demo requires GL_ARB_shader_objects\n");
  204. exit(1);
  205. }
  206. if (!glutExtensionSupported ("GL_ARB_shading_language_100"))
  207. {
  208. printf ("Sorry, this demo requires GL_ARB_shading_language_100\n");
  209. exit(1);
  210. }
  211. if (!glutExtensionSupported ("GL_ARB_vertex_shader"))
  212. {
  213. printf ("Sorry, this demo requires GL_ARB_vertex_shader\n");
  214. exit(1);
  215. }
  216. glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GETPROCADDRESS ("glCreateShaderObjectARB");
  217. glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GETPROCADDRESS ("glShaderSourceARB");
  218. glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GETPROCADDRESS ("glCompileShaderARB");
  219. glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GETPROCADDRESS ("glCreateProgramObjectARB");
  220. glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GETPROCADDRESS ("glAttachObjectARB");
  221. glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GETPROCADDRESS ("glLinkProgramARB");
  222. glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GETPROCADDRESS ("glUseProgramObjectARB");
  223. glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GETPROCADDRESS ("glGetUniformLocationARB");
  224. glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GETPROCADDRESS ("glUniform3fvARB");
  225. glUniform4fvARB = (PFNGLUNIFORM3FVARBPROC) GETPROCADDRESS ("glUniform4fvARB");
  226. fragShader = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB);
  227. glShaderSourceARB (fragShader, 1, &fragShaderText, NULL);
  228. glCompileShaderARB (fragShader);
  229. vertShader = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
  230. glShaderSourceARB (vertShader, 1, &vertShaderText, NULL);
  231. glCompileShaderARB (vertShader);
  232. program = glCreateProgramObjectARB ();
  233. glAttachObjectARB (program, fragShader);
  234. glAttachObjectARB (program, vertShader);
  235. glLinkProgramARB (program);
  236. glUseProgramObjectARB (program);
  237. uLightPos = glGetUniformLocationARB (program, "lightPos");
  238. uDiffuse = glGetUniformLocationARB (program, "diffuse");
  239. uSpecular = glGetUniformLocationARB (program, "specular");
  240. glUniform4fvARB (uDiffuse, 1, diffuse);
  241. glUniform4fvARB (uSpecular, 1, specular);
  242. glClearColor (0.3f, 0.3f, 0.3f, 0.0f);
  243. glEnable (GL_DEPTH_TEST);
  244. glEnable (GL_LIGHT0);
  245. glEnable (GL_LIGHTING);
  246. glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
  247. glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  248. glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
  249. printf ("GL_RENDERER = %s\n", (const char *) glGetString (GL_RENDERER));
  250. printf ("Press p to toggle between per-pixel and per-vertex lighting\n");
  251. }
  252. int main (int argc, char *argv[])
  253. {
  254. glutInit (&argc, argv);
  255. glutInitWindowPosition ( 0, 0);
  256. glutInitWindowSize (200, 200);
  257. glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  258. glutCreateWindow (argv[0]);
  259. glutReshapeFunc (Reshape);
  260. glutKeyboardFunc (Key);
  261. glutSpecialFunc (SpecialKey);
  262. glutDisplayFunc (Redisplay);
  263. if (anim)
  264. glutIdleFunc (Idle);
  265. Init ();
  266. glutMainLoop ();
  267. return 0;
  268. }