]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
most of the framework for hardware accelerated transforms is back, just the actual...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 28 Aug 2002 11:56:00 +0000 (11:56 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 28 Aug 2002 11:56:00 +0000 (11:56 +0000)
gl_backend internal mesh structure now has a matrix stored in it
entity_render_t now has a matrix and a inverse matrix
many additions of const to various functions, this required restructuring some code
transparent mesh sorting is gone, this also means subsorting of triangles by depth is gone (meshqueue should be used for transparent mesh sorting, I have not yet written a new triangle sorter)
rewrote RSurf_ shader functions *yet again*, they are now more compact and share code (by way of using lots of function calls)
lots of changes/bugfixes/additions to matrixlib.c and .h, including an actual working Matrix4x4_Invert_Simple function
added gl_flashblend (brightens and enlarges coronas, turns off all actual lighting)
added r_coronas (can turn off coronas)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2295 d7cf8633-e32d-0410-b094-e92efae38249

24 files changed:
cl_collision.c
cl_collision.h
cl_light.c
cl_particles.c
cl_screen.c
client.h
gl_backend.c
gl_backend.h
gl_models.c
gl_rmain.c
gl_rsurf.c
matrixlib.c
matrixlib.h
meshqueue.c
meshqueue.h
model_brush.c
model_brush.h
model_shared.h
r_crosshairs.c
r_explosion.c
r_light.c
r_light.h
r_sky.c
r_sprites.c

index 6457fbf2fd52392cb8c0d56f800a7afbd87cc8a4..1bc60f72a26ae88411683ccd7e507654d87179dd 100644 (file)
@@ -30,7 +30,7 @@ physentity_t;
 
 int cl_traceline_endcontents;
 
-float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels)
+float CL_TraceLine (const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels)
 {
        double maxfrac;
        trace_t trace;
index 370349c25820063743fab02ffdce56e44a7fddfb..15c1e06afa7dea345f674ce3fe54f3ca452e9564 100644 (file)
@@ -6,6 +6,6 @@
 // (leafs matching contents are considered empty, others are solid)
 extern int cl_traceline_endcontents; // set by TraceLine
 
-float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels);
+float CL_TraceLine (const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int contents, int hitbmodels);
 
 #endif
index 5d0bcec682acbdee66064ffcc1d9f3521ca7cc5b..9c5d291d4e26d43f87ef6e61283752d6cdd06bf7 100644 (file)
@@ -33,6 +33,7 @@ void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red,
        return;
 
 dlightsetup:
+       //Con_Printf("dlight %i : %f %f %f : %f %f %f\n", i, org[0], org[1], org[2], red * radius, green * radius, blue * radius);
        memset (dl, 0, sizeof(*dl));
        //dl->ent = ent;
        VectorCopy(org, dl->origin);
index be86db568bf96f0d113f6590e21679ea30b02eb8..a2d00944b07991bc8680931228341fcac9fb0fc0 100644 (file)
@@ -1183,16 +1183,14 @@ void R_Particles_Init (void)
 
 int partindexarray[6] = {0, 1, 2, 0, 2, 3};
 
-void R_DrawParticleCallback(void *calldata1, int calldata2)
+void R_DrawParticleCallback(const void *calldata1, int calldata2)
 {
        int lighting, dynlight, additive, texnum, orientation;
        float org[3], up2[3], right2[3], v[3], right[3], up[3], fog, ifog, fogvec[3], cr, cg, cb, ca;
        particletexture_t *tex;
        mleaf_t *leaf;
        rmeshbufferinfo_t m;
-       particle_t *p;
-
-       p = calldata1;
+       const particle_t *p = calldata1;
 
        // LordHavoc: check if it's in a visible leaf
        leaf = Mod_PointInLeaf(p->org, cl.worldmodel);
@@ -1274,6 +1272,7 @@ void R_DrawParticleCallback(void *calldata1, int calldata2)
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = R_GetTexture(particlefonttexture);
+       Matrix4x4_CreateIdentity(&m.matrix);
        if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                m.index[0] = 0;
index bbe0883416bf13f8bf151c775922bce80cc7a84f..c29c7ca7e81f02fadf57cbe1306d40e51197981c 100644 (file)
@@ -357,11 +357,11 @@ void R_TimeReport_Start(void)
                        "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
                        "world:%6i faces%6i nodes%6i leafs%6i walls%6i dlitwalls\n"
                        "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
-                       "%6i modeltris%6i transmeshs%6i transtris%6i meshs%6i meshtris\n",
+                       "%6i modeltris%6i meshs%6i meshtris\n",
                        r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2], r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2], vpn[0], vpn[1], vpn[2],
                        c_faces, c_nodes, c_leafs, c_brush_polys, c_light_polys,
                        c_models, c_bmodels, c_sprites, c_particles, c_dlights,
-                       c_alias_polys, c_transmeshs, c_transtris, c_meshs, c_meshtris);
+                       c_alias_polys, c_meshs, c_meshtris);
 
                c_brush_polys = 0;
                c_alias_polys = 0;
index c7e61e491e0b90dc411d02e2ab8563bebf7fb817..02a6c558f7666b52bbbee9fdcd5190389759073b 100644 (file)
--- a/client.h
+++ b/client.h
@@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #ifndef CLIENT_H
 #define CLIENT_H
 
+#include "matrixlib.h"
+
 // LordHavoc: 256 dynamic lights
 #define MAX_DLIGHTS 256
 // LordHavoc: this affects the lighting scale of the whole game
@@ -92,6 +94,10 @@ typedef struct entity_render_s
        vec3_t origin;
        // orientation
        vec3_t angles;
+       // transform matrix for model to world
+       matrix4x4_t matrix;
+       // transform matrix for world to model
+       matrix4x4_t inversematrix;
        // opacity (alpha) of the model
        float alpha;
        // size the model is shown
@@ -135,6 +141,7 @@ typedef struct entity_render_s
        // caching results of static light traces (this is semi-persistent)
        double entlightstime;
        vec3_t entlightsorigin;
+       int entlightsframe;
        int numentlights;
        unsigned short entlights[MAXENTLIGHTS];
 }
index 0dd8752fa33a0b7b32d9df7ee26b139139aeb9f6..19b70cd16f0a9010bad79993ae448a33f9188a80 100644 (file)
@@ -2,7 +2,6 @@
 #include "quakedef.h"
 
 cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "1024"};
-cvar_t gl_mesh_transtriangles = {0, "gl_mesh_transtriangles", "16384"};
 cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"};
 cvar_t gl_mesh_drawmode = {CVAR_SAVE, "gl_mesh_drawmode", "3"};
 
@@ -13,8 +12,6 @@ cvar_t gl_lockarrays = {0, "gl_lockarrays", "1"};
 // this is used to increase gl_mesh_maxtriangles automatically if a mesh was
 // too large for the buffers in the previous frame
 int overflowedverts = 0;
-// increase transtriangles automatically too
-int overflowedtransverts = 0;
 
 int gl_maxdrawrangeelementsvertices;
 int gl_maxdrawrangeelementsindices;
@@ -74,7 +71,7 @@ static float viewdist;
 // sign bits (true if negative) for vpn[] entries, so quick integer compares can be used instead of float compares
 static int vpnbit0, vpnbit1, vpnbit2;
 
-int c_meshs, c_meshtris, c_transmeshs, c_transtris;
+int c_meshs, c_meshtris;
 
 int lightscalebit;
 float lightscale;
@@ -83,10 +80,7 @@ float overbrightscale;
 void SCR_ScreenShot_f (void);
 
 static int max_meshs;
-static int max_transmeshs;
 static int max_verts; // always max_meshs * 3
-static int max_transverts; // always max_transmeshs * 3
-#define TRANSDEPTHRES 4096
 
 typedef struct buf_mesh_s
 {
@@ -99,20 +93,11 @@ typedef struct buf_mesh_s
        int triangles;
        int firstvert;
        int verts;
+       matrix4x4_t matrix;
        struct buf_mesh_s *chain;
-       struct buf_transtri_s *transchain;
 }
 buf_mesh_t;
 
-typedef struct buf_transtri_s
-{
-       struct buf_transtri_s *next;
-       struct buf_transtri_s *meshsortchain;
-       buf_mesh_t *mesh;
-       int index[3];
-}
-buf_transtri_t;
-
 typedef struct buf_tri_s
 {
        int index[3];
@@ -143,7 +128,7 @@ typedef struct
 }
 buf_texcoord_t;
 
-static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive, transranout;
+static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive;
 static buf_mesh_t *buf_mesh;
 static buf_tri_t *buf_tri;
 static buf_vertex_t *buf_vertex;
@@ -151,15 +136,6 @@ static buf_fcolor_t *buf_fcolor;
 static buf_bcolor_t *buf_bcolor;
 static buf_texcoord_t *buf_texcoord[MAX_TEXTUREUNITS];
 
-static int currenttransmesh, currenttransvertex, currenttranstriangle;
-static buf_mesh_t *buf_transmesh;
-static buf_transtri_t *buf_sorttranstri;
-static buf_transtri_t **buf_sorttranstri_list;
-static buf_tri_t *buf_transtri;
-static buf_vertex_t *buf_transvertex;
-static buf_fcolor_t *buf_transfcolor;
-static buf_texcoord_t *buf_transtexcoord[MAX_TEXTUREUNITS];
-
 static mempool_t *gl_backend_mempool;
 static int resizingbuffers = false;
 
@@ -170,7 +146,7 @@ static void gl_backend_start(void)
        qglGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &gl_maxdrawrangeelementsvertices);
        qglGetIntegerv(GL_MAX_ELEMENTS_INDICES, &gl_maxdrawrangeelementsindices);
 
-       Con_Printf("OpenGL Backend started with gl_mesh_maxtriangles %i, gl_mesh_transtriangles %i\n", gl_mesh_maxtriangles.integer, gl_mesh_transtriangles.integer);
+       Con_Printf("OpenGL Backend started with gl_mesh_maxtriangles %i\n", gl_mesh_maxtriangles.integer);
        if (qglDrawRangeElements != NULL)
                Con_Printf("glDrawRangeElements detected (max vertices %i, max indices %i)\n", gl_maxdrawrangeelementsvertices, gl_maxdrawrangeelementsindices);
        if (strstr(gl_renderer, "3Dfx"))
@@ -181,7 +157,6 @@ static void gl_backend_start(void)
        Con_Printf("\n");
 
        max_verts = max_meshs * 3;
-       max_transverts = max_transmeshs * 3;
 
        if (!gl_backend_mempool)
                gl_backend_mempool = Mem_AllocPool("GL_Backend");
@@ -200,25 +175,16 @@ static void gl_backend_start(void)
        BACKENDALLOC(buf_fcolor, max_verts, buf_fcolor_t, "buf_fcolor")
        BACKENDALLOC(buf_bcolor, max_verts, buf_bcolor_t, "buf_bcolor")
 
-       BACKENDALLOC(buf_transmesh, max_transmeshs, buf_mesh_t, "buf_transmesh")
-       BACKENDALLOC(buf_sorttranstri, max_transmeshs, buf_transtri_t, "buf_sorttranstri")
-       BACKENDALLOC(buf_sorttranstri_list, TRANSDEPTHRES, buf_transtri_t *, "buf_sorttranstri_list")
-       BACKENDALLOC(buf_transtri, max_transmeshs, buf_tri_t, "buf_transtri")
-       BACKENDALLOC(buf_transvertex, max_transverts, buf_vertex_t, "buf_vertex")
-       BACKENDALLOC(buf_transfcolor, max_transverts, buf_fcolor_t, "buf_fcolor")
-
        for (i = 0;i < MAX_TEXTUREUNITS;i++)
        {
                // only allocate as many texcoord arrays as we need
                if (i < gl_textureunits)
                {
                        BACKENDALLOC(buf_texcoord[i], max_verts, buf_texcoord_t, va("buf_texcoord[%d]", i))
-                       BACKENDALLOC(buf_transtexcoord[i], max_transverts, buf_texcoord_t, va("buf_transtexcoord[%d]", i))
                }
                else
                {
                        buf_texcoord[i] = NULL;
-                       buf_transtexcoord[i] = NULL;
                }
        }
        backendunits = min(MAX_TEXTUREUNITS, gl_textureunits);
@@ -244,10 +210,6 @@ static void gl_backend_bufferchanges(int init)
                Cvar_SetValueQuick(&gl_mesh_maxtriangles, (int) ((overflowedverts + 2) / 3));
        overflowedverts = 0;
 
-       if (overflowedtransverts > gl_mesh_transtriangles.integer * 3)
-               Cvar_SetValueQuick(&gl_mesh_transtriangles, (int) ((overflowedtransverts + 2) / 3));
-       overflowedtransverts = 0;
-
        if (gl_mesh_drawmode.integer < 0)
                Cvar_SetValueQuick(&gl_mesh_drawmode, 0);
        if (gl_mesh_drawmode.integer > 3)
@@ -265,15 +227,9 @@ static void gl_backend_bufferchanges(int init)
        if (gl_mesh_maxtriangles.integer > 21760)
                Cvar_SetValueQuick(&gl_mesh_maxtriangles, 21760);
 
