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

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