Guest User

Untitled

a guest
Dec 12th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.09 KB | None | 0 0
  1. /*
  2. Copyright (C) 2010 COR Entertainment, LLC.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19. */
  20.  
  21. #ifdef HAVE_CONFIG_H
  22. #include "config.h"
  23. #endif
  24.  
  25. #include "r_local.h"
  26. #include "r_ragdoll.h"
  27. #include <GL/gl.h>
  28.  
  29. extern void MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
  30.  
  31. // GL_EXT_framebuffer_object
  32. GLboolean(APIENTRY * qglIsRenderbufferEXT) (GLuint renderbuffer);
  33. void (APIENTRY * qglBindRenderbufferEXT) (GLenum target, GLuint renderbuffer);
  34. void (APIENTRY * qglDeleteRenderbuffersEXT) (GLsizei n, const GLuint * renderbuffers);
  35. void (APIENTRY * qglGenRenderbuffersEXT) (GLsizei n, GLuint * renderbuffers);
  36. void (APIENTRY * qglRenderbufferStorageEXT) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
  37. void (APIENTRY * qglGetRenderbufferParameterivEXT) (GLenum target, GLenum pname, GLint * params);
  38.  
  39. GLboolean(APIENTRY * qglIsFramebufferEXT) (GLuint framebuffer);
  40. void (APIENTRY * qglBindFramebufferEXT) (GLenum target, GLuint framebuffer);
  41. void (APIENTRY * qglDeleteFramebuffersEXT) (GLsizei n, const GLuint * framebuffers);
  42. void (APIENTRY * qglGenFramebuffersEXT) (GLsizei n, GLuint * framebuffers);
  43.  
  44. GLenum(APIENTRY * qglCheckFramebufferStatusEXT) (GLenum target);
  45. void (APIENTRY * qglFramebufferTexture1DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
  46. GLint level);
  47. void (APIENTRY * qglFramebufferTexture2DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
  48. GLint level);
  49. void (APIENTRY * qglFramebufferTexture3DEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
  50. GLint level, GLint zoffset);
  51. void (APIENTRY * qglFramebufferRenderbufferEXT) (GLenum target, GLenum attachment, GLenum renderbuffertarget,
  52. GLuint renderbuffer);
  53. void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT) (GLenum target, GLenum attachment, GLenum pname,
  54. GLint * params);
  55. void (APIENTRY * qglGenerateMipmapEXT) (GLenum target);
  56.  
  57. // GL_EXT_framebuffer_blit
  58. void (APIENTRY * qglBlitFramebufferEXT) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
  59.  
  60. GLuint fboId[3];
  61. GLuint rboId;
  62.  
  63. void getOpenGLFunctionPointers(void)
  64. {
  65. // FBO
  66. qglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) qwglGetProcAddress("glGenFramebuffersEXT");
  67. qglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) qwglGetProcAddress("glBindFramebufferEXT");
  68. qglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) qwglGetProcAddress("glFramebufferTexture2DEXT");
  69. qglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) qwglGetProcAddress("glCheckFramebufferStatusEXT");
  70. qglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)qwglGetProcAddress("glGenRenderbuffersEXT");
  71. qglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)qwglGetProcAddress("glBindRenderbufferEXT");
  72. qglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)qwglGetProcAddress("glRenderbufferStorageEXT");
  73. qglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)qwglGetProcAddress("glFramebufferRenderbufferEXT");
  74. qglBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)qwglGetProcAddress("glBlitFramebufferEXT");
  75. }
  76.  
  77. //used for post process stencil volume blurring and shadowmapping
  78. void R_GenerateShadowFBO()
  79. {
  80. int shadowMapWidth = vid.width * r_shadowmapratio->value;
  81. int shadowMapHeight = vid.height * r_shadowmapratio->value;
  82. GLenum FBOstatus;
  83.  
  84. gl_state.fbo = true;
  85.  
  86. getOpenGLFunctionPointers();
  87.  
  88. if(!qglGenFramebuffersEXT || !qglBindFramebufferEXT || !qglFramebufferTexture2DEXT || !qglCheckFramebufferStatusEXT
  89. || !qglGenRenderbuffersEXT || !qglBindRenderbufferEXT || !qglRenderbufferStorageEXT || !qglFramebufferRenderbufferEXT)
  90. {
  91. Com_Printf("...GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n");
  92. gl_state.fbo = false;
  93. return;
  94. }
  95.  
  96. // Framebuffer object blit
  97. gl_state.hasFBOblit = false;
  98. if (strstr(gl_config.extensions_string, "GL_EXT_framebuffer_blit"))
  99. {
  100. Com_Printf("...using GL_EXT_framebuffer_blit\n");
  101. gl_state.hasFBOblit = true;
  102. } else
  103. {
  104. Com_Printf("...GL_EXT_framebuffer_blit not found\n");
  105. gl_state.hasFBOblit = false;
  106. }
  107.  
  108. //FBO for shadowmapping
  109. qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum);
  110.  
  111. // GL_LINEAR does not make sense for depth texture.
  112. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  113. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  114.  
  115. // Remove artefact on the edges of the shadowmap
  116. qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  117. qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  118.  
  119. // This is to allow usage of shadow2DProj function in the shader
  120. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
  121. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  122. qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
  123.  
  124. // No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available
  125. qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
  126. qglBindTexture(GL_TEXTURE_2D, 0);
  127.  
  128. // create a framebuffer object
  129. qglGenFramebuffersEXT(1, &fboId[0]);
  130.  
  131. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[0]);
  132.  
  133. // Instruct openGL that we won't bind a color texture with the currently binded FBO
  134. qglDrawBuffer(GL_NONE);
  135. qglReadBuffer(GL_NONE);
  136.  
  137. // attach the texture to FBO depth attachment point
  138. qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture->texnum, 0);
  139.  
  140. // check FBO status
  141. FBOstatus = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  142. if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
  143. {
  144. Com_Printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n");
  145. gl_state.fbo = false;
  146. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  147. }
  148.  
  149. //Second FBO for shadowmapping
  150. qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum);
  151.  
  152. // GL_LINEAR does not make sense for depth texture.
  153. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  154. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  155.  
  156. // Remove artefact on the edges of the shadowmap
  157. qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  158. qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  159.  
  160. // This is to allow usage of shadow2DProj function in the shader
  161. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
  162. qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  163. qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
  164.  
  165. // No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available
  166. qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
  167. qglBindTexture(GL_TEXTURE_2D, 0);
  168.  
  169. // create a framebuffer object
  170. qglGenFramebuffersEXT(1, &fboId[1]);
  171.  
  172. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[1]);
  173.  
  174. // Instruct openGL that we won't bind a color texture with the currently binded FBO
  175. qglDrawBuffer(GL_NONE);
  176. qglReadBuffer(GL_NONE);
  177.  
  178. // attach the texture to FBO depth attachment point
  179. qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0);
  180.  
  181. // check FBO status
  182. FBOstatus = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  183. if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
  184. {
  185. Com_Printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n");
  186. gl_state.fbo = false;
  187. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  188. }
  189.  
  190. //FBO for capturing stencil volumes
  191.  
  192. //must check for abilit to blit(Many old ATI drivers do not support)
  193. if(gl_state.hasFBOblit) {
  194. if(!qglBlitFramebufferEXT) {
  195. Com_Printf("qglBlitFramebufferEXT not found...\n");
  196. //no point in continuing on
  197. gl_state.hasFBOblit = false;
  198. return;
  199. }
  200. }
  201.  
  202. qglBindTexture(GL_TEXTURE_2D, r_colorbuffer->texnum);
  203. qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.width, vid.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  204. qglBindTexture(GL_TEXTURE_2D, 0);
  205.  
  206. qglGenFramebuffersEXT(1, &fboId[2]);
  207. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]);
  208.  
  209. qglGenRenderbuffersEXT(1, &rboId);
  210. qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
  211. qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, vid.width, vid.height);
  212. qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
  213.  
  214. // attach a texture to FBO color attachement point
  215. qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, r_colorbuffer->texnum, 0);
  216.  
  217. // attach a renderbuffer to depth attachment point
  218. qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId);
  219.  
  220. // attach a renderbuffer to stencil attachment point
  221. qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId);
  222.  
  223. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]);
  224.  
  225. // check FBO status
  226. FBOstatus = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  227. if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
  228. Com_Printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use secondary FBO\n");
  229.  
  230. // switch back to window-system-provided framebuffer
  231. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  232. }
  233.  
  234. #define M3D_INV_PI_DIV_180 (57.2957795130823229)
  235. #define m3dRadToDeg(x) ((x)*M3D_INV_PI_DIV_180)
  236.  
  237. static void normalize( float vec[3] )
  238. {
  239. float len;
  240. len = sqrt( vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] );
  241. if ( len > 0 ) {
  242. vec[0] /= len;
  243. vec[1] /= len;
  244. vec[2] /= len;
  245. }
  246. }
  247.  
  248. static void cross( float result[3] , float v1[3] , float v2[3] )
  249. {
  250. result[0] = v1[1] * v2[2] - v1[2] * v2[1];
  251. result[1] = v1[2] * v2[0] - v1[0] * v2[2];
  252. result[2] = v1[0] * v2[1] - v1[1] * v2[0];
  253. }
  254.  
  255.  
  256. static void lookAt( float position_x , float position_y , float position_z , float lookAt_x , float lookAt_y , float lookAt_z )
  257. {
  258. float forward[3] , side[3] , up[3];
  259. float matrix[4][4];
  260. int i;
  261.  
  262. // forward = normalized( lookAt - position )
  263. forward[0] = lookAt_x - position_x;
  264. forward[1] = lookAt_y - position_y;
  265. forward[2] = lookAt_z - position_z;
  266. normalize( forward );
  267.  
  268. // side = normalized( forward x [0;1;0] )
  269. side[0] = -forward[2];
  270. side[1] = 0;
  271. side[2] = forward[0];
  272. normalize( side );
  273.  
  274. // up = side x forward
  275. cross( up , side , forward );
  276.  
  277. // Build matrix
  278. for ( i = 0 ; i < 3 ; i ++ ) {
  279. matrix[i][0] = side[i];
  280. matrix[i][1] = up[i];
  281. matrix[i][2] = - forward[i];
  282. }
  283. for ( i = 0 ; i < 3 ; i ++ )
  284. matrix[i][3] = matrix[3][i] = 0;
  285. matrix[3][3] = 1;
  286.  
  287. qglMultMatrixf( (const GLfloat *) &matrix[0][0] );
  288. qglTranslated( -position_x , -position_y , -position_z );
  289. }
  290.  
  291. void SM_SetupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z)
  292. {
  293.  
  294. qglMatrixMode(GL_PROJECTION);
  295. qglLoadIdentity();
  296. MYgluPerspective(120.0f, vid.width/vid.height, 10.0f, 4096.0f);
  297. qglMatrixMode(GL_MODELVIEW);
  298. qglLoadIdentity();
  299. lookAt( position_x , position_y , position_z , lookAt_x , lookAt_y , lookAt_z );
  300. }
  301.  
  302. void SM_SetTextureMatrix( qboolean mapnum )
  303. {
  304. static double modelView[16];
  305. static double projection[16];
  306.  
  307. // Moving from unit cube [-1,1] to [0,1]
  308. const GLdouble bias[16] = {
  309. 0.5, 0.0, 0.0, 0.0,
  310. 0.0, 0.5, 0.0, 0.0,
  311. 0.0, 0.0, 0.5, 0.0,
  312. 0.5, 0.5, 0.5, 1.0};
  313.  
  314. // Grab modelview and transformation matrices
  315. qglGetDoublev(GL_MODELVIEW_MATRIX, modelView);
  316. qglGetDoublev(GL_PROJECTION_MATRIX, projection);
  317.  
  318. qglMatrixMode(GL_TEXTURE);
  319. if(mapnum)
  320. {
  321. qglActiveTextureARB(GL_TEXTURE6);
  322. qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum);
  323. }
  324. else
  325. {
  326. qglActiveTextureARB(GL_TEXTURE7);
  327. qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum);
  328. }
  329.  
  330. qglLoadIdentity();
  331. qglLoadMatrixd(bias);
  332.  
  333. // concatating all matrice into one.
  334. qglMultMatrixd (projection);
  335. qglMultMatrixd (modelView);
  336.  
  337. // Go back to normal matrix mode
  338. qglMatrixMode(GL_MODELVIEW);
  339.  
  340. qglActiveTextureARB(GL_TEXTURE0);
  341.  
  342. }
  343.  
  344. static int r_shadowframecount = 0;
  345.  
  346. /*
  347. ================
  348. SM_RecursiveWorldNode - this variant of the classic routine renders both sides for shadowing
  349. ================
  350. */
  351.  
  352. void SM_RecursiveWorldNode (mnode_t *node, int clipflags)
  353. {
  354. int c;
  355. msurface_t *surf, **mark;
  356. mleaf_t *pleaf;
  357.  
  358. if (node->contents == CONTENTS_SOLID)
  359. return; // solid
  360.  
  361. if (node->visframe != r_visframecount)
  362. return;
  363.  
  364. if (!r_nocull->value)
  365. {
  366. int i, clipped;
  367. cplane_t *clipplane;
  368.  
  369. for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++)
  370. {
  371. if (!(clipflags & (1<<i)))
  372. continue;
  373. clipped = BoxOnPlaneSide (node->minmaxs, node->minmaxs+3, clipplane);
  374.  
  375. if (clipped == 1)
  376. clipflags &= ~(1<<i); // node is entirely on screen
  377. else if (clipped == 2)
  378. return; // fully clipped
  379. }
  380. }
  381.  
  382. // if a leaf node, draw stuff
  383. if (node->contents != -1)
  384. {
  385. pleaf = (mleaf_t *)node;
  386.  
  387. // check for door connected areas
  388. if (r_newrefdef.areabits)
  389. {
  390. if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
  391. return; // not visible
  392. }
  393.  
  394. mark = pleaf->firstmarksurface;
  395. if (! (c = pleaf->nummarksurfaces) )
  396. return;
  397.  
  398. do
  399. {
  400. (*mark++)->visframe = r_shadowframecount;
  401. } while (--c);
  402.  
  403. return;
  404. }
  405.  
  406. // recurse down the children, front side first
  407. SM_RecursiveWorldNode (node->children[0], clipflags);
  408.  
  409. // draw stuff
  410. for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
  411. {
  412. if (surf->visframe != r_shadowframecount)
  413. continue;
  414.  
  415. if (R_CullBox (surf->mins, surf->maxs))
  416. continue;
  417.  
  418. if (surf->texinfo->flags & SURF_SKY)
  419. { // no skies here
  420. continue;
  421. }
  422. else if (SurfaceIsTranslucent(surf) && !SurfaceIsAlphaBlended(surf))
  423. { // no trans surfaces
  424. continue;
  425. }
  426. else
  427. {
  428. if (!( surf->flags & SURF_DRAWTURB ) )
  429. {
  430. BSP_DrawTexturelessPoly (surf);
  431. }
  432. }
  433. }
  434.  
  435. // recurse down the back side
  436. SM_RecursiveWorldNode (node->children[1], clipflags);
  437. }
  438.  
  439.  
  440. inline float point_dist_from_plane (cplane_t *plane, vec3_t point)
  441. {
  442. switch (plane->type)
  443. {
  444. case PLANE_X:
  445. return point[0] - plane->dist;
  446. case PLANE_Y:
  447. return point[1] - plane->dist;
  448. case PLANE_Z:
  449. return point[2] - plane->dist;
  450. default:
  451. return DotProduct (point, plane->normal) - plane->dist;
  452. }
  453. }
  454.  
  455. /*
  456. ================
  457. SM_RecursiveWorldNode2 - this variant of the classic routine renders only one side for shadowing
  458. ================
  459. */
  460.  
  461. void SM_RecursiveWorldNode2 (mnode_t *node, int clipflags, vec3_t origin, vec3_t absmins, vec3_t absmaxs)
  462. {
  463. int c;
  464. float dist, dist_model, dist_light;
  465. int side, side_model, side_light, side_model_flags = 0;
  466. cplane_t *plane;
  467. msurface_t *surf, **mark;
  468. mleaf_t *pleaf;
  469.  
  470. if (node->contents == CONTENTS_SOLID)
  471. return; // solid
  472.  
  473. if (node->visframe != r_visframecount)
  474. return;
  475.  
  476. if (!r_nocull->value)
  477. {
  478. int i, clipped;
  479. cplane_t *clipplane;
  480.  
  481. for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++)
  482. {
  483. if (!(clipflags & (1<<i)))
  484. continue;
  485. clipped = BoxOnPlaneSide (node->minmaxs, node->minmaxs+3, clipplane);
  486.  
  487. if (clipped == 1)
  488. clipflags &= ~(1<<i); // node is entirely on screen
  489. else if (clipped == 2)
  490. return; // fully clipped
  491. }
  492. }
  493.  
  494. // if a leaf node, draw stuff
  495. if (node->contents != -1)
  496. {
  497. pleaf = (mleaf_t *)node;
  498.  
  499. // check for door connected areas
  500. if (r_newrefdef.areabits)
  501. {
  502. if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
  503. return; // not visible
  504. }
  505.  
  506. mark = pleaf->firstmarksurface;
  507. if (! (c = pleaf->nummarksurfaces) )
  508. return;
  509.  
  510. do
  511. {
  512. (*mark++)->visframe = r_shadowframecount;
  513. } while (--c);
  514.  
  515. return;
  516. }
  517.  
  518. // node is just a decision point, so go down the apropriate sides
  519.  
  520. // find which side of the node we are on
  521. plane = node->plane;
  522.  
  523. dist = point_dist_from_plane (plane, r_origin);
  524. dist_model = point_dist_from_plane (plane, origin);
  525. dist_light = point_dist_from_plane (plane, statLightPosition);
  526.  
  527. side = dist < 0;
  528. side_model = dist_model < 0;
  529. side_light = dist_light < 0;
  530.  
  531. dist = fabs (dist);
  532. dist_model = fabs (dist_model);
  533. dist_light = fabs (dist_light);
  534.  
  535. if (side != side_model && side_light != side)
  536. if (dist_light < dist_model)
  537. goto skip_draw;
  538. if (side != side_model && side_light == side)
  539. if ((side_model_flags = BoxOnPlaneSide (absmins, absmaxs, plane)) != 3)
  540. goto skip_draw;
  541.  
  542. // recurse down the children, front side first
  543. SM_RecursiveWorldNode2 (node->children[side], clipflags, origin, absmins, absmaxs);
  544.  
  545. // draw stuff
  546. for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
  547. {
  548. if (surf->visframe != r_shadowframecount)
  549. continue;
  550.  
  551. if (R_CullBox (surf->mins, surf->maxs))
  552. continue;
  553.  
  554. if (surf->texinfo->flags & SURF_SKY)
  555. { // no skies here
  556. continue;
  557. }
  558. else if (SurfaceIsTranslucent(surf) || SurfaceIsAlphaBlended(surf))
  559. { // no trans surfaces
  560. continue;
  561. }
  562. else
  563. {
  564. if (!( surf->flags & SURF_DRAWTURB ) )
  565. {
  566. BSP_DrawShadowPoly (surf, origin);
  567. }
  568. }
  569. }
  570.  
  571. if (side == side_model && side == side_light)
  572. if (dist_light < dist_model)
  573. return;
  574. if (side == side_model && side != side_light && side_model_flags != 3)
  575. return;
  576.  
  577. skip_draw:
  578.  
  579. // recurse down the back side
  580. SM_RecursiveWorldNode2 (node->children[!side], clipflags, origin, absmins, absmaxs);
  581. }
  582.  
  583.  
  584. /*
  585. =============
  586. R_DrawWorld
  587. =============
  588. */
  589.  
  590. void R_DrawShadowMapWorld (qboolean forEnt, vec3_t origin)
  591. {
  592. int i;
  593.  
  594. if (!r_drawworld->value)
  595. return;
  596.  
  597. if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
  598. return;
  599.  
  600. if(forEnt)
  601. {
  602. vec3_t absmins, absmaxs;
  603.  
  604. glUseProgramObjectARB( g_shadowprogramObj );
  605.  
  606. glUniform1iARB( g_location_entShadow, 6);
  607. qglActiveTextureARB(GL_TEXTURE6);
  608. qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum);
  609.  
  610. glUniform1fARB( g_location_xOffset, 1.0/(viddef.width*r_shadowmapratio->value));
  611. glUniform1fARB( g_location_yOffset, 1.0/(viddef.height*r_shadowmapratio->value));
  612.  
  613. glUniform1fARB( g_location_fadeShadow, fadeShadow );
  614.  
  615. R_InitVArrays(VERT_NO_TEXTURE);
  616.  
  617. VectorAdd (currentmodel->mins, origin, absmins);
  618. VectorAdd (currentmodel->maxs, origin, absmaxs);
  619.  
  620. r_shadowframecount++;
  621.  
  622. SM_RecursiveWorldNode2 (r_worldmodel->nodes, 15, origin, absmins, absmaxs);
  623.  
  624. R_KillVArrays();
  625.  
  626. glUseProgramObjectARB( 0 );
  627.  
  628. qglActiveTextureARB(GL_TEXTURE0);
  629.  
  630. return;
  631. }
  632. else
  633. {
  634. R_InitVArrays(VERT_NO_TEXTURE);
  635.  
  636. r_shadowframecount++;
  637.  
  638. SM_RecursiveWorldNode (r_worldmodel->nodes, 15);
  639.  
  640. R_KillVArrays();
  641.  
  642. //draw brush models(not for ent shadow, for now)
  643. for (i=0 ; i<r_newrefdef.num_entities ; i++)
  644. {
  645. currententity = &r_newrefdef.entities[i];
  646. if (currententity->flags & RF_TRANSLUCENT)
  647. continue; // transluscent
  648.  
  649. currentmodel = currententity->model;
  650.  
  651. if (!currentmodel)
  652. {
  653. continue;
  654. }
  655. if( currentmodel->type == mod_brush)
  656. BSP_DrawTexturelessBrushModel (currententity);
  657. else
  658. continue;
  659. }
  660. }
  661. }
  662.  
  663. #include "r_lodcalc.h"
  664.  
  665. void R_DrawDynamicCaster(void)
  666. {
  667. int i;
  668. vec3_t dist, mins, maxs;
  669. trace_t r_trace;
  670. int RagDollID;
  671. vec3_t origin = {0, 0, 0};
  672.  
  673. VectorSet(mins, 0, 0, 0);
  674. VectorSet(maxs, 0, 0, 0);
  675.  
  676. r_shadowmapcount = 0;
  677.  
  678. if(!dynLight)
  679. return; //we have no lights of consequence
  680.  
  681. qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum);
  682.  
  683. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[0]);
  684.  
  685. // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly.
  686. qglViewport(0,0,(int)(vid.width * r_shadowmapratio->value),(int)(vid.height * r_shadowmapratio->value));
  687.  
  688. // Clear previous frame values
  689. qglClear( GL_DEPTH_BUFFER_BIT);
  690.  
  691. //Disable color rendering, we only want to write to the Z-Buffer
  692. qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  693.  
  694. // Culling switching, rendering only frontfaces
  695. qglCullFace(GL_BACK);
  696.  
  697. // attach the texture to FBO depth attachment point
  698. qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture->texnum, 0);
  699.  
  700. //set camera
  701. SM_SetupMatrices(dynLight->origin[0],dynLight->origin[1],dynLight->origin[2]+64,dynLight->origin[0],dynLight->origin[1],dynLight->origin[2]-128);
  702.  
  703. qglEnable( GL_POLYGON_OFFSET_FILL );
  704. qglPolygonOffset( 0.5f, 0.5f );
  705.  
  706. //render world - very basic geometry
  707. R_DrawShadowMapWorld(false, origin);
  708.  
  709. //render entities near light
  710. for (i=0 ; i<r_newrefdef.num_entities ; i++)
  711. {
  712. currententity = &r_newrefdef.entities[i];
  713.  
  714. if (currententity->flags & RF_NOSHADOWS || currententity->flags & RF_TRANSLUCENT)
  715. continue;
  716.  
  717. if(!currententity->model)
  718. continue;
  719.  
  720. if (currententity->model->type != mod_alias && currententity->model->type != mod_iqm)
  721. {
  722. continue;
  723. }
  724.  
  725. if(r_ragdolls->value && currententity->model->type == mod_iqm && currententity->model->hasRagDoll)
  726. {
  727. if(currententity->frame > 198)
  728. continue;
  729. }
  730.  
  731. //distance from light, if too far, don't render(to do - check against brightness for dist!)
  732. VectorSubtract(dynLight->origin, currententity->origin, dist);
  733. if(VectorLength(dist) > 256.0f)
  734. continue;
  735.  
  736. //trace visibility from light - we don't render objects the light doesn't hit!
  737. r_trace = CM_BoxTrace(dynLight->origin, currententity->origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE);
  738. if(r_trace.fraction != 1.0)
  739. continue;
  740.  
  741. currentmodel = currententity->model;
  742.  
  743. //get distance
  744. VectorSubtract(r_origin, currententity->origin, dist);
  745.  
  746. //set lod if available
  747. if(VectorLength(dist) > LOD_DIST*(3.0/5.0))
  748. {
  749. if(currententity->lod2)
  750. currentmodel = currententity->lod2;
  751. }
  752. else if(VectorLength(dist) > LOD_DIST*(1.0/5.0))
  753. {
  754. if(currententity->lod1)
  755. currentmodel = currententity->lod1;
  756. }
  757. if (currententity->lod2)
  758. currentmodel = currententity->lod2;
  759.  
  760. if(currentmodel->type == mod_iqm)
  761. IQM_DrawCaster ();
  762. else
  763. MD2_DrawCaster ();
  764. }
  765.  
  766. for(RagDollID = 0; RagDollID < MAX_RAGDOLLS; RagDollID++)
  767. {
  768. if(RagDoll[RagDollID].destroyed)
  769. continue;
  770.  
  771. //distance from light, if too far, don't render(to do - check against brightness for dist!)
  772. VectorSubtract(dynLight->origin, RagDoll[RagDollID].curPos, dist);
  773. if(VectorLength(dist) > 256.0f)
  774. continue;
  775.  
  776. //trace visibility from light - we don't render objects the light doesn't hit!
  777. r_trace = CM_BoxTrace(dynLight->origin, RagDoll[RagDollID].curPos, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE);
  778. if(r_trace.fraction != 1.0)
  779. continue;
  780.  
  781. IQM_DrawRagDollCaster (RagDollID);
  782. }
  783.  
  784. SM_SetTextureMatrix(0);
  785.  
  786. r_shadowmapcount = 1;
  787.  
  788. dynLight = NULL; //done with dynamic light shadows for this frame
  789.  
  790. qglDepthMask (1); // back to writing
  791.  
  792. qglPolygonOffset( 0.0f, 0.0f );
  793. qglDisable( GL_POLYGON_OFFSET_FILL );
  794.  
  795. }
  796.  
  797. void R_Vectoangles (vec3_t value1, vec3_t angles)
  798. {
  799. float forward;
  800. float yaw, pitch;
  801.  
  802. if (value1[1] == 0.0f && value1[0] == 0.0f )
  803. {
  804. yaw = 0.0f;
  805. if (value1[2] > 0.0f)
  806. pitch = 90.0f;
  807. else
  808. pitch = 270.0f;
  809. }
  810. else
  811. {
  812. // PMM - fixed to correct for pitch of 0
  813. if (value1[0])
  814. yaw = (atan2(value1[1], value1[0]) * 180.0f / M_PI);
  815. else if (value1[1] > 0)
  816. yaw = 90.0f;
  817. else
  818. yaw = 270.0f;
  819.  
  820. if (yaw < 0.0f)
  821. yaw += 360.0f;
  822.  
  823. forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
  824. pitch = (atan2(value1[2], forward) * 180.0f / M_PI);
  825. if (pitch < 0.0f)
  826. pitch += 360.0f;
  827. }
  828.  
  829. angles[PITCH] = -pitch;
  830. angles[YAW] = yaw;
  831. angles[ROLL] = 0.0f;
  832. }
  833.  
  834. void R_DrawVegetationCasters ( qboolean forShadows )
  835. {
  836. int i, k;
  837. grass_t *grass;
  838. float scale;
  839. vec3_t dir, origin, mins, maxs, angle, right, up, corner[4];
  840. float *corner0 = corner[0];
  841. qboolean visible;
  842. trace_t r_trace;
  843. float sway;
  844.  
  845. if(r_newrefdef.rdflags & RDF_NOWORLDMODEL)
  846. return;
  847.  
  848. grass = r_grasses;
  849.  
  850. VectorSet(mins, 0, 0, 0);
  851. VectorSet(maxs, 0, 0, 0);
  852.  
  853. R_InitVArrays (VERT_SINGLE_TEXTURED);
  854.  
  855. for (i=0; i<r_numgrasses; i++, grass++)
  856. {
  857. if(!grass->type)
  858. continue; //only deal with leaves, grass shadows look kind of bad
  859.  
  860. scale = 10.0*grass->size;
  861.  
  862. VectorSubtract(r_sunLight->origin, r_sunLight->target, dir);
  863. R_Vectoangles(dir, angle);
  864.  
  865. AngleVectors(angle, NULL, right, up);
  866. VectorScale(right, scale, right);
  867. VectorScale(up, scale, up);
  868. VectorCopy(grass->origin, origin);
  869.  
  870. // adjust vertical position, scaled
  871. origin[2] += (grass->texsize/32) * grass->size;
  872.  
  873. //cull for pathline to sunlight
  874. r_trace = CM_BoxTrace(r_sunLight->origin, origin, maxs, mins, r_worldmodel->firstnode, MASK_VISIBILILITY);
  875. visible = r_trace.fraction == 1.0;
  876.  
  877. if(visible)
  878. {
  879. //render grass polygon
  880.  
  881. GL_SelectTexture( GL_TEXTURE0);
  882. qglBindTexture (GL_TEXTURE_2D, grass->texnum);
  883.  
  884. GLSTATE_ENABLE_ALPHATEST
  885.  
  886. qglColor4f( 0, 0, 0, 1 );
  887.  
  888. VectorSet (corner[0],
  889. origin[0] + (up[0] + right[0])*(-0.5),
  890. origin[1] + (up[1] + right[1])*(-0.5),
  891. origin[2] + (up[2] + right[2])*(-0.5));
  892.  
  893. sway = 3;
  894.  
  895. VectorSet ( corner[1],
  896. corner0[0] + up[0] + sway*sin (rs_realtime*sway),
  897. corner0[1] + up[1] + sway*sin (rs_realtime*sway),
  898. corner0[2] + up[2]);
  899.  
  900. VectorSet ( corner[2],
  901. corner0[0] + (up[0]+right[0] + sway*sin (rs_realtime*sway)),
  902. corner0[1] + (up[1]+right[1] + sway*sin (rs_realtime*sway)),
  903. corner0[2] + (up[2]+right[2]));
  904.  
  905. VectorSet ( corner[3],
  906. corner0[0] + right[0],
  907. corner0[1] + right[1],
  908. corner0[2] + right[2]);
  909.  
  910. VArray = &VArrayVerts[0];
  911.  
  912. for(k = 0; k < 4; k++)
  913. {
  914. VArray[0] = corner[k][0];
  915. VArray[1] = corner[k][1];
  916. VArray[2] = corner[k][2];
  917.  
  918. switch(k)
  919. {
  920. case 0:
  921. VArray[3] = 1;
  922. VArray[4] = 1;
  923. break;
  924. case 1:
  925. VArray[3] = 0;
  926. VArray[4] = 1;
  927. break;
  928. case 2:
  929. VArray[3] = 0;
  930. VArray[4] = 0;
  931. break;
  932. case 3:
  933. VArray[3] = 1;
  934. VArray[4] = 0;
  935. break;
  936. }
  937.  
  938. VArray += VertexSizes[VERT_SINGLE_TEXTURED];
  939. }
  940.  
  941. R_DrawVarrays(GL_QUADS, 0, 4, false);
  942.  
  943. if(forShadows)
  944. r_shadowmapcount = 2;
  945. }
  946. }
  947.  
  948. R_KillVArrays ();
  949.  
  950. qglColor4f( 1,1,1,1 );
  951. GLSTATE_DISABLE_ALPHATEST
  952. }
  953.  
  954. void R_DrawVegetationCaster(void)
  955. {
  956. if(!r_sunLight->has_Sun || !r_hasleaves)
  957. return; //no point if there is no sun or leaves!
  958.  
  959. qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum);
  960.  
  961. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[1]);
  962.  
  963. // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly.
  964. qglViewport(0,0,(int)(vid.width * r_shadowmapratio->value),(int)(vid.height * r_shadowmapratio->value));
  965.  
  966. //Clear previous frame values
  967. qglClear( GL_DEPTH_BUFFER_BIT);
  968.  
  969. //Disable color rendering, we only want to write to the Z-Buffer
  970. qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  971.  
  972. // Culling switching, rendering only frontfaces
  973. qglDisable(GL_CULL_FACE);
  974.  
  975. // attach the texture to FBO depth attachment point
  976. qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0);
  977.  
  978. //get sun light origin and target from map info, at map load
  979. //set camera
  980. SM_SetupMatrices(r_sunLight->origin[0],r_sunLight->origin[1],r_sunLight->origin[2],r_sunLight->target[0],r_sunLight->target[1],r_sunLight->target[2]);
  981.  
  982. qglEnable( GL_POLYGON_OFFSET_FILL );
  983. qglPolygonOffset( 0.5f, 0.5f );
  984.  
  985. //render vegetation
  986. R_DrawVegetationCasters(true);
  987.  
  988. SM_SetTextureMatrix(1);
  989.  
  990. qglDepthMask (1); // back to writing
  991.  
  992. qglPolygonOffset( 0.0f, 0.0f );
  993. qglDisable( GL_POLYGON_OFFSET_FILL );
  994. qglEnable(GL_CULL_FACE);
  995. }
  996.  
  997. void R_DrawEntityCaster(entity_t *ent)
  998. {
  999. vec3_t dist, mins, maxs;
  1000. trace_t r_trace;
  1001.  
  1002. VectorSet(mins, 0, 0, 0);
  1003. VectorSet(maxs, 0, 0, 0);
  1004.  
  1005. r_shadowmapcount = 0;
  1006.  
  1007. //check caster validity
  1008. if (ent->flags & RF_NOSHADOWS || ent->flags & RF_TRANSLUCENT)
  1009. return;
  1010.  
  1011. if(!ent->model)
  1012. return;
  1013.  
  1014. if(r_ragdolls->value && ent->model->type == mod_iqm && ent->model->hasRagDoll)
  1015. {
  1016. if(ent->frame > 198)
  1017. return;
  1018. }
  1019.  
  1020. //trace visibility from light - we don't render objects the light doesn't hit!
  1021. r_trace = CM_BoxTrace(statLightPosition, ent->origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE);
  1022. if(r_trace.fraction != 1.0)
  1023. return;
  1024.  
  1025. qglMatrixMode(GL_PROJECTION);
  1026. qglPushMatrix();
  1027. qglMatrixMode(GL_MODELVIEW);
  1028. qglPushMatrix();
  1029.  
  1030. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[1]);
  1031.  
  1032. // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly.
  1033. qglViewport(0,0,(int)(vid.width * r_shadowmapratio->value),(int)(vid.height * r_shadowmapratio->value));
  1034.  
  1035. //Clear previous frame values
  1036. qglClear( GL_DEPTH_BUFFER_BIT);
  1037.  
  1038. //Disable color rendering, we only want to write to the Z-Buffer
  1039. qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  1040.  
  1041. // Culling switching, rendering only frontfaces
  1042. qglDisable(GL_CULL_FACE);
  1043.  
  1044. // attach the texture to FBO depth attachment point
  1045. qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0);
  1046.  
  1047. //get light origin
  1048. //set camera
  1049. SM_SetupMatrices(statLightPosition[0],statLightPosition[1],statLightPosition[2]+64,ent->origin[0],ent->origin[1],ent->origin[2]-128);
  1050.  
  1051. qglEnable( GL_POLYGON_OFFSET_FILL );
  1052. qglPolygonOffset( 0.5f, 0.5f );
  1053.  
  1054. //we could loop the entities here, and render any nearby models, to make sure we get shadows on the this entity if a mesh is nearby.
  1055. //this would be only if we want to do self shadowing, or have player shadows cast on other mesh objects. At this time, I think that the
  1056. //performance losses would not be worth doing this, but we can revisit.
  1057.  
  1058. currentmodel = ent->model;
  1059.  
  1060. //get view distance
  1061. VectorSubtract(r_origin, ent->origin, dist);
  1062.  
  1063. //set lod if available
  1064. if(VectorLength(dist) > LOD_DIST*(3.0/5.0))
  1065. {
  1066. if(currententity->lod2)
  1067. currentmodel = currententity->lod2;
  1068. }
  1069. else if(VectorLength(dist) > LOD_DIST*(1.0/5.0))
  1070. {
  1071. if(currententity->lod1)
  1072. currentmodel = currententity->lod1;
  1073. }
  1074. if (currententity->lod2)
  1075. currentmodel = currententity->lod2;
  1076.  
  1077. if(currentmodel->type == mod_iqm)
  1078. IQM_DrawCaster ();
  1079. else
  1080. MD2_DrawCaster ();
  1081.  
  1082. SM_SetTextureMatrix(1);
  1083.  
  1084. qglDepthMask (1); // back to writing
  1085.  
  1086. qglPolygonOffset( 0.0f, 0.0f );
  1087. qglDisable( GL_POLYGON_OFFSET_FILL );
  1088. qglEnable(GL_CULL_FACE);
  1089.  
  1090. qglViewport( 0, 0, viddef.width, viddef.height );
  1091.  
  1092. qglPopMatrix();
  1093. qglMatrixMode(GL_PROJECTION);
  1094. qglPopMatrix();
  1095. qglMatrixMode(GL_MODELVIEW);
  1096.  
  1097. r_shadowmapcount = 1;
  1098. }
  1099.  
  1100. void R_GenerateEntityShadow( void )
  1101. {
  1102. if(gl_shadowmaps->integer && gl_state.vbo && gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer)
  1103. {
  1104. vec3_t dist, tmp;
  1105. float rad, fadeshadow_cutoff;
  1106.  
  1107. if((r_newrefdef.rdflags & RDF_NOWORLDMODEL) || (currententity->flags & RF_MENUMODEL))
  1108. return;
  1109.  
  1110. if (r_newrefdef.vieworg[2] < (currententity->origin[2] - 128))
  1111. return;
  1112.  
  1113. VectorSubtract(currententity->model->maxs, currententity->model->mins, tmp);
  1114. VectorScale (tmp, 1.666, tmp);
  1115. rad = VectorLength (tmp);
  1116.  
  1117. if( R_CullSphere( currententity->origin, rad, 15 ) )
  1118. return;
  1119.  
  1120. //get view distance
  1121. VectorSubtract(r_origin, currententity->origin, dist);
  1122.  
  1123. //fade out shadows both by distance from view, and by distance from light
  1124. fadeshadow_cutoff = r_shadowcutoff->value * (LOD_DIST/LOD_BASE_DIST);
  1125.  
  1126. if (r_shadowcutoff->value < 0.1)
  1127. fadeShadow = 1.0;
  1128. else if (VectorLength (dist) > fadeshadow_cutoff)
  1129. {
  1130. fadeShadow = VectorLength(dist) - fadeshadow_cutoff;
  1131. if (fadeShadow > 512)
  1132. return;
  1133. else
  1134. fadeShadow = 1.0 - fadeShadow/512.0; //fade out smoothly over 512 units.
  1135. }
  1136. else
  1137. fadeShadow = 1.0;
  1138.  
  1139. qglEnable(GL_DEPTH_TEST);
  1140. qglClearColor(0,0,0,1.0f);
  1141.  
  1142. qglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
  1143.  
  1144. R_DrawEntityCaster(currententity);
  1145.  
  1146. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
  1147.  
  1148. //Enabling color write (previously disabled for light POV z-buffer rendering)
  1149. qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  1150.  
  1151. //re-render affected polys with shadowmap for this entity
  1152. if(r_shadowmapcount > 0)
  1153. {
  1154. qglEnable( GL_BLEND );
  1155. qglBlendFunc (GL_ZERO, GL_SRC_COLOR);
  1156.  
  1157. R_DrawShadowMapWorld(true, currententity->origin);
  1158.  
  1159. qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1160. qglDisable ( GL_BLEND );
  1161. }
  1162.  
  1163. currentmodel = currententity->model;
  1164.  
  1165. r_shadowmapcount = 0;
  1166. }
  1167. }
  1168.  
  1169. void R_DrawRagdollCaster(int RagDollID)
  1170. {
  1171. vec3_t mins, maxs;
  1172. trace_t r_trace;
  1173.  
  1174. VectorSet(mins, 0, 0, 0);
  1175. VectorSet(maxs, 0, 0, 0);
  1176.  
  1177. r_shadowmapcount = 0;
  1178.  
  1179. //trace visibility from light - we don't render objects the light doesn't hit!
  1180. r_trace = CM_BoxTrace(statLightPosition, RagDoll[RagDollID].origin, mins, maxs, r_worldmodel->firstnode, MASK_OPAQUE);
  1181. if(r_trace.fraction != 1.0)
  1182. return;
  1183.  
  1184. qglMatrixMode(GL_PROJECTION);
  1185. qglPushMatrix();
  1186. qglMatrixMode(GL_MODELVIEW);
  1187. qglPushMatrix();
  1188.  
  1189. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId[1]);
  1190.  
  1191. // In the case we render the shadowmap to a higher resolution, the viewport must be modified accordingly.
  1192. qglViewport(0,0,(int)(vid.width * r_shadowmapratio->value),(int)(vid.height * r_shadowmapratio->value));
  1193.  
  1194. //Clear previous frame values
  1195. qglClear( GL_DEPTH_BUFFER_BIT);
  1196.  
  1197. //Disable color rendering, we only want to write to the Z-Buffer
  1198. qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  1199.  
  1200. // Culling switching, rendering only frontfaces
  1201. qglDisable(GL_CULL_FACE);
  1202.  
  1203. // attach the texture to FBO depth attachment point
  1204. qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, r_depthtexture2->texnum, 0);
  1205.  
  1206. //get light origin
  1207. //set camera
  1208. SM_SetupMatrices(statLightPosition[0],statLightPosition[1],statLightPosition[2]+64,RagDoll[RagDollID].origin[0],RagDoll[RagDollID].origin[1],RagDoll[RagDollID].origin[2]-128);
  1209.  
  1210. qglEnable( GL_POLYGON_OFFSET_FILL );
  1211. qglPolygonOffset( 0.5f, 0.5f );
  1212.  
  1213. IQM_DrawRagDollCaster ( RagDollID );
  1214.  
  1215. SM_SetTextureMatrix(1);
  1216.  
  1217. qglDepthMask (1); // back to writing
  1218.  
  1219. qglPolygonOffset( 0.0f, 0.0f );
  1220. qglDisable( GL_POLYGON_OFFSET_FILL );
  1221. qglEnable(GL_CULL_FACE);
  1222.  
  1223. qglViewport( 0, 0, viddef.width, viddef.height );
  1224.  
  1225. qglPopMatrix();
  1226. qglMatrixMode(GL_PROJECTION);
  1227. qglPopMatrix();
  1228. qglMatrixMode(GL_MODELVIEW);
  1229.  
  1230. r_shadowmapcount = 1;
  1231. }
  1232.  
  1233. void R_GenerateRagdollShadow( int RagDollID )
  1234. {
  1235. if(gl_shadowmaps->integer && gl_state.vbo && gl_glsl_shaders->integer && gl_state.glsl_shaders && gl_normalmaps->integer)
  1236. {
  1237. vec3_t dist, tmp;
  1238. float rad, fadeshadow_cutoff;
  1239.  
  1240. VectorSubtract(RagDoll[RagDollID].ragDollMesh->maxs, RagDoll[RagDollID].ragDollMesh->mins, tmp);
  1241. VectorScale (tmp, 1.666, tmp);
  1242. rad = VectorLength (tmp);
  1243.  
  1244. if( R_CullSphere( RagDoll[RagDollID].origin, rad, 15 ) )
  1245. return;
  1246.  
  1247. //get view distance
  1248. VectorSubtract(r_origin, RagDoll[RagDollID].origin, dist);
  1249.  
  1250. //fade out shadows both by distance from view, and by distance from light
  1251. fadeshadow_cutoff = r_shadowcutoff->value * (LOD_DIST/LOD_BASE_DIST);
  1252.  
  1253. if (r_shadowcutoff->value < 0.1)
  1254. fadeShadow = 1.0;
  1255. else if (VectorLength (dist) > fadeshadow_cutoff)
  1256. {
  1257. fadeShadow = VectorLength(dist) - fadeshadow_cutoff;
  1258. if (fadeShadow > 512)
  1259. return;
  1260. else
  1261. fadeShadow = 1.0 - fadeShadow/512.0; //fade out smoothly over 512 units.
  1262. }
  1263. else
  1264. fadeShadow = 1.0;
  1265.  
  1266. qglEnable(GL_DEPTH_TEST);
  1267. qglClearColor(0,0,0,1.0f);
  1268.  
  1269. qglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
  1270.  
  1271. R_DrawRagdollCaster(RagDollID);
  1272.  
  1273. qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
  1274.  
  1275. //Enabling color write (previously disabled for light POV z-buffer rendering)
  1276. qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  1277.  
  1278. //re-render affected polys with shadowmap for this entity(note - blend "if darker").
  1279. if(r_shadowmapcount > 0)
  1280. {
  1281. qglEnable( GL_BLEND );
  1282. qglBlendFunc (GL_ZERO, GL_SRC_COLOR);
  1283.  
  1284. R_DrawShadowMapWorld(true, RagDoll[RagDollID].origin);
  1285.  
  1286. qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1287. qglDisable ( GL_BLEND );
  1288. }
  1289.  
  1290. currentmodel = RagDoll[RagDollID].ragDollMesh;
  1291.  
  1292. r_shadowmapcount = 0;
  1293. }
  1294. }
Add Comment
Please, Sign In to add comment