-       if (gl_mesh_transtriangles.integer < 1024)
-               Cvar_SetValueQuick(&gl_mesh_transtriangles, 1024);
-       if (gl_mesh_transtriangles.integer > 65536)
-               Cvar_SetValueQuick(&gl_mesh_transtriangles, 65536);
-
-       if (max_meshs != gl_mesh_maxtriangles.integer || max_transmeshs != gl_mesh_transtriangles.integer)
+       if (max_meshs != gl_mesh_maxtriangles.integer)
        {
                max_meshs = gl_mesh_maxtriangles.integer;
-               max_transmeshs = gl_mesh_transtriangles.integer;
 
                if (!init)
                {
@@ -299,7 +255,6 @@ void gl_backend_init(void)
 #endif
 
        Cvar_RegisterVariable(&gl_mesh_maxtriangles);
-       Cvar_RegisterVariable(&gl_mesh_transtriangles);
        Cvar_RegisterVariable(&gl_mesh_floatcolors);
        Cvar_RegisterVariable(&gl_mesh_drawmode);
        R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
@@ -492,10 +447,6 @@ void R_Mesh_Start(float farclip)
        currentmesh = 0;
        currenttriangle = 0;
        currentvertex = 0;
-       currenttransmesh = 0;
-       currenttranstriangle = 0;
-       currenttransvertex = 0;
-       transranout = false;
        r_mesh_farclip = farclip;
        viewdist = DotProduct(r_origin, vpn);
        vpnbit0 = vpn[0] < 0;
@@ -504,8 +455,6 @@ void R_Mesh_Start(float farclip)
 
        c_meshs = 0;
        c_meshtris = 0;
-       c_transmeshs = 0;
-       c_transtris = 0;
 
        GL_SetupFrame();
 
@@ -761,7 +710,8 @@ void GL_DrawRangeElements(int firstvert, int endvert, int indexcount, GLuint *in
 // renders mesh buffers, called to flush buffers when full
 void R_Mesh_Render(void)
 {
-       int k;
+       int i, k;
+       float *v, tempv[4];
        buf_mesh_t *mesh;
 
        if (!backendactive)
@@ -791,6 +741,14 @@ void R_Mesh_Render(void)
        }
 
        GL_MeshState(buf_mesh);
+       for (k = 0, mesh = buf_mesh;k < currentmesh;k++, mesh++)
+       {
+               for (i = 0, v = buf_vertex[mesh->firstvert].v;i < mesh->verts;i++, v += 4)
+               {
+                       VectorCopy(v, tempv);
+                       Matrix4x4_Transform(&mesh->matrix, tempv, v);
+               }
+       }
        GL_LockArray(0, currentvertex);
        GL_DrawRangeElements(buf_mesh->firstvert, buf_mesh->firstvert + buf_mesh->verts, buf_mesh->triangles * 3, (unsigned int *)&buf_tri[buf_mesh->firsttriangle].index[0]);CHECKGLERROR
 
@@ -868,8 +826,6 @@ void R_Mesh_Finish(void)
 
 void R_Mesh_ClearDepth(void)
 {
-       if (currenttransmesh)
-               R_Mesh_AddTransparent();
        if (currentmesh)
                R_Mesh_Render();
        R_Mesh_Finish();
@@ -877,123 +833,6 @@ void R_Mesh_ClearDepth(void)
        R_Mesh_Start(r_mesh_farclip);
 }
 
-void R_Mesh_AddTransparent(void)
-{
-       int i, j, k, *index;
-       float viewdistcompare, centerscaler, dist1, dist2, dist3, center, maxdist;
-       buf_vertex_t *vert1, *vert2, *vert3;
-       buf_transtri_t *tri;
-       buf_mesh_t *mesh, *transmesh;
-
-       if (!currenttransmesh)
-               return;
-
-       // convert index data to transtris for sorting
-       for (j = 0;j < currenttransmesh;j++)
-       {
-               mesh = buf_transmesh + j;
-               k = mesh->firsttriangle;
-               index = &buf_transtri[k].index[0];
-               for (i = 0;i < mesh->triangles;i++)
-               {
-                       tri = &buf_sorttranstri[k++];
-                       tri->mesh = mesh;
-                       tri->index[0] = *index++;
-                       tri->index[1] = *index++;
-                       tri->index[2] = *index++;
-               }
-       }
-
-       // map farclip to 0-4095 list range
-       centerscaler = (TRANSDEPTHRES / r_mesh_farclip) * (1.0f / 3.0f);
-       viewdistcompare = viewdist + 4.0f;
-
-       memset(buf_sorttranstri_list, 0, TRANSDEPTHRES * sizeof(buf_transtri_t *));
-
-       k = 0;
-       for (j = 0;j < currenttranstriangle;j++)
-       {
-               tri = &buf_sorttranstri[j];
-               i = tri->mesh->firstvert;
-
-               vert1 = &buf_transvertex[tri->index[0] + i];
-               vert2 = &buf_transvertex[tri->index[1] + i];
-               vert3 = &buf_transvertex[tri->index[2] + i];
-
-               dist1 = DotProduct(vert1->v, vpn);
-               dist2 = DotProduct(vert2->v, vpn);
-               dist3 = DotProduct(vert3->v, vpn);
-
-               maxdist = max(dist1, max(dist2, dist3));
-               if (maxdist < viewdistcompare)
-                       continue;
-
-               center = (dist1 + dist2 + dist3) * centerscaler - viewdist;
-#if SLOWMATH
-               i = (int) center;
-               i = bound(0, i, (TRANSDEPTHRES - 1));
-#else
-               if (center < 0.0f)
-                       center = 0.0f;
-               center += 8388608.0f;
-               i = *((int *)&center) & 0x7FFFFF;
-               i = min(i, (TRANSDEPTHRES - 1));
-#endif
-               tri->next = buf_sorttranstri_list[i];
-               buf_sorttranstri_list[i] = tri;
-               k++;
-       }
-
-       for (i = 0;i < currenttransmesh;i++)
-               buf_transmesh[i].transchain = NULL;
-       transmesh = NULL;
-       for (j = 0;j < TRANSDEPTHRES;j++)
-       {
-               if ((tri = buf_sorttranstri_list[j]))
-               {
-                       for (;tri;tri = tri->next)
-                       {
-                               if (!tri->mesh->transchain)
-                               {
-                                       tri->mesh->chain = transmesh;
-                                       transmesh = tri->mesh;
-                               }
-                               tri->meshsortchain = tri->mesh->transchain;
-                               tri->mesh->transchain = tri;
-                       }
-               }
-       }
-
-       R_Mesh_Render();
-       for (;transmesh;transmesh = transmesh->chain)
-       {
-               mesh = &buf_mesh[currentmesh++];
-               *mesh = *transmesh; // copy mesh properties
-
-               mesh->firstvert = currentvertex;
-               memcpy(&buf_vertex[currentvertex], &buf_transvertex[transmesh->firstvert], transmesh->verts * sizeof(buf_vertex_t));
-               memcpy(&buf_fcolor[currentvertex], &buf_transfcolor[transmesh->firstvert], transmesh->verts * sizeof(buf_fcolor_t));
-               for (i = 0;i < backendunits && transmesh->textures[i];i++)
-                       memcpy(&buf_texcoord[i][currentvertex], &buf_transtexcoord[i][transmesh->firstvert], transmesh->verts * sizeof(buf_texcoord_t));
-               currentvertex += mesh->verts;
-
-               mesh->firsttriangle = currenttriangle;
-               for (tri = transmesh->transchain;tri;tri = tri->meshsortchain)
-               {
-                       buf_tri[currenttriangle].index[0] = tri->index[0];
-                       buf_tri[currenttriangle].index[1] = tri->index[1];
-                       buf_tri[currenttriangle].index[2] = tri->index[2];
-                       currenttriangle++;
-               }
-               mesh->triangles = currenttriangle - mesh->firsttriangle;
-               R_Mesh_Render();
-       }
-
-       currenttransmesh = 0;
-       currenttranstriangle = 0;
-       currenttransvertex = 0;
-}
-
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
 // (this is used for very high speed rendering, no copying)
 int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
@@ -1030,65 +869,36 @@ int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
        }
 
        if (m->transparent)
-       {
-               overflowedtransverts += max(m->numtriangles * 3, m->numverts);
-               if (currenttransmesh >= max_transmeshs || (currenttranstriangle + m->numtriangles) > max_transmeshs || (currenttransvertex + m->numverts) > max_transverts)
-               {
-                       if (!transranout)
-                       {
-                               Con_Printf("R_Mesh_Draw_GetBuffer: ran out of room for transparent meshs\n");
-                               transranout = true;
-                       }
-                       return false;
-               }
+               Con_Printf("R_Mesh_Draw_GetBuffer: m.transparent is no longer supported\n");
 
-               c_transmeshs++;
-               c_transtris += m->numtriangles;
-               m->index = &buf_transtri[currenttranstriangle].index[0];
-               m->vertex = &buf_transvertex[currenttransvertex].v[0];
-               m->color = &buf_transfcolor[currenttransvertex].c[0];
-               for (i = 0;i < backendunits;i++)
-                       m->texcoords[i] = &buf_transtexcoord[i][currenttransvertex].t[0];
-
-               // transmesh is only for storage of transparent meshs until they
-               // are inserted into the main mesh array
-               mesh = &buf_transmesh[currenttransmesh++];
-               mesh->firsttriangle = currenttranstriangle;
-               mesh->firstvert = currenttransvertex;
-               currenttranstriangle += m->numtriangles;
-               currenttransvertex += m->numverts;
-       }
-       else
+       if (currentmesh)
        {
-               if (currentmesh)
-               {
-                       R_Mesh_Render();
-                       Con_Printf("mesh queue not empty, flushing.\n");
-               }
-
-               c_meshs++;
-               c_meshtris += m->numtriangles;
-               m->index = &buf_tri[currenttriangle].index[0];
-               m->vertex = &buf_vertex[currentvertex].v[0];
-               m->color = &buf_fcolor[currentvertex].c[0];
-               for (i = 0;i < backendunits;i++)
-                       m->texcoords[i] = &buf_texcoord[i][currentvertex].t[0];
-
-               // opaque meshs are rendered directly
-               mesh = &buf_mesh[currentmesh++];
-               mesh->firsttriangle = currenttriangle;
-               mesh->firstvert = currentvertex;
-               currenttriangle += m->numtriangles;
-               currentvertex += m->numverts;
+               R_Mesh_Render();
+               Con_Printf("mesh queue not empty, flushing.\n");
        }
 
-       // code shared for transparent and opaque meshs
+       c_meshs++;
+       c_meshtris += m->numtriangles;
+       m->index = &buf_tri[currenttriangle].index[0];
+       m->vertex = &buf_vertex[currentvertex].v[0];
+       m->color = &buf_fcolor[currentvertex].c[0];
+       for (i = 0;i < backendunits;i++)
+               m->texcoords[i] = &buf_texcoord[i][currentvertex].t[0];
+
+       // opaque meshs are rendered directly
+       mesh = &buf_mesh[currentmesh++];
+       mesh->firsttriangle = currenttriangle;
+       mesh->firstvert = currentvertex;
+       currenttriangle += m->numtriangles;
+       currentvertex += m->numverts;
+
        mesh->blendfunc1 = m->blendfunc1;
        mesh->blendfunc2 = m->blendfunc2;
        mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite);
        mesh->depthtest = !m->depthdisable;
        mesh->triangles = m->numtriangles;
        mesh->verts = m->numverts;
+       mesh->matrix = m->matrix; // this copies the struct
 
        overbright = false;
        scaler = 1;
index 2efbd9a0ff90a38861a2a2d06d7c1ee8d45cbc9c..51c6a12f8a59a0d26ed77bcbe2e4feafe2a91c15 100644 (file)
@@ -6,28 +6,6 @@
 
 extern int c_meshtris, c_meshs, c_transtris, c_transmeshs;
 
-typedef struct
-{
-       int transparent;
-       int depthwrite; // force depth writing enabled even if polygon is not opaque
-       int depthdisable; // disable depth read/write entirely
-       int blendfunc1;
-       int blendfunc2;
-       int numtriangles;
-       int *index;
-       int numverts;
-       float *vertex;
-       int vertexstep;
-       float *color;
-       int colorstep;
-       float cr, cg, cb, ca; // if color is NULL, these are used for all vertices
-       int tex[MAX_TEXTUREUNITS];
-       float *texcoords[MAX_TEXTUREUNITS];
-       int texcoordstep[MAX_TEXTUREUNITS];
-       int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
-}
-rmeshinfo_t;
-
 typedef struct
 {
        //input to R_Mesh_Draw_GetBuffer
@@ -40,6 +18,8 @@ typedef struct
        int numverts;
        int tex[MAX_TEXTUREUNITS];
        int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
+       // model to world transform matrix
+       matrix4x4_t matrix;
 
        // output
        int *index;
index bf87df5a9993edeecc3c747ab7e020d32cdf407a..893d9a0b822f9406e6644bc99ced54cb999292b0 100644 (file)
@@ -50,6 +50,7 @@ void GL_Models_Init(void)
        R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap);
 }
 
