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.

fslight.c 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /**
  2. * Test OpenGL 2.0 vertex/fragment shaders.
  3. * Brian Paul
  4. * 1 November 2006
  5. *
  6. * Based on ARB version by:
  7. * Michal Krol
  8. * 20 February 2006
  9. *
  10. * Based on the original demo by:
  11. * Brian Paul
  12. * 17 April 2003
  13. */
  14. #include <assert.h>
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <math.h>
  19. #include <GL/gl.h>
  20. #include <GL/glut.h>
  21. #include <GL/glext.h>
  22. static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
  23. static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
  24. static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f };
  25. static GLfloat delta = 1.0f;
  26. static GLuint fragShader;
  27. static GLuint vertShader;
  28. static GLuint program;
  29. static GLint uLightPos;
  30. static GLint uDiffuse;
  31. static GLint uSpecular;
  32. static GLint win = 0;
  33. static GLboolean anim = GL_TRUE;
  34. static GLboolean wire = GL_FALSE;
  35. static GLboolean pixelLight = GL_TRUE;
  36. static GLint t0 = 0;
  37. static GLint frames = 0;
  38. static GLfloat xRot = 0.0f, yRot = 0.0f;
  39. static PFNGLCREATESHADERPROC glCreateShader_func = NULL;
  40. static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL;
  41. static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL;
  42. static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL;
  43. static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL;
  44. static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL;
  45. static PFNGLDELETESHADERPROC glDeleteShader_func = NULL;
  46. static PFNGLATTACHSHADERPROC glAttachShader_func = NULL;
  47. static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL;
  48. static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL;
  49. static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL;
  50. static PFNGLISPROGRAMPROC glIsProgram_func = NULL;
  51. static PFNGLISSHADERPROC glIsShader_func = NULL;
  52. static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL;
  53. static PFNGLUNIFORM3FVPROC glUniform4fv_func = NULL;
  54. static void
  55. normalize(GLfloat *dst, const GLfloat *src)
  56. {
  57. GLfloat len = sqrtf(src[0] * src[0] + src[1] * src[1] + src[2] * src[2]);
  58. dst[0] = src[0] / len;
  59. dst[1] = src[1] / len;
  60. dst[2] = src[2] / len;
  61. }
  62. static void
  63. Redisplay(void)
  64. {
  65. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  66. if (pixelLight) {
  67. GLfloat vec[3];
  68. glUseProgram_func(program);
  69. normalize(vec, lightPos);
  70. glUniform3fv_func(uLightPos, 1, vec);
  71. glDisable(GL_LIGHTING);
  72. }
  73. else {
  74. glUseProgram_func(0);
  75. glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  76. glEnable(GL_LIGHTING);
  77. }
  78. glPushMatrix();
  79. glRotatef(xRot, 1.0f, 0.0f, 0.0f);
  80. glRotatef(yRot, 0.0f, 1.0f, 0.0f);
  81. glutSolidSphere(2.0, 10, 5);
  82. glPopMatrix();
  83. glutSwapBuffers();
  84. frames++;
  85. if (anim) {
  86. GLint t = glutGet(GLUT_ELAPSED_TIME);
  87. if (t - t0 >= 5000) {
  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",
  91. frames, seconds, fps);
  92. t0 = t;
  93. frames = 0;
  94. }
  95. }
  96. }
  97. static void
  98. Idle(void)
  99. {
  100. lightPos[0] += delta;
  101. if (lightPos[0] > 25.0f || lightPos[0] < -25.0f)
  102. delta = -delta;
  103. glutPostRedisplay();
  104. }
  105. static void
  106. Reshape(int width, int height)
  107. {
  108. glViewport(0, 0, width, height);
  109. glMatrixMode(GL_PROJECTION);
  110. glLoadIdentity();
  111. glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
  112. glMatrixMode(GL_MODELVIEW);
  113. glLoadIdentity();
  114. glTranslatef(0.0f, 0.0f, -15.0f);
  115. }
  116. static void
  117. CleanUp(void)
  118. {
  119. glDeleteShader_func(fragShader);
  120. glDeleteShader_func(vertShader);
  121. glDeleteProgram_func(program);
  122. glutDestroyWindow(win);
  123. }
  124. static void
  125. Key(unsigned char key, int x, int y)
  126. {
  127. (void) x;
  128. (void) y;
  129. switch(key) {
  130. case ' ':
  131. case 'a':
  132. anim = !anim;
  133. if (anim)
  134. glutIdleFunc(Idle);
  135. else
  136. glutIdleFunc(NULL);
  137. break;
  138. case 'x':
  139. lightPos[0] -= 1.0f;
  140. break;
  141. case 'X':
  142. lightPos[0] += 1.0f;
  143. break;
  144. case 'w':
  145. wire = !wire;
  146. if (wire)
  147. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  148. else
  149. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  150. break;
  151. case 'p':
  152. pixelLight = !pixelLight;
  153. if (pixelLight)
  154. printf("Per-pixel lighting\n");
  155. else
  156. printf("Conventional lighting\n");
  157. break;
  158. case 27:
  159. CleanUp();
  160. exit(0);
  161. break;
  162. }
  163. glutPostRedisplay();
  164. }
  165. static void
  166. SpecialKey(int key, int x, int y)
  167. {
  168. const GLfloat step = 3.0f;
  169. (void) x;
  170. (void) y;
  171. switch(key) {
  172. case GLUT_KEY_UP:
  173. xRot -= step;
  174. break;
  175. case GLUT_KEY_DOWN:
  176. xRot += step;
  177. break;
  178. case GLUT_KEY_LEFT:
  179. yRot -= step;
  180. break;
  181. case GLUT_KEY_RIGHT:
  182. yRot += step;
  183. break;
  184. }
  185. glutPostRedisplay();
  186. }
  187. static void
  188. Init(void)
  189. {
  190. static const char *fragShaderText =
  191. "uniform vec3 lightPos;\n"
  192. "uniform vec4 diffuse;\n"
  193. "uniform vec4 specular;\n"
  194. "varying vec3 normal;\n"
  195. "void main() {\n"
  196. " // Compute dot product of light direction and normal vector\n"
  197. " float dotProd = max(dot(lightPos, normalize(normal)), 0.0);\n"
  198. " // Compute diffuse and specular contributions\n"
  199. " gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n"
  200. "}\n";
  201. static const char *vertShaderText =
  202. "varying vec3 normal;\n"
  203. "void main() {\n"
  204. " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
  205. " normal = gl_NormalMatrix * gl_Normal;\n"
  206. "}\n";
  207. const char *version;
  208. version = (const char *) glGetString(GL_VERSION);
  209. if (version[0] != '2' || version[1] != '.') {
  210. printf("Warning: this program expects OpenGL 2.0\n");
  211. /*exit(1);*/
  212. }
  213. glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader");
  214. glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader");
  215. glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram");
  216. glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource");
  217. glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource");
  218. glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader");
  219. glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram");
  220. glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader");
  221. glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram");
  222. glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram");
  223. glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation");
  224. glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram");
  225. glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader");
  226. glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv");
  227. glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv");
  228. fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
  229. glShaderSource_func(fragShader, 1, &fragShaderText, NULL);
  230. glCompileShader_func(fragShader);
  231. vertShader = glCreateShader_func(GL_VERTEX_SHADER);
  232. glShaderSource_func(vertShader, 1, &vertShaderText, NULL);
  233. glCompileShader_func(vertShader);
  234. program = glCreateProgram_func();
  235. glAttachShader_func(program, fragShader);
  236. glAttachShader_func(program, vertShader);
  237. glLinkProgram_func(program);
  238. glUseProgram_func(program);
  239. uLightPos = glGetUniformLocation_func(program, "lightPos");
  240. uDiffuse = glGetUniformLocation_func(program, "diffuse");
  241. uSpecular = glGetUniformLocation_func(program, "specular");
  242. glUniform4fv_func(uDiffuse, 1, diffuse);
  243. glUniform4fv_func(uSpecular, 1, specular);
  244. glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
  245. glEnable(GL_DEPTH_TEST);
  246. glEnable(GL_LIGHT0);
  247. glEnable(GL_LIGHTING);
  248. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
  249. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  250. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
  251. printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
  252. printf("Press p to toggle between per-pixel and per-vertex lighting\n");
  253. /* test glGetShaderSource() */
  254. {
  255. GLsizei len = strlen(fragShaderText) + 1;
  256. GLsizei lenOut;
  257. GLchar *src =(GLchar *) malloc(len * sizeof(GLchar));
  258. glGetShaderSource_func(fragShader, 0, NULL, src);
  259. glGetShaderSource_func(fragShader, len, &lenOut, src);
  260. assert(len == lenOut + 1);
  261. assert(strcmp(src, fragShaderText) == 0);
  262. free(src);
  263. }
  264. assert(glIsProgram_func(program));
  265. assert(glIsShader_func(fragShader));
  266. assert(glIsShader_func(vertShader));
  267. }
  268. int
  269. main(int argc, char *argv[])
  270. {
  271. glutInit(&argc, argv);
  272. glutInitWindowPosition( 0, 0);
  273. glutInitWindowSize(200, 200);
  274. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  275. win = glutCreateWindow(argv[0]);
  276. glutReshapeFunc(Reshape);
  277. glutKeyboardFunc(Key);
  278. glutSpecialFunc(SpecialKey);
  279. glutDisplayFunc(Redisplay);
  280. if (anim)
  281. glutIdleFunc(Idle);
  282. Init();
  283. glutMainLoop();
  284. return 0;
  285. }