varray_* rewritten to remove padding (varray_vertex3f, varray_texcoord2f, varray_texc...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 15 Mar 2003 04:54:47 +0000 (04:54 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 15 Mar 2003 04:54:47 +0000 (04:54 +0000)
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

26 files changed:
cl_main.c
cl_particles.c
cl_screen.c
cl_screen.h
cl_video.c
gl_backend.c
gl_backend.h
gl_draw.c
gl_models.c
gl_rmain.c
gl_rsurf.c
mathlib.h
model_alias.c
model_alias.h
model_brush.c
model_brush.h
model_shared.c
model_shared.h
portals.c
r_crosshairs.c
r_explosion.c
r_light.c
r_shadow.c
r_sky.c
r_sprites.c
render.h

index 9b70f0f..341cdcc 100644 (file)
--- 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();
index 68a2b56..d0b5fd5 100644 (file)
@@ -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);
index 9c350b6..8e23cc5 100644 (file)
@@ -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;
 }
 
index 76c343d..ec41eac 100644 (file)
@@ -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;
 
index 4778c81..fb42b6f 100644 (file)
@@ -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);
        }
index 3be6965..a454952 100644 (file)
@@ -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]));
+}
+
+
index 9569ade..89f0a88 100644 (file)
@@ -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
index d36af9c..8885586 100644 (file)
--- 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);
                }
        }
index 9d85d07..13cc278 100644 (file)
@@ -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
 }
+
index 16f5acc..b35afaf 100644 (file)
@@ -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);
+}
+
index 017d403..8ace2fa 100644 (file)
@@ -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);
                                                }
                                        }
                                }
index 002c3f1..3d56785 100644 (file)
--- 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
index 9b0f33e..b095d9b 100644 (file)
@@ -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]);
                }
        }
 
index 7e5a88c..36d4e50 100644 (file)
@@ -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;
 
index 5e74ea4..ac88de7 100644 (file)
@@ -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];
index 0f2ee07..c4d0c18 100644 (file)
@@ -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;
 
index e3fa83e..97efa1f 100644 (file)
@@ -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);
index 43cadd1..4a43454 100644 (file)
@@ -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;
index 6c1a191..339fd80 100644 (file)
--- 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;
                                        }
index 212d654..ba08ed9 100644 (file)
@@ -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)
index 6feff62..f7cdd72 100644 (file)
@@ -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);
index 74ca47e..2824929 100644 (file)
--- 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
index 50de897..2036a8b 100644 (file)
@@ -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 4fa301d..fa689d9 100644 (file)
--- 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)
index de9a7c4..d839057 100644 (file)
@@ -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)
index 01c5844..88ccbed 100644 (file)
--- 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