+/*
 void R_AliasTransformVerts(int vertcount)
 {
        vec3_t point;
@@ -69,16 +70,17 @@ void R_AliasTransformVerts(int vertcount)
                vertcount--;
        }
 }
+*/
 
 void R_AliasLerpVerts(int vertcount,
-               float lerp1, trivertx_t *verts1, vec3_t fscale1, vec3_t translate1,
-               float lerp2, trivertx_t *verts2, vec3_t fscale2, vec3_t translate2,
-               float lerp3, trivertx_t *verts3, vec3_t fscale3, vec3_t translate3,
-               float lerp4, trivertx_t *verts4, vec3_t fscale4, vec3_t translate4)
+               float lerp1, const trivertx_t *verts1, const vec3_t fscale1, const vec3_t translate1,
+               float lerp2, const trivertx_t *verts2, const vec3_t fscale2, const vec3_t translate2,
+               float lerp3, const trivertx_t *verts3, const vec3_t fscale3, const vec3_t translate3,
+               float lerp4, const trivertx_t *verts4, const vec3_t fscale4, const vec3_t translate4)
 {
        int i;
        vec3_t scale1, scale2, scale3, scale4, translate;
-       float *n1, *n2, *n3, *n4;
+       const float *n1, *n2, *n3, *n4;
        float *av, *avn;
        av = aliasvert;
        avn = aliasvertnorm;
@@ -198,7 +200,7 @@ void R_AliasLerpVerts(int vertcount,
        }
 }
 
-skinframe_t *R_FetchSkinFrame(entity_render_t *ent)
+skinframe_t *R_FetchSkinFrame(const entity_render_t *ent)
 {
        model_t *model = ent->model;
        if (model->skinscenes[ent->skinnum].framecount > 1)
@@ -207,12 +209,11 @@ skinframe_t *R_FetchSkinFrame(entity_render_t *ent)
                return &model->skinframes[model->skinscenes[ent->skinnum].firstframe];
 }
 
-void R_SetupMDLMD2Frames(entity_render_t *ent, float colorr, float colorg, float colorb)
+void R_SetupMDLMD2Frames(const entity_render_t *ent, float colorr, float colorg, float colorb)
 {
-       md2frame_t *frame1, *frame2, *frame3, *frame4;
-       trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
-       model_t *model;
-       model = ent->model;
+       const md2frame_t *frame1, *frame2, *frame3, *frame4;
+       const trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
+       const model_t *model = ent->model;
 
        frame1 = &model->mdlmd2data_frames[ent->frameblend[0].frame];
        frame2 = &model->mdlmd2data_frames[ent->frameblend[1].frame];
@@ -230,10 +231,10 @@ void R_SetupMDLMD2Frames(entity_render_t *ent, float colorr, float colorg, float
 
        R_LightModel(ent, model->numverts, colorr, colorg, colorb, false);
 
-       R_AliasTransformVerts(model->numverts);
+       //R_AliasTransformVerts(model->numverts);
 }
 
-void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
+void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2)
 {
        int c, pantsfullbright, shirtfullbright, colormapped;
        float pantscolor[3], shirtcolor[3];
@@ -243,10 +244,9 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
        rmeshbufferinfo_t m;
        model_t *model;
        skinframe_t *skinframe;
-       entity_render_t *ent;
+       const entity_render_t *ent = calldata1;
 
-       ent = calldata1;
-       softwaretransformforentity(ent);
+//     softwaretransformforentity(ent);
 
        fog = 0;
        if (fogenabled)
@@ -292,6 +292,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
                m.numtriangles = model->numtris;
                m.numverts = model->numverts;
                m.tex[0] = R_GetTexture(skinframe->merged);
+               m.matrix = ent->matrix;
 
                c_alias_polys += m.numtriangles;
                if (R_Mesh_Draw_GetBuffer(&m, true))
@@ -349,6 +350,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
        m.numtriangles = model->numtris;
        m.numverts = model->numverts;
        m.tex[0] = colormapped ? R_GetTexture(skinframe->base) : R_GetTexture(skinframe->merged);
+       m.matrix = ent->matrix;
        if (R_Mesh_Draw_GetBuffer(&m, true))
        {
                c_alias_polys += m.numtriangles;
@@ -369,6 +371,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
                        m.numtriangles = model->numtris;
                        m.numverts = model->numverts;
                        m.tex[0] = R_GetTexture(skinframe->pants);
+                       m.matrix = ent->matrix;
                        if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
                                c_alias_polys += m.numtriangles;
@@ -390,6 +393,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
                        m.numtriangles = model->numtris;
                        m.numverts = model->numverts;
                        m.tex[0] = R_GetTexture(skinframe->shirt);
+                       m.matrix = ent->matrix;
                        if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
                                c_alias_polys += m.numtriangles;
@@ -412,6 +416,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
                m.numtriangles = model->numtris;
                m.numverts = model->numverts;
                m.tex[0] = R_GetTexture(skinframe->glow);
+               m.matrix = ent->matrix;
                if (R_Mesh_Draw_GetBuffer(&m, true))
                {
                        c_alias_polys += m.numtriangles;
@@ -430,6 +435,7 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
                m.numtriangles = model->numtris;
                m.numverts = model->numverts;
                m.tex[0] = R_GetTexture(skinframe->fog);
+               m.matrix = ent->matrix;
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                        c_alias_polys += m.numtriangles;
@@ -442,12 +448,14 @@ void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
        }
 }
 
-int ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone)
+int ZymoticLerpBones(int count, const zymbonematrix *bonebase, const frameblend_t *blend, const zymbone_t *bone)
 {
        int i;
        float lerp1, lerp2, lerp3, lerp4;
-       zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
+       zymbonematrix *out, rootmatrix, m;
+       const zymbonematrix *bone1, *bone2, *bone3, *bone4;
 
+       /*
        // LordHavoc: combine transform from zym coordinate space to quake coordinate space with model to world transform matrix
        rootmatrix.m[0][0] = softwaretransform_matrix[0][1];
        rootmatrix.m[0][1] = -softwaretransform_matrix[0][0];
@@ -461,6 +469,19 @@ int ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zy
        rootmatrix.m[2][1] = -softwaretransform_matrix[2][0];
        rootmatrix.m[2][2] = softwaretransform_matrix[2][2];
        rootmatrix.m[2][3] = softwaretransform_matrix[2][3];
+       */
+       rootmatrix.m[0][0] = 1;
+       rootmatrix.m[0][1] = 0;
+       rootmatrix.m[0][2] = 0;
+       rootmatrix.m[0][3] = 0;
+       rootmatrix.m[1][0] = 0;
+       rootmatrix.m[1][1] = 1;
+       rootmatrix.m[1][2] = 0;
+       rootmatrix.m[1][3] = 0;
+       rootmatrix.m[2][0] = 0;
+       rootmatrix.m[2][1] = 0;
+       rootmatrix.m[2][2] = 1;
+       rootmatrix.m[2][3] = 0;
 
        bone1 = bonebase + blend[0].frame * count;
        lerp1 = blend[0].lerp;
@@ -702,7 +723,7 @@ void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
        }
 }
 
-void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2)
+void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2)
 {
        float fog;
        vec3_t diff;
@@ -710,11 +731,8 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2)
        zymtype1header_t *m;
        rtexture_t *texture;
        rmeshbufferinfo_t mbuf;
-       entity_render_t *ent;
-       int shadernum;
-
-       ent = calldata1;
-       shadernum = calldata2;
+       const entity_render_t *ent = calldata1;
+       int shadernum = calldata2;
 
        // find the vertex index list and texture
        m = ent->model->zymdata_header;
@@ -740,12 +758,11 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2)
                // 2. render fog as additive
        }
 
-       softwaretransformforentity(ent);
        ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), ent->frameblend, (zymbone_t *)(m->lump_bones.start + (int) m));
        ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
        ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
 
-       R_LightModel(ent, m->numverts, 1 - fog, 1 - fog, 1 - fog, true);
+       R_LightModel(ent, m->numverts, 1 - fog, 1 - fog, 1 - fog, false);
 
        memset(&mbuf, 0, sizeof(mbuf));
        mbuf.numverts = m->numverts;
@@ -766,6 +783,7 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2)
                mbuf.blendfunc2 = GL_ZERO;
        }
        mbuf.tex[0] = R_GetTexture(texture);
+       mbuf.matrix = ent->matrix;
        if (R_Mesh_Draw_GetBuffer(&mbuf, true))
        {
                c_alias_polys += mbuf.numtriangles;
@@ -786,6 +804,7 @@ void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2)
                mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
                // FIXME: need alpha mask for fogging...
                //mbuf.tex[0] = R_GetTexture(texture);
+               mbuf.matrix = ent->matrix;
                if (R_Mesh_Draw_GetBuffer(&mbuf, false))
                {
                        c_alias_polys += mbuf.numtriangles;
index fbb0c1dc4c0f15518ee9e3596f1c3ecdc981afbd..09c48a7c9fedb09662ed814ccf3c136895713456 100644 (file)
@@ -389,6 +389,10 @@ static void R_MarkEntities (void)
        vec3_t v;
        entity_render_t *ent;
 
+       ent = &cl_entities[0].render;
+       Matrix4x4_CreateIdentity(&ent->matrix);
+       Matrix4x4_CreateIdentity(&ent->inversematrix);
+
        R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
 
        if (!r_drawentities.integer)
@@ -431,10 +435,17 @@ static void R_MarkEntities (void)
                if (R_VisibleCullBox(ent->mins, ent->maxs))
                        continue;
 
+               VectorCopy(ent->angles, v);
+               if (ent->model->type != mod_brush)
+                       v[0] = -v[0];
+               Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], v[0], v[1], v[2], ent->scale);
+               Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
                R_LerpAnimation(ent);
                ent->visframe = r_framecount;
 
                R_FarClip_Box(ent->mins, ent->maxs);
+
+               R_UpdateEntLights(ent);
        }
 }
 
@@ -566,6 +577,7 @@ static void R_BlendView(void)
        m.depthdisable = true; // magic
        m.numtriangles = 1;
        m.numverts = 3;
+       Matrix4x4_CreateIdentity(&m.matrix);
        if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                m.index[0] = 0;
@@ -678,8 +690,6 @@ void R_RenderView (void)
        R_TimeReport("explosions");
 
        R_MeshQueue_RenderTransparent();
-
-       R_Mesh_AddTransparent();
        R_TimeReport("addtrans");
 
        R_DrawCoronas();
index 3ce3800e44c4fbfa294c74f039fade6893e04aaf..aa83cc9ef53b8d2fb7ae9394c4138c772195f6c8 100644 (file)
@@ -236,7 +236,7 @@ R_BuildLightMap
 Combine and scale multiple lightmaps into the 8.8 format in blocklights
 ===============
 */
-static void R_BuildLightMap (entity_render_t *ent, msurface_t *surf, int dlightchanged)
+static void R_BuildLightMap (const entity_render_t *ent, msurface_t *surf, int dlightchanged)
 {
        if (!r_floatbuildlightmap.integer)
        {
@@ -587,7 +587,6 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i
        icolor[7] = ca2;
 
        model = cl.worldmodel;
-       softwaretransformidentity();
        R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, origin, radius, icolor);
 
        // look for embedded bmodels
@@ -600,8 +599,7 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i
                        Mod_CheckLoaded(model);
                        if (model->type == mod_brush)
                        {
-                               softwaretransformforentity(ent);
-                               softwareuntransform(origin, org);
+                               Matrix4x4_Transform(&ent->inversematrix, origin, org);
                                R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, org, radius, icolor);
                        }
                }
@@ -617,72 +615,160 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i
 =============================================================
 */
 
