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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * EXT_fog_coord.
  3. *
  4. * Based on glutskel.c by Brian Paul
  5. * and NeHe's Volumetric fog tutorial!
  6. *
  7. * Daniel Borca
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include <GL/glut.h>
  13. #include "readtex.c" /* the compulsory hack */
  14. #define TEXTURE_FILE "../images/bw.rgb"
  15. #define ARRAYS 0 /* use glDrawElements */
  16. #define VERBOSE 1 /* tell me what happens */
  17. #define DEPTH 15.0f
  18. #define EPS 1e-6f
  19. typedef void (GLAPIENTRYP GLFOGCOORDFEXTPROC) (GLfloat f);
  20. typedef void (GLAPIENTRYP GLFOGCOORDPOINTEREXTPROC) (GLenum, GLsizei, const GLvoid *);
  21. static GLFOGCOORDFEXTPROC glFogCoordf_ext;
  22. static GLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext;
  23. static GLboolean have_fog_coord;
  24. static GLfloat camz;
  25. static GLuint texture[1];
  26. static GLint fogMode;
  27. static GLboolean fogCoord;
  28. static GLfloat fogDensity = 0.75;
  29. static GLfloat fogStart = 0.0, fogEnd = 1.0;
  30. static GLfloat fogColor[4] = {0.6f, 0.3f, 0.0f, 1.0f};
  31. void APIENTRY glFogCoordf_nop (GLfloat f)
  32. {
  33. (void)f;
  34. }
  35. static int BuildTexture (const char *filename, GLuint texid[])
  36. {
  37. GLubyte *tex_data;
  38. GLenum tex_format;
  39. GLint tex_width, tex_height;
  40. tex_data = LoadRGBImage(filename, &tex_width, &tex_height, &tex_format);
  41. if (tex_data == NULL) {
  42. return -1;
  43. }
  44. {
  45. GLint tex_max;
  46. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &tex_max);
  47. if ((tex_width > tex_max) || (tex_height > tex_max)) {
  48. return -1;
  49. }
  50. }
  51. glGenTextures(1, texid);
  52. glBindTexture(GL_TEXTURE_2D, texid[0]);
  53. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  54. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  55. glTexImage2D(GL_TEXTURE_2D, 0, tex_format, tex_width, tex_height, 0, tex_format, GL_UNSIGNED_BYTE, tex_data);
  56. return 0;
  57. }
  58. static int SetFogMode (GLint fogMode)
  59. {
  60. fogMode &= 3;
  61. switch (fogMode) {
  62. case 0:
  63. glDisable(GL_FOG);
  64. #if VERBOSE
  65. printf("fog(disable)\n");
  66. #endif
  67. break;
  68. case 1:
  69. glEnable(GL_FOG);
  70. glFogi(GL_FOG_MODE, GL_LINEAR);
  71. glFogf(GL_FOG_START, fogStart);
  72. glFogf(GL_FOG_END, fogEnd);
  73. #if VERBOSE
  74. printf("fog(GL_LINEAR, %.2f, %.2f)\n", fogStart, fogEnd);
  75. #endif
  76. break;
  77. case 2:
  78. glEnable(GL_FOG);
  79. glFogi(GL_FOG_MODE, GL_EXP);
  80. glFogf(GL_FOG_DENSITY, fogDensity);
  81. #if VERBOSE
  82. printf("fog(GL_EXP, %.2f)\n", fogDensity);
  83. #endif
  84. break;
  85. case 3:
  86. glEnable(GL_FOG);
  87. glFogi(GL_FOG_MODE, GL_EXP2);
  88. glFogf(GL_FOG_DENSITY, fogDensity);
  89. #if VERBOSE
  90. printf("fog(GL_EXP2, %.2f)\n", fogDensity);
  91. #endif
  92. break;
  93. }
  94. return fogMode;
  95. }
  96. static GLboolean SetFogCoord (GLboolean fogCoord)
  97. {
  98. glFogCoordf_ext = glFogCoordf_nop;
  99. if (!have_fog_coord) {
  100. #if VERBOSE
  101. printf("fog(GL_FRAGMENT_DEPTH_EXT)%s\n", fogCoord ? " EXT_fog_coord not available!" : "");
  102. #endif
  103. return GL_FALSE;
  104. }
  105. if (fogCoord) {
  106. glFogCoordf_ext = (GLFOGCOORDFEXTPROC)glutGetProcAddress("glFogCoordfEXT");
  107. glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
  108. #if VERBOSE
  109. printf("fog(GL_FOG_COORDINATE_EXT)\n");
  110. #endif
  111. } else {
  112. glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
  113. #if VERBOSE
  114. printf("fog(GL_FRAGMENT_DEPTH_EXT)\n");
  115. #endif
  116. }
  117. return fogCoord;
  118. }
  119. #if ARRAYS
  120. /* could reuse vertices */
  121. static GLuint vertex_index[] = {
  122. /* Back */
  123. 0, 1, 2, 3,
  124. /* Floor */
  125. 4, 5, 6, 7,
  126. /* Roof */
  127. 8, 9, 10, 11,
  128. /* Right */
  129. 12, 13, 14, 15,
  130. /* Left */
  131. 16, 17, 18, 19
  132. };
  133. static GLfloat vertex_pointer[][3] = {
  134. /* Back */
  135. {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, {-2.5f, 2.5f,-DEPTH},
  136. /* Floor */
  137. {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f, DEPTH}, {-2.5f,-2.5f, DEPTH},
  138. /* Roof */
  139. {-2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH},
  140. /* Right */
  141. { 2.5f,-2.5f, DEPTH}, { 2.5f, 2.5f, DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH},
  142. /* Left */
  143. {-2.5f,-2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f,-DEPTH}, {-2.5f,-2.5f,-DEPTH}
  144. };
  145. static GLfloat texcoord_pointer[][2] = {
  146. /* Back */
  147. {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
  148. /* Floor */
  149. {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
  150. /* Roof */
  151. {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
  152. /* Right */
  153. {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f},
  154. /* Left */
  155. {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}
  156. };
  157. static GLfloat fogcoord_pointer[][1] = {
  158. /* Back */
  159. {1.0f}, {1.0f}, {1.0f}, {1.0f},
  160. /* Floor */
  161. {1.0f}, {1.0f}, {0.0f}, {0.0f},
  162. /* Roof */
  163. {1.0f}, {1.0f}, {0.0f}, {0.0f},
  164. /* Right */
  165. {0.0f}, {0.0f}, {1.0f}, {1.0f},
  166. /* Left */
  167. {0.0f}, {0.0f}, {1.0f}, {1.0f}
  168. };
  169. #endif
  170. static void Display( void )
  171. {
  172. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  173. glLoadIdentity ();
  174. glTranslatef(0.0f, 0.0f, camz);
  175. #if ARRAYS
  176. glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]), GL_UNSIGNED_INT, vertex_index);
  177. #else
  178. /* Back */
  179. glBegin(GL_QUADS);
  180. glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f,-2.5f,-DEPTH);
  181. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f,-2.5f,-DEPTH);
  182. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f, 2.5f,-DEPTH);
  183. glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f, 2.5f,-DEPTH);
  184. glEnd();
  185. /* Floor */
  186. glBegin(GL_QUADS);
  187. glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f,-2.5f,-DEPTH);
  188. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f,-2.5f,-DEPTH);
  189. glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f,-2.5f, DEPTH);
  190. glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f,-2.5f, DEPTH);
  191. glEnd();
  192. /* Roof */
  193. glBegin(GL_QUADS);
  194. glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f, 2.5f,-DEPTH);
  195. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f, 2.5f,-DEPTH);
  196. glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f, 2.5f, DEPTH);
  197. glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f, 2.5f, DEPTH);
  198. glEnd();
  199. /* Right */
  200. glBegin(GL_QUADS);
  201. glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 2.5f,-2.5f, DEPTH);
  202. glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 2.5f, 2.5f, DEPTH);
  203. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f, 2.5f,-DEPTH);
  204. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f,-2.5f,-DEPTH);
  205. glEnd();
  206. /* Left */
  207. glBegin(GL_QUADS);
  208. glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f,-2.5f, DEPTH);
  209. glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f, 2.5f, DEPTH);
  210. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.5f, 2.5f,-DEPTH);
  211. glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.5f,-2.5f,-DEPTH);
  212. glEnd();
  213. #endif
  214. glutSwapBuffers();
  215. }
  216. static void Reshape( int width, int height )
  217. {
  218. glViewport(0, 0, width, height);
  219. glMatrixMode(GL_PROJECTION);
  220. glLoadIdentity();
  221. gluPerspective(45.0f, (GLfloat)(width)/(GLfloat)(height), 0.1f, 100.0f);
  222. glMatrixMode(GL_MODELVIEW);
  223. glLoadIdentity();
  224. }
  225. static void Key( unsigned char key, int x, int y )
  226. {
  227. (void) x;
  228. (void) y;
  229. switch (key) {
  230. case 'f':
  231. fogMode = SetFogMode(fogMode + 1);
  232. break;
  233. case '+':
  234. if (fogDensity < 1.0 - EPS) {
  235. fogDensity += 0.05;
  236. }
  237. SetFogMode(fogMode);
  238. break;
  239. case '-':
  240. if (fogDensity > EPS) {
  241. fogDensity -= 0.05;
  242. }
  243. SetFogMode(fogMode);
  244. break;
  245. case 's':
  246. if (fogStart > EPS) {
  247. fogStart -= 0.1;
  248. }
  249. SetFogMode(fogMode);
  250. break;
  251. case 'S':
  252. if (fogStart < fogEnd - EPS) {
  253. fogStart += 0.1;
  254. }
  255. SetFogMode(fogMode);
  256. break;
  257. case 'e':
  258. if (fogEnd > fogStart + EPS) {
  259. fogEnd -= 0.1;
  260. }
  261. SetFogMode(fogMode);
  262. break;
  263. case 'E':
  264. if (fogEnd < 1.0 - EPS) {
  265. fogEnd += 0.1;
  266. }
  267. SetFogMode(fogMode);
  268. break;
  269. case 'c':
  270. fogCoord = SetFogCoord(fogCoord ^ GL_TRUE);
  271. break;
  272. case 27:
  273. exit(0);
  274. break;
  275. }
  276. glutPostRedisplay();
  277. }
  278. static void SpecialKey( int key, int x, int y )
  279. {
  280. (void) x;
  281. (void) y;
  282. switch (key) {
  283. case GLUT_KEY_UP:
  284. if (camz < (DEPTH - 1.0)) {
  285. camz += 1.0f;
  286. }
  287. break;
  288. case GLUT_KEY_DOWN:
  289. if (camz > -19.0) {
  290. camz -= 1.0f;
  291. }
  292. break;
  293. }
  294. glutPostRedisplay();
  295. }
  296. static void Init( void )
  297. {
  298. have_fog_coord = glutExtensionSupported("GL_EXT_fog_coord");
  299. if (BuildTexture(TEXTURE_FILE, texture) == -1) {
  300. exit(1);
  301. }
  302. glEnable(GL_TEXTURE_2D);
  303. glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
  304. glClearDepth(1.0f);
  305. glDepthFunc(GL_LEQUAL);
  306. glEnable(GL_DEPTH_TEST);
  307. glShadeModel(GL_SMOOTH);
  308. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  309. glFogfv(GL_FOG_COLOR, fogColor);
  310. glHint(GL_FOG_HINT, GL_NICEST);
  311. fogCoord = SetFogCoord(GL_TRUE); /* try to enable fog_coord */
  312. fogMode = SetFogMode(2); /* GL_EXP */
  313. camz = -19.0f;
  314. #if ARRAYS
  315. glEnableClientState(GL_VERTEX_ARRAY);
  316. glVertexPointer(3, GL_FLOAT, 0, vertex_pointer);
  317. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  318. glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer);
  319. if (have_fog_coord) {
  320. glFogCoordPointer_ext = (GLFOGCOORDPOINTEREXTPROC)glutGetProcAddress("glFogCoordPointerEXT");
  321. glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
  322. glFogCoordPointer_ext(GL_FLOAT, 0, fogcoord_pointer);
  323. }
  324. #endif
  325. }
  326. int main( int argc, char *argv[] )
  327. {
  328. glutInit( &argc, argv );
  329. glutInitWindowPosition( 0, 0 );
  330. glutInitWindowSize( 640, 480 );
  331. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
  332. glutCreateWindow(argv[0]);
  333. glutReshapeFunc( Reshape );
  334. glutKeyboardFunc( Key );
  335. glutSpecialFunc( SpecialKey );
  336. glutDisplayFunc( Display );
  337. Init();
  338. glutMainLoop();
  339. return 0;
  340. }