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.

bump.c 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /**
  2. * Procedural Bump Mapping demo. Uses the example shaders from
  3. * chapter 11 of the OpenGL Shading Language "orange" book.
  4. * 16 Jan 2007
  5. */
  6. #include <assert.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11. #include <GL/glut.h>
  12. #include <GL/glu.h>
  13. #include <GL/glext.h>
  14. #include "extfuncs.h"
  15. static char *FragProgFile = "CH11-bumpmap.frag.txt";
  16. static char *VertProgFile = "CH11-bumpmap.vert.txt";
  17. /* program/shader objects */
  18. static GLuint fragShader;
  19. static GLuint vertShader;
  20. static GLuint program;
  21. struct uniform_info {
  22. const char *name;
  23. GLuint size;
  24. GLint location;
  25. GLfloat value[4];
  26. };
  27. static struct uniform_info Uniforms[] = {
  28. { "LightPosition", 3, -1, { 0.57737, 0.57735, 0.57735, 0.0 } },
  29. { "SurfaceColor", 3, -1, { 0.8, 0.8, 0.2, 0 } },
  30. { "BumpDensity", 1, -1, { 10.0, 0, 0, 0 } },
  31. { "BumpSize", 1, -1, { 0.125, 0, 0, 0 } },
  32. { "SpecularFactor", 1, -1, { 0.5, 0, 0, 0 } },
  33. { NULL, 0, 0, { 0, 0, 0, 0 } }
  34. };
  35. static GLint win = 0;
  36. static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f;
  37. static GLuint tangentAttrib;
  38. static GLboolean Anim = GL_FALSE;
  39. static void
  40. CheckError(int line)
  41. {
  42. GLenum err = glGetError();
  43. if (err) {
  44. printf("GL Error %s (0x%x) at line %d\n",
  45. gluErrorString(err), (int) err, line);
  46. }
  47. }
  48. /*
  49. * Draw a square, specifying normal and tangent vectors.
  50. */
  51. static void
  52. Square(GLfloat size)
  53. {
  54. glNormal3f(0, 0, 1);
  55. glVertexAttrib3f_func(tangentAttrib, 1, 0, 0);
  56. glBegin(GL_POLYGON);
  57. glTexCoord2f(0, 0); glVertex2f(-size, -size);
  58. glTexCoord2f(1, 0); glVertex2f( size, -size);
  59. glTexCoord2f(1, 1); glVertex2f( size, size);
  60. glTexCoord2f(0, 1); glVertex2f(-size, size);
  61. glEnd();
  62. }
  63. static void
  64. Cube(GLfloat size)
  65. {
  66. /* +X */
  67. glPushMatrix();
  68. glRotatef(90, 0, 1, 0);
  69. glTranslatef(0, 0, size);
  70. Square(size);
  71. glPopMatrix();
  72. /* -X */
  73. glPushMatrix();
  74. glRotatef(-90, 0, 1, 0);
  75. glTranslatef(0, 0, size);
  76. Square(size);
  77. glPopMatrix();
  78. /* +Y */
  79. glPushMatrix();
  80. glRotatef(90, 1, 0, 0);
  81. glTranslatef(0, 0, size);
  82. Square(size);
  83. glPopMatrix();
  84. /* -Y */
  85. glPushMatrix();
  86. glRotatef(-90, 1, 0, 0);
  87. glTranslatef(0, 0, size);
  88. Square(size);
  89. glPopMatrix();
  90. /* +Z */
  91. glPushMatrix();
  92. glTranslatef(0, 0, size);
  93. Square(size);
  94. glPopMatrix();
  95. /* -Z */
  96. glPushMatrix();
  97. glRotatef(180, 0, 1, 0);
  98. glTranslatef(0, 0, size);
  99. Square(size);
  100. glPopMatrix();
  101. }
  102. static void
  103. Idle(void)
  104. {
  105. GLint t = glutGet(GLUT_ELAPSED_TIME);
  106. yRot = t * 0.05;
  107. glutPostRedisplay();
  108. }
  109. static void
  110. Redisplay(void)
  111. {
  112. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  113. glPushMatrix();
  114. glRotatef(xRot, 1.0f, 0.0f, 0.0f);
  115. glRotatef(yRot, 0.0f, 1.0f, 0.0f);
  116. glRotatef(zRot, 0.0f, 0.0f, 1.0f);
  117. Cube(1.5);
  118. glPopMatrix();
  119. glFinish();
  120. glFlush();
  121. CheckError(__LINE__);
  122. glutSwapBuffers();
  123. }
  124. static void
  125. Reshape(int width, int height)
  126. {
  127. glViewport(0, 0, width, height);
  128. glMatrixMode(GL_PROJECTION);
  129. glLoadIdentity();
  130. glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
  131. glMatrixMode(GL_MODELVIEW);
  132. glLoadIdentity();
  133. glTranslatef(0.0f, 0.0f, -15.0f);
  134. }
  135. static void
  136. CleanUp(void)
  137. {
  138. glDeleteShader_func(fragShader);
  139. glDeleteShader_func(vertShader);
  140. glDeleteProgram_func(program);
  141. glutDestroyWindow(win);
  142. }
  143. static void
  144. Key(unsigned char key, int x, int y)
  145. {
  146. const GLfloat step = 2.0;
  147. (void) x;
  148. (void) y;
  149. switch(key) {
  150. case 'a':
  151. Anim = !Anim;
  152. glutIdleFunc(Anim ? Idle : NULL);
  153. break;
  154. case 'z':
  155. zRot += step;
  156. break;
  157. case 'Z':
  158. zRot -= step;
  159. break;
  160. case 27:
  161. CleanUp();
  162. exit(0);
  163. break;
  164. }
  165. glutPostRedisplay();
  166. }
  167. static void
  168. SpecialKey(int key, int x, int y)
  169. {
  170. const GLfloat step = 2.0;
  171. (void) x;
  172. (void) y;
  173. switch(key) {
  174. case GLUT_KEY_UP:
  175. xRot += step;
  176. break;
  177. case GLUT_KEY_DOWN:
  178. xRot -= step;
  179. break;
  180. case GLUT_KEY_LEFT:
  181. yRot -= step;
  182. break;
  183. case GLUT_KEY_RIGHT:
  184. yRot += step;
  185. break;
  186. }
  187. glutPostRedisplay();
  188. }
  189. static void
  190. LoadAndCompileShader(GLuint shader, const char *text)
  191. {
  192. GLint stat;
  193. glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
  194. glCompileShader_func(shader);
  195. glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
  196. if (!stat) {
  197. GLchar log[1000];
  198. GLsizei len;
  199. glGetShaderInfoLog_func(shader, 1000, &len, log);
  200. fprintf(stderr, "brick: problem compiling shader: %s\n", log);
  201. exit(1);
  202. }
  203. else {
  204. printf("Shader compiled OK\n");
  205. }
  206. }
  207. /**
  208. * Read a shader from a file.
  209. */
  210. static void
  211. ReadShader(GLuint shader, const char *filename)
  212. {
  213. const int max = 100*1000;
  214. int n;
  215. char *buffer = (char*) malloc(max);
  216. FILE *f = fopen(filename, "r");
  217. if (!f) {
  218. fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
  219. exit(1);
  220. }
  221. n = fread(buffer, 1, max, f);
  222. printf("brick: read %d bytes from shader file %s\n", n, filename);
  223. if (n > 0) {
  224. buffer[n] = 0;
  225. LoadAndCompileShader(shader, buffer);
  226. }
  227. fclose(f);
  228. free(buffer);
  229. }
  230. static void
  231. CheckLink(GLuint prog)
  232. {
  233. GLint stat;
  234. glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
  235. if (!stat) {
  236. GLchar log[1000];
  237. GLsizei len;
  238. glGetProgramInfoLog_func(prog, 1000, &len, log);
  239. fprintf(stderr, "Linker error:\n%s\n", log);
  240. }
  241. else {
  242. fprintf(stderr, "Link success!\n");
  243. }
  244. }
  245. static void
  246. Init(void)
  247. {
  248. const char *version;
  249. GLint i;
  250. version = (const char *) glGetString(GL_VERSION);
  251. if (version[0] != '2' || version[1] != '.') {
  252. printf("Warning: this program expects OpenGL 2.0\n");
  253. /*exit(1);*/
  254. }
  255. printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
  256. GetExtensionFuncs();
  257. vertShader = glCreateShader_func(GL_VERTEX_SHADER);
  258. ReadShader(vertShader, VertProgFile);
  259. fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
  260. ReadShader(fragShader, FragProgFile);
  261. program = glCreateProgram_func();
  262. glAttachShader_func(program, fragShader);
  263. glAttachShader_func(program, vertShader);
  264. glLinkProgram_func(program);
  265. CheckLink(program);
  266. glUseProgram_func(program);
  267. assert(glIsProgram_func(program));
  268. assert(glIsShader_func(fragShader));
  269. assert(glIsShader_func(vertShader));
  270. assert(glGetError() == 0);
  271. CheckError(__LINE__);
  272. for (i = 0; Uniforms[i].name; i++) {
  273. Uniforms[i].location
  274. = glGetUniformLocation_func(program, Uniforms[i].name);
  275. printf("Uniform %s location: %d\n", Uniforms[i].name,
  276. Uniforms[i].location);
  277. switch (Uniforms[i].size) {
  278. case 1:
  279. glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  280. break;
  281. case 2:
  282. glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  283. break;
  284. case 3:
  285. glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  286. break;
  287. case 4:
  288. glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value);
  289. break;
  290. default:
  291. abort();
  292. }
  293. }
  294. CheckError(__LINE__);
  295. tangentAttrib = glGetAttribLocation_func(program, "Tangent");
  296. printf("Tangent Attrib: %d\n", tangentAttrib);
  297. assert(tangentAttrib >= 0);
  298. CheckError(__LINE__);
  299. glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
  300. glEnable(GL_DEPTH_TEST);
  301. glColor3f(1, 0, 0);
  302. }
  303. static void
  304. ParseOptions(int argc, char *argv[])
  305. {
  306. int i;
  307. for (i = 1; i < argc; i++) {
  308. if (strcmp(argv[i], "-fs") == 0) {
  309. FragProgFile = argv[i+1];
  310. }
  311. else if (strcmp(argv[i], "-vs") == 0) {
  312. VertProgFile = argv[i+1];
  313. }
  314. }
  315. }
  316. int
  317. main(int argc, char *argv[])
  318. {
  319. glutInit(&argc, argv);
  320. glutInitWindowPosition( 0, 0);
  321. glutInitWindowSize(400, 400);
  322. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  323. win = glutCreateWindow(argv[0]);
  324. glutReshapeFunc(Reshape);
  325. glutKeyboardFunc(Key);
  326. glutSpecialFunc(SpecialKey);
  327. glutDisplayFunc(Redisplay);
  328. ParseOptions(argc, argv);
  329. Init();
  330. glutMainLoop();
  331. return 0;
  332. }