-static void RSurfShader_Sky(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurf_CopyXYZ(const surfvertex_t *in, float *out, int numverts)
 {
-       msurface_t *surf;
        int i;
-       surfvertex_t *v;
-       surfmesh_t *mesh;
-       rmeshbufferinfo_t m;
-       float cr, cg, cb, ca;
-       float *outv, *outc;
+       for (i = 0;i < numverts;i++, in++, out += 4)
+       {
+               VectorCopy(in->v, out);
+               out[3] = 1;
+       }
+}
 
-       // LordHavoc: HalfLife maps have freaky skypolys...
-       if (ent->model->ishlbsp)
-               return;
+static void RSurf_CopyST(const surfvertex_t *in, float *out, int numverts)
+{
+       int i;
+       for (i = 0;i < numverts;i++, in++, out += 2)
+       {
+               out[0] = in->st[0];
+               out[1] = in->st[1];
+       }
+}
 
-       if (skyrendernow)
+static void RSurf_CopyUV(const surfvertex_t *in, float *out, int numverts)
+{
+       int i;
+       for (i = 0;i < numverts;i++, in++, out += 2)
        {
-               skyrendernow = false;
-               if (skyrendermasked)
-                       R_Sky();
+               out[0] = in->uv[0];
+               out[1] = in->uv[1];
        }
-       for (surf = firstsurf;surf;surf = surf->chain)
+}
+
+static void RSurf_CopyAB(const surfvertex_t *in, float *out, int numverts)
+{
+       int i;
+       for (i = 0;i < numverts;i++, in++, out += 2)
        {
-               // draw depth-only polys
-               memset(&m, 0, sizeof(m));
-               if (skyrendermasked)
-               {
-                       m.blendfunc1 = GL_ZERO;
-                       m.blendfunc2 = GL_ONE;
-                       m.depthwrite = true;
-               }
-               else
-               {
-                       m.blendfunc1 = GL_ONE;
-                       m.blendfunc2 = GL_ZERO;
-               }
-               for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+               out[0] = in->ab[0];
+               out[1] = in->ab[1];
+       }
+}
+
+static void RSurf_AddLightmapToVertexColors(const surfvertex_t *in, float *c, int numverts, const qbyte *samples, int size3, const qbyte *styles)
+{
+       int i;
+       float scale;
+       const qbyte *lm;
+       if (styles[0] != 255)
+       {
+               for (i = 0;i < numverts;i++, in++, c += 4)
                {
-                       m.numtriangles = mesh->numtriangles;
-                       m.numverts = mesh->numverts;
-                       if (R_Mesh_Draw_GetBuffer(&m, false))
+                       lm = samples + in->lightmapoffset;
+                       scale = d_lightstylevalue[styles[0]] * (1.0f / 32768.0f);
+                       VectorMA(c, scale, lm, c);
+                       if (styles[1] != 255)
                        {
-                               cr = fogcolor[0] * m.colorscale;
-                               cg = fogcolor[1] * m.colorscale;
-                               cb = fogcolor[2] * m.colorscale;
-                               ca = 1;
-                               memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                               for (i = 0, v = mesh->vertex, outv = m.vertex;i < m.numverts;i++, v++, outv += 4, outc += 4)
+                               lm += size3;
+                               scale = d_lightstylevalue[styles[1]] * (1.0f / 32768.0f);
+                               VectorMA(c, scale, lm, c);
+                               if (styles[2] != 255)
                                {
-                                       softwaretransform(v->v, outv);
-                               }
-                               for (i = 0, outc = m.color;i < m.numverts;i++, outc += 4)
-                               {
-                                       outc[0] = cr;
-                                       outc[1] = cg;
-                                       outc[2] = cb;
-                                       outc[3] = ca;
+                                       lm += size3;
+                                       scale = d_lightstylevalue[styles[2]] * (1.0f / 32768.0f);
+                                       VectorMA(c, scale, lm, c);
+                                       if (styles[3] != 255)
+                                       {
+                                               lm += size3;
+                                               scale = d_lightstylevalue[styles[3]] * (1.0f / 32768.0f);
+                                               VectorMA(c, scale, lm, c);
+                                       }
                                }
-                               R_Mesh_Render();
                        }
                }
        }
 }
 
-static int RSurf_LightSeparate(int *dlightbits, int numverts, float *vert, float *color)
+static void RSurf_FogColors(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)
+               {
+                       VectorSubtract(v, modelorg, diff);
+                       f = colorscale * (1 - exp(fogdensity/DotProduct(diff, diff)));
+                       VectorScale(c, f, c);
+               }
+       }
+       else if (colorscale != 1)
+               for (i = 0;i < numverts;i++, c += 4)
+                       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)
+{
+       int i;
+       float diff[3], f;
+       r *= colorscale;
+       g *= colorscale;
+       b *= colorscale;
+       if (fogenabled)
+       {
+               for (i = 0;i < numverts;i++, v += 4, c += 4)
+               {
+                       VectorSubtract(v, modelorg, diff);
+                       f = 1 - exp(fogdensity/DotProduct(diff, diff));
+                       c[0] = r * f;
+                       c[1] = g * f;
+                       c[2] = b * f;
+                       c[3] = a;
+               }
+       }
+       else
+       {
+               for (i = 0;i < numverts;i++, c += 4)
+               {
+                       c[0] = r;
+                       c[1] = g;
+                       c[2] = b;
+                       c[3] = a;
+               }
+       }
+}
+
+static void RSurf_FogPassColors(const float *v, float *c, float r, float g, float b, float a, float colorscale, int numverts, const float *modelorg)
 {
-       float f, *v, *c;
+       int i;
+       float diff[3], f;
+       r *= colorscale;
+       g *= colorscale;
+       b *= colorscale;
+       for (i = 0;i < numverts;i++, v += 4, c += 4)
+       {
+               VectorSubtract(v, modelorg, diff);
+               f = exp(fogdensity/DotProduct(diff, diff));
+               c[0] = r * f;
+               c[1] = g * f;
+               c[2] = b * f;
+               c[3] = a;
+       }
+}
+
+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)
+{
+       float f;
+       const float *v;
+       float *c;
        int i, l, lit = false;
        rdlight_t *rd;
        vec3_t lightorigin;
@@ -691,8 +777,7 @@ static int RSurf_LightSeparate(int *dlightbits, int numverts, float *vert, float
                if (dlightbits[l >> 5] & (1 << (l & 31)))
                {
                        rd = &r_dlight[l];
-                       // FIXME: support softwareuntransform here and make bmodels use hardware transform?
-                       VectorCopy(rd->origin, lightorigin);
+                       Matrix4x4_Transform(matrix, rd->origin, lightorigin);
                        for (i = 0, v = vert, c = color;i < numverts;i++, v += 4, c += 4)
                        {
                                f = VectorDistance2(v, lightorigin) + LIGHTOFFSET;
@@ -710,7 +795,7 @@ static int RSurf_LightSeparate(int *dlightbits, int numverts, float *vert, float
 
 // note: this untransforms lights to do the checking,
 // and takes surf->mesh->vertex data
-static int RSurf_LightCheck(int *dlightbits, surfmesh_t *mesh)
+static int RSurf_LightCheck(const int *dlightbits, surfmesh_t *mesh)
 {
        int i, l;
        rdlight_t *rd;
@@ -730,20 +815,56 @@ static int RSurf_LightCheck(int *dlightbits, surfmesh_t *mesh)
        return false;
 }
 
-static void RSurfShader_Water_Callback(void *calldata1, int calldata2)
+static void RSurfShader_Sky(const entity_render_t *ent, const msurface_t *firstsurf)
+{
+       const msurface_t *surf;
+       surfmesh_t *mesh;
+       rmeshbufferinfo_t m;
+
+       // LordHavoc: HalfLife maps have freaky skypolys...
+       if (ent->model->ishlbsp)
+               return;
+
+       if (skyrendernow)
+       {
+               skyrendernow = false;
+               R_Sky();
+       }
+
+       // draw depth-only polys
+       memset(&m, 0, sizeof(m));
+       m.blendfunc1 = GL_ZERO;
+       m.blendfunc2 = GL_ONE;
+       m.depthwrite = true;
+       m.matrix = ent->matrix;
+       for (surf = firstsurf;surf;surf = surf->chain)
+       {
+               for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+               {
+                       m.numtriangles = mesh->numtriangles;
+                       m.numverts = mesh->numverts;
+                       if (R_Mesh_Draw_GetBuffer(&m, false))
+                       {
+                               memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
+                               RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                               memset(m.color, 0, m.numverts * sizeof(float[4]));
+                               R_Mesh_Render();
+                       }
+               }
+       }
+}
+
+static void RSurfShader_Water_Callback(const void *calldata1, int calldata2)
 {
-       entity_render_t *ent = calldata1;
+       const entity_render_t *ent = calldata1;
        msurface_t *surf = ent->model->surfaces + calldata2;
-       int i, size3;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl, diff[3];
-       float base[3], scale, f;
-       qbyte *lm;
+       float f;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        float alpha = ent->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
+       float modelorg[3];
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
 
-       softwaretransformforentity(ent);
        memset(&m, 0, sizeof(m));
        if (ent->effects & EF_ADDITIVE)
        {
@@ -761,75 +882,26 @@ static void RSurfShader_Water_Callback(void *calldata1, int calldata2)
                m.blendfunc2 = GL_ZERO;
        }
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3;
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
                if (R_Mesh_Draw_GetBuffer(&m, true))
                {
-                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outst += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                       }
-                       base[0] = base[1] = base[2] = surf->flags & SURF_DRAWFULLBRIGHT ? 1.0f : ((surf->flags & SURF_LIGHTMAP) ? 0 : 0.5f);
-                       for (i = 0, outc = m.color;i < m.numverts;i++, outc += 4)
-                       {
-                               VectorCopy(base, outc);
-                               outc[3] = alpha;
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       f = surf->flags & SURF_DRAWFULLBRIGHT ? 1.0f : ((surf->flags & SURF_LIGHTMAP) ? 0 : 0.5f);
+                       R_FillColors(m.color, m.numverts, f, f, f, alpha);
                        if (!(surf->flags & SURF_DRAWFULLBRIGHT || ent->effects & EF_FULLBRIGHT))
                        {
                                if (surf->dlightframe == r_framecount)
-                                       RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
-                               {
-                                       if (surf->flags & SURF_LIGHTMAP)
-                                       if (surf->styles[0] != 255)
-                                       {
-                                               lm = surf->samples + v->lightmapoffset;
-                                               scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
-                                               VectorMA(outc, scale, lm, outc);
-                                               if (surf->styles[1] != 255)
-                                               {
-                                                       lm += size3;
-                                                       scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
-                                                       VectorMA(outc, scale, lm, outc);
-                                                       if (surf->styles[2] != 255)
-                                                       {
-                                                               lm += size3;
-                                                               scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
-                                                               VectorMA(outc, scale, lm, outc);
-                                                               if (surf->styles[3] != 255)
-                                                               {
-                                                                       lm += size3;
-                                                                       scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
-                                                                       VectorMA(outc, scale, lm, outc);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if (fogenabled)
-                       {
-                               for (i = 0, outv = m.vertex, outc = m.color;i < m.numverts;i++, outv += 4, outc += 4)
-                               {
-                                       VectorSubtract(outv, r_origin, diff);
-                                       f = m.colorscale * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                       VectorScale(outc, f, outc);
-                               }
-                       }
-                       else if (m.colorscale != 1)
-                       {
-                               for (i = 0, outv = m.vertex, outc = m.color;i < m.numverts;i++, outv += 4, outc += 4)
-                                       VectorScale(outc, m.colorscale, outc);
+                                       RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, m.numverts, m.vertex, m.color);
+                               if (surf->flags & SURF_LIGHTMAP)
+                                       RSurf_AddLightmapToVertexColors(mesh->vertex, m.color, m.numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
                        }
+                       RSurf_FogColors(m.vertex, m.color, m.colorscale, m.numverts, modelorg);
                        R_Mesh_Render();
                }
        }
@@ -840,40 +912,27 @@ static void RSurfShader_Water_Callback(void *calldata1, int calldata2)
                m.blendfunc1 = GL_SRC_ALPHA;
                m.blendfunc2 = GL_ONE;
                m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
+               m.matrix = ent->matrix;
                for (mesh = surf->mesh;mesh;mesh = mesh->chain)
                {
                        m.numtriangles = mesh->numtriangles;
                        m.numverts = mesh->numverts;
                        if (R_Mesh_Draw_GetBuffer(&m, false))
                        {
-                               VectorScale(fogcolor, m.colorscale, base);
                                memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
-                               {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       VectorSubtract(outv, r_origin, diff);
-                                       f = exp(fogdensity/DotProduct(diff, diff));
-                                       VectorScale(base, f, outc);
-                                       outc[3] = alpha;
-                               }
+                               RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
                                if (m.tex[0])
-                               {
-                                       for (i = 0, v = mesh->vertex, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outst += 2)
-                                       {
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
+                                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                               RSurf_FogPassColors(m.vertex, m.color, fogcolor[0], fogcolor[1], fogcolor[2], alpha, m.colorscale, m.numverts, modelorg);
                                R_Mesh_Render();
                        }
                }
        }
 }
 
-static void RSurfShader_Water(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Water(const entity_render_t *ent, const msurface_t *firstsurf)
 {
-       msurface_t *surf;
+       const msurface_t *surf;
        for (surf = firstsurf;surf;surf = surf->chain)
        {
                if ((r_wateralpha.value < 1 && !(surf->flags & SURF_DRAWNOALPHA)) || ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture)
@@ -883,15 +942,13 @@ static void RSurfShader_Water(entity_render_t *ent, msurface_t *firstsurf)
        }
 }
 
-static void RSurfShader_Wall_Pass_BaseVertex(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseVertex(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i, size3;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3];
-       float base[3], scale, f;
-       qbyte *lm;
+       float base;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float modelorg[3];
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        memset(&m, 0, sizeof(m));
        if (ent->effects & EF_ADDITIVE)
        {
@@ -911,98 +968,37 @@ static void RSurfShader_Wall_Pass_BaseVertex(entity_render_t *ent, msurface_t *s
                m.blendfunc2 = GL_ZERO;
        }
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-
-       size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3;
-
-       base[0] = base[1] = base[2] = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
-
-       ca = ent->alpha;
+       base = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, true))
                {
-                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-
-                       if (ent->effects & EF_FULLBRIGHT)
-                       {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       VectorSubtract(outv, r_origin, diff);
-                                       outc[0] = outc[1] = outc[2] = 2.0f * cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
-                       }
-                       else
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       R_FillColors(m.color, m.numverts, base, base, base, ent->alpha);
+                       if (!(ent->effects & EF_FULLBRIGHT))
                        {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       VectorCopy(base, outc);
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
-
                                if (surf->dlightframe == r_framecount)
-                                       RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
-
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
-                               {
-                                       if (surf->styles[0] != 255)
-                                       {
-                                               lm = surf->samples + v->lightmapoffset;
-                                               scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
-                                               VectorMA(outc, scale, lm, outc);
-                                               if (surf->styles[1] != 255)
-                                               {
-                                                       lm += size3;
-                                                       scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
-                                                       VectorMA(outc, scale, lm, outc);
-                                                       if (surf->styles[2] != 255)
-                                                       {
-                                                               lm += size3;
-                                                               scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
-                                                               VectorMA(outc, scale, lm, outc);
-                                                               if (surf->styles[3] != 255)
-                                                               {
-                                                                       lm += size3;
-                                                                       scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
-                                                                       VectorMA(outc, scale, lm, outc);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                                       if (fogenabled)
-                                       {
-                                               VectorSubtract(outv, r_origin, diff);
-                                               f = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               VectorScale(outc, f, outc);
-                                       }
-                                       else
-                                               VectorScale(outc, cl, outc);
-                               }
+                                       RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, m.numverts, m.vertex, m.color);
+                               if (surf->flags & SURF_LIGHTMAP)
+                                       RSurf_AddLightmapToVertexColors(mesh->vertex, m.color, m.numverts, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
                        }
+                       RSurf_FogColors(m.vertex, m.color, m.colorscale, m.numverts, modelorg);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_BaseFullbright(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseFullbright(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3];
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float modelorg[3];
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        memset(&m, 0, sizeof(m));
        if (ent->effects & EF_ADDITIVE)
        {
@@ -1022,122 +1018,82 @@ static void RSurfShader_Wall_Pass_BaseFullbright(entity_render_t *ent, msurface_
                m.blendfunc2 = GL_ZERO;
        }
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       ca = ent->alpha;
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               if (fogenabled)
-                               {
-                                       VectorSubtract(outv, r_origin, diff);
-                                       outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                               }
-                               else
-                                       outc[0] = outc[1] = outc[2] = cl;
-                               outc[3] = ca;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       RSurf_FoggedColors(m.vertex, m.color, 1, 1, 1, ent->alpha, m.colorscale, m.numverts, modelorg);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_Glow(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3];
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float modelorg[3];
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        memset(&m, 0, sizeof(m));
        m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || ent->alpha != 1;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
        m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
-       ca = ent->alpha;
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               if (fogenabled)
-                               {
-                                       VectorSubtract(outv, r_origin, diff);
-                                       outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                               }
-                               else
-                                       outc[0] = outc[1] = outc[2] = cl;
-                               outc[3] = ca;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       RSurf_FoggedColors(m.vertex, m.color, 1, 1, 1, ent->alpha, m.colorscale, m.numverts, modelorg);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_Fog(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3], f;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float modelorg[3];
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        memset(&m, 0, sizeof(m));
        m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || ent->alpha != 1;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       ca = ent->alpha;
+       m.matrix = ent->matrix;
+       m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               VectorSubtract(outv, r_origin, diff);
-                               f = cl * exp(fogdensity/DotProduct(diff, diff));
-                               VectorScale(fogcolor, f, outc);
-                               outc[3] = ca;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       if (m.tex[0])
+                               RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       RSurf_FogPassColors(m.vertex, m.color, fogcolor[0], fogcolor[1], fogcolor[2], ent->alpha, m.colorscale, m.numverts, modelorg);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, *outuv, *outab, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float cl;
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_ONE;
        m.blendfunc2 = GL_ZERO;
@@ -1147,143 +1103,107 @@ static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(entity_render_t *ent, m
        m.texrgbscale[1] = 4.0f;
        m.tex[2] = R_GetTexture(surf->currenttexture->detailtexture);
        m.texrgbscale[2] = 2.0f;
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = (float) (1 << lightscalebit) * m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1], outab = m.texcoords[2];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2, outab += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               outc[0] = outc[1] = outc[2] = cl;
-                               outc[3] = 1;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                               outuv[0] = v->uv[0];
-                               outuv[1] = v->uv[1];
-                               outab[0] = v->ab[0];
-                               outab[1] = v->ab[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       RSurf_CopyUV(mesh->vertex, m.texcoords[1], m.numverts);
+                       RSurf_CopyAB(mesh->vertex, m.texcoords[2], m.numverts);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseMTex(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseMTex(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, *outuv, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float cl;
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_ONE;
        m.blendfunc2 = GL_ZERO;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
        m.tex[1] = R_GetTexture(surf->lightmaptexture);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, true))
                {
-                       cl = (float) (1 << lightscalebit) * m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               outc[0] = outc[1] = outc[2] = cl;
-                               outc[3] = 1;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                               outuv[0] = v->uv[0];
-                               outuv[1] = v->uv[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       RSurf_CopyUV(mesh->vertex, m.texcoords[1], m.numverts);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseTexture(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float cl;
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_ONE;
        m.blendfunc2 = GL_ZERO;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = (float) (1 << lightscalebit) * m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               outc[0] = outc[1] = outc[2] = cl;
-                               outc[3] = 1;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       cl = m.colorscale;
+                       R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+                       RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseLightmap(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outuv, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float cl;
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_ZERO;
        m.blendfunc2 = GL_SRC_COLOR;
        m.tex[0] = R_GetTexture(surf->lightmaptexture);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, true))
                {
-                       cl = (float) (1 << lightscalebit) * m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outuv = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outuv += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               outc[0] = outc[1] = outc[2] = cl;
-                               outc[3] = 1;
-                               outuv[0] = v->uv[0];
-                               outuv[1] = v->uv[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       R_FillColors(m.color, m.numverts, cl, cl, cl, 1);
+                       RSurf_CopyUV(mesh->vertex, m.texcoords[0], m.numverts);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_Light(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
 
@@ -1296,138 +1216,105 @@ static void RSurfShader_OpaqueWall_Pass_Light(entity_render_t *ent, msurface_t *
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                if (RSurf_LightCheck(surf->dlightbits, mesh))
                {
                        m.numtriangles = mesh->numtriangles;
                        m.numverts = mesh->numverts;
-
                        if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
-                               cl = m.colorscale;
                                memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       VectorClear(outc);
-                                       outc[3] = 1;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
-                               RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
-                               if (cl != 1)
-                                       for (i = 0, outc = m.color;i < m.numverts;i++, outc += 4)
-                                               VectorScale(outc, cl, outc);
+                               RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                               RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                               R_FillColors(m.color, m.numverts, 0, 0, 0, 1);
+                               RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, m.numverts, m.vertex, m.color);
+                               RSurf_ScaleColors(m.color, m.colorscale, m.numverts);
                                R_Mesh_Render();
                        }
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_Fog(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, cl, diff[3], fcolor[3];
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
+       float modelorg[3];
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = m.colorscale;
-                       VectorScale(fogcolor, cl, fcolor);
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               VectorCopy(fcolor, outc);
-                               VectorSubtract(outv, r_origin, diff);
-                               outc[3] = exp(fogdensity/DotProduct(diff, diff));
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       if (m.tex[0])
+                               RSurf_CopyST(mesh->vertex, m.texcoords[0], m.numverts);
+                       RSurf_FogPassColors(m.vertex, m.color, fogcolor[0], fogcolor[1], fogcolor[2], 1, m.colorscale, m.numverts, modelorg);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseDetail(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_DST_COLOR;
        m.blendfunc2 = GL_SRC_COLOR;
        m.tex[0] = R_GetTexture(surf->currenttexture->detailtexture);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               outc[0] = outc[1] = outc[2] = outc[3] = 1;
-                               outst[0] = v->ab[0];
-                               outst[1] = v->ab[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       R_FillColors(m.color, m.numverts, 1, 1, 1, 1);
+                       RSurf_CopyAB(mesh->vertex, m.texcoords[0], m.numverts);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_Glow(entity_render_t *ent, msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf)
 {
-       int i;
-       surfvertex_t *v;
-       float *outv, *outc, *outst, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
        m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
+       m.matrix = ent->matrix;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                       {
-                               softwaretransform(v->v, outv);
-                               outv[3] = 1;
-                               outc[0] = outc[1] = outc[2] = cl;
-                               outc[3] = 1;
-                               outst[0] = v->st[0];
-                               outst[1] = v->st[1];
-                       }
+                       RSurf_CopyXYZ(mesh->vertex, m.vertex, m.numverts);
+                       R_FillColors(m.color, m.numverts, m.colorscale, m.colorscale, m.colorscale, 1);
+                       RSurf_CopyAB(mesh->vertex, m.texcoords[0], m.numverts);
                        R_Mesh_Render();
                }
        }
 }
 
-static void RSurfShader_Wall_Fullbright(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Wall_Fullbright(const entity_render_t *ent, const msurface_t *firstsurf)
 {
-       msurface_t *surf;
+       const msurface_t *surf;
        for (surf = firstsurf;surf;surf = surf->chain)
        {
                c_brush_polys++;
@@ -1441,9 +1328,9 @@ static void RSurfShader_Wall_Fullbright(entity_render_t *ent, msurface_t *firsts
                        RSurfShader_Wall_Pass_Fog(ent, surf);
 }
 
-static void RSurfShader_Wall_Vertex(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Wall_Vertex(const entity_render_t *ent, const msurface_t *firstsurf)
 {
-       msurface_t *surf;
+       const msurface_t *surf;
        for (surf = firstsurf;surf;surf = surf->chain)
        {
                c_brush_polys++;
@@ -1457,9 +1344,9 @@ static void RSurfShader_Wall_Vertex(entity_render_t *ent, msurface_t *firstsurf)
                        RSurfShader_Wall_Pass_Fog(ent, surf);
 }
 
-static void RSurfShader_Wall_Lightmap(entity_render_t *ent, msurface_t *firstsurf)
+static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface_t *firstsurf)
 {
-       msurface_t *surf;
+       const msurface_t *surf;
        if (r_vertexsurfaces.integer || firstsurf->currenttexture->fogtexture != NULL || ent->alpha != 1 || ent->effects & EF_ADDITIVE)
        {
                for (surf = firstsurf;surf;surf = surf->chain)
@@ -1848,6 +1735,7 @@ void R_DrawPortals(entity_render_t *ent)
                        m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
                        m.numverts = portal->numpoints;
                        m.numtriangles = portal->numpoints - 2;
+                       Matrix4x4_CreateIdentity(&m.matrix);
                        if (R_Mesh_Draw_GetBuffer(&m, false))
                        {
                                for (i = 0;i < m.numtriangles;i++)
@@ -1888,9 +1776,7 @@ void R_SetupForBModelRendering(entity_render_t *ent)
 
        model = ent->model;
 
-       softwaretransformforentity (ent);
-       softwareuntransform(r_origin, modelorg);
-
+       Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
        for (i = 0;i < model->nummodelsurfaces;i++)
        {
                surf = model->modelsortedsurfaces[i];
@@ -1909,7 +1795,6 @@ void R_SetupForWorldRendering(entity_render_t *ent)
 {
        // there is only one instance of the world, but it can be rendered in
        // multiple stages
-       softwaretransformidentity();
 }
 
 static void R_SurfMarkLights (entity_render_t *ent)
index c6c4161afc796318d30155fcb6f7f93d66855a7c..ff447d7ab5f3a7a5dc17d81a5048c663b851391e 100644 (file)
@@ -3,12 +3,12 @@
 #include "matrixlib.h"
 #include <math.h>
 
-void Matrix4x4_Copy (matrix4x4_t *out, matrix4x4_t *in)
+void Matrix4x4_Copy (matrix4x4_t *out, const matrix4x4_t *in)
 {
        *out = *in;
 }
 
-void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, matrix4x4_t *in)
+void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, const matrix4x4_t *in)
 {
        out->m[0][0] = in->m[0][0];
        out->m[0][1] = in->m[0][1];
@@ -28,7 +28,7 @@ void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, matrix4x4_t *in)
        out->m[3][3] = 1.0f;
 }
 
-void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, matrix4x4_t *in)
+void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, const matrix4x4_t *in)
 {
        out->m[0][0] = 0.0f;
        out->m[0][1] = 0.0f;
@@ -48,7 +48,7 @@ void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, matrix4x4_t *in)
        out->m[3][3] = 1.0f;
 }
 
-void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, matrix3x4_t *in)
+void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, const matrix3x4_t *in)
 {
        out->m[0][0] = in->m[0][0];
        out->m[0][1] = in->m[0][1];
@@ -90,32 +90,75 @@ void Matrix4x4_Concat (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4
 
 void Matrix4x4_Transpose (matrix4x4_t *out, const matrix4x4_t *in1)
 {
-       float scale;
-       scale = 3.0 / (in1->m[0][0] * in1->m[0][0]
-                    + in1->m[0][1] * in1->m[0][1]
-                    + in1->m[0][2] * in1->m[0][2]
-                    + in1->m[1][0] * in1->m[1][0]
-                    + in1->m[1][1] * in1->m[1][1]
-                    + in1->m[1][2] * in1->m[1][2]
-                    + in1->m[2][0] * in1->m[2][0]
-                    + in1->m[2][1] * in1->m[2][1]
-                    + in1->m[2][2] * in1->m[2][2]);
+       out->m[0][0] = in1->m[0][0];
+       out->m[0][1] = in1->m[1][0];
+       out->m[0][2] = in1->m[2][0];
+       out->m[0][3] = in1->m[3][0];
+       out->m[1][0] = in1->m[0][1];
+       out->m[1][1] = in1->m[1][1];
+       out->m[1][2] = in1->m[2][1];
+       out->m[1][3] = in1->m[3][1];
+       out->m[2][0] = in1->m[0][2];
+       out->m[2][1] = in1->m[1][2];
+       out->m[2][2] = in1->m[2][2];
+       out->m[2][3] = in1->m[3][2];
+       out->m[3][0] = in1->m[0][3];
+       out->m[3][1] = in1->m[1][3];
+       out->m[3][2] = in1->m[2][3];
+       out->m[3][3] = in1->m[3][3];
+}
+
+void Matrix4x4_Transpose3x3 (matrix4x4_t *out, const matrix4x4_t *in1)
+{
+       out->m[0][0] = in1->m[0][0];
+       out->m[0][1] = in1->m[1][0];
+       out->m[0][2] = in1->m[2][0];
+       out->m[1][0] = in1->m[0][1];
+       out->m[1][1] = in1->m[1][1];
+       out->m[1][2] = in1->m[2][1];
+       out->m[2][0] = in1->m[0][2];
+       out->m[2][1] = in1->m[1][2];
+       out->m[2][2] = in1->m[2][2];
+
+       out->m[0][3] = in1->m[0][3];
+       out->m[1][3] = in1->m[1][3];
+       out->m[2][3] = in1->m[2][3];
+       out->m[3][0] = in1->m[0][3];
+       out->m[3][1] = in1->m[1][3];
+       out->m[3][2] = in1->m[2][3];
+       out->m[3][3] = in1->m[3][3];
+}
+
+void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1)
+{
+       // we only support uniform scaling, so assume the first row is enough
+       // (note the lack of sqrt here, because we're trying to undo the scaling,
+       // this means multiplying by the inverse scale twice - squaring it, which
+       // makes the sqrt a waste of time)
+       double scale = 1.0 / (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
+
+       // invert the rotation by transposing and multiplying by the squared
+       // recipricol of the input matrix scale as described above
        out->m[0][0] = in1->m[0][0] * scale;
        out->m[0][1] = in1->m[1][0] * scale;
        out->m[0][2] = in1->m[2][0] * scale;
-       out->m[0][3] = in1->m[3][0];
        out->m[1][0] = in1->m[0][1] * scale;
        out->m[1][1] = in1->m[1][1] * scale;
        out->m[1][2] = in1->m[2][1] * scale;
-       out->m[1][3] = in1->m[3][1];
        out->m[2][0] = in1->m[0][2] * scale;
        out->m[2][1] = in1->m[1][2] * scale;
        out->m[2][2] = in1->m[2][2] * scale;
-       out->m[2][3] = in1->m[3][2];
-       out->m[3][0] = in1->m[0][3];
-       out->m[3][1] = in1->m[1][3];
-       out->m[3][2] = in1->m[2][3];
-       out->m[3][3] = in1->m[3][3];
+
+       // invert the translate
+       out->m[0][3] = -(in1->m[0][3] * out->m[0][0] + in1->m[1][3] * out->m[0][1] + in1->m[2][3] * out->m[0][2]);
+       out->m[1][3] = -(in1->m[0][3] * out->m[1][0] + in1->m[1][3] * out->m[1][1] + in1->m[2][3] * out->m[1][2]);
+       out->m[2][3] = -(in1->m[0][3] * out->m[2][0] + in1->m[1][3] * out->m[2][1] + in1->m[2][3] * out->m[2][2]);
+
+       // don't know if there's anything worth doing here
+       out->m[3][0] = 0;
+       out->m[3][1] = 0;
+       out->m[3][2] = 0;
+       out->m[3][3] = 1;
 }
 
 void Matrix4x4_CreateIdentity (matrix4x4_t *out)
@@ -231,6 +274,37 @@ void Matrix4x4_CreateScale3 (matrix4x4_t *out, float x, float y, float z)
        out->m[3][3]=1.0f;
 }
 
+void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale)
+{
+       double angle, sr, sp, sy, cr, cp, cy;
+
+       angle = yaw * (M_PI*2 / 360);
+       sy = sin(angle);
+       cy = cos(angle);
+       angle = pitch * (M_PI*2 / 360);
+       sp = sin(angle);
+       cp = cos(angle);
+       angle = roll * (M_PI*2 / 360);
+       sr = sin(angle);
+       cr = cos(angle);
+       out->m[0][0] = cp*cy * scale;
+       out->m[0][1] = sr*sp*cy+cr*-sy * scale;
+       out->m[0][2] = cr*sp*cy+-sr*-sy * scale;
+       out->m[0][3] = x;
+       out->m[1][0] = cp*sy * scale;
+       out->m[1][1] = sr*sp*sy+cr*cy * scale;
+       out->m[1][2] = cr*sp*sy+-sr*cy * scale;
+       out->m[1][3] = y;
+       out->m[2][0] = -sp * scale;
+       out->m[2][1] = sr*cp * scale;
+       out->m[2][2] = cr*cp * scale;
+       out->m[2][3] = z;
+       out->m[3][0] = 0;
+       out->m[3][1] = 0;
+       out->m[3][2] = 0;
+       out->m[3][3] = 1;
+}
+
 void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
 {
        vx[0] = in->m[0][0];
@@ -282,6 +356,7 @@ void Matrix4x4_Transform4 (const matrix4x4_t *in, const float v[4], float out[4]
        out[3] = v[0] * in->m[3][0] + v[1] * in->m[3][1] + v[2] * in->m[3][2] + v[3] * in->m[3][3];
 }
 
+/*
 void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3])
 {
        float t[3];
@@ -292,6 +367,7 @@ void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float
        out[1] = t[0] * in->m[0][1] + t[1] * in->m[1][1] + t[2] * in->m[2][1];
        out[2] = t[0] * in->m[0][2] + t[1] * in->m[1][2] + t[2] * in->m[2][2];
 }
+*/
 
 // FIXME: optimize
 void Matrix4x4_ConcatTranslate (matrix4x4_t *out, float x, float y, float z)
@@ -336,12 +412,12 @@ void Matrix4x4_ConcatScale3 (matrix4x4_t *out, float x, float y, float z)
 
 
 
-void Matrix3x4_Copy (matrix3x4_t *out, matrix3x4_t *in)
+void Matrix3x4_Copy (matrix3x4_t *out, const matrix3x4_t *in)
 {
        *out = *in;
 }
 
-void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, matrix3x4_t *in)
+void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, const matrix3x4_t *in)
 {
        out->m[0][0] = in->m[0][0];
        out->m[0][1] = in->m[0][1];
@@ -357,7 +433,7 @@ void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, matrix3x4_t *in)
        out->m[2][3] = 0.0f;
 }
 
-void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, matrix3x4_t *in)
+void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, const matrix3x4_t *in)
 {
        out->m[0][0] = 0.0f;
        out->m[0][1] = 0.0f;
@@ -373,7 +449,7 @@ void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, matrix3x4_t *in)
        out->m[2][3] = in->m[0][3];
 }
 
-void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, matrix4x4_t *in)
+void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, const matrix4x4_t *in)
 {
        out->m[0][0] = in->m[0][0];
        out->m[0][1] = in->m[0][1];
@@ -407,30 +483,47 @@ void Matrix3x4_Concat (matrix3x4_t *out, const matrix3x4_t *in1, const matrix3x4
 
 void Matrix3x4_Transpose3x3 (matrix3x4_t *out, const matrix3x4_t *in1)
 {
-       float scale;
-       scale = 3.0 / (in1->m[0][0] * in1->m[0][0]
-                    + in1->m[0][1] * in1->m[0][1]
-                    + in1->m[0][2] * in1->m[0][2]
-                    + in1->m[1][0] * in1->m[1][0]
-                    + in1->m[1][1] * in1->m[1][1]
-                    + in1->m[1][2] * in1->m[1][2]
-                    + in1->m[2][0] * in1->m[2][0]
-                    + in1->m[2][1] * in1->m[2][1]
-                    + in1->m[2][2] * in1->m[2][2]);
+       out->m[0][0] = in1->m[0][0];
+       out->m[0][1] = in1->m[1][0];
+       out->m[0][2] = in1->m[2][0];
+       out->m[0][3] = 0.0f;
+       out->m[1][0] = in1->m[0][1];
+       out->m[1][1] = in1->m[1][1];
+       out->m[1][2] = in1->m[2][1];
+       out->m[1][3] = 0.0f;
+       out->m[2][0] = in1->m[0][2];
+       out->m[2][1] = in1->m[1][2];
+       out->m[2][2] = in1->m[2][2];
+       out->m[2][3] = 0.0f;
+}
+
+void Matrix3x4_Invert_Simple (matrix3x4_t *out, const matrix3x4_t *in1)
+{
+       // we only support uniform scaling, so assume the first row is enough
+       // (note the lack of sqrt here, because we're trying to undo the scaling,
+       // this means multiplying by the inverse scale twice - squaring it, which
+       // makes the sqrt a waste of time)
+       double scale = 1.0 / (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
+
+       // invert the rotation by transposing and multiplying by the squared
+       // recipricol of the input matrix scale as described above
        out->m[0][0] = in1->m[0][0] * scale;
        out->m[0][1] = in1->m[1][0] * scale;
        out->m[0][2] = in1->m[2][0] * scale;
-       out->m[0][3] = 0.0f;
        out->m[1][0] = in1->m[0][1] * scale;
        out->m[1][1] = in1->m[1][1] * scale;
        out->m[1][2] = in1->m[2][1] * scale;
-       out->m[1][3] = 0.0f;
        out->m[2][0] = in1->m[0][2] * scale;
        out->m[2][1] = in1->m[1][2] * scale;
        out->m[2][2] = in1->m[2][2] * scale;
-       out->m[2][3] = 0.0f;
+
+       // invert the translate
+       out->m[0][3] = -(in1->m[0][3] * out->m[0][0] + in1->m[1][3] * out->m[0][1] + in1->m[2][3] * out->m[0][2]);
+       out->m[1][3] = -(in1->m[0][3] * out->m[1][0] + in1->m[1][3] * out->m[1][1] + in1->m[2][3] * out->m[1][2]);
+       out->m[2][3] = -(in1->m[0][3] * out->m[2][0] + in1->m[1][3] * out->m[2][1] + in1->m[2][3] * out->m[2][2]);
 }
 
+
 void Matrix3x4_CreateIdentity (matrix3x4_t *out)
 {
        out->m[0][0]=1.0f;
@@ -524,6 +617,33 @@ void Matrix3x4_CreateScale3 (matrix3x4_t *out, float x, float y, float z)
        out->m[2][3]=0.0f;
 }
 
+void Matrix3x4_CreateFromQuakeEntity(matrix3x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale)
+{
+       double angle, sr, sp, sy, cr, cp, cy;
+
+       angle = yaw * (M_PI*2 / 360);
+       sy = sin(angle);
+       cy = cos(angle);
+       angle = pitch * (M_PI*2 / 360);
+       sp = sin(angle);
+       cp = cos(angle);
+       angle = roll * (M_PI*2 / 360);
+       sr = sin(angle);
+       cr = cos(angle);
+       out->m[0][0] = cp*cy * scale;
+       out->m[0][1] = sr*sp*cy+cr*-sy * scale;
+       out->m[0][2] = cr*sp*cy+-sr*-sy * scale;
+       out->m[0][3] = x;
+       out->m[1][0] = cp*sy * scale;
+       out->m[1][1] = sr*sp*sy+cr*cy * scale;
+       out->m[1][2] = cr*sp*sy+-sr*cy * scale;
+       out->m[1][3] = y;
+       out->m[2][0] = -sp * scale;
+       out->m[2][1] = sr*cp * scale;
+       out->m[2][2] = cr*cp * scale;
+       out->m[2][3] = z;
+}
+
 void Matrix3x4_ToVectors(const matrix3x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
 {
        vx[0] = in->m[0][0];
index 77c20b0cec8830bf784039f9fb330e064527fe3a..62b8a3e1ff36c2942c235351dda9b36aa5c9e9d0 100644 (file)
@@ -17,21 +17,25 @@ matrix3x4_t;
 // functions for manipulating 4x4 matrices
 
 // copy a matrix4x4
-void Matrix4x4_Copy (matrix4x4_t *out, matrix4x4_t *in);
+void Matrix4x4_Copy (matrix4x4_t *out, const matrix4x4_t *in);
 // copy only the rotation portion of a matrix4x4
-void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, matrix4x4_t *in);
+void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, const matrix4x4_t *in);
 // copy only the translate portion of a matrix4x4
-void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, matrix4x4_t *in);
+void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, const matrix4x4_t *in);
 // make a matrix4x4 from a matrix3x4
-void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, matrix3x4_t *in);
+void Matrix4x4_FromMatrix3x4 (matrix4x4_t *out, const matrix3x4_t *in);
 // multiply two matrix4x4 together, combining their transformations
 // (warning: order matters - Concat(a, b, c) != Concat(a, c, b))
 void Matrix4x4_Concat (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2);
-// swaps the rows and columns of the matrix4x4 and attempts to undo uniform
-// scaling (Scale, not Scale3), resulting in a matrix that will do the opposite
-// (warning: this only inverts rotation, uniform scaling and translation,
-// do not use with shearing, Scale3, or other complex matrices)
+// swaps the rows and columns of the matrix
+// (is this useful for anything?)
 void Matrix4x4_Transpose (matrix4x4_t *out, const matrix4x4_t *in1);
+// swaps the rows and columns of the rotation matrix
+// (inverting the rotation, but leaving everything else the same)
+void Matrix4x4_Transpose3x3 (matrix4x4_t *out, const matrix4x4_t *in1);
+// creates a matrix that does the opposite of the matrix provided
+// only supports translate, rotate, scale (not scale3) matrices
+void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1);
 
 // creates an identity matrix
 // (a matrix which does nothing)
@@ -44,13 +48,15 @@ void Matrix4x4_CreateTranslate (matrix4x4_t *out, float x, float y, float z);
 void Matrix4x4_CreateRotate (matrix4x4_t *out, float angle, float x, float y, float z);
 // creates a scaling matrix
 // (expands or contracts vectors)
-// (warning: this is not reversed by Transpose)
+// (warning: do not apply this kind of matrix to direction vectors)
 void Matrix4x4_CreateScale (matrix4x4_t *out, float x);
 // creates a squishing matrix
 // (expands or contracts vectors differently in different axis)
-// (warning: this is not reversed by Transpose)
+// (warning: this is not reversed by Invert_Simple)
 // (warning: do not apply this kind of matrix to direction vectors)
 void Matrix4x4_CreateScale3 (matrix4x4_t *out, float x, float y, float z);
+// creates a matrix for a quake entity
+void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale);
 
 // converts a matrix4x4 to a set of 3D vectors for the 3 axial directions, and the translate
 void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3]);
@@ -66,7 +72,7 @@ void Matrix4x4_Transform4 (const matrix4x4_t *in, const float v[4], float out[4]
 // reverse transforms a 3D vector through a matrix4x4, at least for *simple*
 // cases (rotation and translation *ONLY*), this attempts to undo the results
 // of Transform
-void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3]);
+//void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3]);
 
 // ease of use functions
 // immediately applies a Translate to the matrix
@@ -83,22 +89,22 @@ void Matrix4x4_ConcatScale3 (matrix4x4_t *out, float x, float y, float z);
 // functions for manipulating 3x4 matrices
 
 // copy a matrix3x4
-void Matrix3x4_Copy (matrix3x4_t *out, matrix3x4_t *in);
+void Matrix3x4_Copy (matrix3x4_t *out, const matrix3x4_t *in);
 // copy only the rotation portion of a matrix3x4
-void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, matrix3x4_t *in);
+void Matrix3x4_CopyRotateOnly (matrix3x4_t *out, const matrix3x4_t *in);
 // copy only the translate portion of a matrix3x4
-void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, matrix3x4_t *in);
+void Matrix3x4_CopyTranslateOnly (matrix3x4_t *out, const matrix3x4_t *in);
 // make a matrix3x4 from a matrix4x4
-void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, matrix4x4_t *in);
+void Matrix3x4_FromMatrix4x4 (matrix3x4_t *out, const matrix4x4_t *in);
 // multiply two matrix3x4 together, combining their transformations
 // (warning: order matters - Concat(a, b, c) != Concat(a, c, b))
 void Matrix3x4_Concat (matrix3x4_t *out, const matrix3x4_t *in1, const matrix3x4_t *in2);
-// swaps the rows and columns of the rotation portion of the matrix, and
-// attempts to undo uniform scaling (Scale, not Scale3), resulting in a
-// matrix that will do the opposite
-// (warning: this only inverts rotation and uniform scaling, do not use with
-//  translation, shearing, Scale3 or other complex matrices)
+// swaps the rows and columns of the rotation matrix
+// (inverting the rotation, but leaving everything else the same)
 void Matrix3x4_Transpose3x3 (matrix3x4_t *out, const matrix3x4_t *in1);
+// creates a matrix that does the opposite of the matrix provided
+// only supports translate, rotate, scale (not scale3) matrices
+void Matrix3x4_Invert_Simple (matrix3x4_t *out, const matrix3x4_t *in1);
 
 // creates an identity matrix
 // (a matrix which does nothing)
@@ -111,13 +117,15 @@ void Matrix3x4_CreateTranslate (matrix3x4_t *out, float x, float y, float z);
 void Matrix3x4_CreateRotate (matrix3x4_t *out, float angle, float x, float y, float z);
 // creates a scaling matrix
 // (expands or contracts vectors)
-// (warning: this is not reversed by Transpose)
+// (warning: do not apply this kind of matrix to direction vectors)
 void Matrix3x4_CreateScale (matrix3x4_t *out, float x);
 // creates a squishing matrix
 // (expands or contracts vectors differently in different axis)
-// (warning: this is not reversed by Transpose)
+// (warning: this is not reversed by Invert_Simple)
 // (warning: do not apply this kind of matrix to direction vectors)
 void Matrix3x4_CreateScale3 (matrix3x4_t *out, float x, float y, float z);
+// creates a matrix for a quake entity
+void Matrix3x4_CreateFromQuakeEntity(matrix3x4_t *out, float x, float y, float z, float pitch, float yaw, float roll, float scale);
 
 // converts a matrix3x4 to a set of 3D vectors for the 3 axial directions, and the translate
 void Matrix3x4_ToVectors(const matrix3x4_t *in, float vx[3], float vy[3], float vz[3], float t[3]);
index 467b4c555e865f4350ff5f0b558ee4135273a9dd..fdbb60e9a7b5db9e0734ea72f1aa09f1a324e4dc 100644 (file)
@@ -9,8 +9,8 @@ cvar_t r_meshqueue_sort = {0, "r_meshqueue_sort", "0"};
 typedef struct meshqueue_s
 {
        struct meshqueue_s *next;
-       void (*callback)(void *data1, int data2);
-       void *data1;
+       void (*callback)(const void *data1, int data2);
+       const void *data1;
        int data2;
        float dist;
 }
@@ -60,7 +60,7 @@ static void R_MeshQueue_EnlargeTransparentArray(int newtotal)
        mqt_total = newtotal;
 }
 
-void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int data2)
+void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void *data1, int data2)
 {
        meshqueue_t *mq, **mqnext;
        if (r_meshqueue_immediaterender.integer)
@@ -103,7 +103,7 @@ void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int
        *mqnext = mq;
 }
 
-void R_MeshQueue_AddTransparent(vec3_t center, void (*callback)(void *data1, int data2), void *data1, int data2)
+void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const void *data1, int data2), const void *data1, int data2)
 {
        meshqueue_t *mq;
        if (mqt_count >= mqt_total)
index f3f9e3fc170516c181ad06255abebeb720391638..ed587e14e93a22432228458350037775684dd2db 100644 (file)
@@ -3,8 +3,8 @@
 #define MESHQUEUE_H
 
 void R_MeshQueue_Init(void);
-void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int data2);
-void R_MeshQueue_AddTransparent(vec3_t center, void (*callback)(void *data1, int data2), void *data1, int data2);
+void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void *data1, int data2);
+void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const void *data1, int data2), const void *data1, int data2);
 void R_MeshQueue_BeginScene(void);
 void R_MeshQueue_Render(void);
 void R_MeshQueue_RenderTransparent(void);
index 79be4373212982d91f523c03ce38bdab4431824e..92244c451766043a293caeeef637f281afffb23c 100644 (file)
@@ -109,7 +109,7 @@ void Mod_BrushShutdown (void)
 Mod_PointInLeaf
 ===============
 */
-mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
+mleaf_t *Mod_PointInLeaf (const vec3_t p, model_t *model)
 {
        mnode_t         *node;
 
index eebdc525096406495974642490a19102c5446cbb..fdc69165e7ec50614a0c04f36a331799318ad88f 100644 (file)
@@ -210,7 +210,7 @@ struct entity_render_s;
 // change this stuff when real shaders are added
 typedef struct Cshader_s
 {
-       void (*shaderfunc[SHADERSTAGE_COUNT])(struct entity_render_s *ent, msurface_t *firstsurf);
+       void (*shaderfunc[SHADERSTAGE_COUNT])(const struct entity_render_s *ent, const msurface_t *firstsurf);
        // list of surfaces using this shader (used during surface rendering)
        msurface_t *chain;
 }
index 6fc568cf3f835777b71e110e8b5fd279c4d4f8e0..f6a6bdc9f6d7dc40c942b8d6e4e8bb2d267c637e 100644 (file)
@@ -226,7 +226,7 @@ model_t *Mod_ForName (char *name, qboolean crash, qboolean checkdisk, qboolean i
 void Mod_TouchModel (char *name);
 void Mod_UnloadModel (model_t *mod);
 
-mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
+mleaf_t *Mod_PointInLeaf (const float *p, model_t *model);
 qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
 
 void Mod_ClearUsed(void);
index 4a765927393be2f30134bc6223ea9ee425a3d34b..49b68a3b7b8ea0736e76e81c121884be7a2ac1ca 100644 (file)
@@ -172,6 +172,7 @@ void R_DrawCrosshairSprite(rtexture_t *texture, vec3_t origin, vec_t scale, floa
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = R_GetTexture(texture);
+       Matrix4x4_CreateIdentity(&m.matrix);
        if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                m.index[0] = 0;
index 5cd7fb9aed3d8fb7c9e0dab174b165efd5ae89f0..0f027e5f2c3af4fc43e21d502c4718ad66b3c1bc 100644 (file)
@@ -173,12 +173,12 @@ void R_NewExplosion(vec3_t org)
        }
 }
 
-void R_DrawExplosionCallback(void *calldata1, int calldata2)
+void R_DrawExplosionCallback(const void *calldata1, int calldata2)
 {
        int i;
        float *c, *v, diff[3], centerdir[3], ifog, alpha, dist;
        rmeshbufferinfo_t m;
-       explosion_t *e;
+       const explosion_t *e;
        e = calldata1;
 
        memset(&m, 0, sizeof(m));
@@ -187,6 +187,7 @@ void R_DrawExplosionCallback(void *calldata1, int calldata2)
        m.numtriangles = EXPLOSIONTRIS;
        m.numverts = EXPLOSIONVERTS;
        m.tex[0] = R_GetTexture(explosiontexture);
+       Matrix4x4_CreateIdentity(&m.matrix);
        if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, explosiontris, m.numtriangles * sizeof(int[3]));
index 13895c3e3f986cdcdf37e0f2941b9b16f48a01a6..965b8191196644688974498d71e36beaa99d05ab 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -27,6 +27,8 @@ int r_numdlights = 0;
 
 cvar_t r_modellights = {CVAR_SAVE, "r_modellights", "4"};
 cvar_t r_vismarklights = {0, "r_vismarklights", "1"};
+cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1"};
+cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "1"};
 
 static rtexture_t *lightcorona;
 static rtexturepool_t *lighttexturepool;
@@ -68,6 +70,8 @@ void R_Light_Init(void)
 {
        Cvar_RegisterVariable(&r_modellights);
        Cvar_RegisterVariable(&r_vismarklights);
+       Cvar_RegisterVariable(&r_coronas);
+       Cvar_RegisterVariable(&gl_flashblend);
        R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap);
 }
 
@@ -126,7 +130,6 @@ void R_BuildLightList(void)
                rd->cullradius = sqrt(rd->cullradius2);
                rd->subtract = 1.0f / rd->cullradius2;
                //rd->ent = cd->ent;
-               r_numdlights++;
                c_dlights++; // count every dlight in use
        }
 }
