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.

fplight.c 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * Use GL_NV_fragment_program to implement per-pixel lighting.
  3. *
  4. * Brian Paul
  5. * 7 April 2003
  6. */
  7. #include <assert.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #define GL_GLEXT_PROTOTYPES
  13. #include <GL/glut.h>
  14. static GLfloat Diffuse[4] = { 0.5, 0.5, 1.0, 1.0 };
  15. static GLfloat Specular[4] = { 0.8, 0.8, 0.8, 1.0 };
  16. static GLfloat LightPos[4] = { 0.0, 10.0, 20.0, 1.0 };
  17. static GLfloat Delta = 1.0;
  18. static GLuint FragProg;
  19. static GLuint VertProg;
  20. static GLboolean Anim = GL_TRUE;
  21. static GLboolean Wire = GL_FALSE;
  22. static GLboolean PixelLight = GL_TRUE;
  23. static GLint Win;
  24. static GLfloat Xrot = 0, Yrot = 0;
  25. #define NAMED_PARAMETER4FV(prog, name, v) \
  26. glProgramNamedParameter4fvNV(prog, strlen(name), (const GLubyte *) name, v)
  27. static void Display( void )
  28. {
  29. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  30. if (PixelLight) {
  31. #if defined(GL_NV_fragment_program)
  32. NAMED_PARAMETER4FV(FragProg, "LightPos", LightPos);
  33. glEnable(GL_FRAGMENT_PROGRAM_NV);
  34. glEnable(GL_VERTEX_PROGRAM_NV);
  35. #endif
  36. glDisable(GL_LIGHTING);
  37. }
  38. else {
  39. glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  40. #if defined(GL_NV_fragment_program)
  41. glDisable(GL_FRAGMENT_PROGRAM_NV);
  42. glDisable(GL_VERTEX_PROGRAM_NV);
  43. #endif
  44. glEnable(GL_LIGHTING);
  45. }
  46. glPushMatrix();
  47. glRotatef(Xrot, 1, 0, 0);
  48. glRotatef(Yrot, 0, 1, 0);
  49. #if 1
  50. glutSolidSphere(2.0, 10, 5);
  51. #else
  52. {
  53. GLUquadricObj *q = gluNewQuadric();
  54. gluQuadricNormals(q, GL_SMOOTH);
  55. gluQuadricTexture(q, GL_TRUE);
  56. glRotatef(90, 1, 0, 0);
  57. glTranslatef(0, 0, -1);
  58. gluCylinder(q, 1.0, 1.0, 2.0, 24, 1);
  59. gluDeleteQuadric(q);
  60. }
  61. #endif
  62. glPopMatrix();
  63. glutSwapBuffers();
  64. }
  65. static void Idle(void)
  66. {
  67. LightPos[0] += Delta;
  68. if (LightPos[0] > 25.0)
  69. Delta = -1.0;
  70. else if (LightPos[0] <- 25.0)
  71. Delta = 1.0;
  72. glutPostRedisplay();
  73. }
  74. static void Reshape( int width, int height )
  75. {
  76. glViewport( 0, 0, width, height );
  77. glMatrixMode( GL_PROJECTION );
  78. glLoadIdentity();
  79. glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
  80. /*glOrtho( -2.0, 2.0, -2.0, 2.0, 5.0, 25.0 );*/
  81. glMatrixMode( GL_MODELVIEW );
  82. glLoadIdentity();
  83. glTranslatef( 0.0, 0.0, -15.0 );
  84. }
  85. static void Key( unsigned char key, int x, int y )
  86. {
  87. (void) x;
  88. (void) y;
  89. switch (key) {
  90. case ' ':
  91. Anim = !Anim;
  92. if (Anim)
  93. glutIdleFunc(Idle);
  94. else
  95. glutIdleFunc(NULL);
  96. break;
  97. case 'x':
  98. LightPos[0] -= 1.0;
  99. break;
  100. case 'X':
  101. LightPos[0] += 1.0;
  102. break;
  103. case 'w':
  104. Wire = !Wire;
  105. if (Wire)
  106. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  107. else
  108. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  109. break;
  110. case 'p':
  111. PixelLight = !PixelLight;
  112. if (PixelLight) {
  113. printf("Per-pixel lighting\n");
  114. }
  115. else {
  116. printf("Conventional lighting\n");
  117. }
  118. break;
  119. case 27:
  120. glutDestroyWindow(Win);
  121. exit(0);
  122. }
  123. glutPostRedisplay();
  124. }
  125. static void SpecialKey( int key, int x, int y )
  126. {
  127. const GLfloat step = 3.0;
  128. (void) x;
  129. (void) y;
  130. switch (key) {
  131. case GLUT_KEY_UP:
  132. Xrot -= step;
  133. break;
  134. case GLUT_KEY_DOWN:
  135. Xrot += step;
  136. break;
  137. case GLUT_KEY_LEFT:
  138. Yrot -= step;
  139. break;
  140. case GLUT_KEY_RIGHT:
  141. Yrot += step;
  142. break;
  143. }
  144. glutPostRedisplay();
  145. }
  146. static void Init( void )
  147. {
  148. static const char *fragProgramText =
  149. "!!FP1.0\n"
  150. "DECLARE Diffuse; \n"
  151. "DECLARE Specular; \n"
  152. "DECLARE LightPos; \n"
  153. "# Compute normalized LightPos, put it in R0\n"
  154. "DP3 R0.x, LightPos, LightPos;\n"
  155. "RSQ R0.y, R0.x;\n"
  156. "MUL R0, LightPos, R0.y;\n"
  157. "# Compute normalized normal, put it in R1\n"
  158. "DP3 R1, f[TEX0], f[TEX0]; \n"
  159. "RSQ R1.y, R1.x;\n"
  160. "MUL R1, f[TEX0], R1.y;\n"
  161. "# Compute dot product of light direction and normal vector\n"
  162. "DP3_SAT R2, R0, R1;"
  163. "MUL R3, Diffuse, R2; # diffuse attenuation\n"
  164. "POW R4, R2.x, {20.0}.x; # specular exponent\n"
  165. "MUL R5, Specular, R4; # specular attenuation\n"
  166. "ADD o[COLR], R3, R5; # add diffuse and specular colors\n"
  167. "END \n"
  168. ;
  169. static const char *vertProgramText =
  170. "!!VP1.0\n"
  171. "# typical modelview/projection transform\n"
  172. "DP4 o[HPOS].x, c[0], v[OPOS] ;\n"
  173. "DP4 o[HPOS].y, c[1], v[OPOS] ;\n"
  174. "DP4 o[HPOS].z, c[2], v[OPOS] ;\n"
  175. "DP4 o[HPOS].w, c[3], v[OPOS] ;\n"
  176. "# transform normal by inv transpose of modelview, put in tex0\n"
  177. "DP3 o[TEX0].x, c[4], v[NRML] ;\n"
  178. "DP3 o[TEX0].y, c[5], v[NRML] ;\n"
  179. "DP3 o[TEX0].z, c[6], v[NRML] ;\n"
  180. "DP3 o[TEX0].w, c[7], v[NRML] ;\n"
  181. "END\n";
  182. ;
  183. if (!glutExtensionSupported("GL_NV_vertex_program")) {
  184. printf("Sorry, this demo requires GL_NV_vertex_program\n");
  185. exit(1);
  186. }
  187. if (!glutExtensionSupported("GL_NV_fragment_program")) {
  188. printf("Sorry, this demo requires GL_NV_fragment_program\n");
  189. exit(1);
  190. }
  191. #if defined(GL_NV_fragment_program)
  192. glGenProgramsNV(1, &FragProg);
  193. assert(FragProg > 0);
  194. glGenProgramsNV(1, &VertProg);
  195. assert(VertProg > 0);
  196. /*
  197. * Fragment program
  198. */
  199. glLoadProgramNV(GL_FRAGMENT_PROGRAM_NV, FragProg,
  200. strlen(fragProgramText),
  201. (const GLubyte *) fragProgramText);
  202. assert(glIsProgramNV(FragProg));
  203. glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, FragProg);
  204. NAMED_PARAMETER4FV(FragProg, "Diffuse", Diffuse);
  205. NAMED_PARAMETER4FV(FragProg, "Specular", Specular);
  206. /*
  207. * Vertex program
  208. */
  209. glLoadProgramNV(GL_VERTEX_PROGRAM_NV, VertProg,
  210. strlen(vertProgramText),
  211. (const GLubyte *) vertProgramText);
  212. assert(glIsProgramNV(VertProg));
  213. glBindProgramNV(GL_VERTEX_PROGRAM_NV, VertProg);
  214. glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);
  215. glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV);
  216. #endif
  217. /*
  218. * Misc init
  219. */
  220. glClearColor(0.3, 0.3, 0.3, 0.0);
  221. glEnable(GL_DEPTH_TEST);
  222. glEnable(GL_LIGHT0);
  223. glEnable(GL_LIGHTING);
  224. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
  225. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
  226. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0);
  227. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  228. printf("Press p to toggle between per-pixel and per-vertex lighting\n");
  229. }
  230. int main( int argc, char *argv[] )
  231. {
  232. glutInit( &argc, argv );
  233. glutInitWindowPosition( 0, 0 );
  234. glutInitWindowSize( 200, 200 );
  235. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
  236. Win = glutCreateWindow(argv[0]);
  237. glutReshapeFunc( Reshape );
  238. glutKeyboardFunc( Key );
  239. glutSpecialFunc( SpecialKey );
  240. glutDisplayFunc( Display );
  241. if (Anim)
  242. glutIdleFunc(Idle);
  243. Init();
  244. glutMainLoop();
  245. return 0;
  246. }