From: havoc Date: Sun, 9 Mar 2003 11:39:08 +0000 (+0000) Subject: changed R_Mesh_ system (again), now uses R_Mesh_GetSpace to set up varray_* pointers... X-Git-Tag: xonotic-v0.1.0preview~6730 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=e93d18b81c4c43ade8be7bb9c5d30710e12554b8 changed R_Mesh_ system (again), now uses R_Mesh_GetSpace to set up varray_* pointers, then fills in the data, then calls R_Mesh_Draw (this can be done repeatedly, but vertex data should *NOT* be modified after the first call) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2818 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_main.c b/cl_main.c index 9488601a..9b70f0fc 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1158,6 +1158,8 @@ void R_DrawLightningBeamCallback(const void *calldata1, int calldata2) // (and realize that the whole polygon assembly orients itself to face // the viewer) + R_Mesh_GetSpace(12); + // polygon 1, verts 0-3 VectorScale(right, r_lightningbeam_thickness.value, offset); R_CalcLightningBeamPolygonVertices(varray_vertex, varray_texcoord[0], b->start, b->end, offset, t1, t2); diff --git a/cl_particles.c b/cl_particles.c index da745f49..68a2b56b 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -676,6 +676,7 @@ CL_SparkShower */ void CL_SparkShower (vec3_t org, vec3_t dir, int count) { + vec3_t org2, org3; int k; if (!cl_particles.integer) return; @@ -690,7 +691,11 @@ void CL_SparkShower (vec3_t org, vec3_t dir, int count) k = count / 4; while(k--) { - particle(pt_grow, PARTICLE_BILLBOARD, 0x101010, 0x202020, tex_smoke[rand()&7], true, PBLEND_ADD, 3, 3, 255, 1024, 9999, -0.2, 0, org[0] + 0.125f * lhrandom(-count, count), org[1] + 0.125f * lhrandom (-count, count), org[2] + 0.125f * lhrandom(-count, count), lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(0, 16), 15, 0, 0, 0, 0, 0); + org2[0] = org[0] + 0.125f * lhrandom(-count, count); + org2[1] = org[1] + 0.125f * lhrandom(-count, count); + org2[2] = org[2] + 0.125f * lhrandom(-count, count); + CL_TraceLine(org, org2, org3, NULL, 0, true, NULL); + particle(pt_grow, PARTICLE_BILLBOARD, 0x101010, 0x202020, tex_smoke[rand()&7], true, PBLEND_ADD, 3, 3, 255, 1024, 9999, -0.2, 0, org3[0], org3[1], org3[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(0, 16), 15, 0, 0, 0, 0, 0); } } @@ -716,6 +721,7 @@ static float bloodcount = 0; void CL_BloodPuff (vec3_t org, vec3_t vel, int count) { float s, r, a; + vec3_t org2, org3; // bloodcount is used to accumulate counts too small to cause a blood particle if (!cl_particles.integer) return; if (!cl_particles_blood.integer) return; @@ -729,8 +735,12 @@ void CL_BloodPuff (vec3_t org, vec3_t vel, int count) a = cl_particles_blood_alpha.value * 255; while(bloodcount > 0) { - particle(pt_blood, PARTICLE_BILLBOARD, 0xFFFFFF, 0xFFFFFF, tex_blooddecal[rand()&7], true, PBLEND_MOD, r, r, a * 3, a * 1.5, 9999, 0, -1, org[0], org[1], org[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 0, 0, 0, 0, 1, 0); - //particle(pt_blood, PARTICLE_BILLBOARD, 0x000000, 0x200000, tex_smoke[rand()&7], true, PBLEND_ALPHA, r, r, a, a * 0.5, 9999, 0, -1, org[0], org[1], org[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 0, 0, 0, 0, 1, 0); + org2[0] = org[0] + 0.125f * lhrandom(-bloodcount, bloodcount); + org2[1] = org[1] + 0.125f * lhrandom(-bloodcount, bloodcount); + org2[2] = org[2] + 0.125f * lhrandom(-bloodcount, bloodcount); + CL_TraceLine(org, org2, org3, NULL, 0, true, NULL); + particle(pt_blood, PARTICLE_BILLBOARD, 0xFFFFFF, 0xFFFFFF, tex_blooddecal[rand()&7], true, PBLEND_MOD, r, r, a * 3, a * 1.5, 9999, 0, -1, org3[0], org3[1], org3[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 0, 0, 0, 0, 1, 0); + //particle(pt_blood, PARTICLE_BILLBOARD, 0x000000, 0x200000, tex_smoke[rand()&7], true, PBLEND_ALPHA, r, r, a, a * 0.5, 9999, 0, -1, org3[0], org3[1], org3[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 0, 0, 0, 0, 1, 0); bloodcount -= r; } } @@ -1659,7 +1669,7 @@ void R_InitParticles(void) R_Particles_Init(); } -float varray_vertex[16]; +float varray_vertex[16], varray_texcoord[1][16]; #endif #ifdef WORKINGLQUAKE @@ -1676,59 +1686,6 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) VectorCopy(p->org, org); - if (p->orientation == PARTICLE_BILLBOARD) - { - VectorScale(vright, p->scalex, right); - VectorScale(vup, p->scaley, up); - varray_vertex[ 0] = org[0] + right[0] - up[0]; - varray_vertex[ 1] = org[1] + right[1] - up[1]; - varray_vertex[ 2] = org[2] + right[2] - up[2]; - varray_vertex[ 4] = org[0] - right[0] - up[0]; - varray_vertex[ 5] = org[1] - right[1] - up[1]; - varray_vertex[ 6] = org[2] - right[2] - up[2]; - varray_vertex[ 8] = org[0] - right[0] + up[0]; - varray_vertex[ 9] = org[1] - right[1] + up[1]; - varray_vertex[10] = org[2] - right[2] + up[2]; - varray_vertex[12] = org[0] + right[0] + up[0]; - varray_vertex[13] = org[1] + right[1] + up[1]; - varray_vertex[14] = org[2] + right[2] + up[2]; - } - else if (p->orientation == PARTICLE_SPARK) - { - VectorMA(p->org, -p->scaley, p->vel, v); - VectorMA(p->org, p->scaley, p->vel, up2); - R_CalcBeamVerts(varray_vertex, v, up2, p->scalex); - } - else if (p->orientation == PARTICLE_BEAM) - R_CalcBeamVerts(varray_vertex, p->org, p->vel2, p->scalex); - else if (p->orientation == PARTICLE_ORIENTED_DOUBLESIDED) - { - // double-sided - if (DotProduct(p->vel2, r_origin) > DotProduct(p->vel2, org)) - { - VectorNegate(p->vel2, v); - VectorVectors(v, right, up); - } - else - VectorVectors(p->vel2, right, up); - VectorScale(right, p->scalex, right); - VectorScale(up, p->scaley, up); - varray_vertex[ 0] = org[0] + right[0] - up[0]; - varray_vertex[ 1] = org[1] + right[1] - up[1]; - varray_vertex[ 2] = org[2] + right[2] - up[2]; - varray_vertex[ 4] = org[0] - right[0] - up[0]; - varray_vertex[ 5] = org[1] - right[1] - up[1]; - varray_vertex[ 6] = org[2] - right[2] - up[2]; - varray_vertex[ 8] = org[0] - right[0] + up[0]; - varray_vertex[ 9] = org[1] - right[1] + up[1]; - varray_vertex[10] = org[2] - right[2] + up[2]; - varray_vertex[12] = org[0] + right[0] + up[0]; - varray_vertex[13] = org[1] + right[1] + up[1]; - varray_vertex[14] = org[2] + right[2] + up[2]; - } - else - Host_Error("R_DrawParticles: unknown particle orientation %i\n", p->orientation); - tex = &particletexture[p->texnum]; cr = p->color[0] * (1.0f / 255.0f); cg = p->color[1] * (1.0f / 255.0f); @@ -1745,21 +1702,7 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) ca = 1; } -#if WORKINGLQUAKE - if (p->blendmode == 0) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - else if (p->blendmode == 1) - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - else - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - glBegin(GL_QUADS); - glColor4f(cr, cg, cb, ca); - glTexCoord2f(tex->s2, tex->t1);glVertex3f(varray_vertex[ 0], varray_vertex[ 1], varray_vertex[ 2]); - glTexCoord2f(tex->s1, tex->t1);glVertex3f(varray_vertex[ 4], varray_vertex[ 5], varray_vertex[ 6]); - glTexCoord2f(tex->s1, tex->t2);glVertex3f(varray_vertex[ 8], varray_vertex[ 9], varray_vertex[10]); - glTexCoord2f(tex->s2, tex->t2);glVertex3f(varray_vertex[12], varray_vertex[13], varray_vertex[14]); - glEnd(); -#else +#ifndef WORKINGLQUAKE memset(&m, 0, sizeof(m)); if (p->blendmode == 0) { @@ -1799,6 +1742,63 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) cg *= r_colorscale; cb *= r_colorscale; + GL_Color(cr, cg, cb, ca); + + R_Mesh_GetSpace(4); +#endif + if (p->orientation == PARTICLE_BILLBOARD) + { + VectorScale(vright, p->scalex, right); + VectorScale(vup, p->scaley, up); + varray_vertex[ 0] = org[0] + right[0] - up[0]; + varray_vertex[ 1] = org[1] + right[1] - up[1]; + varray_vertex[ 2] = org[2] + right[2] - up[2]; + varray_vertex[ 4] = org[0] - right[0] - up[0]; + varray_vertex[ 5] = org[1] - right[1] - up[1]; + varray_vertex[ 6] = org[2] - right[2] - up[2]; + varray_vertex[ 8] = org[0] - right[0] + up[0]; + varray_vertex[ 9] = org[1] - right[1] + up[1]; + varray_vertex[10] = org[2] - right[2] + up[2]; + varray_vertex[12] = org[0] + right[0] + up[0]; + varray_vertex[13] = org[1] + right[1] + up[1]; + varray_vertex[14] = org[2] + right[2] + up[2]; + } + else if (p->orientation == PARTICLE_SPARK) + { + VectorMA(p->org, -p->scaley, p->vel, v); + VectorMA(p->org, p->scaley, p->vel, up2); + R_CalcBeamVerts(varray_vertex, v, up2, p->scalex); + } + else if (p->orientation == PARTICLE_BEAM) + R_CalcBeamVerts(varray_vertex, p->org, p->vel2, p->scalex); + else if (p->orientation == PARTICLE_ORIENTED_DOUBLESIDED) + { + // double-sided + if (DotProduct(p->vel2, r_origin) > DotProduct(p->vel2, org)) + { + VectorNegate(p->vel2, v); + VectorVectors(v, right, up); + } + else + VectorVectors(p->vel2, right, up); + VectorScale(right, p->scalex, right); + VectorScale(up, p->scaley, up); + varray_vertex[ 0] = org[0] + right[0] - up[0]; + varray_vertex[ 1] = org[1] + right[1] - up[1]; + varray_vertex[ 2] = org[2] + right[2] - up[2]; + varray_vertex[ 4] = org[0] - right[0] - up[0]; + varray_vertex[ 5] = org[1] - right[1] - up[1]; + varray_vertex[ 6] = org[2] - right[2] - up[2]; + varray_vertex[ 8] = org[0] - right[0] + up[0]; + varray_vertex[ 9] = org[1] - right[1] + up[1]; + varray_vertex[10] = org[2] - right[2] + up[2]; + varray_vertex[12] = org[0] + right[0] + up[0]; + varray_vertex[13] = org[1] + right[1] + up[1]; + varray_vertex[14] = org[2] + right[2] + up[2]; + } + else + Host_Error("R_DrawParticles: unknown particle orientation %i\n", p->orientation); + if (p->orientation == PARTICLE_BEAM) { VectorSubtract(p->vel2, p->org, up); @@ -1818,7 +1818,21 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) varray_texcoord[0][12] = tex->s2;varray_texcoord[0][13] = tex->t2; } - GL_Color(cr, cg, cb, ca); +#if WORKINGLQUAKE + if (p->blendmode == 0) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else if (p->blendmode == 1) + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else + glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + glColor4f(cr, cg, cb, ca); + glBegin(GL_QUADS); + glTexCoord2f(varray_texcoord[0][ 0], varray_texcoord[0][ 1]);glVertex3f(varray_vertex[ 0], varray_vertex[ 1], varray_vertex[ 2]); + glTexCoord2f(varray_texcoord[0][ 4], varray_texcoord[0][ 5]);glVertex3f(varray_vertex[ 4], varray_vertex[ 5], varray_vertex[ 6]); + glTexCoord2f(varray_texcoord[0][ 8], varray_texcoord[0][ 9]);glVertex3f(varray_vertex[ 8], varray_vertex[ 9], varray_vertex[10]); + glTexCoord2f(varray_texcoord[0][12], varray_texcoord[0][13]);glVertex3f(varray_vertex[12], varray_vertex[13], varray_vertex[14]); + glEnd(); +#else R_Mesh_Draw(4, 2, polygonelements); #endif } diff --git a/gl_backend.c b/gl_backend.c index 2d2ddc6a..d41570e5 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -72,10 +72,13 @@ void SCR_ScreenShot_f (void); // these are externally accessible int r_lightmapscalebit; float r_colorscale; -float *varray_vertex; -float *varray_color; -float *varray_texcoord[MAX_TEXTUREUNITS]; +GLfloat *varray_vertex, *varray_buf_vertex; +GLfloat *varray_color, *varray_buf_color; +GLfloat *varray_texcoord[MAX_TEXTUREUNITS], *varray_buf_texcoord[MAX_TEXTUREUNITS]; int mesh_maxverts; +int varray_offset = 0, varray_offsetnext = 0; +GLuint *varray_buf_elements; +int mesh_maxelements = 3072; static matrix4x4_t backend_viewmatrix; static matrix4x4_t backend_modelmatrix; @@ -84,7 +87,7 @@ static matrix4x4_t backend_glmodelviewmatrix; static matrix4x4_t backend_projectmatrix; static int backendunits, backendactive; -static qbyte *varray_bcolor; +static GLubyte *varray_bcolor, *varray_buf_bcolor; static mempool_t *gl_backend_mempool; /* @@ -104,43 +107,76 @@ A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E *elements++ = i + row + 1; */ +void GL_Backend_AllocElementsArray(void) +{ + if (varray_buf_elements) + Mem_Free(varray_buf_elements); + varray_buf_elements = Mem_Alloc(gl_backend_mempool, mesh_maxelements * sizeof(GLuint)); +} + +void GL_Backend_FreeElementArray(void) +{ + if (varray_buf_elements) + Mem_Free(varray_buf_elements); + varray_buf_elements = NULL; +} + int polygonelements[768]; void GL_Backend_AllocArrays(void) { int i; - for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++) + if (!gl_backend_mempool) { - polygonelements[i * 3 + 0] = 0; - polygonelements[i * 3 + 1] = i + 1; - polygonelements[i * 3 + 2] = i + 2; + gl_backend_mempool = Mem_AllocPool("GL_Backend"); + varray_buf_vertex = NULL; + varray_buf_color = NULL; + varray_buf_bcolor = NULL; + varray_buf_elements = NULL; + for (i = 0;i < MAX_TEXTUREUNITS;i++) + varray_buf_texcoord[i] = NULL; } - if (!gl_backend_mempool) - gl_backend_mempool = Mem_AllocPool("GL_Backend"); + if (varray_buf_vertex) + Mem_Free(varray_buf_vertex); + varray_buf_vertex = NULL; + if (varray_buf_color) + Mem_Free(varray_buf_color); + varray_buf_color = NULL; + if (varray_buf_bcolor) + Mem_Free(varray_buf_bcolor); + varray_buf_bcolor = NULL; + for (i = 0;i < MAX_TEXTUREUNITS;i++) + { + if (varray_buf_texcoord[i]) + Mem_Free(varray_buf_texcoord[i]); + varray_buf_texcoord[i] = NULL; + } - varray_vertex = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(float[4])); - varray_color = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(float[4])); - varray_bcolor = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(qbyte[4])); + varray_buf_vertex = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(GLfloat[4])); + varray_buf_color = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(GLfloat[4])); + varray_buf_bcolor = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(GLubyte[4])); for (i = 0;i < backendunits;i++) - varray_texcoord[i] = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(float[4])); + varray_buf_texcoord[i] = Mem_Alloc(gl_backend_mempool, mesh_maxverts * sizeof(GLfloat[4])); for (;i < MAX_TEXTUREUNITS;i++) - varray_texcoord[i] = NULL; + varray_buf_texcoord[i] = NULL; + + GL_Backend_AllocElementsArray(); } -void GL_Backend_FreeArrays(int resizingbuffers) +void GL_Backend_FreeArrays(void) { int i; - if (resizingbuffers) - Mem_EmptyPool(gl_backend_mempool); - else - Mem_FreePool(&gl_backend_mempool); - varray_vertex = NULL; - varray_color = NULL; - varray_bcolor = NULL; + Mem_FreePool(&gl_backend_mempool); + + varray_buf_vertex = NULL; + varray_buf_color = NULL; + varray_buf_bcolor = NULL; for (i = 0;i < MAX_TEXTUREUNITS;i++) - varray_texcoord[i] = NULL; + varray_buf_texcoord[i] = NULL; + + varray_buf_elements = NULL; } static void gl_backend_start(void) @@ -173,7 +209,7 @@ static void gl_backend_shutdown(void) Con_Printf("OpenGL Backend shutting down\n"); - GL_Backend_FreeArrays(false); + GL_Backend_FreeArrays(); } void GL_Backend_CheckCvars(void) @@ -185,12 +221,11 @@ void GL_Backend_CheckCvars(void) Cvar_SetValueQuick(&gl_mesh_maxverts, 21760); } -void GL_Backend_ResizeArrays(int numtriangles) +void GL_Backend_ResizeArrays(int numvertices) { - Cvar_SetValueQuick(&gl_mesh_maxverts, numtriangles); + Cvar_SetValueQuick(&gl_mesh_maxverts, numvertices); GL_Backend_CheckCvars(); mesh_maxverts = gl_mesh_maxverts.integer; - GL_Backend_FreeArrays(true); GL_Backend_AllocArrays(); } @@ -200,6 +235,15 @@ static void gl_backend_newmap(void) void gl_backend_init(void) { + int i; + + for (i = 0;i < POLYGONELEMENTS_MAXPOINTS - 2;i++) + { + polygonelements[i * 3 + 0] = 0; + polygonelements[i * 3 + 1] = i + 1; + polygonelements[i * 3 + 2] = i + 2; + } + Cvar_RegisterVariable(&r_render); Cvar_RegisterVariable(&gl_dither); Cvar_RegisterVariable(&gl_lockarrays); @@ -370,11 +414,11 @@ void GL_SetupTextureState(void) qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR if (gl_texture3d || gl_texturecubemap) { - qglTexCoordPointer(3, GL_FLOAT, sizeof(float[4]), varray_texcoord[i]);CHECKGLERROR + qglTexCoordPointer(3, GL_FLOAT, sizeof(float[4]), varray_buf_texcoord[i]);CHECKGLERROR } else { - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[4]), varray_texcoord[i]);CHECKGLERROR + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[4]), varray_buf_texcoord[i]);CHECKGLERROR } qglDisable(GL_TEXTURE_1D);CHECKGLERROR qglDisable(GL_TEXTURE_2D);CHECKGLERROR @@ -432,15 +476,15 @@ void GL_Backend_ResetState(void) qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR qglDisable(GL_BLEND);CHECKGLERROR qglDepthMask(gl_state.depthmask);CHECKGLERROR - qglVertexPointer(3, GL_FLOAT, sizeof(float[4]), varray_vertex);CHECKGLERROR + qglVertexPointer(3, GL_FLOAT, sizeof(GLfloat[4]), varray_buf_vertex);CHECKGLERROR qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR if (gl_mesh_floatcolors.integer) { - qglColorPointer(4, GL_FLOAT, sizeof(float[4]), varray_color);CHECKGLERROR + qglColorPointer(4, GL_FLOAT, sizeof(GLfloat[4]), varray_buf_color);CHECKGLERROR } else { - qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(qbyte[4]), varray_bcolor);CHECKGLERROR + qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(GLubyte[4]), varray_buf_bcolor);CHECKGLERROR } GL_Color(1, 1, 1, 1); @@ -502,12 +546,12 @@ void GL_ConvertColorsFloatToByte(int numverts) // (or a union) volatile int *icolor; volatile float *fcolor; - qbyte *bcolor; + GLubyte *bcolor; total = numverts * 4; // shift float to have 8bit fraction at base of number - fcolor = varray_color; + fcolor = varray_buf_color; for (i = 0;i < total;) { fcolor[i ] += 32768.0f; @@ -518,18 +562,19 @@ void GL_ConvertColorsFloatToByte(int numverts) } // then read as integer and kill float bits... - icolor = (int *)varray_color; - bcolor = varray_bcolor; + icolor = (int *)varray_buf_color; + bcolor = varray_buf_bcolor; for (i = 0;i < total;) { - k = icolor[i ] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i ] = (qbyte) k; - k = icolor[i + 1] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 1] = (qbyte) k; - k = icolor[i + 2] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 2] = (qbyte) k; - k = icolor[i + 3] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 3] = (qbyte) k; + k = icolor[i ] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i ] = (GLubyte) k; + k = icolor[i + 1] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 1] = (GLubyte) k; + k = icolor[i + 2] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 2] = (GLubyte) k; + k = icolor[i + 3] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 3] = (GLubyte) k; i += 4; } } +/* // enlarges geometry buffers if they are too small void _R_Mesh_ResizeCheck(int numverts) { @@ -540,8 +585,47 @@ void _R_Mesh_ResizeCheck(int numverts) GL_Backend_ResetState(); } } +*/ + +void GL_Backend_RenumberElements(int numelements, const int *in, int offset) +{ + int i; + for (i = 0;i < numelements;i++) + varray_buf_elements[i] = in[i] + offset; +} + +// gets geometry space for a mesh +void R_Mesh_GetSpace(int numverts) +{ + int i; + + varray_offset = varray_offsetnext; + if (varray_offset + numverts > mesh_maxverts) + { + //flush stuff here + varray_offset = 0; + } + if (numverts > mesh_maxverts) + { + BACKENDACTIVECHECK + GL_Backend_ResizeArrays(numverts + 100); + GL_Backend_ResetState(); + varray_offset = 0; + } + + // for debugging + //varray_offset = rand() % (mesh_maxverts - numverts); + + varray_vertex = varray_buf_vertex + varray_offset * 4; + varray_color = varray_buf_color + varray_offset * 4; + varray_bcolor = varray_buf_bcolor + varray_offset * 4; + for (i = 0;i < backendunits;i++) + varray_texcoord[i] = varray_buf_texcoord[i] + varray_offset * 4; + + varray_offsetnext = varray_offset + numverts; +} -// renders the mesh +// renders the current mesh void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) { int numelements; @@ -551,28 +635,40 @@ void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) return; } numelements = numtriangles * 3; + if (mesh_maxelements < numelements) + { + mesh_maxelements = numelements; + GL_Backend_AllocElementsArray(); + } + GL_Backend_RenumberElements(numelements, elements, varray_offset); c_meshs++; c_meshelements += numelements; if (gl_state.colorarray && !gl_mesh_floatcolors.integer) GL_ConvertColorsFloatToByte(numverts); - if (!r_render.integer) - return; - if (gl_supportslockarrays && gl_lockarrays.integer) + if (r_render.integer) { - qglLockArraysEXT(0, numverts); - CHECKGLERROR - if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL) - qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numelements, GL_UNSIGNED_INT, (const GLuint *) elements); + if (gl_supportslockarrays && gl_lockarrays.integer) + { + qglLockArraysEXT(varray_offset, numverts); + CHECKGLERROR + if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL) + { + qglDrawRangeElements(GL_TRIANGLES, varray_offset, varray_offset + numverts, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements); + CHECKGLERROR + } + else + { + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements); + CHECKGLERROR + } + qglUnlockArraysEXT(); + CHECKGLERROR + } else - qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) elements); - CHECKGLERROR - qglUnlockArraysEXT(); - CHECKGLERROR - } - else - { - qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) elements); - CHECKGLERROR + { + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements); + CHECKGLERROR + } } } diff --git a/gl_backend.h b/gl_backend.h index 143b0f24..9569ade2 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -70,10 +70,8 @@ void R_Mesh_MainState(const rmeshstate_t *m); // sets up the requested texture state void R_Mesh_TextureState(const rmeshstate_t *m); -// enlarges vertex arrays if they are too small -#define R_Mesh_ResizeCheck(numverts) if ((numverts) > mesh_maxverts) _R_Mesh_ResizeCheck(numverts); -void _R_Mesh_ResizeCheck(int numverts); - +// prepares varray_* buffers for rendering a mesh +void R_Mesh_GetSpace(int numverts); // renders the mesh in the varray_* buffers void R_Mesh_Draw(int numverts, int numtriangles, const int *elements); diff --git a/gl_draw.c b/gl_draw.c index d203b6f7..d36af9c4 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -378,6 +378,8 @@ void GL_Draw_Init (void) } int quadelements[768]; +float textverts[128*4*4]; +float texttexcoords[128*4*4]; void R_DrawQueue(void) { int pos, num, chartexnum, overbright, texnum, additive, batch; @@ -471,6 +473,8 @@ void R_DrawQueue(void) if (h == 0) h = pic->height; } + GL_Color(c[0], c[1], c[2], c[3]); + R_Mesh_GetSpace(4); varray_texcoord[0][ 0] = 0;varray_texcoord[0][ 1] = 0; varray_texcoord[0][ 4] = 1;varray_texcoord[0][ 5] = 0; varray_texcoord[0][ 8] = 1;varray_texcoord[0][ 9] = 1; @@ -479,7 +483,6 @@ void R_DrawQueue(void) varray_vertex[ 4] = x+w;varray_vertex[ 5] = y ;varray_vertex[ 6] = 10; varray_vertex[ 8] = x+w;varray_vertex[ 9] = y+h;varray_vertex[10] = 10; varray_vertex[12] = x ;varray_vertex[13] = y+h;varray_vertex[14] = 10; - GL_Color(c[0], c[1], c[2], c[3]); R_Mesh_Draw(4, 2, quadelements); break; case DRAWQUEUE_STRING: @@ -491,8 +494,8 @@ void R_DrawQueue(void) R_Mesh_TextureState(&m); } batchcount = 0; - at = varray_texcoord[0]; - av = varray_vertex; + at = texttexcoords; + av = textverts; GL_Color(c[0], c[1], c[2], c[3]); while ((num = *str++) && x < vid.conwidth) { @@ -515,26 +518,34 @@ void R_DrawQueue(void) batchcount++; if (batchcount >= 128) { + R_Mesh_GetSpace(batchcount * 4); + memcpy(varray_vertex, textverts, sizeof(float[16]) * batchcount); + memcpy(varray_texcoord[0], texttexcoords, sizeof(float[16]) * batchcount); R_Mesh_Draw(batchcount * 4, batchcount * 2, quadelements); batchcount = 0; - at = varray_texcoord[0]; - av = varray_vertex; + at = texttexcoords; + av = textverts; } } x += w; } if (batchcount > 0) + { + R_Mesh_GetSpace(batchcount * 4); + memcpy(varray_vertex, textverts, sizeof(float[16]) * batchcount); + memcpy(varray_texcoord[0], texttexcoords, sizeof(float[16]) * batchcount); R_Mesh_Draw(batchcount * 4, batchcount * 2, quadelements); + } break; case DRAWQUEUE_MESH: mesh = (void *)(dq + 1); m.tex[0] = R_GetTexture(mesh->texture); R_Mesh_TextureState(&m); - R_Mesh_ResizeCheck(mesh->numvertices); + GL_UseColorArray(); + R_Mesh_GetSpace(mesh->numvertices); memcpy(varray_vertex, mesh->vertices, sizeof(float[4]) * mesh->numvertices); memcpy(varray_texcoord[0], mesh->texcoords, sizeof(float[4]) * mesh->numvertices); memcpy(varray_color, mesh->colors, sizeof(float[4]) * mesh->numvertices); - GL_UseColorArray(); R_Mesh_Draw(mesh->numvertices, mesh->numtriangles, mesh->indices); currentpic = "\0"; break; @@ -543,13 +554,6 @@ void R_DrawQueue(void) if (!vid_usinghwgamma) { - // we use one big triangle for all the screen blends - varray_texcoord[0][0] = 0;varray_texcoord[0][1] = 0; - varray_texcoord[0][4] = 0;varray_texcoord[0][5] = 0; - varray_texcoord[0][8] = 0;varray_texcoord[0][9] = 0; - varray_vertex[0] = -5000;varray_vertex[1] = -5000;varray_vertex[2] = 10; - varray_vertex[4] = 10000;varray_vertex[5] = -5000;varray_vertex[6] = 10; - varray_vertex[8] = -5000;varray_vertex[9] = 10000;varray_vertex[10] = 10; // all the blends ignore depth memset(&m, 0, sizeof(m)); m.depthdisable = true; @@ -570,6 +574,13 @@ void R_DrawQueue(void) while (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f) { GL_Color(bound(0, c[0] - 1, 1), bound(0, c[1] - 1, 1), bound(0, c[2] - 1, 1), 1); + R_Mesh_GetSpace(3); + varray_texcoord[0][0] = 0;varray_texcoord[0][1] = 0; + varray_texcoord[0][4] = 0;varray_texcoord[0][5] = 0; + varray_texcoord[0][8] = 0;varray_texcoord[0][9] = 0; + varray_vertex[0] = -5000;varray_vertex[1] = -5000;varray_vertex[2] = 10; + varray_vertex[4] = 10000;varray_vertex[5] = -5000;varray_vertex[6] = 10; + varray_vertex[8] = -5000;varray_vertex[9] = 10000;varray_vertex[10] = 10; R_Mesh_Draw(3, 1, polygonelements); VectorScale(c, 0.5, c); } @@ -588,6 +599,13 @@ void R_DrawQueue(void) m.blendfunc2 = GL_ONE; R_Mesh_State(&m); GL_Color(c[0], c[1], c[2], 1); + R_Mesh_GetSpace(3); + varray_texcoord[0][0] = 0;varray_texcoord[0][1] = 0; + varray_texcoord[0][4] = 0;varray_texcoord[0][5] = 0; + varray_texcoord[0][8] = 0;varray_texcoord[0][9] = 0; + varray_vertex[0] = -5000;varray_vertex[1] = -5000;varray_vertex[2] = 10; + varray_vertex[4] = 10000;varray_vertex[5] = -5000;varray_vertex[6] = 10; + varray_vertex[8] = -5000;varray_vertex[9] = 10000;varray_vertex[10] = 10; R_Mesh_Draw(3, 1, polygonelements); } } diff --git a/gl_models.c b/gl_models.c index 4a703a2f..9d85d079 100644 --- a/gl_models.c +++ b/gl_models.c @@ -233,9 +233,6 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) memset(&m, 0, sizeof(m)); skin = R_FetchAliasSkin(ent, mesh); - R_Mesh_ResizeCheck(mesh->num_vertices); - R_Model_Alias_GetMeshVerts(ent, mesh, varray_vertex, aliasvert_normals, NULL, NULL); - memcpy(varray_texcoord[0], mesh->data_texcoords, mesh->num_vertices * sizeof(float[4])); for (layernum = 0, layer = skin->data_layers;layernum < skin->num_layers;layernum++, layer++) { if (((layer->flags & ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED) && ent->colormap < 0) @@ -252,6 +249,9 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) R_Mesh_State(&m); GL_Color(fogcolor[0] * fog * colorscale, fogcolor[1] * fog * colorscale, fogcolor[2] * fog * colorscale, ent->alpha); c_alias_polys += mesh->num_triangles; + R_Mesh_GetSpace(mesh->num_vertices); + R_Model_Alias_GetMeshVerts(ent, mesh, varray_vertex, aliasvert_normals, NULL, NULL); + memcpy(varray_texcoord[0], mesh->data_texcoords, mesh->num_vertices * sizeof(float[4])); R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_elements); continue; } @@ -305,11 +305,14 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) fullbright = true; if (ent->effects & EF_FULLBRIGHT) fullbright = true; + c_alias_polys += mesh->num_triangles; + R_Mesh_GetSpace(mesh->num_vertices); + R_Model_Alias_GetMeshVerts(ent, mesh, varray_vertex, aliasvert_normals, NULL, NULL); + memcpy(varray_texcoord[0], mesh->data_texcoords, mesh->num_vertices * sizeof(float[4])); if (fullbright) GL_Color(tint[0], tint[1], tint[2], ent->alpha); else R_LightModel(ent, mesh->num_vertices, varray_vertex, aliasvert_normals, varray_color, tint[0], tint[1], tint[2], false); - c_alias_polys += mesh->num_triangles; R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_elements); } } @@ -379,7 +382,7 @@ void R_Model_Alias_DrawFakeShadow (entity_render_t *ent) skin = R_FetchAliasSkin(ent, mesh); if (skin->flags & ALIASSKIN_TRANSPARENT) continue; - R_Mesh_ResizeCheck(mesh->num_vertices); + R_Mesh_GetSpace(mesh->num_vertices); R_Model_Alias_GetMeshVerts(ent, mesh, varray_vertex, NULL, NULL, NULL); for (i = 0, v = varray_vertex;i < mesh->num_vertices;i++, v += 4) { @@ -409,7 +412,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor skin = R_FetchAliasSkin(ent, mesh); if (skin->flags & ALIASSKIN_TRANSPARENT) continue; - R_Mesh_ResizeCheck(mesh->num_vertices * 2); + R_Mesh_GetSpace(mesh->num_vertices * 2); R_Model_Alias_GetMeshVerts(ent, mesh, varray_vertex, NULL, NULL, NULL); R_Shadow_Volume(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, mesh->data_neighbors, relativelightorigin, lightradius, projectdistance); } @@ -419,7 +422,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz) { int c, meshnum, layernum; - float fog, ifog, lightcolor2[3]; + float fog, ifog, lightcolor2[3], *vertices; vec3_t diff; qbyte *bcolor; aliasmesh_t *mesh; @@ -454,8 +457,8 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v skin = R_FetchAliasSkin(ent, mesh); if (skin->flags & ALIASSKIN_TRANSPARENT) continue; - R_Mesh_ResizeCheck(mesh->num_vertices); - R_Model_Alias_GetMeshVerts(ent, mesh, varray_vertex, aliasvert_normals, aliasvert_svectors, aliasvert_tvectors); + vertices = R_Shadow_VertexBuffer(mesh->num_vertices); + R_Model_Alias_GetMeshVerts(ent, mesh, vertices, aliasvert_normals, aliasvert_svectors, aliasvert_tvectors); for (layernum = 0, layer = skin->data_layers;layernum < skin->num_layers;layernum++, layer++) { if (!(layer->flags & ALIASLAYER_DRAW_PER_LIGHT) @@ -468,7 +471,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v if (layer->flags & ALIASLAYER_SPECULAR) { c_alias_polys += mesh->num_triangles; - R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, mesh->data_texcoords, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL); + R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, vertices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, mesh->data_texcoords, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL); } else if (layer->flags & ALIASLAYER_DIFFUSE) { @@ -497,7 +500,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v lightcolor2[2] *= bcolor[2] * (1.0f / 255.0f); } c_alias_polys += mesh->num_triangles; - R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, mesh->data_texcoords, relativelightorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL); + R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, vertices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, mesh->data_texcoords, relativelightorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL); } } } @@ -785,7 +788,6 @@ void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2) numverts = ent->model->zymnum_verts; numtriangles = *renderlist++; elements = renderlist; - R_Mesh_ResizeCheck(numverts); fog = 0; if (fogenabled) @@ -830,10 +832,11 @@ void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2) mstate.tex[0] = R_GetTexture(texture); R_Mesh_State(&mstate); ZymoticLerpBones(ent->model->zymnum_bones, (zymbonematrix *) ent->model->zymdata_poses, ent->frameblend, ent->model->zymdata_bones); + + R_Mesh_GetSpace(numverts); ZymoticTransformVerts(numverts, varray_vertex, ent->model->zymdata_vertbonecounts, ent->model->zymdata_verts); - ZymoticCalcNormals(numverts, varray_vertex, aliasvert_normals, ent->model->zymnum_shaders, ent->model->zymdata_renderlist); memcpy(varray_texcoord[0], ent->model->zymdata_texcoords, ent->model->zymnum_verts * sizeof(float[4])); - GL_UseColorArray(); + ZymoticCalcNormals(numverts, varray_vertex, aliasvert_normals, ent->model->zymnum_shaders, ent->model->zymdata_renderlist); R_LightModel(ent, numverts, varray_vertex, aliasvert_normals, varray_color, ifog * colorscale, ifog * colorscale, ifog * colorscale, false); R_Mesh_Draw(numverts, numtriangles, elements); c_alias_polys += numtriangles; @@ -847,6 +850,8 @@ void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2) //mstate.tex[0] = R_GetTexture(texture); R_Mesh_State(&mstate); GL_Color(fogcolor[0] * r_colorscale, fogcolor[1] * r_colorscale, fogcolor[2] * r_colorscale, ent->alpha * fog); + R_Mesh_GetSpace(numverts); + ZymoticTransformVerts(numverts, varray_vertex, ent->model->zymdata_vertbonecounts, ent->model->zymdata_verts); R_Mesh_Draw(numverts, numtriangles, elements); c_alias_polys += numtriangles; } diff --git a/gl_rmain.c b/gl_rmain.c index 6c743205..16f5acc5 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -1136,6 +1136,7 @@ static void R_BlendView(void) R_Mesh_Matrix(&r_identitymatrix); R_Mesh_State(&m); + R_Mesh_GetSpace(3); r = 64000; varray_vertex[0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r; varray_vertex[1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r; @@ -1295,6 +1296,7 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa R_Mesh_Matrix(&r_identitymatrix); R_Mesh_State(&m); + R_Mesh_GetSpace(8); varray_vertex[ 0] = mins[0];varray_vertex[ 1] = mins[1];varray_vertex[ 2] = mins[2]; varray_vertex[ 4] = maxs[0];varray_vertex[ 5] = mins[1];varray_vertex[ 6] = mins[2]; varray_vertex[ 8] = mins[0];varray_vertex[ 9] = maxs[1];varray_vertex[10] = mins[2]; @@ -1322,10 +1324,22 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa } */ +int nomodelelements[24] = +{ + 5, 2, 0, + 5, 1, 2, + 5, 0, 3, + 5, 3, 1, + 0, 2, 4, + 2, 1, 4, + 3, 0, 4, + 1, 3, 4 +}; + void R_DrawNoModelCallback(const void *calldata1, int calldata2) { const entity_render_t *ent = calldata1; - int i, element[24]; + int i; float f1, f2, *c, diff[3]; rmeshstate_t m; memset(&m, 0, sizeof(m)); @@ -1347,14 +1361,8 @@ void R_DrawNoModelCallback(const void *calldata1, int calldata2) R_Mesh_Matrix(&ent->matrix); R_Mesh_State(&m); - element[ 0] = 5;element[ 1] = 2;element[ 2] = 0; - element[ 3] = 5;element[ 4] = 1;element[ 5] = 2; - element[ 6] = 5;element[ 7] = 0;element[ 8] = 3; - element[ 9] = 5;element[10] = 3;element[11] = 1; - element[12] = 0;element[13] = 2;element[14] = 4; - element[15] = 2;element[16] = 1;element[17] = 4; - element[18] = 3;element[19] = 0;element[20] = 4; - element[21] = 1;element[22] = 3;element[23] = 4; + GL_UseColorArray(); + R_Mesh_GetSpace(6); varray_vertex[ 0] = -16;varray_vertex[ 1] = 0;varray_vertex[ 2] = 0; varray_vertex[ 4] = 16;varray_vertex[ 5] = 0;varray_vertex[ 6] = 0; varray_vertex[ 8] = 0;varray_vertex[ 9] = -16;varray_vertex[10] = 0; @@ -1388,8 +1396,7 @@ void R_DrawNoModelCallback(const void *calldata1, int calldata2) c[2] *= r_colorscale; } } - GL_UseColorArray(); - R_Mesh_Draw(6, 8, element); + R_Mesh_Draw(6, 8, nomodelelements); } void R_DrawNoModel(entity_render_t *ent) diff --git a/gl_rsurf.c b/gl_rsurf.c index 4c16a117..017d4039 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -774,9 +774,9 @@ static void RSurfShader_Sky(const entity_render_t *ent, const texture_t *texture { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); GL_Color(fogcolor[0] * r_colorscale, fogcolor[1] * r_colorscale, fogcolor[2] * r_colorscale, 1); + R_Mesh_GetSpace(mesh->numverts); + memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); } } @@ -828,7 +828,7 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) GL_UseColorArray(); for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); scroll[0] = sin(cl.time) * 0.125f; @@ -860,7 +860,7 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) R_Mesh_State(&m); for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); if (m.tex[0]) memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); @@ -927,7 +927,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(const entity_render_t *ent, const m GL_UseColorArray(); for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); R_FillColors(varray_color, mesh->numverts, base, base, base, currentalpha); @@ -957,7 +957,7 @@ static void RSurfShader_Wall_Pass_Glow(const entity_render_t *ent, const msurfac GL_UseColorArray(); for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); RSurf_FoggedColors(varray_vertex, varray_color, 1, 1, 1, currentalpha, r_colorscale, mesh->numverts, modelorg); @@ -979,7 +979,7 @@ static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface GL_UseColorArray(); for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); if (m.tex[0]) memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); @@ -1019,7 +1019,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render } for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[1], mesh->uvw, mesh->numverts * sizeof(float[4])); @@ -1057,7 +1057,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseDoubleTex(const entity_render_t *ent } for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[1], mesh->uvw, mesh->numverts * sizeof(float[4])); @@ -1084,7 +1084,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); @@ -1119,7 +1119,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, } for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->uvw, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); @@ -1155,7 +1155,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const { if (RSurf_LightCheck(&ent->inversematrix, surf->dlightbits, mesh)) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); R_FillColors(varray_color, mesh->numverts, 0, 0, 0, 1); @@ -1186,7 +1186,7 @@ static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const te { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); if (m.tex[0]) memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); @@ -1214,7 +1214,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, c { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->abc, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); @@ -1240,7 +1240,7 @@ static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const t { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); @@ -1269,7 +1269,7 @@ static void RSurfShader_OpaqueWall_Pass_OpaqueGlow(const entity_render_t *ent, c { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); @@ -1511,7 +1511,7 @@ static void R_DrawPortal_Callback(const void *calldata1, int calldata2) m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; R_Mesh_Matrix(&ent->matrix); R_Mesh_State(&m); - R_Mesh_ResizeCheck(portal->numpoints); + R_Mesh_GetSpace(portal->numpoints); i = portal - ent->model->portals; GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_colorscale, ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_colorscale, @@ -1835,7 +1835,7 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts * 2); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); R_Shadow_Volume(mesh->numverts, mesh->numtriangles, mesh->index, mesh->triangleneighbors, relativelightorigin, lightradius, projectdistance); } @@ -1865,10 +1865,8 @@ void R_Model_Brush_DrawLightForSurfaceList(entity_render_t *ent, vec3_t relative { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); - R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); - R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); + R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->verts, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); + R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->verts, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); } } } @@ -1914,10 +1912,8 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); - R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); - R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); + R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->verts, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); + R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->verts, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); } } } @@ -1942,10 +1938,8 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - R_Mesh_ResizeCheck(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); - R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); - R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); + R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->verts, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); + R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->verts, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); } } } diff --git a/r_crosshairs.c b/r_crosshairs.c index 5522a288..212d654d 100644 --- a/r_crosshairs.c +++ b/r_crosshairs.c @@ -42,6 +42,7 @@ void R_DrawCrosshairSprite(rtexture_t *texture, vec3_t origin, vec_t scale, floa R_Mesh_State(&m); GL_Color(cr * r_colorscale, cg * r_colorscale, cb * r_colorscale, ca); + R_Mesh_GetSpace(4); varray_texcoord[0][ 0] = 0;varray_texcoord[0][ 1] = 0; varray_texcoord[0][ 4] = 0;varray_texcoord[0][ 5] = 1; varray_texcoord[0][ 8] = 1;varray_texcoord[0][ 9] = 1; diff --git a/r_explosion.c b/r_explosion.c index b5654092..6feff62c 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -190,7 +190,8 @@ void R_DrawExplosionCallback(const void *calldata1, int calldata2) numtriangles = EXPLOSIONTRIS; numverts = EXPLOSIONVERTS; - R_Mesh_ResizeCheck(numverts); + GL_UseColorArray(); + R_Mesh_GetSpace(numverts); for (i = 0, v = varray_vertex;i < numverts;i++, v += 4) { @@ -241,7 +242,6 @@ void R_DrawExplosionCallback(const void *calldata1, int calldata2) c[3] = 1; } } - GL_UseColorArray(); R_Mesh_Draw(numverts, numtriangles, explosiontris[0]); } diff --git a/r_light.c b/r_light.c index 7aea7676..74ca47ec 100644 --- a/r_light.c +++ b/r_light.c @@ -154,10 +154,6 @@ void R_DrawCoronas(void) R_Mesh_Matrix(&r_identitymatrix); R_Mesh_State(&m); viewdist = DotProduct(r_origin, vpn); - varray_texcoord[0][ 0] = 0;varray_texcoord[0][ 1] = 0; - varray_texcoord[0][ 4] = 0;varray_texcoord[0][ 5] = 1; - varray_texcoord[0][ 8] = 1;varray_texcoord[0][ 9] = 1; - varray_texcoord[0][12] = 1;varray_texcoord[0][13] = 0; for (i = 0;i < r_numdlights;i++) { rd = r_dlight + i; @@ -176,6 +172,11 @@ void R_DrawCoronas(void) scale = rd->cullradius * 0.25f; if (gl_flashblend.integer) scale *= 2.0f; + R_Mesh_GetSpace(4); + varray_texcoord[0][ 0] = 0;varray_texcoord[0][ 1] = 0; + varray_texcoord[0][ 4] = 0;varray_texcoord[0][ 5] = 1; + varray_texcoord[0][ 8] = 1;varray_texcoord[0][ 9] = 1; + varray_texcoord[0][12] = 1;varray_texcoord[0][13] = 0; varray_vertex[0] = rd->origin[0] - vright[0] * scale - vup[0] * scale; varray_vertex[1] = rd->origin[1] - vright[1] * scale - vup[1] * scale; varray_vertex[2] = rd->origin[2] - vright[2] * scale - vup[2] * scale; diff --git a/r_shadow.c b/r_shadow.c index 742ed5a6..50de8978 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -22,6 +22,10 @@ int maxshadowelements; int *shadowelements; int maxtrianglefacinglight; qbyte *trianglefacinglight; +int *trianglefacinglightlist; + +int maxshadowvertices; +float *shadowvertices; rtexturepool_t *r_shadow_texturepool; rtexture_t *r_shadow_normalscubetexture; @@ -61,8 +65,11 @@ void r_shadow_start(void) r_shadow_mempool = Mem_AllocPool("R_Shadow"); maxshadowelements = 0; shadowelements = NULL; + maxshadowvertices = 0; + shadowvertices = NULL; maxtrianglefacinglight = 0; trianglefacinglight = NULL; + trianglefacinglightlist = NULL; r_shadow_normalscubetexture = NULL; r_shadow_attenuation2dtexture = NULL; r_shadow_attenuation3dtexture = NULL; @@ -87,8 +94,11 @@ void r_shadow_shutdown(void) R_FreeTexturePool(&r_shadow_texturepool); maxshadowelements = 0; shadowelements = NULL; + maxshadowvertices = 0; + shadowvertices = NULL; maxtrianglefacinglight = 0; trianglefacinglight = NULL; + trianglefacinglightlist = NULL; Mem_FreePool(&r_shadow_mempool); } @@ -132,9 +142,9 @@ void R_Shadow_ProjectVertices(float *verts, int numverts, const float *relativel } } -void R_Shadow_MakeTriangleShadowFlags(const int *elements, const float *vertex, int numtris, qbyte *trianglefacinglight, const float *relativelightorigin, float lightradius) +int R_Shadow_MakeTriangleShadowFlags(const int *elements, const float *vertex, int numtris, qbyte *facing, int *list, const float *relativelightorigin) { - int i; + int i, tris = 0; const float *v0, *v1, *v2; for (i = 0;i < numtris;i++, elements += 3) { @@ -150,13 +160,18 @@ void R_Shadow_MakeTriangleShadowFlags(const int *elements, const float *vertex, // fast version // subtracts v1 from v0 and v2, combined into a crossproduct, // combined with a dotproduct of the light location relative to the - // first point of the triangle (any point works, since the triangle + // first point of the triangle (any point works, since any triangle // is obviously flat), and finally a comparison to determine if the // light is infront of the triangle (the goal of this statement) - trianglefacinglight[i] = - (relativelightorigin[0] - v0[0]) * ((v0[1] - v1[1]) * (v2[2] - v1[2]) - (v0[2] - v1[2]) * (v2[1] - v1[1])) + if((relativelightorigin[0] - v0[0]) * ((v0[1] - v1[1]) * (v2[2] - v1[2]) - (v0[2] - v1[2]) * (v2[1] - v1[1])) + (relativelightorigin[1] - v0[1]) * ((v0[2] - v1[2]) * (v2[0] - v1[0]) - (v0[0] - v1[0]) * (v2[2] - v1[2])) - + (relativelightorigin[2] - v0[2]) * ((v0[0] - v1[0]) * (v2[1] - v1[1]) - (v0[1] - v1[1]) * (v2[0] - v1[0])) > 0; + + (relativelightorigin[2] - v0[2]) * ((v0[0] - v1[0]) * (v2[1] - v1[1]) - (v0[1] - v1[1]) * (v2[0] - v1[0])) > 0) + { + facing[i] = true; + list[tris++] = i; + } + else + facing[i] = false; #else // readable version { @@ -179,69 +194,85 @@ void R_Shadow_MakeTriangleShadowFlags(const int *elements, const float *vertex, // I.E. flat, so all points give the same answer) // the normal is not normalized because it is used on both sides of // the comparison, so it's magnitude does not matter - trianglefacinglight[i] = DotProduct(relativelightorigin, temp) >= DotProduct(v0, temp); + if (DotProduct(relativelightorigin, temp) >= DotProduct(v0, temp)) + { + facing[i] = true; + list[tris++] = i; + } + else + facing[i] = false; } #endif } + return tris; } -int R_Shadow_BuildShadowVolumeTriangles(const int *elements, const int *neighbors, int numtris, int numverts, const qbyte *trianglefacinglight, int *out) +int R_Shadow_BuildShadowVolumeTriangles(const int *elements, const int *neighbors, int numverts, const qbyte *facing, const int *facinglist, int numfacing, int *out) { int i, tris; + const int *e, *n; // check each frontface for bordering backfaces, // and cast shadow polygons from those edges, // also create front and back caps for shadow volume - tris = 0; - for (i = 0;i < numtris;i++, elements += 3, neighbors += 3) - { - if (trianglefacinglight[i]) + tris = numfacing * 2; + // output front caps + for (i = 0;i < numfacing;i++) + { + e = elements + facinglist[i] * 3; + out[0] = e[0]; + out[1] = e[1]; + out[2] = e[2]; + out += 3; + } + // output back caps + for (i = 0;i < numfacing;i++) + { + e = elements + facinglist[i] * 3; + out[0] = e[2] + numverts; + out[1] = e[1] + numverts; + out[2] = e[0] + numverts; + out += 3; + } + // output sides around frontfaces + for (i = 0;i < numfacing;i++) + { + n = neighbors + facinglist[i] * 3; + // check the edges + if (n[0] < 0 || !facing[n[0]]) { - // triangle is frontface and therefore casts shadow, - // output front and back caps for shadow volume - // front cap - out[0] = elements[0]; - out[1] = elements[1]; - out[2] = elements[2]; - // rear cap (with flipped winding order) - out[3] = elements[0] + numverts; - out[4] = elements[2] + numverts; - out[5] = elements[1] + numverts; + e = elements + facinglist[i] * 3; + out[0] = e[1]; + out[1] = e[0]; + out[2] = e[0] + numverts; + out[3] = e[1]; + out[4] = e[0] + numverts; + out[5] = e[1] + numverts; + out += 6; + tris += 2; + } + if (n[1] < 0 || !facing[n[1]]) + { + e = elements + facinglist[i] * 3; + out[0] = e[2]; + out[1] = e[1]; + out[2] = e[1] + numverts; + out[3] = e[2]; + out[4] = e[1] + numverts; + out[5] = e[2] + numverts; + out += 6; + tris += 2; + } + if (n[2] < 0 || !facing[n[2]]) + { + e = elements + facinglist[i] * 3; + out[0] = e[0]; + out[1] = e[2]; + out[2] = e[2] + numverts; + out[3] = e[0]; + out[4] = e[2] + numverts; + out[5] = e[0] + numverts; out += 6; tris += 2; - // check the edges - if (neighbors[0] < 0 || !trianglefacinglight[neighbors[0]]) - { - out[0] = elements[1]; - out[1] = elements[0]; - out[2] = elements[0] + numverts; - out[3] = elements[1]; - out[4] = elements[0] + numverts; - out[5] = elements[1] + numverts; - out += 6; - tris += 2; - } - if (neighbors[1] < 0 || !trianglefacinglight[neighbors[1]]) - { - out[0] = elements[2]; - out[1] = elements[1]; - out[2] = elements[1] + numverts; - out[3] = elements[2]; - out[4] = elements[1] + numverts; - out[5] = elements[2] + numverts; - out += 6; - tris += 2; - } - if (neighbors[2] < 0 || !trianglefacinglight[neighbors[2]]) - { - out[0] = elements[0]; - out[1] = elements[2]; - out[2] = elements[2] + numverts; - out[3] = elements[0]; - out[4] = elements[2] + numverts; - out[5] = elements[0] + numverts; - out += 6; - tris += 2; - } } } return tris; @@ -250,16 +281,21 @@ int R_Shadow_BuildShadowVolumeTriangles(const int *elements, const int *neighbor void R_Shadow_ResizeTriangleFacingLight(int numtris) { // make sure trianglefacinglight is big enough for this volume + // ameks ru ertaignelaficgnilhg tsib gie ongu hof rhtsiv lomu e + // m4k3 5ur3 7r14ng13f4c1n5115h7 15 b15 3n0u5h f0r 7h15 v01um3 if (maxtrianglefacinglight < numtris) { maxtrianglefacinglight = numtris; if (trianglefacinglight) Mem_Free(trianglefacinglight); + if (trianglefacinglightlist) + Mem_Free(trianglefacinglightlist); trianglefacinglight = Mem_Alloc(r_shadow_mempool, maxtrianglefacinglight); + trianglefacinglightlist = Mem_Alloc(r_shadow_mempool, sizeof(int) * maxtrianglefacinglight); } } -void R_Shadow_ResizeShadowElements(int numtris) +int *R_Shadow_ResizeShadowElements(int numtris) { // make sure shadowelements is big enough for this volume if (maxshadowelements < numtris * 24) @@ -269,6 +305,19 @@ void R_Shadow_ResizeShadowElements(int numtris) Mem_Free(shadowelements); shadowelements = Mem_Alloc(r_shadow_mempool, maxshadowelements * sizeof(int)); } + return shadowelements; +} + +float *R_Shadow_VertexBuffer(int numvertices) +{ + if (maxshadowvertices < numvertices) + { + maxshadowvertices = numvertices; + if (shadowvertices) + Mem_Free(shadowvertices); + shadowvertices = Mem_Alloc(r_shadow_mempool, maxshadowvertices * sizeof(float[4])); + } + return shadowvertices; } void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance) @@ -279,6 +328,8 @@ void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, v Con_Printf("R_Shadow_Volume: projectdistance %f\n"); return; } + if (!numverts) + return; // terminology: // // frontface: @@ -296,8 +347,8 @@ void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, v // description: // draws the shadow volumes of the model. // requirements: -// vertex locations must already be in varray_vertex before use. -// varray_vertex must have capacity for numverts * 2. +// vertex locations must already be in vertices before use. +// vertices must have capacity for numverts * 2. // make sure trianglefacinglight is big enough for this volume if (maxtrianglefacinglight < numtris) @@ -308,35 +359,32 @@ void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, v R_Shadow_ResizeShadowElements(numtris); // check which triangles are facing the light - R_Shadow_MakeTriangleShadowFlags(elements, varray_vertex, numtris, trianglefacinglight, relativelightorigin, lightradius); - - // generate projected vertices - // by clever use of elements we'll construct the whole shadow from - // the unprojected vertices and these projected vertices - R_Shadow_ProjectVertices(varray_vertex, numverts, relativelightorigin, projectdistance); + tris = R_Shadow_MakeTriangleShadowFlags(elements, varray_vertex, numtris, trianglefacinglight, trianglefacinglightlist, relativelightorigin); + if (!tris) + return; // output triangle elements - tris = R_Shadow_BuildShadowVolumeTriangles(elements, neighbors, numtris, numverts, trianglefacinglight, shadowelements); - R_Shadow_RenderVolume(numverts * 2, tris, shadowelements); -} - -void R_Shadow_RenderVolume(int numverts, int numtris, int *elements) -{ - if (!numverts || !numtris) + tris = R_Shadow_BuildShadowVolumeTriangles(elements, neighbors, numverts, trianglefacinglight, trianglefacinglightlist, tris, shadowelements); + if (!tris) return; + + // by clever use of elements we can construct the whole shadow from + // the unprojected vertices and the projected vertices + R_Shadow_ProjectVertices(varray_vertex, numverts, relativelightorigin, projectdistance); + if (r_shadowstage == SHADOWSTAGE_STENCIL) { // increment stencil if backface is behind depthbuffer qglCullFace(GL_BACK); // quake is backwards, this culls front faces qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP); - R_Mesh_Draw(numverts, numtris, elements); + R_Mesh_Draw(numverts * 2, tris, shadowelements); c_rt_shadowmeshes++; c_rt_shadowtris += numtris; // decrement stencil if frontface is behind depthbuffer qglCullFace(GL_FRONT); // quake is backwards, this culls back faces qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP); } - R_Mesh_Draw(numverts, numtris, elements); + R_Mesh_Draw(numverts * 2, tris, shadowelements); c_rt_shadowmeshes++; c_rt_shadowtris += numtris; } @@ -351,7 +399,7 @@ void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *firstmesh) qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP); for (mesh = firstmesh;mesh;mesh = mesh->next) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements); c_rtcached_shadowmeshes++; @@ -363,7 +411,7 @@ void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *firstmesh) } for (mesh = firstmesh;mesh;mesh = mesh->next) { - R_Mesh_ResizeCheck(mesh->numverts); + R_Mesh_GetSpace(mesh->numverts); memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements); c_rtcached_shadowmeshes++; @@ -1024,7 +1072,7 @@ void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out, int numverts, cons } } -void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) +void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) { int renders; float color[3]; @@ -1050,9 +1098,11 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(0,0,0,1); qglDisable(GL_BLEND); GL_Color(1,1,1,1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin); - R_Shadow_TransformVertices(varray_texcoord[2], numverts, varray_vertex, matrix_modeltoattenuationxyz); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin); + R_Shadow_TransformVertices(varray_texcoord[2], numverts, vertices, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1067,13 +1117,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); qglEnable(GL_BLEND); - if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltofilter); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); + if (lightcubemap) + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1087,7 +1140,9 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(0,0,0,1); qglDisable(GL_BLEND); GL_Color(1,1,1,1); - R_Shadow_TransformVertices(varray_texcoord[0], numverts, varray_vertex, matrix_modeltoattenuationxyz); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Shadow_TransformVertices(varray_texcoord[0], numverts, vertices, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1100,8 +1155,10 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_TextureState(&m); qglBlendFunc(GL_DST_ALPHA, GL_ZERO); qglEnable(GL_BLEND); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1113,13 +1170,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_TextureState(&m); qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltofilter); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); + if (lightcubemap) + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1137,8 +1197,10 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element GL_Color(1,1,1,1); qglColorMask(0,0,0,1); qglDisable(GL_BLEND); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1151,12 +1213,15 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); qglEnable(GL_BLEND); - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltoattenuationxyz); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1175,10 +1240,12 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(0,0,0,1); qglDisable(GL_BLEND); GL_Color(1,1,1,1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin); - R_Shadow_TransformVertices(varray_texcoord[2], numverts, varray_vertex, matrix_modeltoattenuationxyz); - R_Shadow_TransformVertices(varray_texcoord[3], numverts, varray_vertex, matrix_modeltoattenuationz); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin); + R_Shadow_TransformVertices(varray_texcoord[2], numverts, vertices, matrix_modeltoattenuationxyz); + R_Shadow_TransformVertices(varray_texcoord[3], numverts, vertices, matrix_modeltoattenuationz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1193,13 +1260,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); qglEnable(GL_BLEND); - if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltofilter); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); + if (lightcubemap) + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1214,8 +1284,10 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(0,0,0,1); qglDisable(GL_BLEND); GL_Color(1,1,1,1); - R_Shadow_TransformVertices(varray_texcoord[0], numverts, varray_vertex, matrix_modeltoattenuationxyz); - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltoattenuationz); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Shadow_TransformVertices(varray_texcoord[0], numverts, vertices, matrix_modeltoattenuationxyz); + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltoattenuationz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1228,8 +1300,10 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_TextureState(&m); qglBlendFunc(GL_DST_ALPHA, GL_ZERO); qglEnable(GL_BLEND); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1241,13 +1315,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_TextureState(&m); qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltofilter); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); + if (lightcubemap) + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1273,10 +1350,12 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_State(&m); #endif GL_UseColorArray(); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltoattenuationxyz); + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltoattenuationxyz); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); - R_Shadow_VertexLightingWithXYAttenuationTexture(varray_color, numverts, varray_vertex, normals, color, relativelightorigin, lightradius, matrix_modeltofilter->m[2]); + R_Shadow_VertexLightingWithXYAttenuationTexture(varray_color, numverts, vertices, normals, color, relativelightorigin, lightradius, matrix_modeltofilter->m[2]); R_Mesh_Draw(numverts, numtriangles, elements); } else @@ -1294,15 +1373,17 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_State(&m); #endif GL_UseColorArray(); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); - R_Shadow_VertexLighting(varray_color, numverts, varray_vertex, normals, color, relativelightorigin, lightradius); + R_Shadow_VertexLighting(varray_color, numverts, vertices, normals, color, relativelightorigin, lightradius); R_Mesh_Draw(numverts, numtriangles, elements); } } } -void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) +void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) { int renders; float color[3]; @@ -1326,8 +1407,10 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglColorMask(0,0,0,1); qglDisable(GL_BLEND); GL_Color(1,1,1,1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); + R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1341,22 +1424,23 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglEnable(GL_BLEND); // these comments are a test run through this math for intensity 0.5 // 0.5 * 0.5 = 0.25 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; // 0.25 * 0.25 = 0.0625 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; // 0.0625 * 0.0625 = 0.00390625 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; + for (renders = 0;renders < 3;renders++) + { + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Mesh_Draw(numverts, numtriangles, elements); + } + c_rt_lightmeshes += 3; + c_rt_lighttris += numtriangles * 3; m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture); R_Mesh_TextureState(&m); qglBlendFunc(GL_DST_ALPHA, GL_ZERO); - R_Shadow_TransformVertices(varray_texcoord[0], numverts, varray_vertex, matrix_modeltoattenuationxyz); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Shadow_TransformVertices(varray_texcoord[0], numverts, vertices, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1367,14 +1451,16 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen R_Mesh_TextureState(&m); qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltofilter); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color); for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); + if (lightcubemap) + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1390,8 +1476,10 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglColorMask(0,0,0,1); qglDisable(GL_BLEND); GL_Color(1,1,1,1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); + R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1405,26 +1493,22 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglEnable(GL_BLEND); // these comments are a test run through this math for intensity 0.5 // 0.5 * 0.5 = 0.25 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; // 0.25 * 0.25 = 0.0625 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; // 0.0625 * 0.0625 = 0.00390625 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; + for (renders = 0;renders < 3;renders++) + { + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Mesh_Draw(numverts, numtriangles, elements); + } + c_rt_lightmeshes += 3; + c_rt_lighttris += numtriangles * 3; m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture); m.tex[1] = R_GetTexture(glosstexture); R_Mesh_TextureState(&m); - R_Shadow_TransformVertices(varray_texcoord[0], numverts, varray_vertex, matrix_modeltoattenuationxyz); - memcpy(varray_texcoord[1], texcoords, numverts * sizeof(float[4])); qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1432,6 +1516,10 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Shadow_TransformVertices(varray_texcoord[0], numverts, vertices, matrix_modeltoattenuationxyz); + memcpy(varray_texcoord[1], texcoords, numverts * sizeof(float[4])); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1447,8 +1535,10 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglColorMask(0,0,0,1); qglDisable(GL_BLEND); GL_Color(1,1,1,1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); + R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord[1], numverts, vertices, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1462,24 +1552,25 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglEnable(GL_BLEND); // these comments are a test run through this math for intensity 0.5 // 0.5 * 0.5 = 0.25 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; // 0.25 * 0.25 = 0.0625 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; // 0.0625 * 0.0625 = 0.00390625 - R_Mesh_Draw(numverts, numtriangles, elements); - c_rt_lightmeshes++; - c_rt_lighttris += numtriangles; + for (renders = 0;renders < 3;renders++) + { + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Mesh_Draw(numverts, numtriangles, elements); + } + c_rt_lightmeshes += 3; + c_rt_lighttris += numtriangles * 3; m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture); m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); R_Mesh_TextureState(&m); qglBlendFunc(GL_DST_ALPHA, GL_ZERO); - R_Shadow_TransformVertices(varray_texcoord[0], numverts, varray_vertex, matrix_modeltoattenuationxyz); - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltoattenuationz); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Shadow_TransformVertices(varray_texcoord[0], numverts, vertices, matrix_modeltoattenuationxyz); + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltoattenuationz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1489,14 +1580,16 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen R_Mesh_TextureState(&m); qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); - if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, varray_vertex, matrix_modeltofilter); VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color); for (renders = 0;renders < 64 && (color[0] > 0 || color[1] > 0 || color[2] > 0);renders++, color[0] = max(0, color[0] - 1.0f), color[1] = max(0, color[1] - 1.0f), color[2] = max(0, color[2] - 1.0f)) { GL_Color(color[0], color[1], color[2], 1); + R_Mesh_GetSpace(numverts); + memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4])); + if (lightcubemap) + R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1697,11 +1790,14 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style // now that we have the buffers big enough, construct shadow volume mesh memcpy(verts, castmesh->verts, castmesh->numverts * sizeof(float[4])); R_Shadow_ProjectVertices(verts, castmesh->numverts, e->origin, r_shadow_projectdistance.value);//, e->lightradius); - R_Shadow_MakeTriangleShadowFlags(castmesh->elements, verts, castmesh->numtriangles, trianglefacinglight, e->origin, e->lightradius); - tris = R_Shadow_BuildShadowVolumeTriangles(castmesh->elements, castmesh->neighbors, castmesh->numtriangles, castmesh->numverts, trianglefacinglight, shadowelements); + tris = R_Shadow_MakeTriangleShadowFlags(castmesh->elements, verts, castmesh->numtriangles, trianglefacinglight, trianglefacinglightlist, e->origin); + tris = R_Shadow_BuildShadowVolumeTriangles(castmesh->elements, castmesh->neighbors, castmesh->numverts, trianglefacinglight, trianglefacinglightlist, tris, shadowelements); // add the constructed shadow volume mesh Mod_ShadowMesh_AddMesh(r_shadow_mempool, e->shadowvolume, castmesh->numverts, verts, tris, shadowelements); } + if (verts) + Mem_Free(verts); + verts = NULL; // we're done with castmesh now Mod_ShadowMesh_Free(castmesh); e->shadowvolume = Mod_ShadowMesh_Finish(r_shadow_mempool, e->shadowvolume); @@ -1767,6 +1863,7 @@ void R_DrawLightSprite(int texnum, const vec3_t origin, vec_t scale, float cr, f R_Mesh_State(&m); GL_Color(cr * r_colorscale, cg * r_colorscale, cb * r_colorscale, ca); + R_Mesh_GetSpace(4); varray_texcoord[0][ 0] = 0;varray_texcoord[0][ 1] = 0; varray_texcoord[0][ 4] = 0;varray_texcoord[0][ 5] = 1; varray_texcoord[0][ 8] = 1;varray_texcoord[0][ 9] = 1; diff --git a/r_shadow.h b/r_shadow.h index 46dac70e..ca623469 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -12,11 +12,13 @@ extern cvar_t r_shadow_bumpscale_basetexture; void R_Shadow_Init(void); void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance); -void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); -void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); +void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); +void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); void R_Shadow_ClearStencil(void); -void R_Shadow_RenderVolume(int numverts, int numtris, int *elements); +// buffer space for the requested number of vertices, for processing +float *R_Shadow_VertexBuffer(int numvertices); + void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *mesh); void R_Shadow_Stage_Begin(void); void R_Shadow_Stage_ShadowVolumes(void); diff --git a/r_sky.c b/r_sky.c index 631da10e..4fa301d2 100644 --- a/r_sky.c +++ b/r_sky.c @@ -127,50 +127,61 @@ static void R_SkyBox(void) varray_texcoord[0][i * 4 + 0] = (s);\ varray_texcoord[0][i * 4 + 1] = (t); + GL_Color(r_colorscale, r_colorscale, r_colorscale, 1); + memset(&m, 0, sizeof(m)); m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; m.depthdisable = true; // don't modify or read zbuffer + m.tex[0] = R_GetTexture(skyboxside[3]); // front R_Mesh_State(&m); - - GL_Color(r_colorscale, r_colorscale, r_colorscale, 1); - + R_Mesh_GetSpace(4); R_SkyBoxPolyVec(0, 1, 0, 1, -1, 1); R_SkyBoxPolyVec(1, 1, 1, 1, -1, -1); R_SkyBoxPolyVec(2, 0, 1, 1, 1, -1); R_SkyBoxPolyVec(3, 0, 0, 1, 1, 1); R_Mesh_Draw(4, 2, polygonelements); + m.tex[0] = R_GetTexture(skyboxside[1]); // back - R_Mesh_State(&m); + R_Mesh_TextureState(&m); + R_Mesh_GetSpace(4); R_SkyBoxPolyVec(0, 1, 0, -1, 1, 1); R_SkyBoxPolyVec(1, 1, 1, -1, 1, -1); R_SkyBoxPolyVec(2, 0, 1, -1, -1, -1); R_SkyBoxPolyVec(3, 0, 0, -1, -1, 1); R_Mesh_Draw(4, 2, polygonelements); + m.tex[0] = R_GetTexture(skyboxside[0]); // right - R_Mesh_State(&m); + R_Mesh_TextureState(&m); + R_Mesh_GetSpace(4); R_SkyBoxPolyVec(0, 1, 0, 1, 1, 1); R_SkyBoxPolyVec(1, 1, 1, 1, 1, -1); R_SkyBoxPolyVec(2, 0, 1, -1, 1, -1); R_SkyBoxPolyVec(3, 0, 0, -1, 1, 1); R_Mesh_Draw(4, 2, polygonelements); + m.tex[0] = R_GetTexture(skyboxside[2]); // left - R_Mesh_State(&m); + R_Mesh_TextureState(&m); + R_Mesh_GetSpace(4); R_SkyBoxPolyVec(0, 1, 0, -1, -1, 1); R_SkyBoxPolyVec(1, 1, 1, -1, -1, -1); R_SkyBoxPolyVec(2, 0, 1, 1, -1, -1); R_SkyBoxPolyVec(3, 0, 0, 1, -1, 1); R_Mesh_Draw(4, 2, polygonelements); + m.tex[0] = R_GetTexture(skyboxside[4]); // up - R_Mesh_State(&m); + R_Mesh_TextureState(&m); + R_Mesh_GetSpace(4); R_SkyBoxPolyVec(0, 1, 0, 1, -1, 1); R_SkyBoxPolyVec(1, 1, 1, 1, 1, 1); R_SkyBoxPolyVec(2, 0, 1, -1, 1, 1); R_SkyBoxPolyVec(3, 0, 0, -1, -1, 1); R_Mesh_Draw(4, 2, polygonelements); + m.tex[0] = R_GetTexture(skyboxside[5]); // down - R_Mesh_State(&m); + R_Mesh_TextureState(&m); + R_Mesh_GetSpace(4); R_SkyBoxPolyVec(0, 1, 0, 1, 1, -1); R_SkyBoxPolyVec(1, 1, 1, 1, -1, -1); R_SkyBoxPolyVec(2, 0, 1, -1, -1, -1); @@ -257,8 +268,6 @@ static void R_SkySphere(void) // wrap the scroll just to be extra kind to float accuracy speedscale -= (int)speedscale; - R_Mesh_ResizeCheck(skysphere_numverts); - memset(&m, 0, sizeof(m)); m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; @@ -268,6 +277,7 @@ static void R_SkySphere(void) GL_Color(r_colorscale, r_colorscale, r_colorscale, 1); + R_Mesh_GetSpace(skysphere_numverts); memcpy(varray_vertex, skysphere_vertex, skysphere_numverts * sizeof(float[4])); memcpy(varray_texcoord[0], skysphere_texcoord, skysphere_numverts * sizeof(float[4])); for (i = 0, t = varray_texcoord[0];i < skysphere_numverts;i++, t += 4) @@ -282,7 +292,12 @@ static void R_SkySphere(void) m.tex[0] = R_GetTexture(alphaskytexture); R_Mesh_State(&m); - // scroll it again, this makes the lower cloud layer scroll twice as fast (just like quake did) + // scroll the lower cloud layer twice as fast (just like quake did) + speedscale *= 2; + + R_Mesh_GetSpace(skysphere_numverts); + memcpy(varray_vertex, skysphere_vertex, skysphere_numverts * sizeof(float[4])); + memcpy(varray_texcoord[0], skysphere_texcoord, skysphere_numverts * sizeof(float[4])); for (i = 0, t = varray_texcoord[0];i < skysphere_numverts;i++, t += 4) { t[0] += speedscale; diff --git a/r_sprites.c b/r_sprites.c index 5da6042a..de9a7c44 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -89,6 +89,8 @@ static void R_DrawSpriteImage (int additive, mspriteframe_t *frame, int texture, m.tex[0] = texture; R_Mesh_State(&m); + GL_Color(red * r_colorscale, green * r_colorscale, blue * r_colorscale, alpha); + R_Mesh_GetSpace(4); varray_texcoord[0][ 0] = 0;varray_texcoord[0][ 1] = 1; varray_texcoord[0][ 4] = 0;varray_texcoord[0][ 5] = 0; varray_texcoord[0][ 8] = 1;varray_texcoord[0][ 9] = 0; @@ -106,7 +108,6 @@ static void R_DrawSpriteImage (int additive, mspriteframe_t *frame, int texture, varray_vertex[12] = origin[0] + frame->down * up[0] - frame->right * left[0]; varray_vertex[13] = origin[1] + frame->down * up[1] - frame->right * left[1]; varray_vertex[14] = origin[2] + frame->down * up[2] - frame->right * left[2]; - GL_Color(red * r_colorscale, green * r_colorscale, blue * r_colorscale, alpha); R_Mesh_Draw(4, 2, polygonelements); }