@@ -137,6 +140,8 @@ void R_DrawCoronas(void)
        rmeshbufferinfo_t m;
        float scale, viewdist, diff[3], dist;
        rdlight_t *rd;
+       if (!r_coronas.integer)
+               return;
        memset(&m, 0, sizeof(m));
        m.blendfunc1 = GL_ONE;
        m.blendfunc2 = GL_ONE;
@@ -151,48 +156,54 @@ void R_DrawCoronas(void)
                dist = (DotProduct(rd->origin, vpn) - viewdist);
                if (dist >= 24.0f)
                {
-                       // trace to a point just barely closer to the eye
-                       VectorSubtract(rd->origin, vpn, diff);
-                       if (CL_TraceLine(r_origin, diff, NULL, NULL, 0, true) == 1 && R_Mesh_Draw_GetBuffer(&m, false))
+                       if (CL_TraceLine(rd->origin, r_origin, NULL, NULL, 0, true) == 1)
                        {
-                               scale = m.colorscale * (1.0f / 131072.0f);
-                               if (fogenabled)
+                               Matrix4x4_CreateIdentity(&m.matrix);
+                               if (R_Mesh_Draw_GetBuffer(&m, false))
                                {
-                                       VectorSubtract(rd->origin, r_origin, diff);
-                                       scale *= 1 - exp(fogdensity/DotProduct(diff,diff));
+                                       scale = m.colorscale * (1.0f / 131072.0f);
+                                       if (gl_flashblend.integer)
+                                               scale *= 4.0f;
+                                       if (fogenabled)
+                                       {
+                                               VectorSubtract(rd->origin, r_origin, diff);
+                                               scale *= 1 - exp(fogdensity/DotProduct(diff,diff));
+                                       }
+                                       m.index[0] = 0;
+                                       m.index[1] = 1;
+                                       m.index[2] = 2;
+                                       m.index[3] = 0;
+                                       m.index[4] = 2;
+                                       m.index[5] = 3;
+                                       m.color[0] = m.color[4] = m.color[8] = m.color[12] = rd->light[0] * scale;
+                                       m.color[1] = m.color[5] = m.color[9] = m.color[13] = rd->light[1] * scale;
+                                       m.color[2] = m.color[6] = m.color[10] = m.color[14] = rd->light[2] * scale;
+                                       m.color[3] = m.color[7] = m.color[11] = m.color[15] = 1;
+                                       m.texcoords[0][0] = 0;
+                                       m.texcoords[0][1] = 0;
+                                       m.texcoords[0][2] = 0;
+                                       m.texcoords[0][3] = 1;
+                                       m.texcoords[0][4] = 1;
+                                       m.texcoords[0][5] = 1;
+                                       m.texcoords[0][6] = 1;
+                                       m.texcoords[0][7] = 0;
+                                       scale = rd->cullradius * 0.25f;
+                                       if (gl_flashblend.integer)
+                                               scale *= 2.0f;
+                                       m.vertex[0] = rd->origin[0] - vright[0] * scale - vup[0] * scale;
+                                       m.vertex[1] = rd->origin[1] - vright[1] * scale - vup[1] * scale;
+                                       m.vertex[2] = rd->origin[2] - vright[2] * scale - vup[2] * scale;
+                                       m.vertex[4] = rd->origin[0] - vright[0] * scale + vup[0] * scale;
+                                       m.vertex[5] = rd->origin[1] - vright[1] * scale + vup[1] * scale;
+                                       m.vertex[6] = rd->origin[2] - vright[2] * scale + vup[2] * scale;
+                                       m.vertex[8] = rd->origin[0] + vright[0] * scale + vup[0] * scale;
+                                       m.vertex[9] = rd->origin[1] + vright[1] * scale + vup[1] * scale;
+                                       m.vertex[10] = rd->origin[2] + vright[2] * scale + vup[2] * scale;
+                                       m.vertex[12] = rd->origin[0] + vright[0] * scale - vup[0] * scale;
+                                       m.vertex[13] = rd->origin[1] + vright[1] * scale - vup[1] * scale;
+                                       m.vertex[14] = rd->origin[2] + vright[2] * scale - vup[2] * scale;
+                                       R_Mesh_Render();
                                }
-                               m.index[0] = 0;
-                               m.index[1] = 1;
-                               m.index[2] = 2;
-                               m.index[3] = 0;
-                               m.index[4] = 2;
-                               m.index[5] = 3;
-                               m.color[0] = m.color[4] = m.color[8] = m.color[12] = rd->light[0] * scale;
-                               m.color[1] = m.color[5] = m.color[9] = m.color[13] = rd->light[1] * scale;
-                               m.color[2] = m.color[6] = m.color[10] = m.color[14] = rd->light[2] * scale;
-                               m.color[3] = m.color[7] = m.color[11] = m.color[15] = 1;
-                               m.texcoords[0][0] = 0;
-                               m.texcoords[0][1] = 0;
-                               m.texcoords[0][2] = 0;
-                               m.texcoords[0][3] = 1;
-                               m.texcoords[0][4] = 1;
-                               m.texcoords[0][5] = 1;
-                               m.texcoords[0][6] = 1;
-                               m.texcoords[0][7] = 0;
-                               scale = rd->cullradius * 0.25f;
-                               m.vertex[0] = rd->origin[0] - vright[0] * scale - vup[0] * scale;
-                               m.vertex[1] = rd->origin[1] - vright[1] * scale - vup[1] * scale;
-                               m.vertex[2] = rd->origin[2] - vright[2] * scale - vup[2] * scale;
-                               m.vertex[4] = rd->origin[0] - vright[0] * scale + vup[0] * scale;
-                               m.vertex[5] = rd->origin[1] - vright[1] * scale + vup[1] * scale;
-                               m.vertex[6] = rd->origin[2] - vright[2] * scale + vup[2] * scale;
-                               m.vertex[8] = rd->origin[0] + vright[0] * scale + vup[0] * scale;
-                               m.vertex[9] = rd->origin[1] + vright[1] * scale + vup[1] * scale;
-                               m.vertex[10] = rd->origin[2] + vright[2] * scale + vup[2] * scale;
-                               m.vertex[12] = rd->origin[0] + vright[0] * scale - vup[0] * scale;
-                               m.vertex[13] = rd->origin[1] + vright[1] * scale - vup[1] * scale;
-                               m.vertex[14] = rd->origin[2] + vright[2] * scale - vup[2] * scale;
-                               R_Mesh_Render();
                        }
                }
        }
@@ -345,7 +356,8 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b
                return;
 
        model = ent->model;
-       softwareuntransform(rd->origin, lightorigin);
+       //softwareuntransform(rd->origin, lightorigin);
+       Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin);
 
        if (!r_vismarklights.integer)
        {
@@ -478,8 +490,9 @@ static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int b
 void R_MarkLights(entity_render_t *ent)
 {
        int i;
-       for (i = 0;i < r_numdlights;i++)
-               R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5);
+       if (!gl_flashblend.integer)
+               for (i = 0;i < r_numdlights;i++)
+                       R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5);
 }
 
 /*
@@ -490,7 +503,7 @@ LIGHT SAMPLING
 =============================================================================
 */
 
-static int RecursiveLightPoint (vec3_t color, mnode_t *node, float x, float y, float startz, float endz)
+static int RecursiveLightPoint (vec3_t color, const mnode_t *node, float x, float y, float startz, float endz)
 {
        int side, distz = endz - startz;
        float front, back;
@@ -630,9 +643,10 @@ middle sample (the one which was requested)
        }
 }
 
-void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf)
+void R_CompleteLightPoint (vec3_t color, const vec3_t p, int dynamic, const mleaf_t *leaf)
 {
-       int i, *dlightbits;
+       int i;
+       const int *dlightbits;
        vec3_t v;
        float f;
        rdlight_t *rd;
@@ -692,7 +706,7 @@ void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf)
        }
 }
 
-void R_ModelLightPoint (entity_render_t *ent, vec3_t color, vec3_t p, int *dlightbits)
+void R_ModelLightPoint (const entity_render_t *ent, vec3_t color, const vec3_t p, int *dlightbits)
 {
        mleaf_t *leaf;
        leaf = Mod_PointInLeaf(p, cl.worldmodel);
@@ -729,7 +743,7 @@ void R_ModelLightPoint (entity_render_t *ent, vec3_t color, vec3_t p, int *dligh
                dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
 }
 
-void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords)
+void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords)
 {
        int i, j, nearlights = 0, maxnearlights = r_modellights.integer;
        float color[3], basecolor[3], v[3], t, *av, *avn, *avc, a, f, dist2, mscale, dot, stylescale, intensity, ambientcolor[3];
@@ -759,16 +773,6 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg
                R_ModelLightPoint(ent, basecolor, ent->origin, modeldlightbits);
 
                nl = &nearlight[0];
-               VectorSubtract(ent->origin, ent->entlightsorigin, v);
-               if ((realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
-               {
-                       ent->numentlights = 0;
-                       ent->entlightstime = realtime + 0.2;
-                       VectorCopy(ent->origin, ent->entlightsorigin);
-                       for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
-                               if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false) == 1)
-                                       ent->entlights[ent->numentlights++] = i;
-               }
                for (i = 0;i < ent->numentlights;i++)
                {
                        sl = cl.worldmodel->lights + ent->entlights[i];
@@ -808,7 +812,8 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg
                                if (worldcoords)
                                        VectorCopy(sl->origin, nl->origin);
                                else
-                                       softwareuntransform(sl->origin, nl->origin);
+                                       //softwareuntransform(sl->origin, nl->origin);
+                                       Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin);
                                // integrate mscale into falloff, for maximum speed
                                nl->falloff = sl->falloff * mscale;
                                VectorCopy(ambientcolor, nl->ambientlight);
@@ -859,7 +864,20 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg
                                if (worldcoords)
                                        VectorCopy(rd->origin, nl->origin);
                                else
-                                       softwareuntransform(rd->origin, nl->origin);
+                               {
+                                       //softwareuntransform(rd->origin, nl->origin);
+                                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
+                                       /*
+                                       Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
+                                       , rd - r_dlight, ent->model->name
+                                       , rd->origin[0], rd->origin[1], rd->origin[2]
+                                       , nl->origin[0], nl->origin[1], nl->origin[2]
+                                       , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
+                                       , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
+                                       , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
+                                       , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
+                                       */
+                               }
                                // integrate mscale into falloff, for maximum speed
                                nl->falloff = mscale;
                                VectorCopy(ambientcolor, nl->ambientlight);
@@ -938,3 +956,20 @@ void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg
        }
 }
 
+void R_UpdateEntLights(entity_render_t *ent)
+{
+       int i;
+       const mlight_t *sl;
+       vec3_t v;
+       VectorSubtract(ent->origin, ent->entlightsorigin, v);
+       if (ent->entlightsframe != (r_framecount - 1) || (realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
+       {
+               ent->entlightstime = realtime + 0.1;
+               VectorCopy(ent->origin, ent->entlightsorigin);
+               ent->numentlights = 0;
+               for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
+                       if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false) == 1)
+                               ent->entlights[ent->numentlights++] = i;
+       }
+       ent->entlightsframe = r_framecount;
+}
index 026a4ec0f8df2efff7907c250bc19998f03c49df..6fafe72239aade27d837f4525a9de5b158364d55 100644 (file)
--- a/r_light.h
+++ b/r_light.h
@@ -20,8 +20,9 @@ void R_BuildLightList(void);
 void R_AnimateLight(void);
 void R_MarkLights(entity_render_t *ent);
 void R_DrawCoronas(void);
-void R_CompleteLightPoint(vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf);
-void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords);
+void R_CompleteLightPoint(vec3_t color, const vec3_t p, int dynamic, const mleaf_t *leaf);
+void R_LightModel(const entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords);
+void R_UpdateEntLights(entity_render_t *ent);
 
 #endif
 
diff --git a/r_sky.c b/r_sky.c
index d7f95cff5dcbef2a4a14b5486aa13ef369f96963..364818a888f3a45e241ac52c009c67bf04eed2c7 100644 (file)
--- a/r_sky.c
+++ b/r_sky.c
@@ -157,9 +157,9 @@ static void R_SkyBox(void)
        rmeshbufferinfo_t m;
 
 #define R_SkyBoxPolyVec(i,s,t,x,y,z) \
-       m.vertex[i * 4 + 0] = (x) * 16.0f + r_origin[0];\
-       m.vertex[i * 4 + 1] = (y) * 16.0f + r_origin[1];\
-       m.vertex[i * 4 + 2] = (z) * 16.0f + r_origin[2];\
+       m.vertex[i * 4 + 0] = (x) * 16.0f;\
+       m.vertex[i * 4 + 1] = (y) * 16.0f;\
+       m.vertex[i * 4 + 2] = (z) * 16.0f;\
        m.texcoords[0][i * 2 + 0] = (s) * (254.0f/256.0f) + (1.0f/256.0f);\
        m.texcoords[0][i * 2 + 1] = (t) * (254.0f/256.0f) + (1.0f/256.0f);
 
@@ -170,6 +170,7 @@ static void R_SkyBox(void)
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = R_GetTexture(skyboxside[3]); // front
+       Matrix4x4_CreateTranslate(&m.matrix, r_origin[0], r_origin[1], r_origin[2]);
        if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skyboxindex, sizeof(int[6]));
@@ -316,9 +317,9 @@ static void skyspherearrays(float *v, float *t, float *c, float *source, float s
                c[3] = 1;
                t[0] = source[0] + s;
                t[1] = source[1] + s;
-               v[0] = source[2] + r_origin[0];
-               v[1] = source[3] + r_origin[1];
-               v[2] = source[4] + r_origin[2];
+               v[0] = source[2];
+               v[1] = source[3];
+               v[2] = source[4];
        }
 }
 
@@ -345,6 +346,7 @@ static void R_SkySphere(void)
        m.numtriangles = skygridx*skygridy*2;
        m.numverts = skygridx1*skygridy1;
        m.tex[0] = R_GetTexture(solidskytexture);
+       Matrix4x4_CreateTranslate(&m.matrix, r_origin[0], r_origin[1], r_origin[2]);
        if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skysphereindices, m.numtriangles * sizeof(int[3]));
index 8277f21179050a378de811ac37c36a5c2115c6af..58dd2d21d6a4d0a1eec689dd140bfd00d5d3817a 100644 (file)
@@ -3,7 +3,7 @@
 
 #define LERPSPRITES
 
-static int R_SpriteSetup (entity_render_t *ent, int type, float org[3], float left[3], float up[3])
+static int R_SpriteSetup (const entity_render_t *ent, int type, float org[3], float left[3], float up[3])
 {
        float matrix1[3][3], matrix2[3][3], matrix3[3][3];
 
@@ -89,6 +89,7 @@ static void R_DrawSpriteImage (int wantoverbright, int additive, mspriteframe_t
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = texture;
+       Matrix4x4_CreateIdentity(&m.matrix);
        if (R_Mesh_Draw_GetBuffer(&m, wantoverbright))
        {
                m.index[0] = 0;
@@ -126,16 +127,15 @@ static void R_DrawSpriteImage (int wantoverbright, int additive, mspriteframe_t
        }
 }
 
-void R_DrawSpriteModelCallback(void *calldata1, int calldata2)
+void R_DrawSpriteModelCallback(const void *calldata1, int calldata2)
 {
-       entity_render_t *ent;
+       const entity_render_t *ent = calldata1;
        int i, wantoverbright;
        vec3_t left, up, org, color;
        mspriteframe_t *frame;
        vec3_t diff;
        float fog, ifog;
 
-       ent = calldata1;
        if (R_SpriteSetup(ent, ent->model->sprnum_type, org, left, up))
                return;