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 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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. #if 1
  187. " gl_FragColor = diffuse * dotProd + specular * pow (dotProd, 20.0);\n"
  188. #elif 1 /* test IF/ELSE/ENDIF */
  189. " if (normal.y > 0.0) { \n"
  190. " gl_FragColor = diffuse * dotProd + specular * pow (dotProd, 20.0);\n"
  191. " } \n"
  192. " else { \n"
  193. " if (normal.x < 0.0) { \n"
  194. " gl_FragColor = vec4(1, 0, 0, 0); \n"
  195. " } \n"
  196. " else { \n"
  197. " gl_FragColor = vec4(1, 1, 0, 0); \n"
  198. " } \n"
  199. " } \n"
  200. #elif 1 /* test LOOP */
  201. " while (1) { \n"
  202. " if (normal.y >= 0.0) { \n"
  203. " gl_FragColor = vec4(1, 0, 0, 0); \n"
  204. " break; \n"
  205. " } else { \n"
  206. " gl_FragColor = diffuse * dotProd + specular * pow (dotProd, 20.0);\n"
  207. " break; \n"
  208. " } \n"
  209. " } \n"
  210. #endif
  211. "}\n"
  212. ;
  213. static const char *vertShaderText =
  214. "varying vec3 normal;\n"
  215. "void main () {\n"
  216. " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  217. " normal = gl_NormalMatrix * gl_Normal;\n"
  218. "}\n"
  219. ;
  220. if (!glutExtensionSupported ("GL_ARB_fragment_shader"))
  221. {
  222. printf ("Sorry, this demo requires GL_ARB_fragment_shader\n");
  223. exit(1);
  224. }
  225. if (!glutExtensionSupported ("GL_ARB_shader_objects"))
  226. {
  227. printf ("Sorry, this demo requires GL_ARB_shader_objects\n");
  228. exit(1);
  229. }
  230. if (!glutExtensionSupported ("GL_ARB_shading_language_100"))
  231. {
  232. printf ("Sorry, this demo requires GL_ARB_shading_language_100\n");
  233. exit(1);
  234. }
  235. if (!glutExtensionSupported ("GL_ARB_vertex_shader"))
  236. {
  237. printf ("Sorry, this demo requires GL_ARB_vertex_shader\n");
  238. exit(1);
  239. }
  240. glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GETPROCADDRESS ("glCreateShaderObjectARB");
  241. glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GETPROCADDRESS ("glShaderSourceARB");
  242. glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GETPROCADDRESS ("glCompileShaderARB");
  243. glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GETPROCADDRESS ("glCreateProgramObjectARB");
  244. glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GETPROCADDRESS ("glAttachObjectARB");
  245. glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GETPROCADDRESS ("glLinkProgramARB");
  246. glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GETPROCADDRESS ("glUseProgramObjectARB");
  247. glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GETPROCADDRESS ("glGetUniformLocationARB");
  248. glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GETPROCADDRESS ("glUniform3fvARB");
  249. glUniform4fvARB = (PFNGLUNIFORM3FVARBPROC) GETPROCADDRESS ("glUniform4fvARB");
  250. fragShader = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB);
  251. glShaderSourceARB (fragShader, 1, &fragShaderText, NULL);
  252. glCompileShaderARB (fragShader);
  253. vertShader = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
  254. glShaderSourceARB (vertShader, 1, &vertShaderText, NULL);
  255. glCompileShaderARB (vertShader);
  256. program = glCreateProgramObjectARB ();
  257. glAttachObjectARB (program, fragShader);
  258. glAttachObjectARB (program, vertShader);
  259. glLinkProgramARB (program);
  260. glUseProgramObjectARB (program);
  261. uLightPos = glGetUniformLocationARB (program, "lightPos");
  262. uDiffuse = glGetUniformLocationARB (program, "diffuse");
  263. uSpecular = glGetUniformLocationARB (program, "specular");
  264. glUniform4fvARB (uDiffuse, 1, diffuse);
  265. glUniform4fvARB (uSpecular, 1, specular);
  266. glClearColor (0.3f, 0.3f, 0.3f, 0.0f);
  267. glEnable (GL_DEPTH_TEST);
  268. glEnable (GL_LIGHT0);
  269. glEnable (GL_LIGHTING);
  270. glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
  271. glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  272. glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
  273. printf ("GL_RENDERER = %s\n", (const char *) glGetString (GL_RENDERER));
  274. printf ("Press p to toggle between per-pixel and per-vertex lighting\n");
  275. }
  276. int main (int argc, char *argv[])
  277. {
  278. glutInit (&argc, argv);
  279. glutInitWindowPosition ( 0, 0);
  280. glutInitWindowSize (200, 200);
  281. glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  282. glutCreateWindow (argv[0]);
  283. glutReshapeFunc (Reshape);
  284. glutKeyboardFunc (Key);
  285. glutSpecialFunc (SpecialKey);
  286. glutDisplayFunc (Redisplay);
  287. if (anim)
  288. glutIdleFunc (Idle);
  289. Init ();
  290. glutMainLoop ();
  291. return 0;
  292. }