From: havoc Date: Sat, 15 Mar 2003 04:54:47 +0000 (+0000) Subject: varray_* rewritten to remove padding (varray_vertex3f, varray_texcoord2f, varray_texc... X-Git-Tag: xonotic-v0.1.0preview~6723 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=224f9edae92441767654e2c10eb568bb91f86eb1 varray_* rewritten to remove padding (varray_vertex3f, varray_texcoord2f, varray_texcoord3f, varray_color4f now exist), this required changes to a huge amount of code (but netted a 30% speed gain typically) fixed some various bugs added voodoo1/2 support in realtime lighting engine (well, except for the fact it still requires stencil, which voodoo1/2 don't have, this will be addressed later when world lights and dlights are independently controlled) changed lightning beams a bit (they're now white) and due to a request I added support for r_lightningbeam_qmbtexture (loads textures/particles/lightning.pcx and knows approximately how to use it, I recommend changing r_lightningbeam_repeatdistance to make it look right) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2842 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_main.c b/cl_main.c index 9b70f0fc..341cdccd 100644 --- a/cl_main.c +++ b/cl_main.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "cl_collision.h" #include "cl_video.h" +#include "image.h" // we need to declare some mouse variables here, because the menu system // references them even when on a unix system. @@ -55,6 +56,7 @@ cvar_t cl_stainmaps = {CVAR_SAVE, "cl_stainmaps", "1"}; cvar_t cl_beams_polygons = {CVAR_SAVE, "cl_beams_polygons", "1"}; cvar_t cl_beams_relative = {CVAR_SAVE, "cl_beams_relative", "1"}; +cvar_t cl_beams_lightatend = {CVAR_SAVE, "cl_beams_lightatend", "0"}; cvar_t cl_noplayershadow = {CVAR_SAVE, "cl_noplayershadow", "0"}; @@ -957,8 +959,13 @@ void CL_RelinkBeams (void) } } - if (b->lightning && cl_beams_polygons.integer) - continue; + if (b->lightning) + { + if (cl_beams_lightatend.integer) + CL_AllocDlight (NULL, b->end, 200, 0.3, 0.7, 1, 0, 0); + if (cl_beams_polygons.integer) + continue; + } // calculate pitch and yaw VectorSubtract (b->end, b->start, dist); @@ -1012,52 +1019,150 @@ cvar_t r_lightningbeam_repeatdistance = {CVAR_SAVE, "r_lightningbeam_repeatdista cvar_t r_lightningbeam_color_red = {CVAR_SAVE, "r_lightningbeam_color_red", "1"}; cvar_t r_lightningbeam_color_green = {CVAR_SAVE, "r_lightningbeam_color_green", "1"}; cvar_t r_lightningbeam_color_blue = {CVAR_SAVE, "r_lightningbeam_color_blue", "1"}; +cvar_t r_lightningbeam_qmbtexture = {CVAR_SAVE, "r_lightningbeam_qmbtexture", "0"}; rtexture_t *r_lightningbeamtexture; +rtexture_t *r_lightningbeamqmbtexture; rtexturepool_t *r_lightningbeamtexturepool; int r_lightningbeamelements[18] = {0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11}; void r_lightningbeams_start(void) { + r_lightningbeamtexturepool = R_AllocTexturePool(); + r_lightningbeamtexture = NULL; + r_lightningbeamqmbtexture = NULL; +} + +void r_lightningbeams_setupqmbtexture(void) +{ + r_lightningbeamqmbtexture = loadtextureimage(r_lightningbeamtexturepool, "textures/particles/lightning.pcx", 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE); + if (r_lightningbeamqmbtexture == NULL) + Cvar_SetValueQuick(&r_lightningbeam_qmbtexture, false); +} + +void r_lightningbeams_setuptexture(void) +{ +#if 0 +#define BEAMWIDTH 128 +#define BEAMHEIGHT 64 +#define PATHPOINTS 8 + int i, j, px, py, nearestpathindex, imagenumber; + float particlex, particley, particlexv, particleyv, dx, dy, s, maxpathstrength; + qbyte *pixels; + int *image; + struct {float x, y, strength;} path[PATHPOINTS], temppath; + + image = Mem_Alloc(tempmempool, BEAMWIDTH * BEAMHEIGHT * sizeof(int)); + pixels = Mem_Alloc(tempmempool, BEAMWIDTH * BEAMHEIGHT * sizeof(qbyte[4])); + + for (imagenumber = 0, maxpathstrength = 0.0339476;maxpathstrength < 0.5;imagenumber++, maxpathstrength += 0.01) + { + for (i = 0;i < PATHPOINTS;i++) + { + path[i].x = lhrandom(0, 1); + path[i].y = lhrandom(0.2, 0.8); + path[i].strength = lhrandom(0, 1); + } + for (i = 0;i < PATHPOINTS;i++) + { + for (j = i + 1;j < PATHPOINTS;j++) + { + if (path[j].x < path[i].x) + { + temppath = path[j]; + path[j] = path[i]; + path[i] = temppath; + } + } + } + particlex = path[0].x; + particley = path[0].y; + particlexv = lhrandom(0, 0.02); + particlexv = lhrandom(-0.02, 0.02); + memset(image, 0, BEAMWIDTH * BEAMHEIGHT * sizeof(int)); + for (i = 0;i < 65536;i++) + { + for (nearestpathindex = 0;nearestpathindex < PATHPOINTS;nearestpathindex++) + if (path[nearestpathindex].x > particlex) + break; + nearestpathindex %= PATHPOINTS; + dx = path[nearestpathindex].x + lhrandom(-0.01, 0.01);dx = bound(0, dx, 1) - particlex;if (dx < 0) dx += 1; + dy = path[nearestpathindex].y + lhrandom(-0.01, 0.01);dy = bound(0, dy, 1) - particley; + s = path[nearestpathindex].strength / sqrt(dx*dx+dy*dy); + particlexv = particlexv /* (1 - lhrandom(0.08, 0.12))*/ + dx * s; + particleyv = particleyv /* (1 - lhrandom(0.08, 0.12))*/ + dy * s; + particlex += particlexv * maxpathstrength;particlex -= (int) particlex; + particley += particleyv * maxpathstrength;particley = bound(0, particley, 1); + px = particlex * BEAMWIDTH; + py = particley * BEAMHEIGHT; + if (px >= 0 && py >= 0 && px < BEAMWIDTH && py < BEAMHEIGHT) + image[py*BEAMWIDTH+px] += 16; + } + + for (py = 0;py < BEAMHEIGHT;py++) + { + for (px = 0;px < BEAMWIDTH;px++) + { + pixels[(py*BEAMWIDTH+px)*4+0] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); + pixels[(py*BEAMWIDTH+px)*4+1] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); + pixels[(py*BEAMWIDTH+px)*4+2] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); + pixels[(py*BEAMWIDTH+px)*4+3] = 255; + } + } + + Image_WriteTGARGBA(va("lightningbeam%i.tga", imagenumber), BEAMWIDTH, BEAMHEIGHT, pixels); + } + + r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, pixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + + Mem_Free(pixels); + Mem_Free(image); +#else +#define BEAMWIDTH 64 +#define BEAMHEIGHT 128 float r, g, b, intensity, fx, width, center; int x, y; qbyte *data, *noise1, *noise2; - data = Mem_Alloc(tempmempool, 32 * 512 * 4); - noise1 = Mem_Alloc(tempmempool, 512 * 512); - noise2 = Mem_Alloc(tempmempool, 512 * 512); - fractalnoise(noise1, 512, 8); - fractalnoise(noise2, 512, 16); - for (y = 0;y < 512;y++) + data = Mem_Alloc(tempmempool, BEAMWIDTH * BEAMHEIGHT * 4); + noise1 = Mem_Alloc(tempmempool, BEAMHEIGHT * BEAMHEIGHT); + noise2 = Mem_Alloc(tempmempool, BEAMHEIGHT * BEAMHEIGHT); + fractalnoise(noise1, BEAMHEIGHT, BEAMHEIGHT / 8); + fractalnoise(noise2, BEAMHEIGHT, BEAMHEIGHT / 16); + + for (y = 0;y < BEAMHEIGHT;y++) { - width = noise1[y * 512] * (1.0f / 256.0f) * 3.0f + 3.0f; - center = (noise1[y * 512 + 64] / 256.0f) * (32.0f - (width + 1.0f) * 2.0f) + (width + 1.0f); - for (x = 0;x < 32;x++, fx++) + width = 0.15;//((noise1[y * BEAMHEIGHT] * (1.0f / 256.0f)) * 0.1f + 0.1f); + center = (noise1[y * BEAMHEIGHT + (BEAMHEIGHT / 2)] / 256.0f) * (1.0f - width * 2.0f) + width; + for (x = 0;x < BEAMWIDTH;x++, fx++) { - fx = (x - center) / width; - intensity = (1.0f - fx * fx) * (noise2[y*512+x] * (1.0f / 256.0f) * 0.33f + 0.66f); + fx = (((float) x / BEAMWIDTH) - center) / width; + intensity = 1.0f - sqrt(fx * fx); + if (intensity > 0) + intensity = pow(intensity, 2) * ((noise2[y * BEAMHEIGHT + x] * (1.0f / 256.0f)) * 0.33f + 0.66f); intensity = bound(0, intensity, 1); - r = intensity * 2.0f - 1.0f; - g = intensity * 3.0f - 1.0f; - b = intensity * 3.0f; - data[(y * 32 + x) * 4 + 0] = (qbyte)(bound(0, r, 1) * 255.0f); - data[(y * 32 + x) * 4 + 1] = (qbyte)(bound(0, g, 1) * 255.0f); - data[(y * 32 + x) * 4 + 2] = (qbyte)(bound(0, b, 1) * 255.0f); - data[(y * 32 + x) * 4 + 3] = (qbyte)255; + r = intensity * 1.0f; + g = intensity * 1.0f; + b = intensity * 1.0f; + data[(y * BEAMWIDTH + x) * 4 + 0] = (qbyte)(bound(0, r, 1) * 255.0f); + data[(y * BEAMWIDTH + x) * 4 + 1] = (qbyte)(bound(0, g, 1) * 255.0f); + data[(y * BEAMWIDTH + x) * 4 + 2] = (qbyte)(bound(0, b, 1) * 255.0f); + data[(y * BEAMWIDTH + x) * 4 + 3] = (qbyte)255; } } - r_lightningbeamtexturepool = R_AllocTexturePool(); - r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", 32, 512, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); Mem_Free(noise1); Mem_Free(noise2); Mem_Free(data); +#endif } void r_lightningbeams_shutdown(void) { r_lightningbeamtexture = NULL; + r_lightningbeamqmbtexture = NULL; R_FreeTexturePool(&r_lightningbeamtexturepool); } @@ -1073,27 +1178,54 @@ void R_LightningBeams_Init(void) Cvar_RegisterVariable(&r_lightningbeam_color_red); Cvar_RegisterVariable(&r_lightningbeam_color_green); Cvar_RegisterVariable(&r_lightningbeam_color_blue); + Cvar_RegisterVariable(&r_lightningbeam_qmbtexture); R_RegisterModule("R_LightningBeams", r_lightningbeams_start, r_lightningbeams_shutdown, r_lightningbeams_newmap); } -void R_CalcLightningBeamPolygonVertices(float *v, float *tc, const float *start, const float *end, const float *offset, float t1, float t2) +void R_CalcLightningBeamPolygonVertex3f(float *v, const float *start, const float *end, const float *offset) { // near right corner - VectorAdd (start, offset, (v + 0));tc[ 0] = 0;tc[ 1] = t1; + VectorAdd (start, offset, (v + 0)); // near left corner - VectorSubtract(start, offset, (v + 4));tc[ 4] = 1;tc[ 5] = t1; + VectorSubtract(start, offset, (v + 3)); // far left corner - VectorSubtract(end , offset, (v + 8));tc[ 8] = 1;tc[ 9] = t2; + VectorSubtract(end , offset, (v + 6)); // far right corner - VectorAdd (end , offset, (v + 12));tc[12] = 0;tc[13] = t2; + VectorAdd (end , offset, (v + 9)); } -void R_FogLightningBeamColors(const float *v, float *c, int numverts, float r, float g, float b, float a) +void R_CalcLightningBeamPolygonTexCoord2f(float *tc, float t1, float t2) +{ + if (r_lightningbeam_qmbtexture.integer) + { + // near right corner + tc[0] = t1;tc[1] = 0; + // near left corner + tc[2] = t1;tc[3] = 1; + // far left corner + tc[4] = t2;tc[5] = 1; + // far right corner + tc[6] = t2;tc[7] = 0; + } + else + { + // near right corner + tc[0] = 0;tc[1] = t1; + // near left corner + tc[2] = 1;tc[3] = t1; + // far left corner + tc[4] = 1;tc[5] = t2; + // far right corner + tc[6] = 0;tc[7] = t2; + } +} + +void R_FogLightningBeam_Vertex3f_Color4f(const float *v, float *c, int numverts, float r, float g, float b, float a) { int i; vec3_t fogvec; float ifog; - for (i = 0;i < numverts;i++, v += 4, c += 4) + for (i = 0;i < numverts;i++, v += 3, c += 4) { VectorSubtract(v, r_origin, fogvec); ifog = 1 - exp(fogdensity/DotProduct(fogvec,fogvec)); @@ -1115,7 +1247,14 @@ void R_DrawLightningBeamCallback(const void *calldata1, int calldata2) memset(&m, 0, sizeof(m)); m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.tex[0] = R_GetTexture(r_lightningbeamtexture); + if (r_lightningbeam_qmbtexture.integer && r_lightningbeamqmbtexture == NULL) + r_lightningbeams_setupqmbtexture(); + if (!r_lightningbeam_qmbtexture.integer && r_lightningbeamtexture == NULL) + r_lightningbeams_setuptexture(); + if (r_lightningbeam_qmbtexture.integer) + m.tex[0] = R_GetTexture(r_lightningbeamqmbtexture); + else + m.tex[0] = R_GetTexture(r_lightningbeamtexture); R_Mesh_State(&m); R_Mesh_Matrix(&r_identitymatrix); @@ -1143,7 +1282,7 @@ void R_DrawLightningBeamCallback(const void *calldata1, int calldata2) CrossProduct(beamdir, up, right); // calculate T coordinate scrolling (start and end texcoord along the beam) - t1 = cl.time * -r_lightningbeam_scroll.value + beamrepeatscale * DotProduct(b->start, beamdir); + t1 = cl.time * -r_lightningbeam_scroll.value;// + beamrepeatscale * DotProduct(b->start, beamdir); t1 = t1 - (int) t1; t2 = t1 + beamrepeatscale * length; @@ -1162,23 +1301,26 @@ void R_DrawLightningBeamCallback(const void *calldata1, int calldata2) // 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); + R_CalcLightningBeamPolygonVertex3f(varray_vertex3f, b->start, b->end, offset); + R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0], t1, t2); // polygon 2, verts 4-7 VectorAdd(right, up, offset); VectorScale(offset, r_lightningbeam_thickness.value * 0.70710681f, offset); - R_CalcLightningBeamPolygonVertices(varray_vertex + 16, varray_texcoord[0] + 16, b->start, b->end, offset, t1 + 0.33, t2 + 0.33); + R_CalcLightningBeamPolygonVertex3f(varray_vertex3f + 12, b->start, b->end, offset); + R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0] + 8, t1 + 0.33, t2 + 0.33); // polygon 3, verts 8-11 VectorSubtract(right, up, offset); VectorScale(offset, r_lightningbeam_thickness.value * 0.70710681f, offset); - R_CalcLightningBeamPolygonVertices(varray_vertex + 32, varray_texcoord[0] + 32, b->start, b->end, offset, t1 + 0.66, t2 + 0.66); + R_CalcLightningBeamPolygonVertex3f(varray_vertex3f + 24, b->start, b->end, offset); + R_CalcLightningBeamPolygonTexCoord2f(varray_texcoord2f[0] + 16, t1 + 0.66, t2 + 0.66); if (fogenabled) { // per vertex colors if fog is used GL_UseColorArray(); - R_FogLightningBeamColors(varray_vertex, varray_color, 12, r_lightningbeam_color_red.value, r_lightningbeam_color_green.value, r_lightningbeam_color_blue.value, 1); + R_FogLightningBeam_Vertex3f_Color4f(varray_vertex3f, varray_color4f, 12, r_lightningbeam_color_red.value, r_lightningbeam_color_green.value, r_lightningbeam_color_blue.value, 1); } else { @@ -1537,6 +1679,7 @@ void CL_Init (void) Cvar_RegisterVariable(&cl_stainmaps); Cvar_RegisterVariable(&cl_beams_polygons); Cvar_RegisterVariable(&cl_beams_relative); + Cvar_RegisterVariable(&cl_beams_lightatend); Cvar_RegisterVariable(&cl_noplayershadow); R_LightningBeams_Init(); diff --git a/cl_particles.c b/cl_particles.c index 68a2b56b..d0b5fd57 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -41,7 +41,7 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i #define CL_RunParticleEffect R_RunParticleEffect #define CL_LavaSplash R_LavaSplash #define CL_RocketTrail2 R_RocketTrail2 -void R_CalcBeamVerts (float *vert, vec3_t org1, vec3_t org2, float width) +void R_CalcBeam_Vertex3f (float *vert, vec3_t org1, vec3_t org2, float width) { vec3_t right1, right2, diff, normal; @@ -61,15 +61,15 @@ void R_CalcBeamVerts (float *vert, vec3_t org1, vec3_t org2, float width) vert[ 0] = org1[0] + width * right1[0]; vert[ 1] = org1[1] + width * right1[1]; vert[ 2] = org1[2] + width * right1[2]; - vert[ 4] = org1[0] - width * right1[0]; - vert[ 5] = org1[1] - width * right1[1]; - vert[ 6] = org1[2] - width * right1[2]; - vert[ 8] = org2[0] - width * right2[0]; - vert[ 9] = org2[1] - width * right2[1]; - vert[10] = org2[2] - width * right2[2]; - vert[12] = org2[0] + width * right2[0]; - vert[13] = org2[1] + width * right2[1]; - vert[14] = org2[2] + width * right2[2]; + vert[ 3] = org1[0] - width * right1[0]; + vert[ 4] = org1[1] - width * right1[1]; + vert[ 5] = org1[2] - width * right1[2]; + vert[ 6] = org2[0] - width * right2[0]; + vert[ 7] = org2[1] - width * right2[1]; + vert[ 8] = org2[2] - width * right2[2]; + vert[ 9] = org2[0] + width * right2[0]; + vert[10] = org2[1] + width * right2[1]; + vert[11] = org2[2] + width * right2[2]; } void fractalnoise(qbyte *noise, int size, int startgrid) { @@ -443,9 +443,9 @@ void CL_EntityParticles (entity_t *ent) forward[2] = -sp; #ifdef WORKINGLQUAKE - particle(pt_static, PARTICLE_BILLBOARD, particlepalette[0x6f], particlepalette[0x6f], tex_particle, false, PBLEND_ALPHA, 2, 2, 255, 0, 0, 0, 0, ent->origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_static, PARTICLE_BILLBOARD, particlepalette[0x6f], particlepalette[0x6f], tex_particle, false, PBLEND_ADD, 2, 2, 255, 0, 0, 0, 0, ent->origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0, 0, 0, 0, 0, 0, 0); #else - particle(pt_static, PARTICLE_BILLBOARD, particlepalette[0x6f], particlepalette[0x6f], tex_particle, false, PBLEND_ALPHA, 2, 2, 255, 0, 0, 0, 0, ent->render.origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->render.origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->render.origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_static, PARTICLE_BILLBOARD, particlepalette[0x6f], particlepalette[0x6f], tex_particle, false, PBLEND_ADD, 2, 2, 255, 0, 0, 0, 0, ent->render.origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->render.origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->render.origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0, 0, 0, 0, 0, 0, 0); #endif } } @@ -572,7 +572,7 @@ void CL_ParticleExplosion (vec3_t org) /* // LordHavoc: smoke effect similar to UT2003, chews fillrate too badly up close // smoke puff - if (cl_particles_smoke.integer) + if (cl_particles.integer && cl_particles_smoke.integer) { for (i = 0;i < 64;i++) { @@ -597,7 +597,7 @@ void CL_ParticleExplosion (vec3_t org) } */ - if (cl_particles_sparks.integer) + if (cl_particles.integer && cl_particles_sparks.integer) { // sparks for (i = 0;i < 256;i++) @@ -678,11 +678,12 @@ void CL_SparkShower (vec3_t org, vec3_t dir, int count) { vec3_t org2, org3; int k; - if (!cl_particles.integer) return; if (cl_stainmaps.integer) R_Stain(org, 32, 96, 96, 96, 24, 128, 128, 128, 24); + if (!cl_particles.integer) return; + if (cl_particles_bulletimpacts.integer) { // smoke puff @@ -1026,7 +1027,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 1: // grenade trail // FIXME: make it gradually stop smoking dec = 3; - if (cl_particles.integer && cl_particles_smoke.integer) + if (smoke) { particle(pt_grow, PARTICLE_BILLBOARD, 0x303030, 0x606060, tex_smoke[rand()&7], false, PBLEND_ADD, dec, dec, cl_particles_smoke_alpha.value*100, cl_particles_smoke_alphafade.value*100, 9999, 0, 0, pos[0], pos[1], pos[2], lhrandom(-5, 5), lhrandom(-5, 5), lhrandom(-5, 5), cl_particles_smoke_size.value, 0, 0, 0, 0, 0); } @@ -1669,7 +1670,7 @@ void R_InitParticles(void) R_Particles_Init(); } -float varray_vertex[16], varray_texcoord[1][16]; +float varray_vertex3f[12], varray_texcoord2f[1][8]; #endif #ifdef WORKINGLQUAKE @@ -1746,77 +1747,67 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) R_Mesh_GetSpace(4); #endif - if (p->orientation == PARTICLE_BILLBOARD) + if (p->orientation == PARTICLE_BILLBOARD || p->orientation == PARTICLE_ORIENTED_DOUBLESIDED) { - 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]; + 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); + } + else + { + VectorScale(vright, p->scalex, right); + VectorScale(vup, p->scaley, up); + } + varray_vertex3f[ 0] = org[0] - right[0] - up[0]; + varray_vertex3f[ 1] = org[1] - right[1] - up[1]; + varray_vertex3f[ 2] = org[2] - right[2] - up[2]; + varray_vertex3f[ 3] = org[0] - right[0] + up[0]; + varray_vertex3f[ 4] = org[1] - right[1] + up[1]; + varray_vertex3f[ 5] = org[2] - right[2] + up[2]; + varray_vertex3f[ 6] = org[0] + right[0] + up[0]; + varray_vertex3f[ 7] = org[1] + right[1] + up[1]; + varray_vertex3f[ 8] = org[2] + right[2] + up[2]; + varray_vertex3f[ 9] = org[0] + right[0] - up[0]; + varray_vertex3f[10] = org[1] + right[1] - up[1]; + varray_vertex3f[11] = org[2] + right[2] - up[2]; + varray_texcoord2f[0][0] = tex->s1;varray_texcoord2f[0][1] = tex->t2; + varray_texcoord2f[0][2] = tex->s1;varray_texcoord2f[0][3] = tex->t1; + varray_texcoord2f[0][4] = tex->s2;varray_texcoord2f[0][5] = tex->t1; + varray_texcoord2f[0][6] = tex->s2;varray_texcoord2f[0][7] = tex->t2; } 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); + R_CalcBeam_Vertex3f(varray_vertex3f, v, up2, p->scalex); + varray_texcoord2f[0][0] = tex->s1;varray_texcoord2f[0][1] = tex->t2; + varray_texcoord2f[0][2] = tex->s1;varray_texcoord2f[0][3] = tex->t1; + varray_texcoord2f[0][4] = tex->s2;varray_texcoord2f[0][5] = tex->t1; + varray_texcoord2f[0][6] = tex->s2;varray_texcoord2f[0][7] = tex->t2; } 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) { + R_CalcBeam_Vertex3f(varray_vertex3f, p->org, p->vel2, p->scalex); VectorSubtract(p->vel2, p->org, up); VectorNormalizeFast(up); v[0] = DotProduct(p->org, up) * (1.0f / 64.0f) - cl.time * 0.25; v[1] = DotProduct(p->vel2, up) * (1.0f / 64.0f) - cl.time * 0.25; - varray_texcoord[0][0] = 1;varray_texcoord[0][1] = v[0]; - varray_texcoord[0][4] = 0;varray_texcoord[0][5] = v[0]; - varray_texcoord[0][8] = 0;varray_texcoord[0][9] = v[1]; - varray_texcoord[0][12] = 1;varray_texcoord[0][13] = v[1]; + varray_texcoord2f[0][0] = 1;varray_texcoord2f[0][1] = v[0]; + varray_texcoord2f[0][2] = 0;varray_texcoord2f[0][3] = v[0]; + varray_texcoord2f[0][4] = 0;varray_texcoord2f[0][5] = v[1]; + varray_texcoord2f[0][6] = 1;varray_texcoord2f[0][7] = v[1]; } else - { - varray_texcoord[0][0] = tex->s2;varray_texcoord[0][1] = tex->t1; - varray_texcoord[0][4] = tex->s1;varray_texcoord[0][5] = tex->t1; - varray_texcoord[0][8] = tex->s1;varray_texcoord[0][9] = tex->t2; - varray_texcoord[0][12] = tex->s2;varray_texcoord[0][13] = tex->t2; - } + Host_Error("R_DrawParticles: unknown particle orientation %i\n", p->orientation); #if WORKINGLQUAKE if (p->blendmode == 0) @@ -1827,10 +1818,10 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) 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]); + glTexCoord2f(varray_texcoord2f[0][0], varray_texcoord2f[0][1]);glVertex3f(varray_vertex3f[ 0], varray_vertex3f[ 1], varray_vertex3f[ 2]); + glTexCoord2f(varray_texcoord2f[0][2], varray_texcoord2f[0][3]);glVertex3f(varray_vertex3f[ 3], varray_vertex3f[ 4], varray_vertex3f[ 5]); + glTexCoord2f(varray_texcoord2f[0][4], varray_texcoord2f[0][5]);glVertex3f(varray_vertex3f[ 6], varray_vertex3f[ 7], varray_vertex3f[ 8]); + glTexCoord2f(varray_texcoord2f[0][6], varray_texcoord2f[0][7]);glVertex3f(varray_vertex3f[ 9], varray_vertex3f[10], varray_vertex3f[11]); glEnd(); #else R_Mesh_Draw(4, 2, polygonelements); diff --git a/cl_screen.c b/cl_screen.c index 9c350b61..8e23cc53 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -513,19 +513,19 @@ void DrawQ_Pic(float x, float y, char *picname, float width, float height, float mesh.numtriangles = 2; mesh.numvertices = 4; mesh.indices = picelements; - mesh.vertices = floats; - mesh.texcoords = floats + 16; - mesh.colors = floats + 32; + mesh.vertex3f = floats; + mesh.texcoord2f = floats + 16; + mesh.color4f = floats + 32; memset(floats, 0, sizeof(floats)); - mesh.vertices[0] = mesh.vertices[12] = x; - mesh.vertices[1] = mesh.vertices[5] = y; - mesh.vertices[4] = mesh.vertices[8] = x + width; - mesh.vertices[9] = mesh.vertices[13] = y + height; - mesh.texcoords[4] = mesh.texcoords[8] = mesh.texcoords[9] = mesh.texcoords[13] = 1; - mesh.colors[0] = mesh.colors[4] = mesh.colors[8] = mesh.colors[12] = red; - mesh.colors[1] = mesh.colors[5] = mesh.colors[9] = mesh.colors[13] = green; - mesh.colors[2] = mesh.colors[6] = mesh.colors[10] = mesh.colors[14] = blue; - mesh.colors[3] = mesh.colors[7] = mesh.colors[11] = mesh.colors[15] = alpha; + mesh.vertex3f[0] = mesh.vertex3f[12] = x; + mesh.vertex3f[1] = mesh.vertex3f[5] = y; + mesh.vertex3f[4] = mesh.vertex3f[8] = x + width; + mesh.vertex3f[9] = mesh.vertex3f[13] = y + height; + mesh.texcoord2f[4] = mesh.texcoord2f[8] = mesh.texcoord2f[9] = mesh.texcoord2f[13] = 1; + mesh.color4f[0] = mesh.color4f[4] = mesh.color4f[8] = mesh.color4f[12] = red; + mesh.color4f[1] = mesh.color4f[5] = mesh.color4f[9] = mesh.color4f[13] = green; + mesh.color4f[2] = mesh.color4f[6] = mesh.color4f[10] = mesh.color4f[14] = blue; + mesh.color4f[3] = mesh.color4f[7] = mesh.color4f[11] = mesh.color4f[15] = alpha; DrawQ_Mesh (&mesh, flags); #else int size; @@ -606,18 +606,18 @@ void DrawQ_Fill (float x, float y, float w, float h, float red, float green, flo mesh.numtriangles = 2; mesh.numvertices = 4; mesh.indices = picelements; - mesh.vertices = floats; - mesh.texcoords = floats + 16; - mesh.colors = floats + 32; + mesh.vertex3f = floats; + mesh.texcoord2f = floats + 16; + mesh.color4f = floats + 32; memset(floats, 0, sizeof(floats)); - mesh.vertices[0] = mesh.vertices[12] = x; - mesh.vertices[1] = mesh.vertices[5] = y; - mesh.vertices[4] = mesh.vertices[8] = x + w; - mesh.vertices[9] = mesh.vertices[13] = y + h; - mesh.colors[0] = mesh.colors[4] = mesh.colors[8] = mesh.colors[12] = red; - mesh.colors[1] = mesh.colors[5] = mesh.colors[9] = mesh.colors[13] = green; - mesh.colors[2] = mesh.colors[6] = mesh.colors[10] = mesh.colors[14] = blue; - mesh.colors[3] = mesh.colors[7] = mesh.colors[11] = mesh.colors[15] = alpha; + mesh.vertex3f[0] = mesh.vertex3f[12] = x; + mesh.vertex3f[1] = mesh.vertex3f[5] = y; + mesh.vertex3f[4] = mesh.vertex3f[8] = x + w; + mesh.vertex3f[9] = mesh.vertex3f[13] = y + h; + mesh.color4f[0] = mesh.color4f[4] = mesh.color4f[8] = mesh.color4f[12] = red; + mesh.color4f[1] = mesh.color4f[5] = mesh.color4f[9] = mesh.color4f[13] = green; + mesh.color4f[2] = mesh.color4f[6] = mesh.color4f[10] = mesh.color4f[14] = blue; + mesh.color4f[3] = mesh.color4f[7] = mesh.color4f[11] = mesh.color4f[15] = alpha; DrawQ_Mesh (&mesh, flags); #else int size; @@ -648,7 +648,7 @@ void DrawQ_Fill (float x, float y, float w, float h, float red, float green, flo void DrawQ_SuperPic(float x, float y, char *picname, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags) { - float floats[48]; + float floats[36]; cachepic_t *pic; drawqueuemesh_t mesh; memset(&mesh, 0, sizeof(mesh)); @@ -663,19 +663,19 @@ void DrawQ_SuperPic(float x, float y, char *picname, float width, float height, } mesh.numtriangles = 2; mesh.numvertices = 4; - mesh.indices = picelements; - mesh.vertices = floats; - mesh.texcoords = floats + 16; - mesh.colors = floats + 32; + mesh.element3i = picelements; + mesh.vertex3f = floats; + mesh.texcoord2f = floats + 12; + mesh.color4f = floats + 20; memset(floats, 0, sizeof(floats)); - mesh.vertices[0] = mesh.vertices[12] = x; - mesh.vertices[1] = mesh.vertices[5] = y; - mesh.vertices[4] = mesh.vertices[8] = x + width; - mesh.vertices[9] = mesh.vertices[13] = y + height; - mesh.texcoords[ 0] = s1;mesh.texcoords[ 1] = t1;mesh.colors[ 0] = r1;mesh.colors[ 1] = g1;mesh.colors[ 2] = b1;mesh.colors[ 3] = a1; - mesh.texcoords[ 4] = s2;mesh.texcoords[ 5] = t2;mesh.colors[ 4] = r2;mesh.colors[ 5] = g2;mesh.colors[ 6] = b2;mesh.colors[ 7] = a2; - mesh.texcoords[ 8] = s4;mesh.texcoords[ 9] = t4;mesh.colors[ 8] = r4;mesh.colors[ 9] = g4;mesh.colors[10] = b4;mesh.colors[11] = a4; - mesh.texcoords[12] = s3;mesh.texcoords[13] = t3;mesh.colors[12] = r3;mesh.colors[13] = g3;mesh.colors[14] = b3;mesh.colors[15] = a3; + mesh.vertex3f[0] = mesh.vertex3f[9] = x; + mesh.vertex3f[1] = mesh.vertex3f[4] = y; + mesh.vertex3f[3] = mesh.vertex3f[6] = x + width; + mesh.vertex3f[7] = mesh.vertex3f[10] = y + height; + mesh.texcoord2f[0] = s1;mesh.texcoord2f[1] = t1;mesh.color4f[ 0] = r1;mesh.color4f[ 1] = g1;mesh.color4f[ 2] = b1;mesh.color4f[ 3] = a1; + mesh.texcoord2f[2] = s2;mesh.texcoord2f[3] = t2;mesh.color4f[ 4] = r2;mesh.color4f[ 5] = g2;mesh.color4f[ 6] = b2;mesh.color4f[ 7] = a2; + mesh.texcoord2f[4] = s4;mesh.texcoord2f[5] = t4;mesh.color4f[ 8] = r4;mesh.color4f[ 9] = g4;mesh.color4f[10] = b4;mesh.color4f[11] = a4; + mesh.texcoord2f[6] = s3;mesh.texcoord2f[7] = t3;mesh.color4f[12] = r3;mesh.color4f[13] = g3;mesh.color4f[14] = b3;mesh.color4f[15] = a3; DrawQ_Mesh (&mesh, flags); } @@ -688,8 +688,8 @@ void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags) size = sizeof(*dq); size += sizeof(drawqueuemesh_t); size += sizeof(int[3]) * mesh->numtriangles; - size += sizeof(float[4]) * mesh->numvertices; - size += sizeof(float[4]) * mesh->numvertices; + size += sizeof(float[3]) * mesh->numvertices; + size += sizeof(float[2]) * mesh->numvertices; size += sizeof(float[4]) * mesh->numvertices; if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize) return; @@ -707,10 +707,10 @@ void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags) m->numtriangles = mesh->numtriangles; m->numvertices = mesh->numvertices; m->texture = mesh->texture; - m->indices = p;memcpy(m->indices , mesh->indices , m->numtriangles * sizeof(int[3]));(qbyte *)p += m->numtriangles * sizeof(int[3]); - m->vertices = p;memcpy(m->vertices , mesh->vertices , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]); - m->texcoords = p;memcpy(m->texcoords, mesh->texcoords, m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]); - m->colors = p;memcpy(m->colors , mesh->colors , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]); + m->element3i = p;memcpy(m->element3i , mesh->element3i , m->numtriangles * sizeof(int[3]));(qbyte *)p += m->numtriangles * sizeof(int[3]); + m->vertex3f = p;memcpy(m->vertex3f , mesh->vertex3f , m->numvertices * sizeof(float[3]));(qbyte *)p += m->numvertices * sizeof(float[3]); + m->texcoord2f = p;memcpy(m->texcoord2f, mesh->texcoord2f, m->numvertices * sizeof(float[2]));(qbyte *)p += m->numvertices * sizeof(float[2]); + m->color4f = p;memcpy(m->color4f , mesh->color4f , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]); r_refdef.drawqueuesize += dq->size; } diff --git a/cl_screen.h b/cl_screen.h index 76c343d3..ec41eace 100644 --- a/cl_screen.h +++ b/cl_screen.h @@ -25,10 +25,10 @@ typedef struct drawqueuemesh_s rtexture_t *texture; int numtriangles; int numvertices; - int *indices; - float *vertices; - float *texcoords; - float *colors; + int *element3i; + float *vertex3f; + float *texcoord2f; + float *color4f; } drawqueuemesh_t; diff --git a/cl_video.c b/cl_video.c index 4778c818..fb42b6f0 100644 --- a/cl_video.c +++ b/cl_video.c @@ -90,38 +90,31 @@ void CL_DrawVideo(void) if (cl_videoplaying) { drawqueuemesh_t mesh; - int indices[6]; - float vertices[16]; - float texcoords[8]; - float colorsf[16]; + float vertex3f[12]; + float texcoord2f[8]; + float color4f[16]; float s1, t1, s2, t2, x1, y1, x2, y2; - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - indices[3] = 0; - indices[4] = 2; - indices[5] = 3; x1 = 0; y1 = 0; x2 = vid.conwidth; y2 = vid.conheight; R_FragmentLocation(cl_videotexture, NULL, NULL, &s1, &t1, &s2, &t2); - texcoords[0] = s1;texcoords[1] = t1; - texcoords[2] = s2;texcoords[3] = t1; - texcoords[4] = s2;texcoords[5] = t2; - texcoords[6] = s1;texcoords[7] = t2; - R_FillColors(colorsf, 4, r_colorscale, r_colorscale, r_colorscale, 1); - vertices[ 0] = x1;vertices[ 1] = y1;vertices[ 2] = 0;vertices[ 3] = 0; - vertices[ 4] = x2;vertices[ 5] = y1;vertices[ 6] = 0;vertices[ 7] = 0; - vertices[ 8] = x2;vertices[ 9] = y2;vertices[10] = 0;vertices[11] = 0; - vertices[12] = x1;vertices[13] = y2;vertices[14] = 0;vertices[15] = 0; + texcoord2f[0] = s1;texcoord2f[1] = t1; + texcoord2f[2] = s2;texcoord2f[3] = t1; + texcoord2f[4] = s2;texcoord2f[5] = t2; + texcoord2f[6] = s1;texcoord2f[7] = t2; + R_FillColors(color4f, 4, r_colorscale, r_colorscale, r_colorscale, 1); + vertex3f[ 0] = x1;vertex3f[ 1] = y1;vertex3f[ 2] = 0; + vertex3f[ 3] = x2;vertex3f[ 4] = y1;vertex3f[ 5] = 0; + vertex3f[ 6] = x2;vertex3f[ 7] = y2;vertex3f[ 8] = 0; + vertex3f[ 9] = x1;vertex3f[10] = y2;vertex3f[11] = 0; mesh.texture = cl_videotexture; mesh.numtriangles = 2; mesh.numvertices = 4; - mesh.indices = indices; - mesh.vertices = vertices; - mesh.texcoords = texcoords; - mesh.colors = colorsf; + mesh.element3i = polygonelements; + mesh.vertex3f = vertex3f; + mesh.texcoord2f = texcoord2f; + mesh.color4f = color4f; DrawQ_Mesh(&mesh, 0); //DrawQ_Pic(0, 0, "engine_videoframe", vid.conwidth, vid.conheight, 1, 1, 1, 1, 0); } diff --git a/gl_backend.c b/gl_backend.c index 3be69651..a4549527 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -76,16 +76,18 @@ void SCR_ScreenShot_f (void); // these are externally accessible int r_lightmapscalebit; float r_colorscale; -GLfloat *varray_vertex, *varray_buf_vertex; -GLfloat *varray_color, *varray_buf_color; -GLfloat *varray_texcoord[MAX_TEXTUREUNITS], *varray_buf_texcoord[MAX_TEXTUREUNITS]; +GLfloat *varray_vertex3f, *varray_buf_vertex3f; +GLfloat *varray_color4f, *varray_buf_color4f; +GLfloat *varray_texcoord3f[MAX_TEXTUREUNITS], *varray_buf_texcoord3f[MAX_TEXTUREUNITS]; +GLfloat *varray_texcoord2f[MAX_TEXTUREUNITS], *varray_buf_texcoord2f[MAX_TEXTUREUNITS]; +static qbyte *varray_color4b, *varray_buf_color4b; int mesh_maxverts; int mesh_var; float mesh_var_readfrequency; float mesh_var_writefrequency; float mesh_var_priority; int varray_offset = 0, varray_offsetnext = 0; -GLuint *varray_buf_elements; +GLuint *varray_buf_elements3i; int mesh_maxelements = 3072; static matrix4x4_t backend_viewmatrix; @@ -95,7 +97,6 @@ static matrix4x4_t backend_glmodelviewmatrix; static matrix4x4_t backend_projectmatrix; static int backendunits, backendactive; -static GLubyte *varray_bcolor, *varray_buf_bcolor; static mempool_t *gl_backend_mempool; /* @@ -117,16 +118,16 @@ A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E 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)); + if (varray_buf_elements3i) + Mem_Free(varray_buf_elements3i); + varray_buf_elements3i = 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; + if (varray_buf_elements3i) + Mem_Free(varray_buf_elements3i); + varray_buf_elements3i = NULL; } void GL_Backend_CheckCvars(void) @@ -157,16 +158,17 @@ int polygonelements[768]; void GL_Backend_AllocArrays(void) { int i, size; + qbyte *data; if (!gl_backend_mempool) { gl_backend_mempool = Mem_AllocPool("GL_Backend"); - varray_buf_vertex = NULL; - varray_buf_color = NULL; - varray_buf_bcolor = NULL; - varray_buf_elements = NULL; + varray_buf_vertex3f = NULL; + varray_buf_color4f = NULL; + varray_buf_color4b = NULL; + varray_buf_elements3i = NULL; for (i = 0;i < MAX_TEXTUREUNITS;i++) - varray_buf_texcoord[i] = NULL; + varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL; } mesh_maxverts = gl_mesh_maxverts.integer; @@ -175,29 +177,33 @@ void GL_Backend_AllocArrays(void) mesh_var_writefrequency = gl_mesh_vertex_array_range_writefrequency.value; mesh_var_priority = gl_mesh_vertex_array_range_priority.value; - if (varray_buf_vertex) - VID_FreeVertexArrays(varray_buf_vertex); - varray_buf_vertex = NULL; - varray_buf_color = NULL; - varray_buf_bcolor = NULL; + if (varray_buf_vertex3f) + VID_FreeVertexArrays(varray_buf_vertex3f); + varray_buf_vertex3f = NULL; + varray_buf_color4f = NULL; + varray_buf_color4b = NULL; for (i = 0;i < MAX_TEXTUREUNITS;i++) - varray_buf_texcoord[i] = NULL; + varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL; - size = mesh_maxverts * (sizeof(GLfloat[4]) + sizeof(GLfloat[4]) + sizeof(GLfloat[4]) * backendunits + sizeof(GLubyte[4])); - varray_buf_vertex = VID_AllocVertexArrays(gl_backend_mempool, size, gl_mesh_vertex_array_range.integer, gl_mesh_vertex_array_range_readfrequency.value, gl_mesh_vertex_array_range_writefrequency.value, gl_mesh_vertex_array_range_priority.value); - varray_buf_color = varray_buf_vertex + 4 * mesh_maxverts; + size = mesh_maxverts * (sizeof(float[3]) + sizeof(float[4]) + sizeof(qbyte[4]) + (sizeof(float[3]) + sizeof(float[2])) * backendunits); + data = VID_AllocVertexArrays(gl_backend_mempool, size, gl_mesh_vertex_array_range.integer, gl_mesh_vertex_array_range_readfrequency.value, gl_mesh_vertex_array_range_writefrequency.value, gl_mesh_vertex_array_range_priority.value); + varray_buf_vertex3f = (void *)data;data += sizeof(float[3]) * mesh_maxverts; + varray_buf_color4f = (void *)data;data += sizeof(float[4]) * mesh_maxverts; for (i = 0;i < backendunits;i++) - varray_buf_texcoord[i] = varray_buf_vertex + (i + 2) * 4 * mesh_maxverts; + { + varray_buf_texcoord3f[i] = (void *)data;data += sizeof(float[3]) * mesh_maxverts; + varray_buf_texcoord2f[i] = (void *)data;data += sizeof(float[2]) * mesh_maxverts; + } for (;i < MAX_TEXTUREUNITS;i++) - varray_buf_texcoord[i] = NULL; - varray_buf_bcolor = (GLubyte *)(varray_buf_vertex + (backendunits + 2) * 4 * mesh_maxverts); + varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL; + varray_buf_color4b = (void *)data;data += sizeof(qbyte[4]) * mesh_maxverts; GL_Backend_AllocElementsArray(); if (gl_support_var) { CHECKGLERROR - qglVertexArrayRangeNV(size, varray_buf_vertex); + qglVertexArrayRangeNV(size, varray_buf_vertex3f); CHECKGLERROR qglEnableClientState(GL_VERTEX_ARRAY_RANGE_NV); CHECKGLERROR @@ -215,17 +221,16 @@ void GL_Backend_FreeArrays(void) CHECKGLERROR } - if (varray_buf_vertex) - VID_FreeVertexArrays(varray_buf_vertex); - varray_buf_vertex = NULL; - varray_buf_color = NULL; - varray_buf_bcolor = NULL; + if (varray_buf_vertex3f) + VID_FreeVertexArrays(varray_buf_vertex3f); + varray_buf_vertex3f = NULL; + varray_buf_color4f = NULL; + varray_buf_color4b = NULL; for (i = 0;i < MAX_TEXTUREUNITS;i++) - varray_buf_texcoord[i] = NULL; + varray_buf_texcoord3f[i] = varray_buf_texcoord2f[i] = NULL; + varray_buf_elements3i = NULL; Mem_FreePool(&gl_backend_mempool); - - varray_buf_elements = NULL; } static void gl_backend_start(void) @@ -417,7 +422,7 @@ void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double typedef struct gltextureunit_s { int t1d, t2d, t3d, tcubemap; - int arrayenabled; + int arrayenabled, arrayis3d; float rgbscale, alphascale; int combinergb, combinealpha; // FIXME: add more combine stuff @@ -458,15 +463,9 @@ void GL_SetupTextureState(void) unit->combinergb = GL_MODULATE; unit->combinealpha = GL_MODULATE; unit->arrayenabled = false; + unit->arrayis3d = false; qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR - if (gl_texture3d || gl_texturecubemap) - { - qglTexCoordPointer(3, GL_FLOAT, sizeof(float[4]), varray_buf_texcoord[i]);CHECKGLERROR - } - else - { - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[4]), varray_buf_texcoord[i]);CHECKGLERROR - } + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), varray_buf_texcoord2f[i]);CHECKGLERROR qglDisable(GL_TEXTURE_1D);CHECKGLERROR qglDisable(GL_TEXTURE_2D);CHECKGLERROR if (gl_texture3d) @@ -523,15 +522,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(GLfloat[4]), varray_buf_vertex);CHECKGLERROR + qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), varray_buf_vertex3f);CHECKGLERROR qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR if (gl_mesh_floatcolors.integer) { - qglColorPointer(4, GL_FLOAT, sizeof(GLfloat[4]), varray_buf_color);CHECKGLERROR + qglColorPointer(4, GL_FLOAT, sizeof(float[4]), varray_buf_color4f);CHECKGLERROR } else { - qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(GLubyte[4]), varray_buf_bcolor);CHECKGLERROR + qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(qbyte[4]), varray_buf_color4b);CHECKGLERROR } GL_Color(1, 1, 1, 1); @@ -610,7 +609,7 @@ void GL_ConvertColorsFloatToByte(int numverts) total = numverts * 4; // shift float to have 8bit fraction at base of number - fcolor = varray_buf_color; + fcolor = varray_buf_color4f; for (i = 0;i < total;) { fcolor[i ] += 32768.0f; @@ -621,8 +620,8 @@ void GL_ConvertColorsFloatToByte(int numverts) } // then read as integer and kill float bits... - icolor = (int *)varray_buf_color; - bcolor = varray_buf_bcolor; + icolor = (int *)varray_buf_color4f; + bcolor = varray_buf_color4b; for (i = 0;i < total;) { k = icolor[i ] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i ] = (GLubyte) k; @@ -650,7 +649,7 @@ 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; + varray_buf_elements3i[i] = in[i] + offset; } // gets geometry space for a mesh @@ -680,11 +679,14 @@ void R_Mesh_GetSpace(int numverts) //if (!mesh_var) // 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; + varray_vertex3f = varray_buf_vertex3f + varray_offset * 3; + varray_color4f = varray_buf_color4f + varray_offset * 4; + varray_color4b = varray_buf_color4b + varray_offset * 4; for (i = 0;i < backendunits;i++) - varray_texcoord[i] = varray_buf_texcoord[i] + varray_offset * 4; + { + varray_texcoord3f[i] = varray_buf_texcoord3f[i] + varray_offset * 3; + varray_texcoord2f[i] = varray_buf_texcoord2f[i] + varray_offset * 2; + } varray_offsetnext = varray_offset + numverts; } @@ -717,12 +719,12 @@ void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) 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); + qglDrawRangeElements(GL_TRIANGLES, varray_offset, varray_offset + numverts, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements3i); CHECKGLERROR } else { - qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements); + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements3i); CHECKGLERROR } qglUnlockArraysEXT(); @@ -730,7 +732,7 @@ void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) } else { - qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements); + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) varray_buf_elements3i); CHECKGLERROR } } @@ -862,12 +864,38 @@ void R_Mesh_TextureState(const rmeshstate_t *m) unit = gl_state.units + i; if (unit->t1d != m->tex1d[i] || unit->t2d != m->tex[i] || unit->t3d != m->tex3d[i] || unit->tcubemap != m->texcubemap[i]) { - if (gl_state.unit != i) + if (m->tex3d[i] || m->texcubemap[i]) { - qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR + if (!unit->arrayis3d) + { + unit->arrayis3d = true; + if (gl_state.clientunit != i) + { + qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR + } + qglTexCoordPointer(3, GL_FLOAT, sizeof(float[3]), varray_buf_texcoord3f[i]); + } + if (!unit->arrayenabled) + { + unit->arrayenabled = true; + if (gl_state.clientunit != i) + { + qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR + } + qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } } - if (m->tex1d[i] || m->tex[i] || m->tex3d[i] || m->texcubemap[i]) + else if (m->tex1d[i] || m->tex[i]) { + if (unit->arrayis3d) + { + unit->arrayis3d = false; + if (gl_state.clientunit != i) + { + qglClientActiveTexture(GL_TEXTURE0_ARB + (gl_state.clientunit = i));CHECKGLERROR + } + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), varray_buf_texcoord2f[i]); + } if (!unit->arrayenabled) { unit->arrayenabled = true; @@ -890,34 +918,12 @@ void R_Mesh_TextureState(const rmeshstate_t *m) qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR } } - combinergb = m->texcombinergb[i]; - combinealpha = m->texcombinealpha[i]; - if (!combinergb) - combinergb = GL_MODULATE; - if (!combinealpha) - combinealpha = GL_MODULATE; - if (unit->combinergb != combinergb) - { - unit->combinergb = combinergb; - if (gl_combine.integer) - { - qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR - } - else - { - qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combinergb);CHECKGLERROR - } - } - if (unit->combinealpha != combinealpha) + if (unit->t1d != m->tex1d[i]) { - unit->combinealpha = combinealpha; - if (gl_combine.integer) + if (gl_state.unit != i) { - qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR + qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR } - } - if (unit->t1d != m->tex1d[i]) - { if (m->tex1d[i]) { if (unit->t1d == 0) @@ -932,6 +938,10 @@ void R_Mesh_TextureState(const rmeshstate_t *m) } if (unit->t2d != m->tex[i]) { + if (gl_state.unit != i) + { + qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR + } if (m->tex[i]) { if (unit->t2d == 0) @@ -946,6 +956,10 @@ void R_Mesh_TextureState(const rmeshstate_t *m) } if (unit->t3d != m->tex3d[i]) { + if (gl_state.unit != i) + { + qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR + } if (m->tex3d[i]) { if (unit->t3d == 0) @@ -960,6 +974,10 @@ void R_Mesh_TextureState(const rmeshstate_t *m) } if (unit->tcubemap != m->texcubemap[i]) { + if (gl_state.unit != i) + { + qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR + } if (m->texcubemap[i]) { if (unit->tcubemap == 0) @@ -973,6 +991,40 @@ void R_Mesh_TextureState(const rmeshstate_t *m) qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, (unit->tcubemap = m->texcubemap[i]));CHECKGLERROR } } + combinergb = m->texcombinergb[i]; + if (!combinergb) + combinergb = GL_MODULATE; + if (unit->combinergb != combinergb) + { + if (gl_state.unit != i) + { + qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR + } + unit->combinergb = combinergb; + if (gl_combine.integer) + { + qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR + } + else + { + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combinergb);CHECKGLERROR + } + } + combinealpha = m->texcombinealpha[i]; + if (!combinealpha) + combinealpha = GL_MODULATE; + if (unit->combinealpha != combinealpha) + { + if (gl_state.unit != i) + { + qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR + } + unit->combinealpha = combinealpha; + if (gl_combine.integer) + { + qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR + } + } scale = max(m->texrgbscale[i], 1); if (gl_state.units[i].rgbscale != scale) { @@ -1126,3 +1178,54 @@ void SCR_UpdateScreen (void) } } +// utility functions + +void R_Mesh_CopyVertex3f(const float *vertex3f, int numverts) +{ + if (mesh_var) + { + float *out = varray_vertex3f; + while (--numverts) + { + *out++ = *vertex3f++; + *out++ = *vertex3f++; + *out++ = *vertex3f++; + } + } + else + memcpy(varray_vertex3f, vertex3f, numverts * sizeof(float[3])); +} + +void R_Mesh_CopyTexCoord2f(int tmu, const float *texcoord2f, int numverts) +{ + if (mesh_var) + { + float *out = varray_texcoord2f[tmu]; + while (--numverts) + { + *out++ = *texcoord2f++; + *out++ = *texcoord2f++; + } + } + else + memcpy(varray_texcoord2f[tmu], texcoord2f, numverts * sizeof(float[2])); +} + +void R_Mesh_CopyColor4f(const float *color4f, int numverts) +{ + if (mesh_var) + { + float *out = varray_color4f; + while (--numverts) + { + *out++ = *color4f++; + *out++ = *color4f++; + *out++ = *color4f++; + *out++ = *color4f++; + } + } + else + memcpy(varray_color4f, color4f, numverts * sizeof(float[4])); +} + + diff --git a/gl_backend.h b/gl_backend.h index 9569ade2..89f0a886 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -43,9 +43,10 @@ rmeshstate_t; // overbright rendering scale for the current state extern int r_lightmapscalebit; extern float r_colorscale; -extern float *varray_vertex; -extern float *varray_color; -extern float *varray_texcoord[MAX_TEXTUREUNITS]; +extern float *varray_vertex3f; +extern float *varray_color4f; +extern float *varray_texcoord3f[MAX_TEXTUREUNITS]; +extern float *varray_texcoord2f[MAX_TEXTUREUNITS]; extern int mesh_maxverts; // adds console variables and registers the render module (only call from GL_Init) @@ -75,6 +76,13 @@ void R_Mesh_GetSpace(int numverts); // renders the mesh in the varray_* buffers void R_Mesh_Draw(int numverts, int numtriangles, const int *elements); +// copies a vertex3f array into varray_vertex3f +void R_Mesh_CopyVertex3f(const float *vertex3f, int numverts); +// copies a texcoord2f array into varray_texcoord[tmu] +void R_Mesh_CopyTexCoord2f(int tmu, const float *texcoord2f, int numverts); +// copies a color4f array into varray_color4f +void R_Mesh_CopyColor4f(const float *color4f, int numverts); + // saves a section of the rendered frame to a .tga file qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height); // used by R_Envmap_f and internally in backend, clears the frame diff --git a/gl_draw.c b/gl_draw.c index d36af9c4..8885586b 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -377,9 +377,12 @@ void GL_Draw_Init (void) R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap); } +float blendtexcoord2f[6] = {0, 0, 0, 0, 0, 0}; +float blendvertex3f[9] = {-5000, -5000, 10, 10000, -5000, 10, -5000, 10000, 10}; + int quadelements[768]; -float textverts[128*4*4]; -float texttexcoords[128*4*4]; +float textverts[128*4*3]; +float texttexcoords[128*4*2]; void R_DrawQueue(void) { int pos, num, chartexnum, overbright, texnum, additive, batch; @@ -475,14 +478,14 @@ void R_DrawQueue(void) } 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; - varray_texcoord[0][12] = 0;varray_texcoord[0][13] = 1; - varray_vertex[ 0] = x ;varray_vertex[ 1] = y ;varray_vertex[ 2] = 10; - 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; + varray_texcoord2f[0][0] = 0;varray_texcoord2f[0][1] = 0; + varray_texcoord2f[0][2] = 1;varray_texcoord2f[0][3] = 0; + varray_texcoord2f[0][4] = 1;varray_texcoord2f[0][5] = 1; + varray_texcoord2f[0][6] = 0;varray_texcoord2f[0][7] = 1; + varray_vertex3f[ 0] = x ;varray_vertex3f[ 1] = y ;varray_vertex3f[ 2] = 10; + varray_vertex3f[ 3] = x+w;varray_vertex3f[ 4] = y ;varray_vertex3f[ 5] = 10; + varray_vertex3f[ 6] = x+w;varray_vertex3f[ 7] = y+h;varray_vertex3f[ 8] = 10; + varray_vertex3f[ 9] = x ;varray_vertex3f[10] = y+h;varray_vertex3f[11] = 10; R_Mesh_Draw(4, 2, quadelements); break; case DRAWQUEUE_STRING: @@ -506,21 +509,21 @@ void R_DrawQueue(void) u = 0.0625f - (1.0f / 256.0f); v = 0.0625f - (1.0f / 256.0f); at[ 0] = s ;at[ 1] = t ; - at[ 4] = s+u;at[ 5] = t ; - at[ 8] = s+u;at[ 9] = t+v; - at[12] = s ;at[13] = t+v; + at[ 2] = s+u;at[ 3] = t ; + at[ 4] = s+u;at[ 5] = t+v; + at[ 6] = s ;at[ 7] = t+v; av[ 0] = x ;av[ 1] = y ;av[ 2] = 10; - av[ 4] = x+w;av[ 5] = y ;av[ 6] = 10; - av[ 8] = x+w;av[ 9] = y+h;av[10] = 10; - av[12] = x ;av[13] = y+h;av[14] = 10; - at += 16; - av += 16; + av[ 3] = x+w;av[ 4] = y ;av[ 5] = 10; + av[ 6] = x+w;av[ 7] = y+h;av[ 8] = 10; + av[ 9] = x ;av[10] = y+h;av[11] = 10; + at += 8; + av += 12; 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_CopyVertex3f(textverts, batchcount * 4); + R_Mesh_CopyTexCoord2f(0, texttexcoords, batchcount * 4); R_Mesh_Draw(batchcount * 4, batchcount * 2, quadelements); batchcount = 0; at = texttexcoords; @@ -532,8 +535,8 @@ void R_DrawQueue(void) 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_CopyVertex3f(textverts, batchcount * 4); + R_Mesh_CopyTexCoord2f(0, texttexcoords, batchcount * 4); R_Mesh_Draw(batchcount * 4, batchcount * 2, quadelements); } break; @@ -543,10 +546,10 @@ void R_DrawQueue(void) R_Mesh_TextureState(&m); 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); - R_Mesh_Draw(mesh->numvertices, mesh->numtriangles, mesh->indices); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numvertices); + R_Mesh_CopyTexCoord2f(0, mesh->texcoord2f, mesh->numvertices); + R_Mesh_CopyColor4f(mesh->color4f, mesh->numvertices); + R_Mesh_Draw(mesh->numvertices, mesh->numtriangles, mesh->element3i); currentpic = "\0"; break; } @@ -575,12 +578,8 @@ void R_DrawQueue(void) { 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_CopyVertex3f(blendvertex3f, 3); + R_Mesh_CopyTexCoord2f(0, blendtexcoord2f, 3); R_Mesh_Draw(3, 1, polygonelements); VectorScale(c, 0.5, c); } @@ -600,12 +599,8 @@ void R_DrawQueue(void) 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_CopyVertex3f(blendvertex3f, 3); + R_Mesh_CopyTexCoord2f(0, blendtexcoord2f, 3); R_Mesh_Draw(3, 1, polygonelements); } } diff --git a/gl_models.c b/gl_models.c index 9d85d079..13cc278d 100644 --- a/gl_models.c +++ b/gl_models.c @@ -9,34 +9,63 @@ typedef struct } zymbonematrix; // LordHavoc: vertex arrays - -float *aliasvertcolorbuf; -float *aliasvertcolor; // this may point at aliasvertcolorbuf or at vertex arrays in the mesh backend -float *aliasvert_svectors; -float *aliasvert_tvectors; -float *aliasvert_normals; - -float *aliasvertcolor2; +int aliasvertmax = 0; +void *aliasvertarrays = NULL; +float *aliasvertcolor4fbuf = NULL; +float *aliasvertcolor4f = NULL; // this may point at aliasvertcolorbuf or at vertex arrays in the mesh backend +float *aliasvert_svector3f = NULL; +float *aliasvert_tvector3f = NULL; +float *aliasvert_normal3f = NULL; + +float *aliasvertcolor2_4f = NULL; int *aliasvertusage; zymbonematrix *zymbonepose; mempool_t *gl_models_mempool; +#define expandaliasvert(newmax) if ((newmax) > aliasvertmax) gl_models_allocarrays(newmax) + +void gl_models_allocarrays(int newmax) +{ + qbyte *data; + aliasvertmax = newmax; + if (aliasvertarrays != NULL) + Mem_Free(aliasvertarrays); + aliasvertarrays = Mem_Alloc(gl_models_mempool, aliasvertmax * (sizeof(float[4+4+3+3+3]) + sizeof(int[3]))); + data = aliasvertarrays; + aliasvertcolor4f = aliasvertcolor4fbuf = (void *)data;data += aliasvertmax * sizeof(float[4]); + aliasvertcolor2_4f = (void *)data;data += aliasvertmax * sizeof(float[4]); // used temporarily for tinted coloring + aliasvert_svector3f = (void *)data;data += aliasvertmax * sizeof(float[3]); + aliasvert_tvector3f = (void *)data;data += aliasvertmax * sizeof(float[3]); + aliasvert_normal3f = (void *)data;data += aliasvertmax * sizeof(float[3]); + aliasvertusage = (void *)data;data += aliasvertmax * sizeof(int[3]); +} + +void gl_models_freearrays(void) +{ + aliasvertmax = 0; + if (aliasvertarrays != NULL) + Mem_Free(aliasvertarrays); + aliasvertarrays = NULL; + aliasvertcolor4f = aliasvertcolor4fbuf = NULL; + aliasvertcolor2_4f = NULL; + aliasvert_svector3f = NULL; + aliasvert_tvector3f = NULL; + aliasvert_normal3f = NULL; + aliasvertusage = NULL; +} + void gl_models_start(void) { // allocate vertex processing arrays gl_models_mempool = Mem_AllocPool("GL_Models"); - aliasvertcolor = aliasvertcolorbuf = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); - aliasvert_svectors = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); - aliasvert_tvectors = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); - aliasvert_normals = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); - aliasvertcolor2 = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); // used temporarily for tinted coloring zymbonepose = Mem_Alloc(gl_models_mempool, sizeof(zymbonematrix[256])); - aliasvertusage = Mem_Alloc(gl_models_mempool, sizeof(int[MD2MAX_VERTS])); + gl_models_allocarrays(4096); } void gl_models_shutdown(void) { + gl_models_freearrays(); Mem_FreePool(&gl_models_mempool); } @@ -49,138 +78,133 @@ void GL_Models_Init(void) R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap); } -void R_Model_Alias_GetMeshVerts(const entity_render_t *ent, aliasmesh_t *mesh, float *vertices, float *normals, float *svectors, float *tvectors) +void R_Model_Alias_GetMesh_Vertex3f(const entity_render_t *ent, aliasmesh_t *mesh, float *vertex3f, float *normal3f, float *svector3f, float *tvector3f) { int i, vertcount; float lerp1, lerp2, lerp3, lerp4; const aliasvertex_t *verts1, *verts2, *verts3, *verts4; - if (vertices == NULL) - Host_Error("R_Model_Alias_GetMeshVerts: vertices == NULL.\n"); - if (svectors != NULL && (tvectors == NULL || normals == NULL)) - Host_Error("R_Model_Alias_GetMeshVerts: svectors requires tvectors and normals.\n"); - if (tvectors != NULL && (svectors == NULL || normals == NULL)) - Host_Error("R_Model_Alias_GetMeshVerts: tvectors requires svectors and normals.\n"); + if (vertex3f == NULL) + Host_Error("R_Model_Alias_GetMesh_Vertex3f: vertices == NULL.\n"); + if (svector3f != NULL && (tvector3f == NULL || normal3f == NULL)) + Host_Error("R_Model_Alias_GetMesh_Vertex3f: svectors requires tvectors and normals.\n"); + if (tvector3f != NULL && (svector3f == NULL || normal3f == NULL)) + Host_Error("R_Model_Alias_GetMesh_Vertex3f: tvectors requires svectors and normals.\n"); vertcount = mesh->num_vertices; - verts1 = mesh->data_vertices + ent->frameblend[0].frame * vertcount; + verts1 = mesh->data_aliasvertex + ent->frameblend[0].frame * vertcount; lerp1 = ent->frameblend[0].lerp; if (ent->frameblend[1].lerp) { - verts2 = mesh->data_vertices + ent->frameblend[1].frame * vertcount; + verts2 = mesh->data_aliasvertex + ent->frameblend[1].frame * vertcount; lerp2 = ent->frameblend[1].lerp; if (ent->frameblend[2].lerp) { - verts3 = mesh->data_vertices + ent->frameblend[2].frame * vertcount; + verts3 = mesh->data_aliasvertex + ent->frameblend[2].frame * vertcount; lerp3 = ent->frameblend[2].lerp; if (ent->frameblend[3].lerp) { - verts4 = mesh->data_vertices + ent->frameblend[3].frame * vertcount; + verts4 = mesh->data_aliasvertex + ent->frameblend[3].frame * vertcount; lerp4 = ent->frameblend[3].lerp; // generate vertices - if (svectors != NULL) + if (svector3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++, verts4++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, svector3f += 3, tvector3f += 3, verts1++, verts2++, verts3++, verts4++) { - VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices); - VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normals); - VectorMAMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, lerp4, verts4->svector, svectors); - CrossProduct(svectors, normals, tvectors); + VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertex3f); + VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normal3f); + VectorMAMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, lerp4, verts4->svector, svector3f); + CrossProduct(svector3f, normal3f, tvector3f); } } - else if (normals != NULL) + else if (normal3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++, verts4++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, verts1++, verts2++, verts3++, verts4++) { - VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices); - VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normals); + VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertex3f); + VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normal3f); } } else - for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++, verts4++) - VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices); + for (i = 0;i < vertcount;i++, vertex3f += 3, verts1++, verts2++, verts3++, verts4++) + VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertex3f); } else { // generate vertices - if (svectors != NULL) + if (svector3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, svector3f += 3, tvector3f += 3, verts1++, verts2++, verts3++) { - VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices); - VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normals); - VectorMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, svectors); - CrossProduct(svectors, normals, tvectors); + VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertex3f); + VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normal3f); + VectorMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, svector3f); + CrossProduct(svector3f, normal3f, tvector3f); } } - else if (normals != NULL) + else if (normal3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, verts1++, verts2++, verts3++) { - VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices); - VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normals); + VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertex3f); + VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normal3f); } } else - for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++) - VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices); + for (i = 0;i < vertcount;i++, vertex3f += 3, verts1++, verts2++, verts3++) + VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertex3f); } } else { // generate vertices - if (svectors != NULL) + if (svector3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, svector3f += 3, tvector3f += 3, verts1++, verts2++) { - VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices); - VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normals); - VectorMAM(lerp1, verts1->svector, lerp2, verts2->svector, svectors); - CrossProduct(svectors, normals, tvectors); + VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertex3f); + VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normal3f); + VectorMAM(lerp1, verts1->svector, lerp2, verts2->svector, svector3f); + CrossProduct(svector3f, normal3f, tvector3f); } } - else if (normals != NULL) + else if (normal3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, verts1++, verts2++) { - VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices); - VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normals); + VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertex3f); + VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normal3f); } } else - for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++) - VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices); + for (i = 0;i < vertcount;i++, vertex3f += 3, verts1++, verts2++) + VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertex3f); } } else { // generate vertices - if (svectors != NULL) + if (svector3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, svector3f += 3, tvector3f += 3, verts1++) { - VectorM(lerp1, verts1->origin, vertices); - VectorM(lerp1, verts1->normal, normals); - VectorM(lerp1, verts1->svector, svectors); - CrossProduct(svectors, normals, tvectors); + VectorCopy(verts1->origin, vertex3f); + VectorCopy(verts1->normal, normal3f); + VectorCopy(verts1->svector, svector3f); + CrossProduct(svector3f, normal3f, tvector3f); } } - else if (normals != NULL) + else if (normal3f != NULL) { - for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++) + for (i = 0;i < vertcount;i++, vertex3f += 3, normal3f += 3, verts1++) { - VectorM(lerp1, verts1->origin, vertices); - VectorM(lerp1, verts1->normal, normals); + VectorCopy(verts1->origin, vertex3f); + VectorCopy(verts1->normal, normal3f); } } - else if (lerp1 != 1) - { - for (i = 0;i < vertcount;i++, vertices += 4, verts1++) - VectorM(lerp1, verts1->origin, vertices); - } else - for (i = 0;i < vertcount;i++, vertices += 4, verts1++) - VectorCopy(verts1->origin, vertices); + for (i = 0;i < vertcount;i++, vertex3f += 3, verts1++) + VectorCopy(verts1->origin, vertex3f); } } @@ -239,6 +263,7 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) || ((layer->flags & ALIASLAYER_NODRAW_IF_COLORMAPPED) && ent->colormap >= 0) || (layer->flags & ALIASLAYER_DRAW_PER_LIGHT)) continue; + expandaliasvert(mesh->num_vertices); if (layer->flags & ALIASLAYER_FOG) { m.blendfunc1 = GL_SRC_ALPHA; @@ -250,9 +275,10 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) 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); + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, aliasvert_normal3f, NULL, NULL); + if (layer->texture != NULL) + R_Mesh_CopyTexCoord2f(0, mesh->data_texcoord2f, mesh->num_vertices); + R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); continue; } if ((layer->flags & ALIASLAYER_ADD) || ((layer->flags & ALIASLAYER_ALPHA) && (ent->effects & EF_ADDITIVE))) @@ -307,13 +333,13 @@ void R_DrawAliasModelCallback (const void *calldata1, int calldata2) 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])); + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, aliasvert_normal3f, NULL, NULL); + R_Mesh_CopyTexCoord2f(0, mesh->data_texcoord2f, mesh->num_vertices); 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); - R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_elements); + R_LightModel(ent, mesh->num_vertices, varray_vertex3f, aliasvert_normal3f, varray_color4f, tint[0], tint[1], tint[2], false); + R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); } } @@ -383,15 +409,15 @@ void R_Model_Alias_DrawFakeShadow (entity_render_t *ent) if (skin->flags & ALIASSKIN_TRANSPARENT) continue; 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) + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, NULL, NULL, NULL); + for (i = 0, v = varray_vertex3f;i < mesh->num_vertices;i++, v += 3) { dist = DotProduct(v, planenormal) - planedist; if (dist > 0) VectorMA(v, dist, projection, v); } c_alias_polys += mesh->num_triangles; - R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_elements); + R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); } } @@ -413,8 +439,8 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor if (skin->flags & ALIASSKIN_TRANSPARENT) continue; 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); + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, varray_vertex3f, NULL, NULL, NULL); + R_Shadow_Volume(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, relativelightorigin, lightradius, projectdistance); } } } @@ -457,8 +483,9 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v skin = R_FetchAliasSkin(ent, mesh); if (skin->flags & ALIASSKIN_TRANSPARENT) continue; + expandaliasvert(mesh->num_vertices); vertices = R_Shadow_VertexBuffer(mesh->num_vertices); - R_Model_Alias_GetMeshVerts(ent, mesh, vertices, aliasvert_normals, aliasvert_svectors, aliasvert_tvectors); + R_Model_Alias_GetMesh_Vertex3f(ent, mesh, vertices, aliasvert_normal3f, aliasvert_svector3f, aliasvert_tvector3f); for (layernum = 0, layer = skin->data_layers;layernum < skin->num_layers;layernum++, layer++) { if (!(layer->flags & ALIASLAYER_DRAW_PER_LIGHT) @@ -471,7 +498,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, 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); + R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, vertices, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL); } else if (layer->flags & ALIASLAYER_DIFFUSE) { @@ -500,7 +527,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, vertices, 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_element3i, vertices, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL); } } } @@ -704,13 +731,13 @@ void ZymoticTransformVerts(int vertcount, float *vertex, int *bonecounts, zymver } } -void ZymoticCalcNormals(int vertcount, float *vertex, float *normals, int shadercount, int *renderlist) +void ZymoticCalcNormal3f(int vertcount, float *vertex3f, float *normal3f, int shadercount, int *renderlist) { int a, b, c, d; float *out, v1[3], v2[3], normal[3], s; int *u; // clear normals - memset(normals, 0, sizeof(float) * vertcount * 3); + memset(normal3f, 0, sizeof(float) * vertcount * 3); memset(aliasvertusage, 0, sizeof(int) * vertcount); // parse render list and accumulate surface normals while(shadercount--) @@ -721,36 +748,36 @@ void ZymoticCalcNormals(int vertcount, float *vertex, float *normals, int shader a = renderlist[0]*4; b = renderlist[1]*4; c = renderlist[2]*4; - v1[0] = vertex[a+0] - vertex[b+0]; - v1[1] = vertex[a+1] - vertex[b+1]; - v1[2] = vertex[a+2] - vertex[b+2]; - v2[0] = vertex[c+0] - vertex[b+0]; - v2[1] = vertex[c+1] - vertex[b+1]; - v2[2] = vertex[c+2] - vertex[b+2]; + v1[0] = vertex3f[a+0] - vertex3f[b+0]; + v1[1] = vertex3f[a+1] - vertex3f[b+1]; + v1[2] = vertex3f[a+2] - vertex3f[b+2]; + v2[0] = vertex3f[c+0] - vertex3f[b+0]; + v2[1] = vertex3f[c+1] - vertex3f[b+1]; + v2[2] = vertex3f[c+2] - vertex3f[b+2]; CrossProduct(v1, v2, normal); VectorNormalizeFast(normal); // add surface normal to vertices a = renderlist[0] * 3; - normals[a+0] += normal[0]; - normals[a+1] += normal[1]; - normals[a+2] += normal[2]; + normal3f[a+0] += normal[0]; + normal3f[a+1] += normal[1]; + normal3f[a+2] += normal[2]; aliasvertusage[renderlist[0]]++; a = renderlist[1] * 3; - normals[a+0] += normal[0]; - normals[a+1] += normal[1]; - normals[a+2] += normal[2]; + normal3f[a+0] += normal[0]; + normal3f[a+1] += normal[1]; + normal3f[a+2] += normal[2]; aliasvertusage[renderlist[1]]++; a = renderlist[2] * 3; - normals[a+0] += normal[0]; - normals[a+1] += normal[1]; - normals[a+2] += normal[2]; + normal3f[a+0] += normal[0]; + normal3f[a+1] += normal[1]; + normal3f[a+2] += normal[2]; aliasvertusage[renderlist[2]]++; renderlist += 3; } } // FIXME: precalc this // average surface normals - out = normals; + out = normal3f; u = aliasvertusage; while(vertcount--) { @@ -789,6 +816,8 @@ void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2) numtriangles = *renderlist++; elements = renderlist; + expandaliasvert(numverts); + fog = 0; if (fogenabled) { @@ -834,10 +863,10 @@ void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2) 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); - memcpy(varray_texcoord[0], ent->model->zymdata_texcoords, ent->model->zymnum_verts * sizeof(float[4])); - 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); + ZymoticTransformVerts(numverts, varray_vertex3f, ent->model->zymdata_vertbonecounts, ent->model->zymdata_verts); + R_Mesh_CopyTexCoord2f(0, ent->model->zymdata_texcoords, ent->model->zymnum_verts); + ZymoticCalcNormal3f(numverts, varray_vertex3f, aliasvert_normal3f, ent->model->zymnum_shaders, ent->model->zymdata_renderlist); + R_LightModel(ent, numverts, varray_vertex3f, aliasvert_normal3f, varray_color4f, ifog * colorscale, ifog * colorscale, ifog * colorscale, false); R_Mesh_Draw(numverts, numtriangles, elements); c_alias_polys += numtriangles; @@ -851,7 +880,7 @@ void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2) 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); + ZymoticTransformVerts(numverts, varray_vertex3f, ent->model->zymdata_vertbonecounts, ent->model->zymdata_verts); R_Mesh_Draw(numverts, numtriangles, elements); c_alias_polys += numtriangles; } @@ -889,3 +918,4 @@ void R_Model_Zymotic_DrawOntoLight(entity_render_t *ent) { // FIXME } + diff --git a/gl_rmain.c b/gl_rmain.c index 16f5acc5..b35afafc 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -1138,16 +1138,15 @@ static void R_BlendView(void) 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; - varray_vertex[2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r; - r *= 3; - varray_vertex[4] = varray_vertex[0] + vup[0] * r; - varray_vertex[5] = varray_vertex[1] + vup[1] * r; - varray_vertex[6] = varray_vertex[2] + vup[2] * r; - varray_vertex[8] = varray_vertex[0] + vright[0] * r; - varray_vertex[9] = varray_vertex[1] + vright[1] * r; - varray_vertex[10] = varray_vertex[2] + vright[2] * r; + varray_vertex3f[0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r; + varray_vertex3f[1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r; + varray_vertex3f[2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r; + varray_vertex3f[3] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r + vup[0] * r * 3; + varray_vertex3f[4] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r + vup[1] * r * 3; + varray_vertex3f[5] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r + vup[2] * r * 3; + varray_vertex3f[6] = r_origin[0] + vpn[0] * 1.5 + vright[0] * r * 3 - vup[0] * r; + varray_vertex3f[7] = r_origin[1] + vpn[1] * 1.5 + vright[1] * r * 3 - vup[1] * r; + varray_vertex3f[8] = r_origin[2] + vpn[2] * 1.5 + vright[2] * r * 3 - vup[2] * r; GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]); R_Mesh_Draw(3, 1, polygonelements); } @@ -1168,6 +1167,7 @@ void R_RenderView (void) if (r_shadow_realtime.integer == 1) { +#if 0 if (!gl_texturecubemap) { Con_Printf("Cubemap texture support not detected, turning off r_shadow_realtime\n"); @@ -1178,14 +1178,16 @@ void R_RenderView (void) Con_Printf("Bumpmapping support not detected, turning off r_shadow_realtime\n"); Cvar_SetValueQuick(&r_shadow_realtime, 0); } - else if (!gl_stencil) + else if (!gl_combine.integer) { - Con_Printf("Stencil not enabled, turning off r_shadow_realtime, please type vid_stencil 1;vid_bitsperpixel 32;vid_restart and try again\n"); + Con_Printf("Combine disabled, please turn on gl_combine, turning off r_shadow_realtime\n"); Cvar_SetValueQuick(&r_shadow_realtime, 0); } - else if (!gl_combine.integer) + else +#endif + if (!gl_stencil) { - Con_Printf("Combine disabled, please turn on gl_combine, turning off r_shadow_realtime\n"); + Con_Printf("Stencil not enabled, turning off r_shadow_realtime, please type vid_stencil 1;vid_bitsperpixel 32;vid_restart and try again\n"); Cvar_SetValueQuick(&r_shadow_realtime, 0); } } @@ -1363,24 +1365,24 @@ void R_DrawNoModelCallback(const void *calldata1, int calldata2) 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; - varray_vertex[12] = 0;varray_vertex[13] = 16;varray_vertex[14] = 0; - varray_vertex[16] = 0;varray_vertex[17] = 0;varray_vertex[18] = -16; - varray_vertex[20] = 0;varray_vertex[21] = 0;varray_vertex[22] = 16; - varray_color[ 0] = 0.00f * r_colorscale;varray_color[ 1] = 0.00f * r_colorscale;varray_color[ 2] = 0.50f * r_colorscale;varray_color[ 3] = ent->alpha; - varray_color[ 4] = 0.00f * r_colorscale;varray_color[ 5] = 0.00f * r_colorscale;varray_color[ 6] = 0.50f * r_colorscale;varray_color[ 7] = ent->alpha; - varray_color[ 8] = 0.00f * r_colorscale;varray_color[ 9] = 0.50f * r_colorscale;varray_color[10] = 0.00f * r_colorscale;varray_color[11] = ent->alpha; - varray_color[12] = 0.00f * r_colorscale;varray_color[13] = 0.50f * r_colorscale;varray_color[14] = 0.00f * r_colorscale;varray_color[15] = ent->alpha; - varray_color[16] = 0.50f * r_colorscale;varray_color[17] = 0.00f * r_colorscale;varray_color[18] = 0.00f * r_colorscale;varray_color[19] = ent->alpha; - varray_color[20] = 0.50f * r_colorscale;varray_color[21] = 0.00f * r_colorscale;varray_color[22] = 0.00f * r_colorscale;varray_color[23] = ent->alpha; + varray_vertex3f[ 0] = -16;varray_vertex3f[ 1] = 0;varray_vertex3f[ 2] = 0; + varray_vertex3f[ 3] = 16;varray_vertex3f[ 4] = 0;varray_vertex3f[ 5] = 0; + varray_vertex3f[ 6] = 0;varray_vertex3f[ 7] = -16;varray_vertex3f[ 8] = 0; + varray_vertex3f[ 9] = 0;varray_vertex3f[10] = 16;varray_vertex3f[11] = 0; + varray_vertex3f[12] = 0;varray_vertex3f[13] = 0;varray_vertex3f[14] = -16; + varray_vertex3f[15] = 0;varray_vertex3f[16] = 0;varray_vertex3f[17] = 16; + varray_color4f[ 0] = 0.00f * r_colorscale;varray_color4f[ 1] = 0.00f * r_colorscale;varray_color4f[ 2] = 0.50f * r_colorscale;varray_color4f[ 3] = ent->alpha; + varray_color4f[ 4] = 0.00f * r_colorscale;varray_color4f[ 5] = 0.00f * r_colorscale;varray_color4f[ 6] = 0.50f * r_colorscale;varray_color4f[ 7] = ent->alpha; + varray_color4f[ 8] = 0.00f * r_colorscale;varray_color4f[ 9] = 0.50f * r_colorscale;varray_color4f[10] = 0.00f * r_colorscale;varray_color4f[11] = ent->alpha; + varray_color4f[12] = 0.00f * r_colorscale;varray_color4f[13] = 0.50f * r_colorscale;varray_color4f[14] = 0.00f * r_colorscale;varray_color4f[15] = ent->alpha; + varray_color4f[16] = 0.50f * r_colorscale;varray_color4f[17] = 0.00f * r_colorscale;varray_color4f[18] = 0.00f * r_colorscale;varray_color4f[19] = ent->alpha; + varray_color4f[20] = 0.50f * r_colorscale;varray_color4f[21] = 0.00f * r_colorscale;varray_color4f[22] = 0.00f * r_colorscale;varray_color4f[23] = ent->alpha; if (fogenabled) { VectorSubtract(ent->origin, r_origin, diff); f2 = exp(fogdensity/DotProduct(diff, diff)); f1 = 1 - f2; - for (i = 0, c = varray_color;i < 6;i++, c += 4) + for (i = 0, c = varray_color4f;i < 6;i++, c += 4) { c[0] = (c[0] * f1 + fogcolor[0] * f2) * r_colorscale; c[1] = (c[1] * f1 + fogcolor[1] * f2) * r_colorscale; @@ -1389,7 +1391,7 @@ void R_DrawNoModelCallback(const void *calldata1, int calldata2) } else { - for (i = 0, c = varray_color;i < 6;i++, c += 4) + for (i = 0, c = varray_color4f;i < 6;i++, c += 4) { c[0] *= r_colorscale; c[1] *= r_colorscale; @@ -1407,7 +1409,7 @@ void R_DrawNoModel(entity_render_t *ent) // R_DrawNoModelCallback(ent, 0); } -void R_CalcBeamVerts (float *vert, const vec3_t org1, const vec3_t org2, float width) +void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width) { vec3_t right1, right2, diff, normal; @@ -1427,13 +1429,36 @@ void R_CalcBeamVerts (float *vert, const vec3_t org1, const vec3_t org2, float w vert[ 0] = org1[0] + width * right1[0]; vert[ 1] = org1[1] + width * right1[1]; vert[ 2] = org1[2] + width * right1[2]; - vert[ 4] = org1[0] - width * right1[0]; - vert[ 5] = org1[1] - width * right1[1]; - vert[ 6] = org1[2] - width * right1[2]; - vert[ 8] = org2[0] - width * right2[0]; - vert[ 9] = org2[1] - width * right2[1]; - vert[10] = org2[2] - width * right2[2]; - vert[12] = org2[0] + width * right2[0]; - vert[13] = org2[1] + width * right2[1]; - vert[14] = org2[2] + width * right2[2]; + vert[ 3] = org1[0] - width * right1[0]; + vert[ 4] = org1[1] - width * right1[1]; + vert[ 5] = org1[2] - width * right1[2]; + vert[ 6] = org2[0] - width * right2[0]; + vert[ 7] = org2[1] - width * right2[1]; + vert[ 8] = org2[2] - width * right2[2]; + vert[ 9] = org2[0] + width * right2[0]; + vert[10] = org2[1] + width * right2[1]; + vert[11] = org2[2] + width * right2[2]; } + +void R_DrawSpriteMesh(const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2) +{ + R_Mesh_GetSpace(4); + varray_texcoord2f[0][0] = 1;varray_texcoord2f[0][1] = 1; + varray_texcoord2f[0][2] = 1;varray_texcoord2f[0][3] = 0; + varray_texcoord2f[0][4] = 0;varray_texcoord2f[0][5] = 0; + varray_texcoord2f[0][6] = 0;varray_texcoord2f[0][7] = 1; + varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1; + varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1; + varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1; + varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2; + varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2; + varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2; + varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2; + varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2; + varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2; + varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1; + varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1; + varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1; + R_Mesh_Draw(4, 2, polygonelements); +} + diff --git a/gl_rsurf.c b/gl_rsurf.c index 017d4039..8ace2fa8 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -571,7 +571,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ============================================================= */ -static void RSurf_AddLightmapToVertexColors(const int *lightmapoffsets, float *c, int numverts, const qbyte *samples, int size3, const qbyte *styles) +static void RSurf_AddLightmapToVertexColors_Color4f(const int *lightmapoffsets, float *c, int numverts, const qbyte *samples, int size3, const qbyte *styles) { int i; float scale; @@ -605,13 +605,13 @@ static void RSurf_AddLightmapToVertexColors(const int *lightmapoffsets, float *c } } -static void RSurf_FogColors(const float *v, float *c, float colorscale, int numverts, const float *modelorg) +static void RSurf_FogColors_Vertex3f_Color4f(const float *v, float *c, float colorscale, int numverts, const float *modelorg) { int i; float diff[3], f; if (fogenabled) { - for (i = 0;i < numverts;i++, v += 4, c += 4) + for (i = 0;i < numverts;i++, v += 3, c += 4) { VectorSubtract(v, modelorg, diff); f = colorscale * (1 - exp(fogdensity/DotProduct(diff, diff))); @@ -623,7 +623,7 @@ static void RSurf_FogColors(const float *v, float *c, float colorscale, int numv VectorScale(c, colorscale, c); } -static void RSurf_FoggedColors(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg) +static void RSurf_FoggedColors_Vertex3f_Color4f(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg) { int i; float diff[3], f; @@ -632,7 +632,7 @@ static void RSurf_FoggedColors(const float *v, float *c, float r, float g, float b *= colorscale; if (fogenabled) { - for (i = 0;i < numverts;i++, v += 4, c += 4) + for (i = 0;i < numverts;i++, v += 3, c += 4) { VectorSubtract(v, modelorg, diff); f = 1 - exp(fogdensity/DotProduct(diff, diff)); @@ -654,14 +654,14 @@ static void RSurf_FoggedColors(const float *v, float *c, float r, float g, float } } -static void RSurf_FogPassColors(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg) +static void RSurf_FogPassColors_Vertex3f_Color4f(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg) { int i; float diff[3], f; r *= colorscale; g *= colorscale; b *= colorscale; - for (i = 0;i < numverts;i++, v += 4, c += 4) + for (i = 0;i < numverts;i++, v += 3, c += 4) { VectorSubtract(v, modelorg, diff); f = exp(fogdensity/DotProduct(diff, diff)); @@ -672,15 +672,7 @@ static void RSurf_FogPassColors(const float *v, float *c, float r, float g, floa } } -static void RSurf_ScaleColors(float *c, float scale, int numverts) -{ - int i; - if (scale != 1) - for (i = 0;i < numverts;i++, c += 4) - VectorScale(c, scale, c); -} - -static int RSurf_LightSeparate(const matrix4x4_t *matrix, const int *dlightbits, int numverts, const float *vert, float *color) +static int RSurf_LightSeparate_Vertex3f_Color4f(const matrix4x4_t *matrix, const int *dlightbits, int numverts, const float *vert, float *color, float scale) { float f; const float *v; @@ -694,12 +686,12 @@ static int RSurf_LightSeparate(const matrix4x4_t *matrix, const int *dlightbits, { rd = &r_dlight[l]; Matrix4x4_Transform(matrix, rd->origin, lightorigin); - for (i = 0, v = vert, c = color;i < numverts;i++, v += 4, c += 4) + for (i = 0, v = vert, c = color;i < numverts;i++, v += 3, c += 4) { f = VectorDistance2(v, lightorigin) + LIGHTOFFSET; if (f < rd->cullradius2) { - f = (1.0f / f) - rd->subtract; + f = ((1.0f / f) - rd->subtract) * scale; VectorMA(c, f, rd->light, c); lit = true; } @@ -709,8 +701,7 @@ static int RSurf_LightSeparate(const matrix4x4_t *matrix, const int *dlightbits, return lit; } -// note: this untransforms lights to do the checking, -// and takes surf->mesh->verts data +// note: this untransforms lights to do the checking static int RSurf_LightCheck(const matrix4x4_t *matrix, const int *dlightbits, const surfmesh_t *mesh) { int i, l; @@ -723,7 +714,7 @@ static int RSurf_LightCheck(const matrix4x4_t *matrix, const int *dlightbits, co { rd = &r_dlight[l]; Matrix4x4_Transform(matrix, rd->origin, lightorigin); - for (i = 0, v = mesh->verts;i < mesh->numverts;i++, v += 4) + for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3) if (VectorDistance2(v, lightorigin) < rd->cullradius2) return true; } @@ -776,8 +767,8 @@ static void RSurfShader_Sky(const entity_render_t *ent, const texture_t *texture { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -789,7 +780,7 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) int i; const entity_render_t *ent = calldata1; const msurface_t *surf = ent->model->surfaces + calldata2; - float f, colorscale, scroll[2], *v; + float f, colorscale, scroll[2], *v, *tc; const surfmesh_t *mesh; rmeshstate_t m; float alpha; @@ -829,26 +820,25 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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_CopyVertex3f(mesh->vertex3f, mesh->numverts); scroll[0] = sin(cl.time) * 0.125f; scroll[1] = sin(cl.time * 0.8f) * 0.125f; - for (i = 0, v = varray_texcoord[0];i < mesh->numverts;i++, v += 4) + for (i = 0, v = varray_texcoord2f[0], tc = mesh->texcoordtexture2f;i < mesh->numverts;i++, v += 2, tc += 2) { - v[0] += scroll[0]; - v[1] += scroll[1]; + v[0] = tc[0] + scroll[0]; + v[1] = tc[1] + scroll[1]; } f = surf->flags & SURF_DRAWFULLBRIGHT ? 1.0f : ((surf->flags & SURF_LIGHTMAP) ? 0 : 0.5f); - R_FillColors(varray_color, mesh->numverts, f, f, f, alpha); + R_FillColors(varray_color4f, mesh->numverts, f, f, f, alpha); if (!(surf->flags & SURF_DRAWFULLBRIGHT || ent->effects & EF_FULLBRIGHT)) { if (surf->dlightframe == r_framecount) - RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, mesh->numverts, varray_vertex, varray_color); + RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, varray_color4f, 1); if (surf->flags & SURF_LIGHTMAP) - RSurf_AddLightmapToVertexColors(mesh->lightmapoffsets, varray_color, mesh->numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles); + RSurf_AddLightmapToVertexColors_Color4f(mesh->lightmapoffsets, varray_color4f, mesh->numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles); } - RSurf_FogColors(varray_vertex, varray_color, colorscale, mesh->numverts, modelorg); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + RSurf_FogColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, colorscale, mesh->numverts, modelorg); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } if (fogenabled) @@ -861,11 +851,11 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) for (mesh = surf->mesh;mesh;mesh = mesh->chain) { R_Mesh_GetSpace(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); if (m.tex[0]) - memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); - RSurf_FogPassColors(varray_vertex, varray_color, fogcolor[0], fogcolor[1], fogcolor[2], alpha, r_colorscale, mesh->numverts, modelorg); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], alpha, r_colorscale, mesh->numverts, modelorg); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -928,18 +918,18 @@ static void RSurfShader_Wall_Pass_BaseVertex(const entity_render_t *ent, const m for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + R_FillColors(varray_color4f, mesh->numverts, base, base, base, currentalpha); if (!(ent->effects & EF_FULLBRIGHT)) { if (surf->dlightframe == r_framecount) - RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, mesh->numverts, varray_vertex, varray_color); + RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, varray_color4f, 1); if (surf->flags & SURF_LIGHTMAP) - RSurf_AddLightmapToVertexColors(mesh->lightmapoffsets, varray_color, mesh->numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles); + RSurf_AddLightmapToVertexColors_Color4f(mesh->lightmapoffsets, varray_color4f, mesh->numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles); } - RSurf_FogColors(varray_vertex, varray_color, colorscale, mesh->numverts, modelorg); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + RSurf_FogColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, colorscale, mesh->numverts, modelorg); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } @@ -958,10 +948,10 @@ static void RSurfShader_Wall_Pass_Glow(const entity_render_t *ent, const msurfac for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + RSurf_FoggedColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, 1, 1, 1, currentalpha, r_colorscale, mesh->numverts, modelorg); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } @@ -980,11 +970,11 @@ static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface for (mesh = surf->mesh;mesh;mesh = mesh->chain) { R_Mesh_GetSpace(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); if (m.tex[0]) - memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); - RSurf_FogPassColors(varray_vertex, varray_color, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha, r_colorscale, mesh->numverts, modelorg); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha, r_colorscale, mesh->numverts, modelorg); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } @@ -1020,11 +1010,11 @@ static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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])); - memcpy(varray_texcoord[2], mesh->abc, mesh->numverts * sizeof(float[4])); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + R_Mesh_CopyTexCoord2f(1, mesh->texcoordlightmap2f, mesh->numverts); + R_Mesh_CopyTexCoord2f(2, mesh->texcoorddetail2f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1058,10 +1048,10 @@ static void RSurfShader_OpaqueWall_Pass_BaseDoubleTex(const entity_render_t *ent for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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])); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + R_Mesh_CopyTexCoord2f(1, mesh->texcoordlightmap2f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1085,9 +1075,9 @@ static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1120,9 +1110,9 @@ static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordlightmap2f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1156,12 +1146,11 @@ static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const if (RSurf_LightCheck(&ent->inversematrix, surf->dlightbits, mesh)) { 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); - RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, mesh->numverts, varray_vertex, varray_color); - RSurf_ScaleColors(varray_color, colorscale, mesh->numverts); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + R_FillColors(varray_color4f, mesh->numverts, 0, 0, 0, 1); + RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, mesh->numverts, mesh->vertex3f, varray_color4f, colorscale); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1187,11 +1176,11 @@ static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const te for (mesh = surf->mesh;mesh;mesh = mesh->chain) { R_Mesh_GetSpace(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); if (m.tex[0]) - memcpy(varray_texcoord[0], mesh->str, mesh->numverts * sizeof(float[4])); - RSurf_FogPassColors(varray_vertex, varray_color, fogcolor[0], fogcolor[1], fogcolor[2], 1, r_colorscale, mesh->numverts, modelorg); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->index); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + RSurf_FogPassColors_Vertex3f_Color4f(mesh->vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], 1, r_colorscale, mesh->numverts, modelorg); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1215,9 +1204,9 @@ static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, c for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoorddetail2f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1241,9 +1230,9 @@ static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const t for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1270,9 +1259,9 @@ static void RSurfShader_OpaqueWall_Pass_OpaqueGlow(const entity_render_t *ent, c for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_CopyTexCoord2f(0, mesh->texcoordtexture2f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); } } } @@ -1519,11 +1508,11 @@ static void R_DrawPortal_Callback(const void *calldata1, int calldata2) 0.125f); if (PlaneDiff(r_origin, (&portal->plane)) > 0) { - for (i = portal->numpoints - 1, v = varray_vertex;i >= 0;i--, v += 4) + for (i = portal->numpoints - 1, v = varray_vertex3f;i >= 0;i--, v += 3) VectorCopy(portal->points[i].position, v); } else - for (i = 0, v = varray_vertex;i < portal->numpoints;i++, v += 4) + for (i = 0, v = varray_vertex3f;i < portal->numpoints;i++, v += 3) VectorCopy(portal->points[i].position, v); R_Mesh_Draw(portal->numpoints, portal->numpoints - 2, polygonelements); } @@ -1836,8 +1825,8 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto for (mesh = surf->mesh;mesh;mesh = mesh->chain) { 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); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Shadow_Volume(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->neighbor3i, relativelightorigin, lightradius, projectdistance); } } } @@ -1865,8 +1854,8 @@ void R_Model_Brush_DrawLightForSurfaceList(entity_render_t *ent, vec3_t relative { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - 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); + R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); + R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); } } } @@ -1912,8 +1901,8 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - 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); + R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); + R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); } } } @@ -1938,8 +1927,8 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v { for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - 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); + R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL); + R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL); } } } diff --git a/mathlib.h b/mathlib.h index 002c3f13..3d567852 100644 --- a/mathlib.h +++ b/mathlib.h @@ -94,6 +94,38 @@ extern vec3_t vec3_origin; #define VectorBlend(b1, b2, blend, c) do{float iblend = 1 - (blend);VectorMAM(iblend, b1, blend, b2, c);}while(0) #define BoxesOverlap(a,b,c,d) ((a)[0] <= (d)[0] && (b)[0] >= (c)[0] && (a)[1] <= (d)[1] && (b)[1] >= (c)[1] && (a)[2] <= (d)[2] && (b)[2] >= (c)[2]) +// fast PointInfrontOfTriangle +// 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 any triangle is obviously flat), and +// finally a comparison to determine if the light is infront of the triangle +// (the goal of this statement) we do not need to normalize the surface +// normal because both sides of the comparison use it, therefore they are +// both multiplied the same amount... furthermore the subtract can be done +// on the vectors, saving a little bit of math in the dotproducts +#define PointInfrontOfTriangle(p,a,b,c) (((p)[0] - (a)[0]) * (((a)[1] - (b)[1]) * ((c)[2] - (b)[2]) - ((a)[2] - (b)[2]) * ((c)[1] - (b)[1])) + ((p)[1] - (a)[1]) * (((a)[2] - (b)[2]) * ((c)[0] - (b)[0]) - ((a)[0] - (b)[0]) * ((c)[2] - (b)[2])) + ((p)[2] - (a)[2]) * (((a)[0] - (b)[0]) * ((c)[1] - (b)[1]) - ((a)[1] - (b)[1]) * ((c)[0] - (b)[0])) > 0) +#if 0 +// readable version, kept only for explanatory reasons +int PointInfrontOfTriangle(const float *p, const float *a, const float *b, const float *c) +{ + float dir0[3], dir1[3], normal[3]; + + // calculate two mostly perpendicular edge directions + VectorSubtract(a, b, dir0); + VectorSubtract(c, b, dir1); + + // we have two edge directions, we can calculate a third vector from + // them, which is the direction of the surface normal (it's magnitude + // is not 1 however) + CrossProduct(dir0, dir1, normal); + + // compare distance of light along normal, with distance of any point + // of the triangle along the same normal (the triangle is planar, + // I.E. flat, so all points give the same answer) + return DotProduct(p, normal) > DotProduct(a, normal); +} +#endif + /* // LordHavoc: quaternion math, untested, don't know if these are correct, // need to add conversion to/from matrices diff --git a/model_alias.c b/model_alias.c index 9b0f33e9..b095d9bf 100644 --- a/model_alias.c +++ b/model_alias.c @@ -29,12 +29,6 @@ void Mod_AliasInit (void) Cvar_RegisterVariable(&r_mipskins); } -static float vertst[MAXALIASVERTS][2]; -static int vertusage[MAXALIASVERTS]; -static int vertonseam[MAXALIASVERTS]; -static int vertremap[MAXALIASVERTS]; -static int temptris[MAXALIASTRIS][3]; - static void Mod_CalcAliasModelBBoxes (void) { int vnum, meshnum; @@ -47,7 +41,7 @@ static void Mod_CalcAliasModelBBoxes (void) radius = 0; for (meshnum = 0, mesh = loadmodel->aliasdata_meshes;meshnum < loadmodel->aliasnum_meshes;meshnum++, mesh++) { - for (vnum = 0, v = mesh->data_vertices;vnum < mesh->num_vertices * mesh->num_frames;vnum++, v++) + for (vnum = 0, v = mesh->data_aliasvertex;vnum < mesh->num_vertices * mesh->num_frames;vnum++, v++) { if (loadmodel->normalmins[0] > v->origin[0]) loadmodel->normalmins[0] = v->origin[0]; if (loadmodel->normalmins[1] > v->origin[1]) loadmodel->normalmins[1] = v->origin[1]; @@ -75,7 +69,7 @@ static void Mod_CalcAliasModelBBoxes (void) loadmodel->radius2 = radius * radius; } -static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, trivertx_t *v, aliasvertex_t *out) +static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, trivertx_t *v, aliasvertex_t *out, int *vertremap) { int i, j; vec3_t temp; @@ -99,21 +93,20 @@ static void Mod_BuildAliasVertexTextureVectors(int numverts, aliasvertex_t *vert { int i; for (i = 0;i < numverts;i++) - VectorCopy(vertices[i].origin, &vertexbuffer[i * 4]); + VectorCopy(vertices[i].origin, &vertexbuffer[i * 3]); Mod_BuildTextureVectorsAndNormals(numverts, numtriangles, vertexbuffer, texcoords, elements, svectorsbuffer, tvectorsbuffer, normalsbuffer); for (i = 0;i < numverts;i++) { - // LordHavoc: alias models are backwards, apparently - vertices[i].normal[0] = normalsbuffer[i * 4 + 0]; - vertices[i].normal[1] = normalsbuffer[i * 4 + 1]; - vertices[i].normal[2] = normalsbuffer[i * 4 + 2]; - vertices[i].svector[0] = svectorsbuffer[i * 4 + 0]; - vertices[i].svector[1] = svectorsbuffer[i * 4 + 1]; - vertices[i].svector[2] = svectorsbuffer[i * 4 + 2]; + vertices[i].normal[0] = normalsbuffer[i * 3 + 0]; + vertices[i].normal[1] = normalsbuffer[i * 3 + 1]; + vertices[i].normal[2] = normalsbuffer[i * 3 + 2]; + vertices[i].svector[0] = svectorsbuffer[i * 3 + 0]; + vertices[i].svector[1] = svectorsbuffer[i * 3 + 1]; + vertices[i].svector[2] = svectorsbuffer[i * 3 + 2]; } } -static void Mod_MDL_LoadFrames (qbyte* datapointer, int inverts, int outverts, vec3_t scale, vec3_t translate, float *texcoords, aliasvertex_t *posedata, int numtris, int *elements) +static void Mod_MDL_LoadFrames (qbyte* datapointer, int inverts, int outverts, vec3_t scale, vec3_t translate, float *texcoords, aliasvertex_t *posedata, int numtris, int *elements, int *vertremap) { int i, f, pose, groupframes; float interval, *vertexbuffer, *svectorsbuffer, *tvectorsbuffer, *normalsbuffer; @@ -124,10 +117,10 @@ static void Mod_MDL_LoadFrames (qbyte* datapointer, int inverts, int outverts, v animscene_t *scene; pose = 0; scene = loadmodel->animscenes; - vertexbuffer = Mem_Alloc(tempmempool, outverts * sizeof(float[4]) * 4); - svectorsbuffer = vertexbuffer + outverts * 4; - tvectorsbuffer = svectorsbuffer + outverts * 4; - normalsbuffer = tvectorsbuffer + outverts * 4; + vertexbuffer = Mem_Alloc(tempmempool, outverts * sizeof(float[3+3+3+3])); + svectorsbuffer = vertexbuffer + outverts * 3; + tvectorsbuffer = svectorsbuffer + outverts * 3; + normalsbuffer = tvectorsbuffer + outverts * 3; for (f = 0;f < loadmodel->numframes;f++) { pframetype = (daliasframetype_t *)datapointer; @@ -169,7 +162,7 @@ static void Mod_MDL_LoadFrames (qbyte* datapointer, int inverts, int outverts, v { pinframe = (daliasframe_t *)datapointer; datapointer += sizeof(daliasframe_t); - Mod_ConvertAliasVerts(inverts, scale, translate, (trivertx_t *)datapointer, posedata + pose * outverts); + Mod_ConvertAliasVerts(inverts, scale, translate, (trivertx_t *)datapointer, posedata + pose * outverts, vertremap); Mod_BuildAliasVertexTextureVectors(outverts, posedata + pose * outverts, texcoords, vertexbuffer, svectorsbuffer, tvectorsbuffer, normalsbuffer, numtris, elements); datapointer += sizeof(trivertx_t) * inverts; pose++; @@ -277,7 +270,7 @@ void Mod_BuildAliasSkinFromSkinFrame(aliasskin_t *skin, skinframe_t *skinframe) } } -void Mod_BuildMDLMD2MeshInfo(int numverts, int numtris, int *elements, float *texcoords, aliasvertex_t *posedata) +void Mod_BuildMDLMD2MeshInfo(int numverts, int numtris, int *elements, float *texcoord2f, aliasvertex_t *posedata) { int i; aliasmesh_t *mesh; @@ -293,12 +286,12 @@ void Mod_BuildMDLMD2MeshInfo(int numverts, int numtris, int *elements, float *te mesh->num_triangles = numtris; mesh->num_vertices = numverts; mesh->data_skins = Mem_Alloc(loadmodel->mempool, mesh->num_skins * sizeof(aliasskin_t)); - mesh->data_elements = elements; - mesh->data_neighbors = Mem_Alloc(loadmodel->mempool, numtris * sizeof(int[3])); - Mod_ValidateElements(mesh->data_elements, mesh->num_triangles, mesh->num_vertices, __FILE__, __LINE__); - Mod_BuildTriangleNeighbors(mesh->data_neighbors, mesh->data_elements, mesh->num_triangles); - mesh->data_texcoords = texcoords; - mesh->data_vertices = posedata; + mesh->data_element3i = elements; + mesh->data_neighbor3i = Mem_Alloc(loadmodel->mempool, numtris * sizeof(int[3])); + Mod_ValidateElements(mesh->data_element3i, mesh->num_triangles, mesh->num_vertices, __FILE__, __LINE__); + Mod_BuildTriangleNeighbors(mesh->data_neighbor3i, mesh->data_element3i, mesh->num_triangles); + mesh->data_texcoord2f = texcoord2f; + mesh->data_aliasvertex = posedata; for (i = 0;i < mesh->num_skins;i++) Mod_BuildAliasSkinFromSkinFrame(mesh->data_skins + i, loadmodel->skinframes + i); Mod_CalcAliasModelBBoxes(); @@ -328,6 +321,8 @@ void Mod_LoadQ1AliasModel (model_t *mod, void *buffer) skinframe_t tempskinframe; animscene_t *tempskinscenes; skinframe_t *tempskinframes; + float *vertst; + int *vertonseam, *vertusage, *vertremap, *temptris; datapointer = buffer; pinmodel = (mdl_t *)datapointer; @@ -353,9 +348,9 @@ void Mod_LoadQ1AliasModel (model_t *mod, void *buffer) skinheight = LittleLong (pinmodel->skinheight); BOUNDI(skinheight,0,4096); numverts = LittleLong(pinmodel->numverts); - BOUNDI(numverts,0,MAXALIASVERTS); + BOUNDI(numverts,0,65536); numtris = LittleLong(pinmodel->numtris); - BOUNDI(numtris,0,MAXALIASTRIS); + BOUNDI(numtris,0,65536 / 3); // max elements limit, rather than max triangles limit loadmodel->numframes = LittleLong(pinmodel->numframes); BOUNDI(loadmodel->numframes,0,65536); loadmodel->synctype = LittleLong (pinmodel->synctype); @@ -500,15 +495,21 @@ void Mod_LoadQ1AliasModel (model_t *mod, void *buffer) } // store texture coordinates into temporary array, they will be stored after usage is determined (triangle data) + vertst = Mem_Alloc(tempmempool, numverts * 2 * sizeof(float[2])); + vertonseam = Mem_Alloc(tempmempool, numverts * sizeof(int)); + vertusage = Mem_Alloc(tempmempool, numverts * 2 * sizeof(int)); + vertremap = Mem_Alloc(tempmempool, numverts * 2 * sizeof(int)); + temptris = Mem_Alloc(tempmempool, numtris * sizeof(int[3])); + scales = 1.0 / skinwidth; scalet = 1.0 / skinheight; for (i = 0;i < numverts;i++) { vertonseam[i] = LittleLong(pinstverts[i].onseam); - vertst[i][0] = (LittleLong(pinstverts[i].s) + 0.5) * scales; - vertst[i][1] = (LittleLong(pinstverts[i].t) + 0.5) * scalet; - vertst[i+numverts][0] = vertst[i][0] + 0.5; - vertst[i+numverts][1] = vertst[i][1]; + vertst[i*2+0] = (LittleLong(pinstverts[i].s) + 0.5) * scales; + vertst[i*2+1] = (LittleLong(pinstverts[i].t) + 0.5) * scalet; + vertst[(i+numverts)*2+0] = vertst[i*2+0] + 0.5; + vertst[(i+numverts)*2+1] = vertst[i*2+1]; vertusage[i] = 0; vertusage[i+numverts] = 0; } @@ -521,18 +522,18 @@ void Mod_LoadQ1AliasModel (model_t *mod, void *buffer) vertusage[i] = 0; for (i = 0;i < numtris;i++) { - temptris[i][0] = LittleLong(pintriangles[i].vertindex[0]); - temptris[i][1] = LittleLong(pintriangles[i].vertindex[1]); - temptris[i][2] = LittleLong(pintriangles[i].vertindex[2]); + temptris[i*3+0] = LittleLong(pintriangles[i].vertindex[0]); + temptris[i*3+1] = LittleLong(pintriangles[i].vertindex[1]); + temptris[i*3+2] = LittleLong(pintriangles[i].vertindex[2]); if (!LittleLong(pintriangles[i].facesfront)) // backface { - if (vertonseam[temptris[i][0]]) temptris[i][0] += numverts; - if (vertonseam[temptris[i][1]]) temptris[i][1] += numverts; - if (vertonseam[temptris[i][2]]) temptris[i][2] += numverts; + if (vertonseam[temptris[i*3+0]]) temptris[i*3+0] += numverts; + if (vertonseam[temptris[i*3+1]]) temptris[i*3+1] += numverts; + if (vertonseam[temptris[i*3+2]]) temptris[i*3+2] += numverts; } - vertusage[temptris[i][0]]++; - vertusage[temptris[i][1]]++; - vertusage[temptris[i][2]]++; + vertusage[temptris[i*3+0]]++; + vertusage[temptris[i*3+1]]++; + vertusage[temptris[i*3+2]]++; } // build remapping table and compact array totalverts = 0; @@ -541,33 +542,35 @@ void Mod_LoadQ1AliasModel (model_t *mod, void *buffer) if (vertusage[i]) { vertremap[i] = totalverts; - vertst[totalverts][0] = vertst[i][0]; - vertst[totalverts][1] = vertst[i][1]; + vertst[totalverts*2+0] = vertst[i*2+0]; + vertst[totalverts*2+1] = vertst[i*2+1]; totalverts++; } else vertremap[i] = -1; // not used at all } // remap the triangle references - for (i = 0;i < numtris;i++) - { - elements[i*3+0] = vertremap[temptris[i][0]]; - elements[i*3+1] = vertremap[temptris[i][1]]; - elements[i*3+2] = vertremap[temptris[i][2]]; - } + for (i = 0;i < numtris * 3;i++) + elements[i] = vertremap[temptris[i]]; // store the texture coordinates - texcoords = Mem_Alloc(loadmodel->mempool, sizeof(float[4]) * totalverts); + texcoords = Mem_Alloc(loadmodel->mempool, sizeof(float[2]) * totalverts); for (i = 0;i < totalverts;i++) { - texcoords[i*4+0] = vertst[i][0]; - texcoords[i*4+1] = vertst[i][1]; + texcoords[i*2+0] = vertst[i*2+0]; + texcoords[i*2+1] = vertst[i*2+1]; } // load the frames loadmodel->animscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes); posedata = Mem_Alloc(loadmodel->mempool, sizeof(aliasvertex_t) * totalposes * totalverts); - Mod_MDL_LoadFrames (startframes, numverts, totalverts, scale, translate, texcoords, posedata, numtris, elements); + Mod_MDL_LoadFrames (startframes, numverts, totalverts, scale, translate, texcoords, posedata, numtris, elements, vertremap); Mod_BuildMDLMD2MeshInfo(totalverts, numtris, elements, texcoords, posedata); + + Mem_Free(vertst); + Mem_Free(vertonseam); + Mem_Free(vertusage); + Mem_Free(vertremap); + Mem_Free(temptris); } static void Mod_MD2_ConvertVerts (vec3_t scale, vec3_t translate, trivertx_t *v, aliasvertex_t *out, int numverts, int *vertremap) @@ -618,13 +621,13 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume; loadmodel->DrawLight = R_Model_Alias_DrawLight; - if (LittleLong(pinmodel->num_tris < 1) || LittleLong(pinmodel->num_tris) > MD2MAX_TRIANGLES) + if (LittleLong(pinmodel->num_tris < 1) || LittleLong(pinmodel->num_tris) > (65536 / 3)) Host_Error ("%s has invalid number of triangles: %i", loadmodel->name, LittleLong(pinmodel->num_tris)); - if (LittleLong(pinmodel->num_xyz < 1) || LittleLong(pinmodel->num_xyz) > MD2MAX_VERTS) + if (LittleLong(pinmodel->num_xyz < 1) || LittleLong(pinmodel->num_xyz) > 65536) Host_Error ("%s has invalid number of vertices: %i", loadmodel->name, LittleLong(pinmodel->num_xyz)); - if (LittleLong(pinmodel->num_frames < 1) || LittleLong(pinmodel->num_frames) > MD2MAX_FRAMES) + if (LittleLong(pinmodel->num_frames < 1) || LittleLong(pinmodel->num_frames) > 65536) Host_Error ("%s has invalid number of frames: %i", loadmodel->name, LittleLong(pinmodel->num_frames)); - if (LittleLong(pinmodel->num_skins < 0) || LittleLong(pinmodel->num_skins) > MAX_SKINS) + if (LittleLong(pinmodel->num_skins < 0) || LittleLong(pinmodel->num_skins) > 256) Host_Error ("%s has invalid number of skins: %i", loadmodel->name, LittleLong(pinmodel->num_skins)); end = LittleLong(pinmodel->ofs_end); @@ -661,7 +664,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->skinscenes[i].loop = true; loadmodel->skinscenes[i].framerate = 10; Mod_LoadSkinFrame (loadmodel->skinframes + i, inskin, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE, true, false, true); - inskin += MD2MAX_SKINNAME; + inskin += MD2_SKINNAME; } } @@ -731,13 +734,13 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) numverts = num; vertremap = Mem_Alloc(loadmodel->mempool, num * sizeof(int)); - texcoords = Mem_Alloc(loadmodel->mempool, num * sizeof(float[4])); + texcoords = Mem_Alloc(loadmodel->mempool, num * sizeof(float[2])); for (i = 0;i < num;i++) { hash = md2verthashdata + i; vertremap[i] = hash->xyz; - texcoords[i*4+0] = hash->st[0]; - texcoords[i*4+1] = hash->st[1]; + texcoords[i*2+0] = hash->st[0]; + texcoords[i*2+1] = hash->st[1]; } Mem_Free(md2verthash); @@ -748,10 +751,10 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->animscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numframes * sizeof(animscene_t)); posedata = Mem_Alloc(loadmodel->mempool, numverts * loadmodel->numframes * sizeof(trivertx_t)); - vertexbuffer = Mem_Alloc(tempmempool, numverts * sizeof(float[4]) * 4); - svectorsbuffer = vertexbuffer + numverts * 4; - tvectorsbuffer = svectorsbuffer + numverts * 4; - normalsbuffer = tvectorsbuffer + numverts * 4; + vertexbuffer = Mem_Alloc(tempmempool, numverts * sizeof(float[3+3+3+3])); + svectorsbuffer = vertexbuffer + numverts * 3; + tvectorsbuffer = svectorsbuffer + numverts * 3; + normalsbuffer = tvectorsbuffer + numverts * 3; for (i = 0;i < loadmodel->numframes;i++) { pinframe = (md2frame_t *)datapointer; @@ -842,36 +845,36 @@ void Mod_LoadQ3AliasModel(model_t *mod, void *buffer) mesh->num_vertices = LittleLong(pinmesh->num_vertices); mesh->num_triangles = LittleLong(pinmesh->num_triangles); mesh->data_skins = Mem_Alloc(loadmodel->mempool, mesh->num_skins * sizeof(aliasskin_t)); - mesh->data_elements = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3])); - mesh->data_neighbors = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3])); - mesh->data_texcoords = Mem_Alloc(loadmodel->mempool, mesh->num_vertices * sizeof(float[4])); - mesh->data_vertices = Mem_Alloc(loadmodel->mempool, mesh->num_vertices * mesh->num_frames * sizeof(aliasvertex_t)); + mesh->data_element3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3])); + mesh->data_neighbor3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3])); + mesh->data_texcoord2f = Mem_Alloc(loadmodel->mempool, mesh->num_vertices * sizeof(float[2])); + mesh->data_aliasvertex = Mem_Alloc(loadmodel->mempool, mesh->num_vertices * mesh->num_frames * sizeof(aliasvertex_t)); for (j = 0;j < mesh->num_triangles * 3;j++) - mesh->data_elements[j] = LittleLong(((int *)((qbyte *)pinmesh + pinmesh->lump_elements))[j]); + mesh->data_element3i[j] = LittleLong(((int *)((qbyte *)pinmesh + pinmesh->lump_elements))[j]); for (j = 0;j < mesh->num_vertices;j++) { - mesh->data_texcoords[j * 4 + 0] = LittleLong(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 0]); - mesh->data_texcoords[j * 4 + 1] = LittleLong(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 1]); + mesh->data_texcoord2f[j * 2 + 0] = LittleLong(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 0]); + mesh->data_texcoord2f[j * 2 + 1] = LittleLong(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 1]); } for (j = 0;j < mesh->num_vertices * mesh->num_frames;j++) { - mesh->data_vertices[j].origin[0] = LittleShort(((short *)((qbyte *)pinmesh + pinmesh->lump_framevertices))[j * 4 + 0]) * (1.0f / 64.0f); - mesh->data_vertices[j].origin[1] = LittleShort(((short *)((qbyte *)pinmesh + pinmesh->lump_framevertices))[j * 4 + 1]) * (1.0f / 64.0f); - mesh->data_vertices[j].origin[2] = LittleShort(((short *)((qbyte *)pinmesh + pinmesh->lump_framevertices))[j * 4 + 2]) * (1.0f / 64.0f); + mesh->data_aliasvertex[j].origin[0] = LittleShort(((short *)((qbyte *)pinmesh + pinmesh->lump_framevertices))[j * 4 + 0]) * (1.0f / 64.0f); + mesh->data_aliasvertex[j].origin[1] = LittleShort(((short *)((qbyte *)pinmesh + pinmesh->lump_framevertices))[j * 4 + 1]) * (1.0f / 64.0f); + mesh->data_aliasvertex[j].origin[2] = LittleShort(((short *)((qbyte *)pinmesh + pinmesh->lump_framevertices))[j * 4 + 2]) * (1.0f / 64.0f); } - vertexbuffer = Mem_Alloc(tempmempool, mesh->num_vertices * sizeof(float[4]) * 4); - svectorsbuffer = vertexbuffer + mesh->num_vertices * 4; - tvectorsbuffer = svectorsbuffer + mesh->num_vertices * 4; - normalsbuffer = tvectorsbuffer + mesh->num_vertices * 4; + vertexbuffer = Mem_Alloc(tempmempool, mesh->num_vertices * sizeof(float[3+3+3+3])); + svectorsbuffer = vertexbuffer + mesh->num_vertices * 3; + tvectorsbuffer = svectorsbuffer + mesh->num_vertices * 3; + normalsbuffer = tvectorsbuffer + mesh->num_vertices * 3; for (j = 0;j < mesh->num_frames;j++) - Mod_BuildAliasVertexTextureVectors(mesh->num_vertices, mesh->data_vertices + j * mesh->num_vertices, mesh->data_texcoords, vertexbuffer, svectorsbuffer, tvectorsbuffer, normalsbuffer, mesh->num_triangles, mesh->data_elements); + Mod_BuildAliasVertexTextureVectors(mesh->num_vertices, mesh->data_aliasvertex + j * mesh->num_vertices, mesh->data_texcoord2f, vertexbuffer, svectorsbuffer, tvectorsbuffer, normalsbuffer, mesh->num_triangles, mesh->data_element3i); Mem_Free(vertexbuffer); memset(&tempskinframe, 0, sizeof(tempskinframe)); if (LittleLong(pinmesh->num_shaders) >= 1 && ((md3shader_t *)((qbyte *) pinmesh + pinmesh->lump_shaders))->name[0]) Mod_LoadSkinFrame (&tempskinframe, ((md3shader_t *)((qbyte *) pinmesh + pinmesh->lump_shaders))->name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE, true, false, true); - Mod_ValidateElements(mesh->data_elements, mesh->num_triangles, mesh->num_vertices, __FILE__, __LINE__); - Mod_BuildTriangleNeighbors(mesh->data_neighbors, mesh->data_elements, mesh->num_triangles); + Mod_ValidateElements(mesh->data_element3i, mesh->num_triangles, mesh->num_vertices, __FILE__, __LINE__); + Mod_BuildTriangleNeighbors(mesh->data_neighbor3i, mesh->data_element3i, mesh->num_triangles); Mod_BuildAliasSkinFromSkinFrame(mesh->data_skins, &tempskinframe); } Mod_CalcAliasModelBBoxes(); @@ -1060,15 +1063,15 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer) { int i; - float *intexcoord, *outtexcoord; + float *intexcoord2f, *outtexcoord2f; // zymlump_t lump_texcoords; // float texcoords[numvertices][2]; - loadmodel->zymdata_texcoords = outtexcoord = Mem_Alloc(loadmodel->mempool, pheader->numverts * sizeof(float[4])); - intexcoord = (void *) (pheader->lump_texcoords.start + pbase); + loadmodel->zymdata_texcoords = outtexcoord2f = Mem_Alloc(loadmodel->mempool, pheader->numverts * sizeof(float[2])); + intexcoord2f = (void *) (pheader->lump_texcoords.start + pbase); for (i = 0;i < pheader->numverts;i++) { - outtexcoord[i*4+0] = BigFloat(intexcoord[i*2+0]); + outtexcoord2f[i*2+0] = BigFloat(intexcoord2f[i*2+0]); // flip T coordinate for OpenGL - outtexcoord[i*4+1] = 1 - BigFloat(intexcoord[i*2+1]); + outtexcoord2f[i*2+1] = 1 - BigFloat(intexcoord2f[i*2+1]); } } diff --git a/model_alias.h b/model_alias.h index 7e5a88c4..36d4e50e 100644 --- a/model_alias.h +++ b/model_alias.h @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -50,10 +50,6 @@ typedef struct { float size; } daliashdr_t; -#define MAXALIASVERTS 4096 -#define MAXALIASFRAMES 1024 -#define MAXALIASTRIS 4096 - /* ======================================================================== @@ -66,13 +62,7 @@ typedef struct { // renamed a things to avoid conflicts #define MD2ALIAS_VERSION 8 - -#define MD2MAX_TRIANGLES 4096 -#define MD2MAX_VERTS 4096 -#define MD2MAX_FRAMES 1024 -#define MD2MAX_SKINNAME 64 -// sanity checking size -#define MD2MAX_SIZE (16777216) +#define MD2_SKINNAME 64 typedef struct { @@ -80,7 +70,7 @@ typedef struct short t; } md2stvert_t; -typedef struct +typedef struct { short index_xyz[3]; short index_st[3]; @@ -286,10 +276,10 @@ typedef struct aliasmesh_s int num_frames; int num_vertices; aliasskin_t *data_skins; - int *data_elements; - int *data_neighbors; - float *data_texcoords; - aliasvertex_t *data_vertices; + int *data_element3i; + int *data_neighbor3i; + float *data_texcoord2f; + aliasvertex_t *data_aliasvertex; } aliasmesh_t; diff --git a/model_brush.c b/model_brush.c index 5e74ea4d..ac88de7f 100644 --- a/model_brush.c +++ b/model_brush.c @@ -128,10 +128,10 @@ void Mod_FindNonSolidLocation_r_Leaf(findnonsolidlocationinfo_t *info, mleaf_t * { for (k = 0;k < mesh->numtriangles;k++) { - tri = mesh->index + k * 3; - VectorCopy((mesh->verts + tri[0] * 4), vert[0]); - VectorCopy((mesh->verts + tri[1] * 4), vert[1]); - VectorCopy((mesh->verts + tri[2] * 4), vert[2]); + tri = mesh->element3i + k * 3; + VectorCopy((mesh->vertex3f + tri[0] * 3), vert[0]); + VectorCopy((mesh->vertex3f + tri[1] * 3), vert[1]); + VectorCopy((mesh->vertex3f + tri[2] * 3), vert[2]); VectorSubtract(vert[1], vert[0], edge[0]); VectorSubtract(vert[2], vert[1], edge[1]); CrossProduct(edge[1], edge[0], facenormal); @@ -1381,19 +1381,19 @@ void Mod_GenerateWarpMesh (msurface_t *surf) surfmesh_t *Mod_AllocSurfMesh(int numverts, int numtriangles) { surfmesh_t *mesh; - mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + numtriangles * sizeof(int[6]) + numverts * (4 + 4 + 4 + 4 + 4 + 4 + 4 + 1) * sizeof(float)); + mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + numtriangles * sizeof(int[6]) + numverts * (3 + 2 + 2 + 2 + 3 + 3 + 3 + 1) * sizeof(float)); mesh->numverts = numverts; mesh->numtriangles = numtriangles; - mesh->verts = (float *)(mesh + 1); - mesh->str = mesh->verts + mesh->numverts * 4; - mesh->uvw = mesh->str + mesh->numverts * 4; - mesh->abc = mesh->uvw + mesh->numverts * 4; - mesh->svectors = (float *)(mesh->abc + mesh->numverts * 4); - mesh->tvectors = mesh->svectors + mesh->numverts * 4; - mesh->normals = mesh->tvectors + mesh->numverts * 4; - mesh->lightmapoffsets = (int *)(mesh->normals + mesh->numverts * 4); - mesh->index = mesh->lightmapoffsets + mesh->numverts; - mesh->triangleneighbors = mesh->index + mesh->numtriangles * 3; + mesh->vertex3f = (float *)(mesh + 1); + mesh->texcoordtexture2f = mesh->vertex3f + mesh->numverts * 3; + mesh->texcoordlightmap2f = mesh->texcoordtexture2f + mesh->numverts * 2; + mesh->texcoorddetail2f = mesh->texcoordlightmap2f + mesh->numverts * 2; + mesh->svector3f = (float *)(mesh->texcoorddetail2f + mesh->numverts * 2); + mesh->tvector3f = mesh->svector3f + mesh->numverts * 3; + mesh->normal3f = mesh->tvector3f + mesh->numverts * 3; + mesh->lightmapoffsets = (int *)(mesh->normal3f + mesh->numverts * 3); + mesh->element3i = mesh->lightmapoffsets + mesh->numverts; + mesh->neighbor3i = mesh->element3i + mesh->numtriangles * 3; return mesh; } @@ -1435,14 +1435,14 @@ void Mod_GenerateWallMesh (msurface_t *surf, int vertexonly) surf->mesh = mesh = Mod_AllocSurfMesh(surf->poly_numverts, surf->poly_numverts - 2); - index = mesh->index; + index = mesh->element3i; for (i = 0;i < mesh->numtriangles;i++) { *index++ = 0; *index++ = i + 1; *index++ = i + 2; } - Mod_BuildTriangleNeighbors(mesh->triangleneighbors, mesh->index, mesh->numtriangles); + Mod_BuildTriangleNeighbors(mesh->neighbor3i, mesh->element3i, mesh->numtriangles); VectorCopy(surf->plane->normal, normal); if (surf->flags & SURF_PLANEBACK) @@ -1461,18 +1461,18 @@ void Mod_GenerateWallMesh (msurface_t *surf, int vertexonly) u = u * uscale + ubase; v = v * vscale + vbase; - mesh->verts[i * 4 + 0] = in[0]; - mesh->verts[i * 4 + 1] = in[1]; - mesh->verts[i * 4 + 2] = in[2]; - mesh->str[i * 4 + 0] = s / surf->texinfo->texture->width; - mesh->str[i * 4 + 1] = t / surf->texinfo->texture->height; - mesh->uvw[i * 4 + 0] = u; - mesh->uvw[i * 4 + 1] = v; - mesh->abc[i * 4 + 0] = s * (1.0f / 16.0f); - mesh->abc[i * 4 + 1] = t * (1.0f / 16.0f); + mesh->vertex3f[i * 3 + 0] = in[0]; + mesh->vertex3f[i * 3 + 1] = in[1]; + mesh->vertex3f[i * 3 + 2] = in[2]; + mesh->texcoordtexture2f[i * 2 + 0] = s / surf->texinfo->texture->width; + mesh->texcoordtexture2f[i * 2 + 1] = t / surf->texinfo->texture->height; + mesh->texcoordlightmap2f[i * 2 + 0] = u; + mesh->texcoordlightmap2f[i * 2 + 1] = v; + mesh->texcoorddetail2f[i * 2 + 0] = s * (1.0f / 16.0f); + mesh->texcoorddetail2f[i * 2 + 1] = t * (1.0f / 16.0f); mesh->lightmapoffsets[i] = ((iv * (smax+1) + iu) * 3); } - Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->verts, mesh->str, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals); + Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->vertex3f, mesh->texcoordtexture2f, mesh->element3i, mesh->svector3f, mesh->tvector3f, mesh->normal3f); } void Mod_GenerateVertexMesh (msurface_t *surf) @@ -1486,14 +1486,14 @@ void Mod_GenerateVertexMesh (msurface_t *surf) surf->mesh = mesh = Mod_AllocSurfMesh(surf->poly_numverts, surf->poly_numverts - 2); - index = mesh->index; + index = mesh->element3i; for (i = 0;i < mesh->numtriangles;i++) { *index++ = 0; *index++ = i + 1; *index++ = i + 2; } - Mod_BuildTriangleNeighbors(mesh->triangleneighbors, mesh->index, mesh->numtriangles); + Mod_BuildTriangleNeighbors(mesh->neighbor3i, mesh->element3i, mesh->numtriangles); VectorCopy(surf->plane->normal, normal); if (surf->flags & SURF_PLANEBACK) @@ -1502,17 +1502,17 @@ void Mod_GenerateVertexMesh (msurface_t *surf) { s = (DotProduct (in, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]); t = (DotProduct (in, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]); - mesh->verts[i * 4 + 0] = in[0]; - mesh->verts[i * 4 + 1] = in[1]; - mesh->verts[i * 4 + 2] = in[2]; - mesh->str[i * 4 + 0] = s / surf->texinfo->texture->width; - mesh->str[i * 4 + 1] = t / surf->texinfo->texture->height; - mesh->uvw[i * 4 + 0] = 0; - mesh->uvw[i * 4 + 1] = 0; - mesh->abc[i * 4 + 0] = s * (1.0f / 16.0f); - mesh->abc[i * 4 + 1] = t * (1.0f / 16.0f); - } - Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->verts, mesh->str, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals); + mesh->vertex3f[i * 3 + 0] = in[0]; + mesh->vertex3f[i * 3 + 1] = in[1]; + mesh->vertex3f[i * 3 + 2] = in[2]; + mesh->texcoordtexture2f[i * 2 + 0] = s / surf->texinfo->texture->width; + mesh->texcoordtexture2f[i * 2 + 1] = t / surf->texinfo->texture->height; + mesh->texcoordlightmap2f[i * 2 + 0] = 0; + mesh->texcoordlightmap2f[i * 2 + 1] = 0; + mesh->texcoorddetail2f[i * 2 + 0] = s * (1.0f / 16.0f); + mesh->texcoorddetail2f[i * 2 + 1] = t * (1.0f / 16.0f); + } + Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->vertex3f, mesh->texcoordtexture2f, mesh->element3i, mesh->svector3f, mesh->tvector3f, mesh->normal3f); } void Mod_GenerateSurfacePolygon (msurface_t *surf, int firstedge, int numedges) @@ -2898,7 +2898,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) // calculate bounding shapes for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - for (k = 0, vec = mesh->verts;k < mesh->numverts;k++, vec += 4) + for (k = 0, vec = mesh->vertex3f;k < mesh->numverts;k++, vec += 3) { if (mod->normalmins[0] > vec[0]) mod->normalmins[0] = vec[0]; if (mod->normalmins[1] > vec[1]) mod->normalmins[1] = vec[1]; diff --git a/model_brush.h b/model_brush.h index 0f2ee072..c4d0c184 100644 --- a/model_brush.h +++ b/model_brush.h @@ -149,16 +149,16 @@ typedef struct surfmesh_s struct surfmesh_s *chain; int numverts; // number of vertices in the mesh int numtriangles; // number of triangles in the mesh - float *verts; // float[verts*4] vertex locations - float *svectors; // float[verts*4] direction of 'S' (right) texture axis for each vertex - float *tvectors; // float[verts*4] direction of 'T' (down) texture axis for each vertex - float *normals; // float[verts*4] direction of 'R' (out) texture axis for each vertex + float *vertex3f; // float[verts*3] vertex locations + float *svector3f; // float[verts*3] direction of 'S' (right) texture axis for each vertex + float *tvector3f; // float[verts*3] direction of 'T' (down) texture axis for each vertex + float *normal3f; // float[verts*3] direction of 'R' (out) texture axis for each vertex int *lightmapoffsets; // index into surface's lightmap samples for vertex lighting - float *str; // float[verts*4] texcoords for surface texture - float *uvw; // float[verts*4] texcoords for lightmap texture - float *abc; // float[verts*4] texcoords for detail texture - int *index; // int[tris*3] triangles of the mesh, 3 indices into vertex arrays for each - int *triangleneighbors; // int[tris*3] neighboring triangle on each edge (-1 if none) + float *texcoordtexture2f; // float[verts*2] texcoords for surface texture + float *texcoordlightmap2f; // float[verts*2] texcoords for lightmap texture + float *texcoorddetail2f; // float[verts*2] texcoords for detail texture + int *element3i; // int[tris*3] triangles of the mesh, 3 indices into vertex arrays for each + int *neighbor3i; // int[tris*3] neighboring triangle on each edge (-1 if none) } surfmesh_t; diff --git a/model_shared.c b/model_shared.c index e3fa83e0..97efa1f5 100644 --- a/model_shared.c +++ b/model_shared.c @@ -486,35 +486,35 @@ multiplies: 18 (6 6 6) rsqrts: 3 (1 1 1) */ -void Mod_BuildTextureVectorsAndNormals(int numverts, int numtriangles, const float *vertex, const float *texcoord, const int *elements, float *svectors, float *tvectors, float *normals) +void Mod_BuildTextureVectorsAndNormals(int numverts, int numtriangles, const float *vertex3f, const float *texcoord2f, const int *elements, float *svector3f, float *tvector3f, float *normal3f) { int i, tnum, voffset; float vert[3][4], vec[3][4], sdir[3], tdir[3], normal[3], f, *v; const int *e; // clear the vectors - memset(svectors, 0, numverts * sizeof(float[4])); - memset(tvectors, 0, numverts * sizeof(float[4])); - memset(normals, 0, numverts * sizeof(float[4])); + memset(svector3f, 0, numverts * sizeof(float[3])); + memset(tvector3f, 0, numverts * sizeof(float[3])); + memset(normal3f, 0, numverts * sizeof(float[3])); // process each vertex of each triangle and accumulate the results for (tnum = 0, e = elements;tnum < numtriangles;tnum++, e += 3) { // calculate texture matrix for triangle // 20 assignments - voffset = e[0] * 4; - vert[0][0] = vertex[voffset+0]; - vert[0][1] = vertex[voffset+1]; - vert[0][2] = vertex[voffset+2]; - vert[0][3] = texcoord[voffset]; - voffset = e[1] * 4; - vert[1][0] = vertex[voffset+0]; - vert[1][1] = vertex[voffset+1]; - vert[1][2] = vertex[voffset+2]; - vert[1][3] = texcoord[voffset]; - voffset = e[2] * 4; - vert[2][0] = vertex[voffset+0]; - vert[2][1] = vertex[voffset+1]; - vert[2][2] = vertex[voffset+2]; - vert[2][3] = texcoord[voffset]; + voffset = e[0]; + vert[0][0] = vertex3f[voffset*3+0]; + vert[0][1] = vertex3f[voffset*3+1]; + vert[0][2] = vertex3f[voffset*3+2]; + vert[0][3] = texcoord2f[voffset*2]; + voffset = e[1]; + vert[1][0] = vertex3f[voffset*3+0]; + vert[1][1] = vertex3f[voffset*3+1]; + vert[1][2] = vertex3f[voffset*3+2]; + vert[1][3] = texcoord2f[voffset*2]; + voffset = e[2]; + vert[2][0] = vertex3f[voffset*3+0]; + vert[2][1] = vertex3f[voffset*3+1]; + vert[2][2] = vertex3f[voffset*3+2]; + vert[2][3] = texcoord2f[voffset*2]; // 3 assignments, 3 subtracts VectorSubtract(vert[1], vert[0], vec[0]); // 3 assignments, 3 subtracts @@ -548,28 +548,28 @@ void Mod_BuildTextureVectorsAndNormals(int numverts, int numtriangles, const flo // 30 assignments, 27 adds for (i = 0;i < 3;i++) { - voffset = e[i] * 4; - svectors[voffset ] += sdir[0]; - svectors[voffset + 1] += sdir[1]; - svectors[voffset + 2] += sdir[2]; - tvectors[voffset ] += tdir[0]; - tvectors[voffset + 1] += tdir[1]; - tvectors[voffset + 2] += tdir[2]; - normals[voffset ] += normal[0]; - normals[voffset + 1] += normal[1]; - normals[voffset + 2] += normal[2]; + voffset = e[i]; + svector3f[voffset*3 ] += sdir[0]; + svector3f[voffset*3+1] += sdir[1]; + svector3f[voffset*3+2] += sdir[2]; + tvector3f[voffset*3 ] += tdir[0]; + tvector3f[voffset*3+1] += tdir[1]; + tvector3f[voffset*3+2] += tdir[2]; + normal3f[voffset*3 ] += normal[0]; + normal3f[voffset*3+1] += normal[1]; + normal3f[voffset*3+2] += normal[2]; } } } // now we could divide the vectors by the number of averaged values on // each vertex... but instead normalize them - for (i = 0, v = svectors;i < numverts;i++, v += 4) + for (i = 0, v = svector3f;i < numverts;i++, v += 3) // 4 assignments, 1 rsqrt, 2 adds, 6 multiplies VectorNormalize(v); - for (i = 0, v = tvectors;i < numverts;i++, v += 4) + for (i = 0, v = tvector3f;i < numverts;i++, v += 3) // 4 assignments, 1 rsqrt, 2 adds, 6 multiplies VectorNormalize(v); - for (i = 0, v = normals;i < numverts;i++, v += 4) + for (i = 0, v = normal3f;i < numverts;i++, v += 3) // 4 assignments, 1 rsqrt, 2 adds, 6 multiplies VectorNormalize(v); } @@ -577,15 +577,15 @@ void Mod_BuildTextureVectorsAndNormals(int numverts, int numtriangles, const flo shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts) { shadowmesh_t *mesh; - mesh = Mem_Alloc(mempool, sizeof(shadowmesh_t) + maxverts * sizeof(float[4]) + maxverts * sizeof(int[3]) + maxverts * sizeof(int[3]) + SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *) + maxverts * sizeof(shadowmeshvertexhash_t)); + mesh = Mem_Alloc(mempool, sizeof(shadowmesh_t) + maxverts * sizeof(float[3]) + maxverts * sizeof(int[3]) + maxverts * sizeof(int[3]) + SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *) + maxverts * sizeof(shadowmeshvertexhash_t)); mesh->maxverts = maxverts; mesh->maxtriangles = maxverts; mesh->numverts = 0; mesh->numtriangles = 0; - mesh->verts = (float *)(mesh + 1); - mesh->elements = (int *)(mesh->verts + mesh->maxverts * 4); - mesh->neighbors = (int *)(mesh->elements + mesh->maxtriangles * 3); - mesh->vertexhashtable = (shadowmeshvertexhash_t **)(mesh->neighbors + mesh->maxtriangles * 3); + mesh->vertex3f = (float *)(mesh + 1); + mesh->element3i = (int *)(mesh->vertex3f + mesh->maxverts * 3); + mesh->neighbor3i = (int *)(mesh->element3i + mesh->maxtriangles * 3); + mesh->vertexhashtable = (shadowmeshvertexhash_t **)(mesh->neighbor3i + mesh->maxtriangles * 3); mesh->vertexhashentries = (shadowmeshvertexhash_t *)(mesh->vertexhashtable + SHADOWMESHVERTEXHASH); return mesh; } @@ -593,15 +593,15 @@ shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts) shadowmesh_t *Mod_ShadowMesh_ReAlloc(mempool_t *mempool, shadowmesh_t *oldmesh) { shadowmesh_t *newmesh; - newmesh = Mem_Alloc(mempool, sizeof(shadowmesh_t) + oldmesh->numverts * sizeof(float[4]) + oldmesh->numtriangles * sizeof(int[3]) + oldmesh->numtriangles * sizeof(int[3])); + newmesh = Mem_Alloc(mempool, sizeof(shadowmesh_t) + oldmesh->numverts * sizeof(float[3]) + oldmesh->numtriangles * sizeof(int[3]) + oldmesh->numtriangles * sizeof(int[3])); newmesh->maxverts = newmesh->numverts = oldmesh->numverts; newmesh->maxtriangles = newmesh->numtriangles = oldmesh->numtriangles; - newmesh->verts = (float *)(newmesh + 1); - newmesh->elements = (int *)(newmesh->verts + newmesh->maxverts * 4); - newmesh->neighbors = (int *)(newmesh->elements + newmesh->maxtriangles * 3); - memcpy(newmesh->verts, oldmesh->verts, newmesh->numverts * sizeof(float[4])); - memcpy(newmesh->elements, oldmesh->elements, newmesh->numtriangles * sizeof(int[3])); - memcpy(newmesh->neighbors, oldmesh->neighbors, newmesh->numtriangles * sizeof(int[3])); + newmesh->vertex3f = (float *)(newmesh + 1); + newmesh->element3i = (int *)(newmesh->vertex3f + newmesh->maxverts * 3); + newmesh->neighbor3i = (int *)(newmesh->element3i + newmesh->maxtriangles * 3); + memcpy(newmesh->vertex3f, oldmesh->vertex3f, newmesh->numverts * sizeof(float[3])); + memcpy(newmesh->element3i, oldmesh->element3i, newmesh->numtriangles * sizeof(int[3])); + memcpy(newmesh->neighbor3i, oldmesh->neighbor3i, newmesh->numtriangles * sizeof(int[3])); return newmesh; } @@ -614,14 +614,14 @@ int Mod_ShadowMesh_AddVertex(shadowmesh_t *mesh, float *v) hashindex = (int) (v[0] * 3 + v[1] * 5 + v[2] * 7) % SHADOWMESHVERTEXHASH; for (hash = mesh->vertexhashtable[hashindex];hash;hash = hash->next) { - m = mesh->verts + (hash - mesh->vertexhashentries) * 4; + m = mesh->vertex3f + (hash - mesh->vertexhashentries) * 3; if (m[0] == v[0] && m[1] == v[1] && m[2] == v[2]) return hash - mesh->vertexhashentries; } hash = mesh->vertexhashentries + mesh->numverts; hash->next = mesh->vertexhashtable[hashindex]; mesh->vertexhashtable[hashindex] = hash; - m = mesh->verts + (hash - mesh->vertexhashentries) * 4; + m = mesh->vertex3f + (hash - mesh->vertexhashentries) * 3; VectorCopy(v, m); mesh->numverts++; return mesh->numverts - 1; @@ -635,9 +635,9 @@ void Mod_ShadowMesh_AddTriangle(mempool_t *mempool, shadowmesh_t *mesh, float *v mesh->next = Mod_ShadowMesh_Alloc(mempool, max(mesh->maxtriangles, 1)); mesh = mesh->next; } - mesh->elements[mesh->numtriangles * 3 + 0] = Mod_ShadowMesh_AddVertex(mesh, vert0); - mesh->elements[mesh->numtriangles * 3 + 1] = Mod_ShadowMesh_AddVertex(mesh, vert1); - mesh->elements[mesh->numtriangles * 3 + 2] = Mod_ShadowMesh_AddVertex(mesh, vert2); + mesh->element3i[mesh->numtriangles * 3 + 0] = Mod_ShadowMesh_AddVertex(mesh, vert0); + mesh->element3i[mesh->numtriangles * 3 + 1] = Mod_ShadowMesh_AddVertex(mesh, vert1); + mesh->element3i[mesh->numtriangles * 3 + 2] = Mod_ShadowMesh_AddVertex(mesh, vert2); mesh->numtriangles++; } @@ -675,7 +675,7 @@ void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, int numverts { int i; for (i = 0;i < numtris;i++, elements += 3) - Mod_ShadowMesh_AddTriangle(mempool, mesh, verts + elements[0] * 4, verts + elements[1] * 4, verts + elements[2] * 4); + Mod_ShadowMesh_AddTriangle(mempool, mesh, verts + elements[0] * 3, verts + elements[1] * 3, verts + elements[2] * 3); } shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int initialnumtriangles) @@ -700,8 +700,8 @@ shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh) //Con_Printf("mesh\n"); //for (i = 0;i < newmesh->numtriangles;i++) // Con_Printf("tri %d %d %d\n", newmesh->elements[i * 3 + 0], newmesh->elements[i * 3 + 1], newmesh->elements[i * 3 + 2]); - Mod_ValidateElements(newmesh->elements, newmesh->numtriangles, newmesh->numverts, __FILE__, __LINE__); - Mod_BuildTriangleNeighbors(newmesh->neighbors, newmesh->elements, newmesh->numtriangles); + Mod_ValidateElements(newmesh->element3i, newmesh->numtriangles, newmesh->numverts, __FILE__, __LINE__); + Mod_BuildTriangleNeighbors(newmesh->neighbor3i, newmesh->element3i, newmesh->numtriangles); } Mem_Free(mesh); } @@ -727,10 +727,10 @@ void Mod_ShadowMesh_CalcBBox(shadowmesh_t *firstmesh, vec3_t mins, vec3_t maxs, { if (mesh == firstmesh) { - VectorCopy(mesh->verts, nmins); - VectorCopy(mesh->verts, nmaxs); + VectorCopy(mesh->vertex3f, nmins); + VectorCopy(mesh->vertex3f, nmaxs); } - for (i = 0, v = mesh->verts;i < mesh->numverts;i++, v += 4) + for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3) { if (nmins[0] > v[0]) nmins[0] = v[0];if (nmaxs[0] < v[0]) nmaxs[0] = v[0]; if (nmins[1] > v[1]) nmins[1] = v[1];if (nmaxs[1] < v[1]) nmaxs[1] = v[1]; @@ -744,7 +744,7 @@ void Mod_ShadowMesh_CalcBBox(shadowmesh_t *firstmesh, vec3_t mins, vec3_t maxs, nradius2 = 0; for (mesh = firstmesh;mesh;mesh = mesh->next) { - for (i = 0, v = mesh->verts;i < mesh->numverts;i++, v += 4) + for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3) { VectorSubtract(v, ncenter, temp); dist2 = DotProduct(temp, temp); diff --git a/model_shared.h b/model_shared.h index 43cadd1a..4a434544 100644 --- a/model_shared.h +++ b/model_shared.h @@ -73,9 +73,9 @@ typedef struct shadowmesh_s struct shadowmesh_s *next; int numverts, maxverts; int numtriangles, maxtriangles; - float *verts; - int *elements; - int *neighbors; + float *vertex3f; + int *element3i; + int *neighbor3i; // these are NULL after Mod_ShadowMesh_Finish is performed, only used // while building meshes shadowmeshvertexhash_t **vertexhashtable, *vertexhashentries; diff --git a/portals.c b/portals.c index 6c1a1914..339fd802 100644 --- a/portals.c +++ b/portals.c @@ -360,14 +360,12 @@ void Portal_RecursiveFlow_ExactMarkSurfaces(portalrecursioninfo_t *info, int *ma { for (surfmesh = surf->mesh;surfmesh;surfmesh = surfmesh->chain) { - for (j = 0, elements = surfmesh->index;j < surfmesh->numtriangles;j++, elements += 3) + for (j = 0, elements = surfmesh->element3i;j < surfmesh->numtriangles;j++, elements += 3) { - VectorCopy((surfmesh->verts + elements[0] * 4), trianglepoints[0]); - VectorCopy((surfmesh->verts + elements[1] * 4), trianglepoints[1]); - VectorCopy((surfmesh->verts + elements[2] * 4), trianglepoints[2]); - if ((info->eye[0] - trianglepoints[0][0]) * ((trianglepoints[0][1] - trianglepoints[1][1]) * (trianglepoints[2][2] - trianglepoints[1][2]) - (trianglepoints[0][2] - trianglepoints[1][2]) * (trianglepoints[2][1] - trianglepoints[1][1])) - + (info->eye[1] - trianglepoints[0][1]) * ((trianglepoints[0][2] - trianglepoints[1][2]) * (trianglepoints[2][0] - trianglepoints[1][0]) - (trianglepoints[0][0] - trianglepoints[1][0]) * (trianglepoints[2][2] - trianglepoints[1][2])) - + (info->eye[2] - trianglepoints[0][2]) * ((trianglepoints[0][0] - trianglepoints[1][0]) * (trianglepoints[2][1] - trianglepoints[1][1]) - (trianglepoints[0][1] - trianglepoints[1][1]) * (trianglepoints[2][0] - trianglepoints[1][0])) > 0 + VectorCopy((surfmesh->vertex3f + elements[0] * 3), trianglepoints[0]); + VectorCopy((surfmesh->vertex3f + elements[1] * 3), trianglepoints[1]); + VectorCopy((surfmesh->vertex3f + elements[2] * 3), trianglepoints[2]); + if (PointInfrontOfTriangle(info->eye, trianglepoints[0], trianglepoints[1], trianglepoints[2]) && Portal_PortalThroughPortalPlanes(&portalplanes[firstclipplane], numclipplanes, trianglepoints[0], 3, &portaltemppoints2[0][0], 256) >= 3) break; } diff --git a/r_crosshairs.c b/r_crosshairs.c index 212d654d..ba08ed9c 100644 --- a/r_crosshairs.c +++ b/r_crosshairs.c @@ -42,24 +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; - varray_texcoord[0][12] = 1;varray_texcoord[0][13] = 0; - varray_vertex[0] = origin[0] - vright[0] * scale - vup[0] * scale; - varray_vertex[1] = origin[1] - vright[1] * scale - vup[1] * scale; - varray_vertex[2] = origin[2] - vright[2] * scale - vup[2] * scale; - varray_vertex[4] = origin[0] - vright[0] * scale + vup[0] * scale; - varray_vertex[5] = origin[1] - vright[1] * scale + vup[1] * scale; - varray_vertex[6] = origin[2] - vright[2] * scale + vup[2] * scale; - varray_vertex[8] = origin[0] + vright[0] * scale + vup[0] * scale; - varray_vertex[9] = origin[1] + vright[1] * scale + vup[1] * scale; - varray_vertex[10] = origin[2] + vright[2] * scale + vup[2] * scale; - varray_vertex[12] = origin[0] + vright[0] * scale - vup[0] * scale; - varray_vertex[13] = origin[1] + vright[1] * scale - vup[1] * scale; - varray_vertex[14] = origin[2] + vright[2] * scale - vup[2] * scale; - R_Mesh_Draw(4, 2, polygonelements); + R_DrawSpriteMesh(origin, vright, vup, scale, -scale, -scale, scale); } void R_GetCrosshairColor(float *out) diff --git a/r_explosion.c b/r_explosion.c index 6feff62c..f7cdd723 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define EXPLOSIONFADESTART (1.5f) #define EXPLOSIONFADERATE (3.0f) -float explosiontexcoords[EXPLOSIONVERTS][4]; +float explosiontexcoord2f[EXPLOSIONVERTS][2]; int explosiontris[EXPLOSIONTRIS][3]; int explosionnoiseindex[EXPLOSIONVERTS]; vec3_t explosionpoint[EXPLOSIONVERTS]; @@ -112,8 +112,8 @@ int R_ExplosionVert(int column, int row) explosionspherevertvel[i][0] = explosionpoint[i][0] * EXPLOSIONSTARTVELOCITY; explosionspherevertvel[i][1] = explosionpoint[i][1] * EXPLOSIONSTARTVELOCITY; explosionspherevertvel[i][2] = explosionpoint[i][2] * EXPLOSIONSTARTVELOCITY; - explosiontexcoords[i][0] = (float) column / (float) EXPLOSIONGRID; - explosiontexcoords[i][1] = (float) row / (float) EXPLOSIONGRID; + explosiontexcoord2f[i][0] = (float) column / (float) EXPLOSIONGRID; + explosiontexcoord2f[i][1] = (float) row / (float) EXPLOSIONGRID; // top and bottom rows are all one position... if (row == 0 || row == EXPLOSIONGRID) column = 0; @@ -176,7 +176,7 @@ void R_NewExplosion(vec3_t org) void R_DrawExplosionCallback(const void *calldata1, int calldata2) { int i, numtriangles, numverts; - float *c, *v, diff[3], centerdir[3], ifog, alpha, dist; + float *c, diff[3], centerdir[3], ifog, alpha, dist; rmeshstate_t m; const explosion_t *e; e = calldata1; @@ -193,19 +193,14 @@ void R_DrawExplosionCallback(const void *calldata1, int calldata2) GL_UseColorArray(); R_Mesh_GetSpace(numverts); - for (i = 0, v = varray_vertex;i < numverts;i++, v += 4) - { - v[0] = e->vert[i][0]; - v[1] = e->vert[i][1]; - v[2] = e->vert[i][2]; - } - memcpy(varray_texcoord[0], explosiontexcoords, numverts * sizeof(float[4])); + R_Mesh_CopyVertex3f(e->vert[0], numverts); + R_Mesh_CopyTexCoord2f(0, explosiontexcoord2f[0], numverts); alpha = e->alpha; VectorSubtract(r_origin, e->origin, centerdir); VectorNormalizeFast(centerdir); if (fogenabled) { - for (i = 0, c = varray_color;i < EXPLOSIONVERTS;i++, c += 4) + for (i = 0, c = varray_color4f;i < EXPLOSIONVERTS;i++, c += 4) { VectorSubtract(e->vert[i], e->origin, diff); VectorNormalizeFast(diff); @@ -229,7 +224,7 @@ void R_DrawExplosionCallback(const void *calldata1, int calldata2) } else { - for (i = 0, c = varray_color;i < EXPLOSIONVERTS;i++, c += 4) + for (i = 0, c = varray_color4f;i < EXPLOSIONVERTS;i++, c += 4) { VectorSubtract(e->vert[i], e->origin, diff); VectorNormalizeFast(diff); diff --git a/r_light.c b/r_light.c index 74ca47ec..2824929d 100644 --- a/r_light.c +++ b/r_light.c @@ -172,24 +172,7 @@ 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; - varray_vertex[4] = rd->origin[0] - vright[0] * scale + vup[0] * scale; - varray_vertex[5] = rd->origin[1] - vright[1] * scale + vup[1] * scale; - varray_vertex[6] = rd->origin[2] - vright[2] * scale + vup[2] * scale; - varray_vertex[8] = rd->origin[0] + vright[0] * scale + vup[0] * scale; - varray_vertex[9] = rd->origin[1] + vright[1] * scale + vup[1] * scale; - varray_vertex[10] = rd->origin[2] + vright[2] * scale + vup[2] * scale; - varray_vertex[12] = rd->origin[0] + vright[0] * scale - vup[0] * scale; - varray_vertex[13] = rd->origin[1] + vright[1] * scale - vup[1] * scale; - varray_vertex[14] = rd->origin[2] + vright[2] * scale - vup[2] * scale; - R_Mesh_Draw(4, 2, polygonelements); + R_DrawSpriteMesh(rd->origin, vright, vup, scale, -scale, -scale, scale); } } } @@ -878,8 +861,8 @@ void R_LightModel(const entity_render_t *ent, int numverts, float *vertices, flo VectorCopy(color, avc); avc[3] = a; avc += 4; - av += 4; - avn += 4; + av += 3; + avn += 3; } } else diff --git a/r_shadow.c b/r_shadow.c index 50de8978..2036a8b5 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -25,10 +25,10 @@ qbyte *trianglefacinglight; int *trianglefacinglightlist; int maxshadowvertices; -float *shadowvertices; +float *shadowvertex3f; rtexturepool_t *r_shadow_texturepool; -rtexture_t *r_shadow_normalscubetexture; +rtexture_t *r_shadow_normalcubetexture; rtexture_t *r_shadow_attenuation2dtexture; rtexture_t *r_shadow_attenuation3dtexture; rtexture_t *r_shadow_blankbumptexture; @@ -66,11 +66,11 @@ void r_shadow_start(void) maxshadowelements = 0; shadowelements = NULL; maxshadowvertices = 0; - shadowvertices = NULL; + shadowvertex3f = NULL; maxtrianglefacinglight = 0; trianglefacinglight = NULL; trianglefacinglightlist = NULL; - r_shadow_normalscubetexture = NULL; + r_shadow_normalcubetexture = NULL; r_shadow_attenuation2dtexture = NULL; r_shadow_attenuation3dtexture = NULL; r_shadow_blankbumptexture = NULL; @@ -85,7 +85,7 @@ void r_shadow_shutdown(void) { R_Shadow_ClearWorldLights(); r_shadow_reloadlights = true; - r_shadow_normalscubetexture = NULL; + r_shadow_normalcubetexture = NULL; r_shadow_attenuation2dtexture = NULL; r_shadow_attenuation3dtexture = NULL; r_shadow_blankbumptexture = NULL; @@ -95,7 +95,7 @@ void r_shadow_shutdown(void) maxshadowelements = 0; shadowelements = NULL; maxshadowvertices = 0; - shadowvertices = NULL; + shadowvertex3f = NULL; maxtrianglefacinglight = 0; trianglefacinglight = NULL; trianglefacinglightlist = NULL; @@ -127,13 +127,13 @@ void R_Shadow_Init(void) R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap); } -void R_Shadow_ProjectVertices(float *verts, int numverts, const float *relativelightorigin, float projectdistance) +void R_Shadow_ProjectVertex3f(float *verts, int numverts, const float *relativelightorigin, float projectdistance) { int i; - float *in, *out, diff[4]; + float *in, *out, diff[3]; in = verts; - out = verts + numverts * 4; - for (i = 0;i < numverts;i++, in += 4, out += 4) + out = verts + numverts * 3; + for (i = 0;i < numverts;i++, in += 3, out += 3) { VectorSubtract(in, relativelightorigin, diff); VectorNormalizeFast(diff); @@ -142,67 +142,23 @@ void R_Shadow_ProjectVertices(float *verts, int numverts, const float *relativel } } -int R_Shadow_MakeTriangleShadowFlags(const int *elements, const float *vertex, int numtris, qbyte *facing, int *list, const float *relativelightorigin) +int R_Shadow_MakeTriangleShadowFlags_Vertex3f(const int *elements, const float *vertex, int numtris, qbyte *facing, int *list, const float *relativelightorigin) { int i, tris = 0; const float *v0, *v1, *v2; for (i = 0;i < numtris;i++, elements += 3) { // calculate triangle facing flag - v0 = vertex + elements[0] * 4; - v1 = vertex + elements[1] * 4; - v2 = vertex + elements[2] * 4; - // we do not need to normalize the surface normal because both sides - // of the comparison use it, therefore they are both multiplied the - // same amount... furthermore the subtract can be done on the - // vectors, saving a little bit of math in the dotproducts -#if 1 - // 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 any triangle - // is obviously flat), and finally a comparison to determine if the - // light is infront of the triangle (the goal of this statement) - 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) + v0 = vertex + elements[0] * 3; + v1 = vertex + elements[1] * 3; + v2 = vertex + elements[2] * 3; + if(PointInfrontOfTriangle(relativelightorigin, v0, v1, v2)) { facing[i] = true; list[tris++] = i; } else facing[i] = false; -#else - // readable version - { - float dir0[3], dir1[3], temp[3]; - - // calculate two mostly perpendicular edge directions - VectorSubtract(v0, v1, dir0); - VectorSubtract(v2, v1, dir1); - - // we have two edge directions, we can calculate a third vector from - // them, which is the direction of the surface normal (it's magnitude - // is not 1 however) - CrossProduct(dir0, dir1, temp); - - // this is entirely unnecessary, but kept for clarity - //VectorNormalize(temp); - - // compare distance of light along normal, with distance of any point - // of the triangle along the same normal (the triangle is planar, - // 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 - if (DotProduct(relativelightorigin, temp) >= DotProduct(v0, temp)) - { - facing[i] = true; - list[tris++] = i; - } - else - facing[i] = false; - } -#endif } return tris; } @@ -313,11 +269,11 @@ 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])); + if (shadowvertex3f) + Mem_Free(shadowvertex3f); + shadowvertex3f = Mem_Alloc(r_shadow_mempool, maxshadowvertices * sizeof(float[3])); } - return shadowvertices; + return shadowvertex3f; } void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance) @@ -347,8 +303,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 vertices before use. -// vertices must have capacity for numverts * 2. +// vertex locations must already be in varray_vertex3f before use. +// varray_vertex3f must have capacity for numverts * 2. // make sure trianglefacinglight is big enough for this volume if (maxtrianglefacinglight < numtris) @@ -359,7 +315,7 @@ void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, v R_Shadow_ResizeShadowElements(numtris); // check which triangles are facing the light - tris = R_Shadow_MakeTriangleShadowFlags(elements, varray_vertex, numtris, trianglefacinglight, trianglefacinglightlist, relativelightorigin); + tris = R_Shadow_MakeTriangleShadowFlags_Vertex3f(elements, varray_vertex3f, numtris, trianglefacinglight, trianglefacinglightlist, relativelightorigin); if (!tris) return; @@ -370,7 +326,7 @@ void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, v // 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); + R_Shadow_ProjectVertex3f(varray_vertex3f, numverts, relativelightorigin, projectdistance); if (r_shadowstage == SHADOWSTAGE_STENCIL) { @@ -400,8 +356,8 @@ void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *firstmesh) for (mesh = firstmesh;mesh;mesh = mesh->next) { R_Mesh_GetSpace(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); c_rtcached_shadowmeshes++; c_rtcached_shadowtris += mesh->numtriangles; } @@ -412,8 +368,8 @@ void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *firstmesh) for (mesh = firstmesh;mesh;mesh = mesh->next) { R_Mesh_GetSpace(mesh->numverts); - memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4])); - R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements); + R_Mesh_CopyVertex3f(mesh->vertex3f, mesh->numverts); + R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i); c_rtcached_shadowmeshes++; c_rtcached_shadowtris += mesh->numtriangles; } @@ -448,56 +404,61 @@ static void R_Shadow_MakeTextures(void) data[2] = 255; data[3] = 255; r_shadow_blankwhitetexture = R_LoadTexture2D(r_shadow_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); - for (side = 0;side < 6;side++) + if (gl_texturecubemap) { - for (y = 0;y < NORMSIZE;y++) + for (side = 0;side < 6;side++) { - for (x = 0;x < NORMSIZE;x++) + for (y = 0;y < NORMSIZE;y++) { - s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f; - t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f; - switch(side) + for (x = 0;x < NORMSIZE;x++) { - case 0: - v[0] = 1; - v[1] = -t; - v[2] = -s; - break; - case 1: - v[0] = -1; - v[1] = -t; - v[2] = s; - break; - case 2: - v[0] = s; - v[1] = 1; - v[2] = t; - break; - case 3: - v[0] = s; - v[1] = -1; - v[2] = -t; - break; - case 4: - v[0] = s; - v[1] = -t; - v[2] = 1; - break; - case 5: - v[0] = -s; - v[1] = -t; - v[2] = -1; - break; + s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f; + t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f; + switch(side) + { + case 0: + v[0] = 1; + v[1] = -t; + v[2] = -s; + break; + case 1: + v[0] = -1; + v[1] = -t; + v[2] = s; + break; + case 2: + v[0] = s; + v[1] = 1; + v[2] = t; + break; + case 3: + v[0] = s; + v[1] = -1; + v[2] = -t; + break; + case 4: + v[0] = s; + v[1] = -t; + v[2] = 1; + break; + case 5: + v[0] = -s; + v[1] = -t; + v[2] = -1; + break; + } + intensity = 127.0f / sqrt(DotProduct(v, v)); + data[((side*NORMSIZE+y)*NORMSIZE+x)*4+0] = 128.0f + intensity * v[0]; + data[((side*NORMSIZE+y)*NORMSIZE+x)*4+1] = 128.0f + intensity * v[1]; + data[((side*NORMSIZE+y)*NORMSIZE+x)*4+2] = 128.0f + intensity * v[2]; + data[((side*NORMSIZE+y)*NORMSIZE+x)*4+3] = 255; } - intensity = 127.0f / sqrt(DotProduct(v, v)); - data[((side*NORMSIZE+y)*NORMSIZE+x)*4+0] = 128.0f + intensity * v[0]; - data[((side*NORMSIZE+y)*NORMSIZE+x)*4+1] = 128.0f + intensity * v[1]; - data[((side*NORMSIZE+y)*NORMSIZE+x)*4+2] = 128.0f + intensity * v[2]; - data[((side*NORMSIZE+y)*NORMSIZE+x)*4+3] = 255; } } + r_shadow_normalcubetexture = R_LoadTextureCubeMap(r_shadow_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL); } - r_shadow_normalscubetexture = R_LoadTextureCubeMap(r_shadow_texturepool, "normalscube", NORMSIZE, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL); + else + r_shadow_normalcubetexture = NULL; for (y = 0;y < ATTEN2DSIZE;y++) { for (x = 0;x < ATTEN2DSIZE;x++) @@ -994,91 +955,115 @@ int R_Shadow_ScissorForBBox(const float *mins, const float *maxs) return false; } -void R_Shadow_VertexLighting(float *color, int numverts, const float *vertex, const float *normal, const float *lightcolor, const float *relativelightorigin, float lightradius) +void R_Shadow_VertexLighting(int numverts, const float *vertex3f, const float *normal3f, const float *lightcolor, const float *relativelightorigin, float lightradius) { + float *color4f = varray_color4f; float dist, dot, intensity, iradius = 1.0f / lightradius, radius2 = lightradius * lightradius, v[3]; - for (;numverts > 0;numverts--, vertex += 4, color += 4, normal += 4) + for (;numverts > 0;numverts--, vertex3f += 3, normal3f += 3, color4f += 4) { - VectorSubtract(vertex, relativelightorigin, v); - if ((dot = DotProduct(normal, v)) > 0 && (dist = DotProduct(v, v)) < radius2) + VectorSubtract(vertex3f, relativelightorigin, v); + if ((dot = DotProduct(normal3f, v)) > 0 && (dist = DotProduct(v, v)) < radius2) { dist = sqrt(dist); intensity = pow(1 - (dist * iradius), r_shadow_attenpower) * r_shadow_attenscale * dot / dist; - VectorScale(lightcolor, intensity, color); + VectorScale(lightcolor, intensity, color4f); + color4f[3] = 1; } else - VectorClear(color); + { + VectorClear(color4f); + color4f[3] = 1; + } } } -void R_Shadow_VertexLightingWithXYAttenuationTexture(float *color, int numverts, const float *vertex, const float *normal, const float *lightcolor, const float *relativelightorigin, float lightradius, const float *zdir) +void R_Shadow_VertexLightingWithXYAttenuationTexture(int numverts, const float *vertex3f, const float *normal3f, const float *lightcolor, const float *relativelightorigin, float lightradius, const float *zdir) { + float *color4f = varray_color4f; float dist, dot, intensity, iradius = 1.0f / lightradius, v[3]; - for (;numverts > 0;numverts--, vertex += 4, color += 4, normal += 4) + for (;numverts > 0;numverts--, vertex3f += 3, normal3f += 3, color4f += 4) { - VectorSubtract(vertex, relativelightorigin, v); - if ((dot = DotProduct(normal, v)) > 0 && (dist = fabs(DotProduct(zdir, v))) < lightradius) + VectorSubtract(vertex3f, relativelightorigin, v); + if ((dot = DotProduct(normal3f, v)) > 0 && (dist = fabs(DotProduct(zdir, v))) < lightradius) { intensity = pow(1 - (dist * iradius), r_shadow_attenpower) * r_shadow_attenscale * dot / sqrt(DotProduct(v,v)); - VectorScale(lightcolor, intensity, color); + VectorScale(lightcolor, intensity, color4f); + color4f[3] = 1; } else - VectorClear(color); + { + VectorClear(color4f); + color4f[3] = 1; + } } } // FIXME: this should be done in a vertex program when possible // FIXME: if vertex program not available, this would really benefit from 3DNow! or SSE -void R_Shadow_TransformVertices(float *out, int numverts, const float *vertex, const matrix4x4_t *matrix) +void R_Shadow_Transform_Vertex3f_TexCoord3f(float *tc3f, int numverts, const float *vertex3f, const matrix4x4_t *matrix) +{ + do + { + tc3f[0] = vertex3f[0] * matrix->m[0][0] + vertex3f[1] * matrix->m[0][1] + vertex3f[2] * matrix->m[0][2] + matrix->m[0][3]; + tc3f[1] = vertex3f[0] * matrix->m[1][0] + vertex3f[1] * matrix->m[1][1] + vertex3f[2] * matrix->m[1][2] + matrix->m[1][3]; + tc3f[2] = vertex3f[0] * matrix->m[2][0] + vertex3f[1] * matrix->m[2][1] + vertex3f[2] * matrix->m[2][2] + matrix->m[2][3]; + vertex3f += 3; + tc3f += 3; + } + while (--numverts); +} + +void R_Shadow_Transform_Vertex3f_TexCoord2f(float *tc2f, int numverts, const float *vertex3f, const matrix4x4_t *matrix) { do { - Matrix4x4_Transform(matrix, vertex, out); - vertex += 4; - out += 4; + tc2f[0] = vertex3f[0] * matrix->m[0][0] + vertex3f[1] * matrix->m[0][1] + vertex3f[2] * matrix->m[0][2] + matrix->m[0][3]; + tc2f[1] = vertex3f[0] * matrix->m[1][0] + vertex3f[1] * matrix->m[1][1] + vertex3f[2] * matrix->m[1][2] + matrix->m[1][3]; + vertex3f += 3; + tc2f += 2; } while (--numverts); } -void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin) +void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(float *out3f, int numverts, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const vec3_t relativelightorigin) { int i; float lightdir[3]; - for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4) + for (i = 0;i < numverts;i++, vertex3f += 3, svector3f += 3, tvector3f += 3, normal3f += 3, out3f += 3) { - VectorSubtract(vertex, relativelightorigin, lightdir); + VectorSubtract(vertex3f, relativelightorigin, lightdir); // the cubemap normalizes this for us - out[0] = DotProduct(svectors, lightdir); - out[1] = DotProduct(tvectors, lightdir); - out[2] = DotProduct(normals, lightdir); + out3f[0] = DotProduct(svector3f, lightdir); + out3f[1] = DotProduct(tvector3f, lightdir); + out3f[2] = DotProduct(normal3f, lightdir); } } -void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, const vec3_t relativeeyeorigin) +void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out3f, int numverts, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const vec3_t relativelightorigin, const vec3_t relativeeyeorigin) { int i; float lightdir[3], eyedir[3], halfdir[3]; - for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4) + for (i = 0;i < numverts;i++, vertex3f += 3, svector3f += 3, tvector3f += 3, normal3f += 3, out3f += 3) { - VectorSubtract(vertex, relativelightorigin, lightdir); + VectorSubtract(vertex3f, relativelightorigin, lightdir); VectorNormalizeFast(lightdir); - VectorSubtract(vertex, relativeeyeorigin, eyedir); + VectorSubtract(vertex3f, relativeeyeorigin, eyedir); VectorNormalizeFast(eyedir); VectorAdd(lightdir, eyedir, halfdir); // the cubemap normalizes this for us - out[0] = DotProduct(svectors, halfdir); - out[1] = DotProduct(tvectors, halfdir); - out[2] = DotProduct(normals, halfdir); + out3f[0] = DotProduct(svector3f, halfdir); + out3f[1] = DotProduct(tvector3f, halfdir); + out3f[2] = DotProduct(normal3f, halfdir); } } -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) +void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, 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]; + float color[3], color2[3]; rmeshstate_t m; memset(&m, 0, sizeof(m)); - if (gl_dot3arb) + if (gl_dot3arb && gl_texturecubemap && gl_combine.integer && gl_stencil) { if (!bumptexture) bumptexture = r_shadow_blankbumptexture; @@ -1088,9 +1073,9 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element // limit mult to 64 for sanity sake if (r_shadow_texture3d.integer && r_textureunits.integer >= 4) { - // 3/2 3D combine path + // 3/2 3D combine path (Geforce3, Radeon 8500) m.tex[0] = R_GetTexture(bumptexture); - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.tex3d[2] = R_GetTexture(r_shadow_attenuation3dtexture); m.texcombinergb[0] = GL_REPLACE; m.texcombinergb[1] = GL_DOT3_RGBA_ARB; @@ -1099,10 +1084,10 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element 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, vertices, svectors, tvectors, normals, relativelightorigin); - R_Shadow_TransformVertices(varray_texcoord[2], numverts, vertices, matrix_modeltoattenuationxyz); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[2], numverts, vertex3f, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1118,15 +1103,18 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglBlendFunc(GL_DST_ALPHA, GL_ONE); qglEnable(GL_BLEND); - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1134,31 +1122,31 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element } else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap) { - // 1/2/2 3D combine path + // 1/2/2 3D combine path (original Radeon) m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture); R_Mesh_TextureState(&m); 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])); - R_Shadow_TransformVertices(varray_texcoord[0], numverts, vertices, matrix_modeltoattenuationxyz); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0], numverts, vertex3f, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; m.tex[0] = R_GetTexture(bumptexture); m.tex3d[0] = 0; - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.texcombinergb[0] = GL_REPLACE; m.texcombinergb[1] = GL_DOT3_RGBA_ARB; 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, vertices, svectors, tvectors, normals, relativelightorigin); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1171,15 +1159,18 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1187,10 +1178,9 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element } else if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && !lightcubemap) { - // 2/2 3D combine path + // 2/2 3D combine path (original Radeon) m.tex[0] = R_GetTexture(bumptexture); - m.tex3d[0] = 0; - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.texcombinergb[0] = GL_REPLACE; m.texcombinergb[1] = GL_DOT3_RGBA_ARB; R_Mesh_TextureState(&m); @@ -1198,15 +1188,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element 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, vertices, svectors, tvectors, normals, relativelightorigin); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; m.tex[0] = R_GetTexture(basetexture); m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture); + m.texcubemap[1] = 0; m.texcombinergb[0] = GL_MODULATE; m.texcombinergb[1] = GL_MODULATE; R_Mesh_TextureState(&m); @@ -1214,14 +1205,17 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglBlendFunc(GL_DST_ALPHA, GL_ONE); qglEnable(GL_BLEND); - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1229,9 +1223,9 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element } else if (r_textureunits.integer >= 4) { - // 4/2 2D combine path + // 4/2 2D combine path (Geforce3, Radeon 8500) m.tex[0] = R_GetTexture(bumptexture); - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.texcombinergb[0] = GL_REPLACE; m.texcombinergb[1] = GL_DOT3_RGBA_ARB; m.tex[2] = R_GetTexture(r_shadow_attenuation2dtexture); @@ -1241,11 +1235,11 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element 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, 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_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin); + R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[2], numverts, vertex3f, matrix_modeltoattenuationxyz); + R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[3], numverts, vertex3f, matrix_modeltoattenuationz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1261,15 +1255,18 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglBlendFunc(GL_DST_ALPHA, GL_ONE); qglEnable(GL_BLEND); - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1277,7 +1274,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element } else { - // 2/2/2 2D combine path + // 2/2/2 2D combine path (any dot3 card) m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture); m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); R_Mesh_TextureState(&m); @@ -1285,25 +1282,25 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglDisable(GL_BLEND); GL_Color(1,1,1,1); 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_CopyVertex3f(vertex3f, numverts); + R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[0], numverts, vertex3f, matrix_modeltoattenuationxyz); + R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; m.tex[0] = R_GetTexture(bumptexture); m.tex[1] = 0; - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.texcombinergb[0] = GL_REPLACE; m.texcombinergb[1] = GL_DOT3_RGBA_ARB; 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, vertices, svectors, tvectors, normals, relativelightorigin); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1316,15 +1313,18 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1349,14 +1349,20 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element m.blendfunc2 = GL_ONE; 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, vertices, matrix_modeltoattenuationxyz); - VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); - R_Shadow_VertexLightingWithXYAttenuationTexture(varray_color, numverts, vertices, normals, color, relativelightorigin, lightradius, matrix_modeltofilter->m[2]); - R_Mesh_Draw(numverts, numtriangles, elements); + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) + { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); + GL_UseColorArray(); + R_Mesh_GetSpace(numverts); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationxyz); + R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color2, relativelightorigin, lightradius, matrix_modeltofilter->m[2]); + R_Mesh_Draw(numverts, numtriangles, elements); + } } else { @@ -1372,23 +1378,30 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element m.blendfunc2 = GL_ONE; 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, vertices, normals, color, relativelightorigin, lightradius); - R_Mesh_Draw(numverts, numtriangles, elements); + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) + { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); + GL_UseColorArray(); + R_Mesh_GetSpace(numverts); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); + R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, relativelightorigin, lightradius); + R_Mesh_Draw(numverts, numtriangles, elements); + } } } } -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) +void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, 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]; + float color[3], color2[3]; rmeshstate_t m; - if (!gl_dot3arb) + if (!gl_dot3arb || !gl_texturecubemap || !gl_combine.integer || !gl_stencil) return; memset(&m, 0, sizeof(m)); if (!bumptexture) @@ -1401,16 +1414,16 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen { // 2/0/0/0/1/2 3D combine blendsquare path m.tex[0] = R_GetTexture(bumptexture); - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; R_Mesh_TextureState(&m); 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, vertices, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1429,7 +1442,7 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen for (renders = 0;renders < 3;renders++) { R_Mesh_GetSpace(numverts); - memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Mesh_CopyVertex3f(vertex3f, numverts); R_Mesh_Draw(numverts, numtriangles, elements); } c_rt_lightmeshes += 3; @@ -1439,8 +1452,8 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen R_Mesh_TextureState(&m); qglBlendFunc(GL_DST_ALPHA, GL_ZERO); R_Mesh_GetSpace(numverts); - memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); - R_Shadow_TransformVertices(varray_texcoord[0], numverts, vertices, matrix_modeltoattenuationxyz); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[0], numverts, vertex3f, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1452,15 +1465,18 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1470,16 +1486,16 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen { // 2/0/0/0/2 3D combine blendsquare path m.tex[0] = R_GetTexture(bumptexture); - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; R_Mesh_TextureState(&m); 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, vertices, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1498,28 +1514,33 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen for (renders = 0;renders < 3;renders++) { R_Mesh_GetSpace(numverts); - memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Mesh_CopyVertex3f(vertex3f, numverts); 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_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + m.tex[0] = R_GetTexture(glosstexture); + m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture); R_Mesh_TextureState(&m); qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltoattenuationxyz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1529,16 +1550,16 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen { // 2/0/0/0/2/2 2D combine blendsquare path m.tex[0] = R_GetTexture(bumptexture); - m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture); + m.texcubemap[1] = R_GetTexture(r_shadow_normalcubetexture); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; R_Mesh_TextureState(&m); 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, vertices, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin); + R_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); + R_Shadow_GenTexCoords_Specular_NormalCubeMap(varray_texcoord3f[1], numverts, vertex3f, svector3f, tvector3f, normal3f, relativelightorigin, relativeeyeorigin); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1557,7 +1578,7 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen for (renders = 0;renders < 3;renders++) { R_Mesh_GetSpace(numverts); - memcpy(varray_vertex, vertices, numverts * sizeof(float[4])); + R_Mesh_CopyVertex3f(vertex3f, numverts); R_Mesh_Draw(numverts, numtriangles, elements); } c_rt_lightmeshes += 3; @@ -1568,9 +1589,9 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen R_Mesh_TextureState(&m); qglBlendFunc(GL_DST_ALPHA, GL_ZERO); 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_CopyVertex3f(vertex3f, numverts); + R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[0], numverts, vertex3f, matrix_modeltoattenuationxyz); + R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationz); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1581,15 +1602,18 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen qglColorMask(1,1,1,0); qglBlendFunc(GL_DST_ALPHA, GL_ONE); - 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)) + VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2); + for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--) { + color[0] = bound(0, color2[0], 1); + color[1] = bound(0, color2[1], 1); + color[2] = bound(0, color2[2], 1); 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_Mesh_CopyVertex3f(vertex3f, numverts); + R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); if (lightcubemap) - R_Shadow_TransformVertices(varray_texcoord[1], numverts, vertices, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1619,8 +1643,8 @@ vec3_t r_editlights_cursorlocation; static int castshadowcount = 1; void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style, const char *cubemapname, int castshadow) { - int i, j, k, l, maxverts, *mark, tris; - float *verts; + int i, j, k, l, maxverts = 256, *mark, tris; + float *vertex3f = NULL; worldlight_t *e; shadowmesh_t *mesh, *castmesh; mleaf_t *leaf; @@ -1749,8 +1773,6 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style if (e->castshadows) { - maxverts = 256; - verts = NULL; castshadowcount++; for (j = 0;j < e->numsurfaces;j++) { @@ -1768,7 +1790,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style for (j = 0;j < e->numsurfaces;j++) if (e->surfaces[j]->castshadow == castshadowcount) for (surfmesh = e->surfaces[j]->mesh;surfmesh;surfmesh = surfmesh->chain) - Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, surfmesh->numverts, surfmesh->verts, surfmesh->numtriangles, surfmesh->index); + Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, surfmesh->numverts, surfmesh->vertex3f, surfmesh->numtriangles, surfmesh->element3i); castmesh = Mod_ShadowMesh_Finish(r_shadow_mempool, castmesh); // cast shadow volume from castmesh @@ -1780,24 +1802,24 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style if (maxverts < castmesh->numverts * 2) { maxverts = castmesh->numverts * 2; - if (verts) - Mem_Free(verts); - verts = NULL; + if (vertex3f) + Mem_Free(vertex3f); + vertex3f = NULL; } - if (verts == NULL && maxverts > 0) - verts = Mem_Alloc(r_shadow_mempool, maxverts * sizeof(float[4])); + if (vertex3f == NULL && maxverts > 0) + vertex3f = Mem_Alloc(r_shadow_mempool, maxverts * sizeof(float[3])); // 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); - 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); + memcpy(vertex3f, castmesh->vertex3f, castmesh->numverts * sizeof(float[3])); + R_Shadow_ProjectVertex3f(vertex3f, castmesh->numverts, e->origin, r_shadow_projectdistance.value);//, e->lightradius); + tris = R_Shadow_MakeTriangleShadowFlags_Vertex3f(castmesh->element3i, vertex3f, castmesh->numtriangles, trianglefacinglight, trianglefacinglightlist, e->origin); + tris = R_Shadow_BuildShadowVolumeTriangles(castmesh->element3i, castmesh->neighbor3i, 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); + Mod_ShadowMesh_AddMesh(r_shadow_mempool, e->shadowvolume, castmesh->numverts, vertex3f, tris, shadowelements); } - if (verts) - Mem_Free(verts); - verts = NULL; + if (vertex3f) + Mem_Free(vertex3f); + vertex3f = NULL; // we're done with castmesh now Mod_ShadowMesh_Free(castmesh); e->shadowvolume = Mod_ShadowMesh_Finish(r_shadow_mempool, e->shadowvolume); @@ -1863,24 +1885,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; - varray_texcoord[0][12] = 1;varray_texcoord[0][13] = 0; - varray_vertex[0] = origin[0] - vright[0] * scale - vup[0] * scale; - varray_vertex[1] = origin[1] - vright[1] * scale - vup[1] * scale; - varray_vertex[2] = origin[2] - vright[2] * scale - vup[2] * scale; - varray_vertex[4] = origin[0] - vright[0] * scale + vup[0] * scale; - varray_vertex[5] = origin[1] - vright[1] * scale + vup[1] * scale; - varray_vertex[6] = origin[2] - vright[2] * scale + vup[2] * scale; - varray_vertex[8] = origin[0] + vright[0] * scale + vup[0] * scale; - varray_vertex[9] = origin[1] + vright[1] * scale + vup[1] * scale; - varray_vertex[10] = origin[2] + vright[2] * scale + vup[2] * scale; - varray_vertex[12] = origin[0] + vright[0] * scale - vup[0] * scale; - varray_vertex[13] = origin[1] + vright[1] * scale - vup[1] * scale; - varray_vertex[14] = origin[2] + vright[2] * scale - vup[2] * scale; - R_Mesh_Draw(4, 2, polygonelements); + R_DrawSpriteMesh(origin, vright, vup, scale, -scale, -scale, scale); } void R_Shadow_DrawCursorCallback(const void *calldata1, int calldata2) diff --git a/r_sky.c b/r_sky.c index 4fa301d2..fa689d9a 100644 --- a/r_sky.c +++ b/r_sky.c @@ -121,11 +121,11 @@ static void R_SkyBox(void) rmeshstate_t m; #define R_SkyBoxPolyVec(i,s,t,x,y,z) \ - varray_vertex[i * 4 + 0] = (x) * 16.0f;\ - varray_vertex[i * 4 + 1] = (y) * 16.0f;\ - varray_vertex[i * 4 + 2] = (z) * 16.0f;\ - varray_texcoord[0][i * 4 + 0] = (s);\ - varray_texcoord[0][i * 4 + 1] = (t); + varray_vertex3f[i * 3 + 0] = (x) * 16.0f;\ + varray_vertex3f[i * 3 + 1] = (y) * 16.0f;\ + varray_vertex3f[i * 3 + 2] = (z) * 16.0f;\ + varray_texcoord2f[0][i * 2 + 0] = (s);\ + varray_texcoord2f[0][i * 2 + 1] = (t); GL_Color(r_colorscale, r_colorscale, r_colorscale, 1); @@ -197,20 +197,20 @@ static void R_SkyBox(void) #define skygridyrecip (1.0f / (skygridy)) #define skysphere_numverts (skygridx1 * skygridy1) #define skysphere_numtriangles (skygridx * skygridy * 2) -static float skysphere_vertex[skysphere_numverts * 4]; -static float skysphere_texcoord[skysphere_numverts * 4]; -static int skysphere_elements[skysphere_numtriangles * 3]; +static float skysphere_vertex3f[skysphere_numverts * 3]; +static float skysphere_texcoord2f[skysphere_numverts * 2]; +static int skysphere_element3i[skysphere_numtriangles * 3]; static void skyspherecalc(void) { int i, j, *e; - float a, b, x, ax, ay, v[3], length, *vertex, *texcoord; + float a, b, x, ax, ay, v[3], length, *vertex3f, *texcoord2f; float dx, dy, dz; dx = 16; dy = 16; dz = 16 / 3; - vertex = skysphere_vertex; - texcoord = skysphere_texcoord; + vertex3f = skysphere_vertex3f; + texcoord2f = skysphere_texcoord2f; for (j = 0;j <= skygridy;j++) { a = j * skygridyrecip; @@ -224,17 +224,14 @@ static void skyspherecalc(void) v[1] = ay*x * dy; v[2] = -sin((b + 0.5) * M_PI) * dz; length = 3.0f / sqrt(v[0]*v[0]+v[1]*v[1]+(v[2]*v[2]*9)); - *texcoord++ = v[0] * length; - *texcoord++ = v[1] * length; - *texcoord++ = 0; - *texcoord++ = 0; - *vertex++ = v[0]; - *vertex++ = v[1]; - *vertex++ = v[2]; - *vertex++ = 1; + *texcoord2f++ = v[0] * length; + *texcoord2f++ = v[1] * length; + *vertex3f++ = v[0]; + *vertex3f++ = v[1]; + *vertex3f++ = v[2]; } } - e = skysphere_elements; + e = skysphere_element3i; for (j = 0;j < skygridy;j++) { for (i = 0;i < skygridx;i++) @@ -254,7 +251,8 @@ static void skyspherecalc(void) static void R_SkySphere(void) { int i; - float speedscale, *t; + float speedscale, *out2f; + const float *in2f; static qboolean skysphereinitialized = false; rmeshstate_t m; if (!skysphereinitialized) @@ -278,14 +276,13 @@ 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) + R_Mesh_CopyVertex3f(skysphere_vertex3f, skysphere_numverts); + for (i = 0, out2f = varray_texcoord2f[0], in2f = skysphere_texcoord2f;i < skysphere_numverts;i++) { - t[0] += speedscale; - t[1] += speedscale; + *out2f++ = *in2f++ + speedscale; + *out2f++ = *in2f++ + speedscale; } - R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_elements); + R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_element3i); m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; @@ -296,14 +293,13 @@ static void R_SkySphere(void) 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) + R_Mesh_CopyVertex3f(skysphere_vertex3f, skysphere_numverts); + for (i = 0, out2f = varray_texcoord2f[0], in2f = skysphere_texcoord2f;i < skysphere_numverts;i++) { - t[0] += speedscale; - t[1] += speedscale; + *out2f++ = *in2f++ + speedscale; + *out2f++ = *in2f++ + speedscale; } - R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_elements); + R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_element3i); } void R_Sky(void) diff --git a/r_sprites.c b/r_sprites.c index de9a7c44..d839057b 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -90,25 +90,8 @@ static void R_DrawSpriteImage (int additive, mspriteframe_t *frame, int 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; - varray_texcoord[0][12] = 1;varray_texcoord[0][13] = 1; // FIXME: negate left and right in loader - varray_vertex[0] = origin[0] + frame->down * up[0] - frame->left * left[0]; - varray_vertex[1] = origin[1] + frame->down * up[1] - frame->left * left[1]; - varray_vertex[2] = origin[2] + frame->down * up[2] - frame->left * left[2]; - varray_vertex[4] = origin[0] + frame->up * up[0] - frame->left * left[0]; - varray_vertex[5] = origin[1] + frame->up * up[1] - frame->left * left[1]; - varray_vertex[6] = origin[2] + frame->up * up[2] - frame->left * left[2]; - varray_vertex[8] = origin[0] + frame->up * up[0] - frame->right * left[0]; - varray_vertex[9] = origin[1] + frame->up * up[1] - frame->right * left[1]; - varray_vertex[10] = origin[2] + frame->up * up[2] - frame->right * left[2]; - 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]; - R_Mesh_Draw(4, 2, polygonelements); + R_DrawSpriteMesh(origin, left, up, frame->left, frame->right, frame->down, frame->up); } void R_DrawSpriteModelCallback(const void *calldata1, int calldata2) diff --git a/render.h b/render.h index 01c58448..88ccbed2 100644 --- a/render.h +++ b/render.h @@ -168,7 +168,8 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int void R_DrawWorldCrosshair(void); void R_Draw2DCrosshair(void); -void R_CalcBeamVerts (float *vert, const vec3_t org1, const vec3_t org2, float width); +void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width); +void R_DrawSpriteMesh(const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2); #endif