Advertisement
Guest User

Untitled

a guest
Aug 17th, 2017
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.65 KB | None | 0 0
  1. #ifdef _WIN32
  2. #include "windows.h"
  3. #endif
  4.  
  5. #include "GL/glut.h"
  6.  
  7. #ifdef _WIN32
  8. #include "glext.h"
  9. #endif
  10.  
  11. #include <cmath>
  12. #include <stdio.h>
  13.  
  14.  
  15. #ifdef _WIN32
  16. // As microsoft did not maintain openGL after version 1.1, Windows platform need to go throught this crap ; macosX and Linux are fine.
  17. // This block simply retries openGL function needed for this example.
  18. // I recommend to use GLEW instead of going this way. This is done this way only to ease beginner's compilation and portability
  19.  
  20.  
  21. PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
  22.  
  23. // FrameBuffer (FBO) gen, bin and texturebind
  24. PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT ;
  25. PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT ;
  26. PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT ;
  27. PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT ;
  28.  
  29.  
  30. // Shader functions
  31. PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB ;
  32. PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB ;
  33. PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB ;
  34. PFNGLSHADERSOURCEARBPROC glShaderSourceARB ;
  35. PFNGLCOMPILESHADERARBPROC glCompileShaderARB ;
  36. PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
  37. PFNGLATTACHOBJECTARBPROC glAttachObjectARB ;
  38. PFNGLLINKPROGRAMARBPROC glLinkProgramARB ;
  39. PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB ;
  40. PFNGLUNIFORM1IARBPROC glUniform1iARB ;
  41. PFNGLUNIFORM1FARBPROC glUniform1fARB ;
  42. //PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
  43. PFNGLGETINFOLOGARBPROC glGetInfoLogARB ;
  44.  
  45. void getOpenGLFunctionPointers(void)
  46. {
  47. // FBO
  48. glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
  49. glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT");
  50. glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT");
  51. glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
  52. glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
  53.  
  54. //Shaders
  55. glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
  56. glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
  57. glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
  58. glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
  59. glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
  60. glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
  61. glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
  62. glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
  63. glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
  64. glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)wglGetProcAddress("glGetUniformLocationARB");
  65. glUniform1iARB = (PFNGLUNIFORM1IARBPROC)wglGetProcAddress("glUniform1iARB");
  66. glUniform1fARB = (PFNGLUNIFORM1FARBPROC)wglGetProcAddress("glUniform1fARB");
  67.  
  68. }
  69. #endif
  70.  
  71. // Expressed as float so gluPerspective division returns a float and not 0 (640/480 != 640.0/480.0).
  72. #define RENDER_WIDTH 640.0
  73. #define RENDER_HEIGHT 480.0
  74. #define SHADOW_MAP_RATIO 2
  75.  
  76.  
  77. //Camera position
  78. float p_camera[3] = {35,25,5};
  79.  
  80. //Camera lookAt
  81. float l_camera[3] = {0,-11,-25};
  82.  
  83. //Light position
  84. float p_light[3] = {3,16,0};
  85.  
  86. //Light lookAt
  87. float l_light[3] = {0,0,-5};
  88.  
  89.  
  90. //Light mouvement circle radius
  91. float light_mvnt = 30.0f;
  92.  
  93. // Hold id of the framebuffer for light POV rendering
  94. GLuint fboId;
  95.  
  96. // Z values will be rendered to this texture when using fboId framebuffer
  97. GLuint depthTextureId;
  98.  
  99. // Use to activate/disable shadowShader
  100. GLhandleARB shadowShaderId;
  101.  
  102. GLuint shadowMapUniform;
  103. GLuint shadowMapStepXUniform;
  104. GLuint shadowMapStepYUniform;
  105.  
  106.  
  107. // Loading shader function
  108. GLhandleARB loadShader(char* filename, unsigned int type)
  109. {
  110. FILE *pfile;
  111. GLhandleARB handle;
  112. const GLcharARB* files[1];
  113.  
  114. // shader Compilation variable
  115. GLint result; // Compilation code result
  116. GLint errorLoglength ;
  117. char* errorLogText;
  118. GLsizei actualErrorLogLength;
  119.  
  120. char buffer[400000];
  121. memset(buffer,0,400000);
  122.  
  123. // This will raise a warning on MS compiler
  124. pfile = fopen(filename, "rb");
  125. if(!pfile)
  126. {
  127. printf("Sorry, can't open file: '%s'.\n", filename);
  128. exit(0);
  129. }
  130.  
  131. fread(buffer,sizeof(char),400000,pfile);
  132. //printf("%s\n",buffer);
  133.  
  134.  
  135. fclose(pfile);
  136.  
  137. handle = glCreateShaderObjectARB(type);
  138. if (!handle)
  139. {
  140. //We have failed creating the vertex shader object.
  141. printf("Failed creating vertex shader object from file: %s.",filename);
  142. exit(0);
  143. }
  144.  
  145. files[0] = (const GLcharARB*)buffer;
  146. glShaderSourceARB(
  147. handle, //The handle to our shader
  148. 1, //The number of files.
  149. files, //An array of const char * data, which represents the source code of theshaders
  150. NULL);
  151.  
  152. glCompileShaderARB(handle);
  153.  
  154. //Compilation checking.
  155. glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &result);
  156.  
  157. // If an error was detected.
  158. if (!result)
  159. {
  160. //We failed to compile.
  161. printf("Shader '%s' failed compilation.\n",filename);
  162.  
  163. //Attempt to get the length of our error log.
  164. glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &errorLoglength);
  165.  
  166. //Create a buffer to read compilation error message
  167. errorLogText = (char*) malloc(sizeof(char) * errorLoglength);
  168.  
  169. //Used to get the final length of the log.
  170. glGetInfoLogARB(handle, errorLoglength, &actualErrorLogLength, errorLogText);
  171.  
  172. // Display errors.
  173. printf("%s\n",errorLogText);
  174.  
  175. // Free the buffer malloced earlier
  176. free(errorLogText);
  177. }
  178.  
  179. return handle;
  180. }
  181.  
  182. void loadShadowShader()
  183. {
  184. GLhandleARB vertexShaderHandle;
  185. GLhandleARB fragmentShaderHandle;
  186.  
  187. vertexShaderHandle = loadShader("VertexShader.c",GL_VERTEX_SHADER);
  188. fragmentShaderHandle = loadShader("FragmentShader.c",GL_FRAGMENT_SHADER);
  189.  
  190. shadowShaderId = glCreateProgramObjectARB();
  191.  
  192. glAttachObjectARB(shadowShaderId,vertexShaderHandle);
  193. glAttachObjectARB(shadowShaderId,fragmentShaderHandle);
  194. glLinkProgramARB(shadowShaderId);
  195.  
  196. shadowMapUniform = glGetUniformLocationARB(shadowShaderId,"ShadowMap");
  197. shadowMapStepXUniform = glGetUniformLocationARB(shadowShaderId,"xPixelOffset");
  198. shadowMapStepYUniform = glGetUniformLocationARB(shadowShaderId,"yPixelOffset");
  199. }
  200.  
  201. void generateShadowFBO()
  202. {
  203. int shadowMapWidth = RENDER_WIDTH * SHADOW_MAP_RATIO;
  204. int shadowMapHeight = RENDER_HEIGHT * SHADOW_MAP_RATIO;
  205.  
  206. //GLfloat borderColor[4] = {0,0,0,0};
  207.  
  208. GLenum FBOstatus;
  209.  
  210. // Try to use a texture depth component
  211. glGenTextures(1, &depthTextureId);
  212. glBindTexture(GL_TEXTURE_2D, depthTextureId);
  213.  
  214. // GL_LINEAR does not make sense for depth texture. However, next tutorial shows usage of GL_LINEAR and PCF. Using GL_NEAREST
  215. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  216. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  217.  
  218. // Remove artefact on the edges of the shadowmap
  219. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  220. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  221.  
  222. // This is to allow usage of shadow2DProj function in the shader
  223. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
  224. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  225. glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
  226.  
  227.  
  228.  
  229. // No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available
  230. glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
  231. glBindTexture(GL_TEXTURE_2D, 0);
  232.  
  233. // create a framebuffer object
  234. glGenFramebuffersEXT(1, &fboId);
  235. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
  236.  
  237. // Instruct openGL that we won't bind a color texture with the currently binded FBO
  238. glDrawBuffer(GL_NONE);
  239. glReadBuffer(GL_NONE);
  240.  
  241. // attach the texture to FBO depth attachment point
  242. glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId, 0);
  243.  
  244. // check FBO status
  245. FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  246. if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
  247. printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n");
  248.  
  249. // switch back to window-system-provided framebuffer
  250. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  251. }
  252.  
  253. void setupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z)
  254. {
  255. glMatrixMode(GL_PROJECTION);
  256. glLoadIdentity();
  257. gluPerspective(45,RENDER_WIDTH/RENDER_HEIGHT,10,40000);
  258. glMatrixMode(GL_MODELVIEW);
  259. glLoadIdentity();
  260. gluLookAt(position_x,position_y,position_z,lookAt_x,lookAt_y,lookAt_z,0,1,0);
  261. }
  262.  
  263.  
  264. // This update only change the position of the light.
  265. //int elapsedTimeCounter = 0;
  266. void update(void)
  267. {
  268. //printf("%d\n",glutGet(GLUT_ELAPSED_TIME));
  269. p_light[0] = light_mvnt * cos(glutGet(GLUT_ELAPSED_TIME)/2000.0);
  270. p_light[2] = light_mvnt * sin(glutGet(GLUT_ELAPSED_TIME)/2000.0);
  271.  
  272. //p_light[0] = light_mvnt * cos(4000/1000.0);
  273. //p_light[2] = light_mvnt * sin(4000/1000.0);
  274.  
  275. //p_light[0] = light_mvnt * cos(3000/1000.0);
  276. //p_light[2] = light_mvnt * sin(3000/1000.0);
  277. }
  278.  
  279.  
  280. void setTextureMatrix(void)
  281. {
  282. static double modelView[16];
  283. static double projection[16];
  284.  
  285. // This is matrix transform every coordinate x,y,z
  286. // x = x* 0.5 + 0.5
  287. // y = y* 0.5 + 0.5
  288. // z = z* 0.5 + 0.5
  289. // Moving from unit cube [-1,1] to [0,1]
  290. const GLdouble bias[16] = {
  291. 0.5, 0.0, 0.0, 0.0,
  292. 0.0, 0.5, 0.0, 0.0,
  293. 0.0, 0.0, 0.5, 0.0,
  294. 0.5, 0.5, 0.5, 1.0};
  295.  
  296. // Grab modelview and transformation matrices
  297. glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
  298. glGetDoublev(GL_PROJECTION_MATRIX, projection);
  299.  
  300.  
  301. glMatrixMode(GL_TEXTURE);
  302. glActiveTextureARB(GL_TEXTURE7);
  303.  
  304. glLoadIdentity();
  305. glLoadMatrixd(bias);
  306.  
  307. // concatating all matrice into one.
  308. glMultMatrixd (projection);
  309. glMultMatrixd (modelView);
  310.  
  311. // Go back to normal matrix mode
  312. glMatrixMode(GL_MODELVIEW);
  313. }
  314.  
  315. // During translation, we also have to maintain the GL_TEXTURE8, used in the shadow shader
  316. // to determine if a vertex is in the shadow.
  317. void startTranslate(float x,float y,float z)
  318. {
  319. glPushMatrix();
  320. glTranslatef(x,y,z);
  321.  
  322. glMatrixMode(GL_TEXTURE);
  323. glActiveTextureARB(GL_TEXTURE7);
  324. glPushMatrix();
  325. glTranslatef(x,y,z);
  326. }
  327.  
  328. void endTranslate()
  329. {
  330. glPopMatrix();
  331. glMatrixMode(GL_MODELVIEW);
  332. glPopMatrix();
  333. }
  334.  
  335. void drawObjects(void)
  336. {
  337. // Ground
  338. glColor4f(0.3f,0.3f,0.3f,1);
  339. glBegin(GL_QUADS);
  340. glVertex3f(-45,2,-45);
  341. glVertex3f(-45,2, 55);
  342. glVertex3f( 55,2, 55);
  343. glVertex3f( 55,2,-45);
  344. glEnd();
  345.  
  346. glColor4f(0.9f,0.9f,0.9f,1);
  347.  
  348. // Instead of calling glTranslatef, we need a custom function that also maintain the light matrix
  349. startTranslate(0,4,-16);
  350. glutSolidCube(4);
  351. endTranslate();
  352.  
  353. startTranslate(0,4,-5);
  354. //glutSolidCube(4);
  355. glutSolidSphere(4,40,40);
  356. endTranslate();
  357.  
  358.  
  359. }
  360.  
  361. void renderScene(void)
  362. {
  363. update();
  364.  
  365. //First step: Render from the light POV to a FBO, story depth values only
  366. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId); //Rendering offscreen
  367.  
  368. //Using the fixed pipeline to render to the depthbuffer
  369. glUseProgramObjectARB(0);
  370.  
  371. // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly.
  372. glViewport(0,0,RENDER_WIDTH * SHADOW_MAP_RATIO,RENDER_HEIGHT* SHADOW_MAP_RATIO);
  373.  
  374. // Clear previous frame values
  375. glClear( GL_DEPTH_BUFFER_BIT);
  376.  
  377. //Disable color rendering, we only want to write to the Z-Buffer
  378. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  379.  
  380. setupMatrices(p_light[0],p_light[1],p_light[2],l_light[0],l_light[1],l_light[2]);
  381.  
  382. // Culling switching, rendering only backface, this is done to avoid self-shadowing
  383. glCullFace(GL_FRONT);
  384. drawObjects();
  385.  
  386. //Save modelview/projection matrice into texture7, also add a biais
  387. setTextureMatrix();
  388.  
  389.  
  390. // Now rendering from the camera POV, using the FBO to generate shadows
  391. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
  392.  
  393. glViewport(0,0,RENDER_WIDTH,RENDER_HEIGHT);
  394.  
  395. //Enabling color write (previously disabled for light POV z-buffer rendering)
  396. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  397.  
  398. // Clear previous frame values
  399. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  400.  
  401. //Using the shadow shader
  402. glUseProgramObjectARB(shadowShaderId);
  403. glUniform1iARB(shadowMapUniform,7);
  404. glUniform1fARB(shadowMapStepXUniform,1.0/ (RENDER_WIDTH * SHADOW_MAP_RATIO));
  405. glUniform1fARB(shadowMapStepYUniform,1.0/ (RENDER_HEIGHT * SHADOW_MAP_RATIO));
  406. glActiveTextureARB(GL_TEXTURE7);
  407. glBindTexture(GL_TEXTURE_2D,depthTextureId);
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414. setupMatrices(p_camera[0],p_camera[1],p_camera[2],l_camera[0],l_camera[1],l_camera[2]);
  415.  
  416. glCullFace(GL_BACK);
  417. drawObjects();
  418.  
  419. // DEBUG only. this piece of code draw the depth buffer onscreen
  420. /*
  421. glUseProgramObjectARB(0);
  422. glMatrixMode(GL_PROJECTION);
  423. glLoadIdentity();
  424. glOrtho(-RENDER_WIDTH/2,RENDER_WIDTH/2,-RENDER_HEIGHT/2,RENDER_HEIGHT/2,1,20);
  425. glMatrixMode(GL_MODELVIEW);
  426. glLoadIdentity();
  427. glColor4f(1,1,1,1);
  428. glActiveTextureARB(GL_TEXTURE0);
  429. glBindTexture(GL_TEXTURE_2D,depthTextureId);
  430. glEnable(GL_TEXTURE_2D);
  431. glTranslated(0,0,-1);
  432. glBegin(GL_QUADS);
  433. glTexCoord2d(0,0);glVertex3f(0,0,0);
  434. glTexCoord2d(1,0);glVertex3f(RENDER_WIDTH/2,0,0);
  435. glTexCoord2d(1,1);glVertex3f(RENDER_WIDTH/2,RENDER_HEIGHT/2,0);
  436. glTexCoord2d(0,1);glVertex3f(0,RENDER_HEIGHT/2,0);
  437.  
  438.  
  439. glEnd();
  440. glDisable(GL_TEXTURE_2D);
  441. */
  442.  
  443. glutSwapBuffers();
  444. }
  445.  
  446. void processNormalKeys(unsigned char key, int x, int y) {
  447.  
  448. if (key == 27)
  449. exit(0);
  450. }
  451.  
  452.  
  453. int main(int argc, char** argv)
  454. {
  455. glutInit(&argc, argv);
  456. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
  457. glutInitWindowPosition(100,100);
  458. glutInitWindowSize(RENDER_WIDTH,RENDER_HEIGHT);
  459. glutCreateWindow("GLSL Shadow mapping");
  460.  
  461. // This call will grab openGL extension function pointers.
  462. // This is not necessary for macosx and linux
  463. #ifdef _WIN32
  464. getOpenGLFunctionPointers();
  465. #endif
  466. generateShadowFBO();
  467. loadShadowShader();
  468.  
  469. // This is important, if not here, FBO's depthbuffer won't be populated.
  470. glEnable(GL_DEPTH_TEST);
  471. glClearColor(0,0,0,1.0f);
  472.  
  473. glEnable(GL_CULL_FACE);
  474.  
  475. glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
  476.  
  477.  
  478.  
  479.  
  480. glutDisplayFunc(renderScene);
  481. glutIdleFunc(renderScene);
  482.  
  483. glutKeyboardFunc(processNormalKeys);
  484.  
  485. glutMainLoop();
  486. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement