engine mostly converted to use R_MeshQueue functions instead of true transparent...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 27 Aug 2002 09:42:59 +0000 (09:42 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 27 Aug 2002 09:42:59 +0000 (09:42 +0000)
the rest of the conversion to R_MeshQueue will be in a future commit, just wanted to get this in now

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

12 files changed:
cl_particles.c
gl_models.c
gl_rmain.c
gl_rsurf.c
model_alias.c
model_brush.h
model_shared.h
r_explosion.c
r_light.c
r_light.h
r_sprites.c
render.h

index 15f78ca..2c9f214 100644 (file)
@@ -1183,30 +1183,147 @@ void R_Particles_Init (void)
 
 int partindexarray[6] = {0, 1, 2, 0, 2, 3};
 
-void R_DrawParticles (void)
+void R_DrawParticleCallback(void *calldata1, int calldata2)
 {
-       int i, lighting, dynlight, additive, texnum, orientation;
-       float minparticledist, org[3], uprightangles[3], up2[3], right2[3], v[3], right[3], up[3], fog, ifog, fogvec[3], cr, cg, cb, ca;
-       mleaf_t *leaf;
+       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;
+
+       // LordHavoc: check if it's in a visible leaf
+       leaf = Mod_PointInLeaf(p->org, cl.worldmodel);
+       if (leaf->visframe != r_framecount)
+               return;
+
+       lighting = r_dynamic.integer ? r_particles_lighting.integer : 0;
+
+       VectorCopy(p->org, org);
+       orientation = (p->flags >> P_ORIENTATION_FIRSTBIT) & ((1 << P_ORIENTATION_BITS) - 1);
+       texnum = (p->flags >> P_TEXNUM_FIRSTBIT) & ((1 << P_TEXNUM_BITS) - 1);
+       dynlight = p->flags & P_DYNLIGHT;
+       additive = p->flags & P_ADDITIVE;
+       if (orientation == PARTICLE_BILLBOARD)
+       {
+               VectorScale(vright, p->scalex, right);
+               VectorScale(vup, p->scaley, up);
+       }
+       else if (orientation == PARTICLE_UPRIGHT_FACING)
+       {
+               v[0] = r_origin[0] - org[0];
+               v[1] = r_origin[1] - org[1];
+               v[2] = 0;
+               VectorNormalizeFast(v);
+               VectorVectors(v, right2, up2);
+               VectorScale(right2, p->scalex, right);
+               VectorScale(up2, p->scaley, up);
+       }
+       else if (orientation == PARTICLE_ORIENTED_DOUBLESIDED)
+       {
+               // double-sided
+               if (DotProduct(p->vel2, r_origin) > DotProduct(p->vel2, org))
+               {
+                       VectorNegate(p->vel2, v);
+                       VectorVectors(v, right, up);
+               }
+               else
+                       VectorVectors(p->vel2, right, up);
+               VectorScale(right, p->scalex, right);
+               VectorScale(up, p->scaley, up);
+       }
+       else
+               Host_Error("R_DrawParticles: unknown particle orientation %i\n", orientation);
+
+       cr = p->color[0] * (1.0f / 255.0f);
+       cg = p->color[1] * (1.0f / 255.0f);
+       cb = p->color[2] * (1.0f / 255.0f);
+       ca = p->alpha * (1.0f / 255.0f);
+       if (lighting >= 1 && (dynlight || lighting >= 2))
+       {
+               R_CompleteLightPoint(v, org, true, leaf);
+               cr *= v[0];
+               cg *= v[1];
+               cb *= v[2];
+       }
+
+       if (fogenabled)
+       {
+               VectorSubtract(org, r_origin, fogvec);
+               fog = exp(fogdensity/DotProduct(fogvec,fogvec));
+               ifog = 1 - fog;
+               cr = cr * ifog;
+               cg = cg * ifog;
+               cb = cb * ifog;
+               if (!additive)
+               {
+                       cr += fogcolor[0] * fog;
+                       cg += fogcolor[1] * fog;
+                       cb += fogcolor[2] * fog;
+               }
+       }
+
+       memset(&m, 0, sizeof(m));
+       m.transparent = false;
+       m.blendfunc1 = GL_SRC_ALPHA;
+       if (additive)
+               m.blendfunc2 = GL_ONE;
+       else
+               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       m.numtriangles = 2;
+       m.numverts = 4;
+       m.tex[0] = R_GetTexture(particlefonttexture);
+       if (R_Mesh_Draw_GetBuffer(&m, false))
+       {
+               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.vertex[0] = org[0] - right[0] - up[0];
+               m.vertex[1] = org[1] - right[1] - up[1];
+               m.vertex[2] = org[2] - right[2] - up[2];
+               m.vertex[4] = org[0] - right[0] + up[0];
+               m.vertex[5] = org[1] - right[1] + up[1];
+               m.vertex[6] = org[2] - right[2] + up[2];
+               m.vertex[8] = org[0] + right[0] + up[0];
+               m.vertex[9] = org[1] + right[1] + up[1];
+               m.vertex[10] = org[2] + right[2] + up[2];
+               m.vertex[12] = org[0] + right[0] - up[0];
+               m.vertex[13] = org[1] + right[1] - up[1];
+               m.vertex[14] = org[2] + right[2] - up[2];
+               tex = &particletexture[texnum];
+               m.texcoords[0][0] = tex->s1;
+               m.texcoords[0][1] = tex->t1;
+               m.texcoords[0][2] = tex->s1;
+               m.texcoords[0][3] = tex->t2;
+               m.texcoords[0][4] = tex->s2;
+               m.texcoords[0][5] = tex->t2;
+               m.texcoords[0][6] = tex->s2;
+               m.texcoords[0][7] = tex->t1;
+               m.color[0] = m.color[4] = m.color[8] = m.color[12] = cr * m.colorscale;
+               m.color[1] = m.color[5] = m.color[9] = m.color[13] = cg * m.colorscale;
+               m.color[2] = m.color[6] = m.color[10] = m.color[14] = cb * m.colorscale;
+               m.color[3] = m.color[7] = m.color[11] = m.color[15] = ca;
+               R_Mesh_Render();
+       }
+}
+
+void R_DrawParticles (void)
+{
+       int i;
+       float minparticledist;
+       particle_t *p;
+
        // LordHavoc: early out conditions
        if ((!cl_numparticles) || (!r_drawparticles.integer))
                return;
 
-       lighting = r_particles_lighting.integer;
-       if (!r_dynamic.integer)
-               lighting = 0;
-
        c_particles += cl_numparticles;
 
-       uprightangles[0] = 0;
-       uprightangles[1] = r_refdef.viewangles[1];
-       uprightangles[2] = 0;
-       AngleVectors (uprightangles, NULL, right2, up2);
-
        minparticledist = DotProduct(r_origin, vpn) + 16.0f;
 
        for (i = 0, p = particles;i < cl_numparticles;i++, p++)
@@ -1215,116 +1332,7 @@ void R_DrawParticles (void)
                if (DotProduct(p->org, vpn) < minparticledist)
                        continue;
 
-               // LordHavoc: check if it's in a visible leaf
-               leaf = Mod_PointInLeaf(p->org, cl.worldmodel);
-               if (leaf->visframe != r_framecount)
-                       continue;
-
-               VectorCopy(p->org, org);
-               orientation = (p->flags >> P_ORIENTATION_FIRSTBIT) & ((1 << P_ORIENTATION_BITS) - 1);
-               texnum = (p->flags >> P_TEXNUM_FIRSTBIT) & ((1 << P_TEXNUM_BITS) - 1);
-               dynlight = p->flags & P_DYNLIGHT;
-               additive = p->flags & P_ADDITIVE;
-               if (orientation == PARTICLE_BILLBOARD)
-               {
-                       VectorScale(vright, p->scalex, right);
-                       VectorScale(vup, p->scaley, up);
-               }
-               else if (orientation == PARTICLE_UPRIGHT_FACING)
-               {
-                       VectorScale(right2, p->scalex, right);
-                       VectorScale(up2, p->scaley, up);
-               }
-               else if (orientation == PARTICLE_ORIENTED_DOUBLESIDED)
-               {
-                       // double-sided
-                       if (DotProduct(p->vel2, r_origin) > DotProduct(p->vel2, org))
-                       {
-                               VectorNegate(p->vel2, v);
-                               VectorVectors(v, right, up);
-                       }
-                       else
-                               VectorVectors(p->vel2, right, up);
-                       VectorScale(right, p->scalex, right);
-                       VectorScale(up, p->scaley, up);
-               }
-               else
-                       Host_Error("R_DrawParticles: unknown particle orientation %i\n", orientation);
-
-               tex = &particletexture[texnum];
-
-               cr = p->color[0] * (1.0f / 255.0f);
-               cg = p->color[1] * (1.0f / 255.0f);
-               cb = p->color[2] * (1.0f / 255.0f);
-               ca = p->alpha * (1.0f / 255.0f);
-               if (lighting >= 1 && (dynlight || lighting >= 2))
-               {
-                       R_CompleteLightPoint(v, org, true, leaf);
-                       cr *= v[0];
-                       cg *= v[1];
-                       cb *= v[2];
-               }
-
-               if (fogenabled)
-               {
-                       VectorSubtract(org, r_origin, fogvec);
-                       fog = exp(fogdensity/DotProduct(fogvec,fogvec));
-                       ifog = 1 - fog;
-                       cr = cr * ifog;
-                       cg = cg * ifog;
-                       cb = cb * ifog;
-                       if (!additive)
-                       {
-                               cr += fogcolor[0] * fog;
-                               cg += fogcolor[1] * fog;
-                               cb += fogcolor[2] * fog;
-                       }
-               }
-
-               memset(&m, 0, sizeof(m));
-               m.transparent = true;
-               m.blendfunc1 = GL_SRC_ALPHA;
-               if (additive)
-                       m.blendfunc2 = GL_ONE;
-               else
-                       m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-               m.numtriangles = 2;
-               m.numverts = 4;
-               m.tex[0] = R_GetTexture(particlefonttexture);
-               if (R_Mesh_Draw_GetBuffer(&m, false))
-               {
-                       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.vertex[0] = org[0] - right[0] - up[0];
-                       m.vertex[1] = org[1] - right[1] - up[1];
-                       m.vertex[2] = org[2] - right[2] - up[2];
-                       m.vertex[4] = org[0] - right[0] + up[0];
-                       m.vertex[5] = org[1] - right[1] + up[1];
-                       m.vertex[6] = org[2] - right[2] + up[2];
-                       m.vertex[8] = org[0] + right[0] + up[0];
-                       m.vertex[9] = org[1] + right[1] + up[1];
-                       m.vertex[10] = org[2] + right[2] + up[2];
-                       m.vertex[12] = org[0] + right[0] - up[0];
-                       m.vertex[13] = org[1] + right[1] - up[1];
-                       m.vertex[14] = org[2] + right[2] - up[2];
-                       m.texcoords[0][0] = tex->s1;
-                       m.texcoords[0][1] = tex->t1;
-                       m.texcoords[0][2] = tex->s1;
-                       m.texcoords[0][3] = tex->t2;
-                       m.texcoords[0][4] = tex->s2;
-                       m.texcoords[0][5] = tex->t2;
-                       m.texcoords[0][6] = tex->s2;
-                       m.texcoords[0][7] = tex->t1;
-                       m.color[0] = m.color[4] = m.color[8] = m.color[12] = cr * m.colorscale;
-                       m.color[1] = m.color[5] = m.color[9] = m.color[13] = cg * m.colorscale;
-                       m.color[2] = m.color[6] = m.color[10] = m.color[14] = cb * m.colorscale;
-                       m.color[3] = m.color[7] = m.color[11] = m.color[15] = ca;
-                       R_Mesh_Render();
-               }
+               R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0);
        }
 }
 
index 8b40edd..acfd701 100644 (file)
@@ -198,66 +198,89 @@ void R_AliasLerpVerts(int vertcount,
        }
 }
 
-skinframe_t *R_FetchSkinFrame(void)
+skinframe_t *R_FetchSkinFrame(entity_render_t *ent)
 {
-       model_t *model = currentrenderentity->model;
-       if (model->skinscenes[currentrenderentity->skinnum].framecount > 1)
-               return &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount];
+       model_t *model = ent->model;
+       if (model->skinscenes[ent->skinnum].framecount > 1)
+               return &model->skinframes[model->skinscenes[ent->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[ent->skinnum].framecount];
        else
-               return &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe];
+               return &model->skinframes[model->skinscenes[ent->skinnum].firstframe];
 }
 
-void R_SetupMDLMD2Frames(float colorr, float colorg, float colorb)
+void R_SetupMDLMD2Frames(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 = currentrenderentity->model;
-
-       frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame];
-       frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame];
-       frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame];
-       frame4 = &model->mdlmd2data_frames[currentrenderentity->frameblend[3].frame];
-       frame1verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[0].frame * model->numverts];
-       frame2verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[1].frame * model->numverts];
-       frame3verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[2].frame * model->numverts];
-       frame4verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[3].frame * model->numverts];
+       model = ent->model;
+
+       frame1 = &model->mdlmd2data_frames[ent->frameblend[0].frame];
+       frame2 = &model->mdlmd2data_frames[ent->frameblend[1].frame];
+       frame3 = &model->mdlmd2data_frames[ent->frameblend[2].frame];
+       frame4 = &model->mdlmd2data_frames[ent->frameblend[3].frame];
+       frame1verts = &model->mdlmd2data_pose[ent->frameblend[0].frame * model->numverts];
+       frame2verts = &model->mdlmd2data_pose[ent->frameblend[1].frame * model->numverts];
+       frame3verts = &model->mdlmd2data_pose[ent->frameblend[2].frame * model->numverts];
+       frame4verts = &model->mdlmd2data_pose[ent->frameblend[3].frame * model->numverts];
        R_AliasLerpVerts(model->numverts,
-               currentrenderentity->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate,
-               currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate,
-               currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate,
-               currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate);
+               ent->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate,
+               ent->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate,
+               ent->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate,
+               ent->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate);
 
-       R_LightModel(model->numverts, colorr, colorg, colorb, false);
+       R_LightModel(ent, model->numverts, colorr, colorg, colorb, false);
 
        R_AliasTransformVerts(model->numverts);
 }
 
-void R_DrawQ1Q2AliasModel (float fog)
+void R_DrawQ1Q2AliasModelCallback (void *calldata1, int calldata2)
 {
        int c, pantsfullbright, shirtfullbright, colormapped;
        float pantscolor[3], shirtcolor[3];
+       float fog;
+       vec3_t diff;
        qbyte *bcolor;
        rmeshbufferinfo_t m;
        model_t *model;
        skinframe_t *skinframe;
+       entity_render_t *ent;
+
+       ent = calldata1;
+       softwaretransformforentity(ent);
+
+       fog = 0;
+       if (fogenabled)
+       {
+               VectorSubtract(ent->origin, r_origin, diff);
+               fog = DotProduct(diff,diff);
+               if (fog < 0.01f)
+                       fog = 0.01f;
+               fog = exp(fogdensity/fog);
+               if (fog > 1)
+                       fog = 1;
+               if (fog < 0.01f)
+                       fog = 0;
+               // fog method: darken, additive fog
+               // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
+               // 2. render fog as additive
+       }
 
-       model = currentrenderentity->model;
+       model = ent->model;
 
-       skinframe = R_FetchSkinFrame();
+       skinframe = R_FetchSkinFrame(ent);
 
-       colormapped = !skinframe->merged || (currentrenderentity->colormap >= 0 && skinframe->base && (skinframe->pants || skinframe->shirt));
+       colormapped = !skinframe->merged || (ent->colormap >= 0 && skinframe->base && (skinframe->pants || skinframe->shirt));
        if (!colormapped && !fog && !skinframe->glow && !skinframe->fog)
        {
                // fastpath for the normal situation (one texture)
                memset(&m, 0, sizeof(m));
-               if (currentrenderentity->effects & EF_ADDITIVE)
+               if (ent->effects & EF_ADDITIVE)
                {
                        m.transparent = true;
                        m.blendfunc1 = GL_SRC_ALPHA;
                        m.blendfunc2 = GL_ONE;
                }
-               else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
+               else if (ent->alpha != 1.0 || skinframe->fog != NULL)
                {
                        m.transparent = true;
                        m.blendfunc1 = GL_SRC_ALPHA;
@@ -281,7 +304,7 @@ void R_DrawQ1Q2AliasModel (float fog)
 
                        aliasvert = m.vertex;
                        aliasvertcolor = m.color;
-                       R_SetupMDLMD2Frames(m.colorscale * (1 - fog), m.colorscale * (1 - fog), m.colorscale * (1 - fog));
+                       R_SetupMDLMD2Frames(ent, m.colorscale * (1 - fog), m.colorscale * (1 - fog), m.colorscale * (1 - fog));
                        aliasvert = aliasvertbuf;
                        aliasvertcolor = aliasvertcolorbuf;
 
@@ -290,16 +313,16 @@ void R_DrawQ1Q2AliasModel (float fog)
                return;
        }
 
-       R_SetupMDLMD2Frames(1 - fog, 1 - fog, 1 - fog);
+       R_SetupMDLMD2Frames(ent, 1 - fog, 1 - fog, 1 - fog);
 
        if (colormapped)
        {
                // 128-224 are backwards ranges
-               c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
+               c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
                bcolor = (qbyte *) (&d_8to24table[c]);
                pantsfullbright = c >= 224;
                VectorScale(bcolor, (1.0f / 255.0f), pantscolor);
-               c = (currentrenderentity->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
+               c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
                bcolor = (qbyte *) (&d_8to24table[c]);
                shirtfullbright = c >= 224;
                VectorScale(bcolor, (1.0f / 255.0f), shirtcolor);
@@ -311,13 +334,13 @@ void R_DrawQ1Q2AliasModel (float fog)
        }
 
        memset(&m, 0, sizeof(m));
-       if (currentrenderentity->effects & EF_ADDITIVE)
+       if (ent->effects & EF_ADDITIVE)
        {
                m.transparent = true;
                m.blendfunc1 = GL_SRC_ALPHA;
                m.blendfunc2 = GL_ONE;
        }
-       else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
+       else if (ent->alpha != 1.0 || skinframe->fog != NULL)
        {
                m.transparent = true;
                m.blendfunc1 = GL_SRC_ALPHA;
@@ -347,7 +370,7 @@ void R_DrawQ1Q2AliasModel (float fog)
                if (skinframe->pants)
                {
                        memset(&m, 0, sizeof(m));
-                       m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+                       m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL;
                        m.blendfunc1 = GL_SRC_ALPHA;
                        m.blendfunc2 = GL_ONE;
                        m.numtriangles = model->numtris;
@@ -357,7 +380,7 @@ void R_DrawQ1Q2AliasModel (float fog)
                        {
                                c_alias_polys += m.numtriangles;
                                if (pantsfullbright)
-                                       R_FillColors(m.color, m.numverts, pantscolor[0] * m.colorscale, pantscolor[1] * m.colorscale, pantscolor[2] * m.colorscale, currentrenderentity->alpha);
+                                       R_FillColors(m.color, m.numverts, pantscolor[0] * m.colorscale, pantscolor[1] * m.colorscale, pantscolor[2] * m.colorscale, ent->alpha);
                                else
                                        R_ModulateColors(aliasvertcolor, m.color, m.numverts, pantscolor[0] * m.colorscale, pantscolor[1] * m.colorscale, pantscolor[2] * m.colorscale);
                                memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3]));
@@ -369,7 +392,7 @@ void R_DrawQ1Q2AliasModel (float fog)
                if (skinframe->shirt)
                {
                        memset(&m, 0, sizeof(m));
-                       m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+                       m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL;
                        m.blendfunc1 = GL_SRC_ALPHA;
                        m.blendfunc2 = GL_ONE;
                        m.numtriangles = model->numtris;
@@ -379,7 +402,7 @@ void R_DrawQ1Q2AliasModel (float fog)
                        {
                                c_alias_polys += m.numtriangles;
                                if (shirtfullbright)
-                                       R_FillColors(m.color, m.numverts, shirtcolor[0] * m.colorscale, shirtcolor[1] * m.colorscale, shirtcolor[2] * m.colorscale, currentrenderentity->alpha);
+                                       R_FillColors(m.color, m.numverts, shirtcolor[0] * m.colorscale, shirtcolor[1] * m.colorscale, shirtcolor[2] * m.colorscale, ent->alpha);
                                else
                                        R_ModulateColors(aliasvertcolor, m.color, m.numverts, shirtcolor[0] * m.colorscale, shirtcolor[1] * m.colorscale, shirtcolor[2] * m.colorscale);
                                memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3]));
@@ -392,7 +415,7 @@ void R_DrawQ1Q2AliasModel (float fog)
        if (skinframe->glow)
        {
                memset(&m, 0, sizeof(m));
-               m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+               m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL;
                m.blendfunc1 = GL_SRC_ALPHA;
                m.blendfunc2 = GL_ONE;
                m.numtriangles = model->numtris;
@@ -401,7 +424,7 @@ void R_DrawQ1Q2AliasModel (float fog)
                if (R_Mesh_Draw_GetBuffer(&m, true))
                {
                        c_alias_polys += m.numtriangles;
-                       R_FillColors(m.color, m.numverts, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, currentrenderentity->alpha);
+                       R_FillColors(m.color, m.numverts, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, (1 - fog) * m.colorscale, ent->alpha);
                        memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3]));
                        memcpy(m.vertex, aliasvert, m.numverts * sizeof(float[4]));
                        memcpy(m.texcoords[0], model->mdlmd2data_texcoords, m.numverts * sizeof(float[2]));
@@ -411,7 +434,7 @@ void R_DrawQ1Q2AliasModel (float fog)
        if (fog)
        {
                memset(&m, 0, sizeof(m));
-               m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+               m.transparent = ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || skinframe->fog != NULL;
                m.blendfunc1 = GL_SRC_ALPHA;
                m.blendfunc2 = GL_ONE;
                m.numtriangles = model->numtris;
@@ -420,7 +443,7 @@ void R_DrawQ1Q2AliasModel (float fog)
                if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                        c_alias_polys += m.numtriangles;
-                       R_FillColors(m.color, m.numverts, fog * m.colorscale, fog * m.colorscale, fog * m.colorscale, currentrenderentity->alpha);
+                       R_FillColors(m.color, m.numverts, fog * m.colorscale, fog * m.colorscale, fog * m.colorscale, ent->alpha);
                        memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3]));
                        memcpy(m.vertex, aliasvert, m.numverts * sizeof(float[4]));
                        memcpy(m.texcoords[0], model->mdlmd2data_texcoords, m.numverts * sizeof(float[2]));
@@ -689,126 +712,136 @@ void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
        }
 }
 
-void R_DrawZymoticModelMesh(zymtype1header_t *m, float fog)
+void R_DrawZymoticModelMeshCallback (void *calldata1, int calldata2)
 {
-       rmeshbufferinfo_t mbuf;
+       float fog;
+       vec3_t diff;
        int i, *renderlist;
-       rtexture_t **texture;
+       zymtype1header_t *m;
+       rtexture_t *texture;
+       rmeshbufferinfo_t mbuf;
+       entity_render_t *ent;
+       int shadernum;
 
-       texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
+       ent = calldata1;
+       shadernum = calldata2;
 
+       // find the vertex index list and texture
+       m = ent->model->zymdata_header;
        renderlist = (int *)(m->lump_render.start + (int) m);
-       for (i = 0;i < m->numshaders;i++)
+       for (i = 0;i < shadernum;i++)
+               renderlist += renderlist[0] * 3 + 1;
+       texture = ((rtexture_t **)(m->lump_shaders.start + (int) m))[shadernum];
+
+       fog = 0;
+       if (fogenabled)
+       {
+               VectorSubtract(ent->origin, r_origin, diff);
+               fog = DotProduct(diff,diff);
+               if (fog < 0.01f)
+                       fog = 0.01f;
+               fog = exp(fogdensity/fog);
+               if (fog > 1)
+                       fog = 1;
+               if (fog < 0.01f)
+                       fog = 0;
+               // fog method: darken, additive fog
+               // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
+               // 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);
+
+       memset(&mbuf, 0, sizeof(mbuf));
+       mbuf.numverts = m->numverts;
+       mbuf.numtriangles = renderlist[0];
+       mbuf.transparent = false;
+       if (ent->effects & EF_ADDITIVE)
+       {
+               mbuf.blendfunc1 = GL_SRC_ALPHA;
+               mbuf.blendfunc2 = GL_ONE;
+       }
+       else if (ent->alpha != 1.0 || R_TextureHasAlpha(texture))
+       {
+               mbuf.blendfunc1 = GL_SRC_ALPHA;
+               mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       }
+       else
+       {
+               mbuf.blendfunc1 = GL_ONE;
+               mbuf.blendfunc2 = GL_ZERO;
+       }
+       mbuf.tex[0] = R_GetTexture(texture);
+       if (R_Mesh_Draw_GetBuffer(&mbuf, true))
+       {
+               c_alias_polys += mbuf.numtriangles;
+               memcpy(mbuf.index, renderlist + 1, mbuf.numtriangles * sizeof(int[3]));
+               memcpy(mbuf.vertex, aliasvert, mbuf.numverts * sizeof(float[4]));
+               R_ModulateColors(aliasvertcolor, mbuf.color, mbuf.numverts, mbuf.colorscale, mbuf.colorscale, mbuf.colorscale);
+               //memcpy(mbuf.color, aliasvertcolor, mbuf.numverts * sizeof(float[4]));
+               memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2]));
+               R_Mesh_Render();
+       }
+
+       if (fog)
        {
                memset(&mbuf, 0, sizeof(mbuf));
                mbuf.numverts = m->numverts;
-               mbuf.numtriangles = *renderlist++;
-               if (currentrenderentity->effects & EF_ADDITIVE)
-               {
-                       mbuf.transparent = true;
-                       mbuf.blendfunc1 = GL_SRC_ALPHA;
-                       mbuf.blendfunc2 = GL_ONE;
-               }
-               else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i]))
-               {
-                       mbuf.transparent = true;
-                       mbuf.blendfunc1 = GL_SRC_ALPHA;
-                       mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-               }
-               else
-               {
-                       mbuf.transparent = false;
-                       mbuf.blendfunc1 = GL_ONE;
-                       mbuf.blendfunc2 = GL_ZERO;
-               }
-               mbuf.tex[0] = R_GetTexture(texture[i]);
-               if (R_Mesh_Draw_GetBuffer(&mbuf, true))
+               mbuf.numtriangles = renderlist[0];
+               mbuf.transparent = false;
+               mbuf.blendfunc1 = GL_SRC_ALPHA;
+               mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+               // FIXME: need alpha mask for fogging...
+               //mbuf.tex[0] = R_GetTexture(texture);
+               if (R_Mesh_Draw_GetBuffer(&mbuf, false))
                {
                        c_alias_polys += mbuf.numtriangles;
-                       memcpy(mbuf.index, renderlist, mbuf.numtriangles * sizeof(int[3]));
+                       memcpy(mbuf.index, renderlist + 1, mbuf.numtriangles * sizeof(int[3]));
                        memcpy(mbuf.vertex, aliasvert, mbuf.numverts * sizeof(float[4]));
-                       R_ModulateColors(aliasvertcolor, mbuf.color, mbuf.numverts, mbuf.colorscale, mbuf.colorscale, mbuf.colorscale);
-                       //memcpy(mbuf.color, aliasvertcolor, mbuf.numverts * sizeof(float[4]));
-                       memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2]));
+                       R_FillColors(mbuf.color, mbuf.numverts, fogcolor[0] * mbuf.colorscale, fogcolor[1] * mbuf.colorscale, fogcolor[2] * mbuf.colorscale, ent->alpha * fog);
+                       //memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2]));
                        R_Mesh_Render();
                }
-               renderlist += mbuf.numtriangles * 3;
-       }
-
-       if (fog)
-       {
-               renderlist = (int *)(m->lump_render.start + (int) m);
-               for (i = 0;i < m->numshaders;i++)
-               {
-                       memset(&mbuf, 0, sizeof(mbuf));
-                       mbuf.numverts = m->numverts;
-                       mbuf.numtriangles = *renderlist++;
-                       mbuf.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i]);
-                       mbuf.blendfunc1 = GL_SRC_ALPHA;
-                       mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-                       // FIXME: need alpha mask for fogging...
-                       //mbuf.tex[0] = R_GetTexture(texture[i]);
-                       if (R_Mesh_Draw_GetBuffer(&mbuf, false))
-                       {
-                               c_alias_polys += mbuf.numtriangles;
-                               memcpy(mbuf.index, renderlist, mbuf.numtriangles * sizeof(int[3]));
-                               memcpy(mbuf.vertex, aliasvert, mbuf.numverts * sizeof(float[4]));
-                               R_FillColors(mbuf.color, mbuf.numverts, fogcolor[0] * mbuf.colorscale, fogcolor[1] * mbuf.colorscale, fogcolor[2] * mbuf.colorscale, currentrenderentity->alpha * fog);
-                               //memcpy(mbuf.texcoords[0], (float *)(m->lump_texcoords.start + (int) m), mbuf.numverts * sizeof(float[2]));
-                               R_Mesh_Render();
-                       }
-                       renderlist += mbuf.numtriangles * 3;
-               }
        }
 }
 
-void R_DrawZymoticModel (float fog)
+void R_DrawZymoticModel (entity_render_t *ent)
 {
+       int i;
        zymtype1header_t *m;
+       rtexture_t *texture;
 
-       // FIXME: do better fog
-       m = currentrenderentity->model->zymdata_header;
-       ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), currentrenderentity->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));
+       if (ent->alpha < (1.0f / 64.0f))
+               return; // basically completely transparent
 
-       R_LightModel(m->numverts, 1 - fog, 1 - fog, 1 - fog, true);
+       c_models++;
 
-       R_DrawZymoticModelMesh(m, fog);
+       m = ent->model->zymdata_header;
+       for (i = 0;i < m->numshaders;i++)
+       {
+               texture = ((rtexture_t **)(m->lump_shaders.start + (int) m))[i];
+               if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_TextureHasAlpha(texture))
+                       R_MeshQueue_AddTransparent(ent->origin, R_DrawZymoticModelMeshCallback, ent, i);
+               else
+                       R_MeshQueue_Add(R_DrawZymoticModelMeshCallback, ent, i);
+       }
 }
 
-void R_DrawAliasModel (void)
+void R_DrawQ1Q2AliasModel(entity_render_t *ent)
 {
-       float fog;
-       vec3_t diff;
-
-       if (currentrenderentity->alpha < (1.0f / 64.0f))
+       if (ent->alpha < (1.0f / 64.0f))
                return; // basically completely transparent
 
        c_models++;
 
-       softwaretransformforentity(currentrenderentity);
-
-       fog = 0;
-       if (fogenabled)
-       {
-               VectorSubtract(currentrenderentity->origin, r_origin, diff);
-               fog = DotProduct(diff,diff);
-               if (fog < 0.01f)
-                       fog = 0.01f;
-               fog = exp(fogdensity/fog);
-               if (fog > 1)
-                       fog = 1;
-               if (fog < 0.01f)
-                       fog = 0;
-               // fog method: darken, additive fog
-               // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
-               // 2. render fog as additive
-       }
-
-       if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM)
-               R_DrawZymoticModel(fog);
+       if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_FetchSkinFrame(ent)->fog != NULL)
+               R_MeshQueue_AddTransparent(ent->origin, R_DrawQ1Q2AliasModelCallback, ent, 0);
        else
-               R_DrawQ1Q2AliasModel(fog);
+               R_MeshQueue_Add(R_DrawQ1Q2AliasModelCallback, ent, 0);
 }
 
index 7640985..6be6b3d 100644 (file)
@@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
-entity_render_t *currentrenderentity;
-
 // used for dlight push checking and other things
 int r_framecount;
 
@@ -351,6 +349,7 @@ void Render_Init(void)
        R_Textures_Init();
        Mod_RenderInit();
        gl_backend_init();
+       R_MeshQueue_Init();
        GL_Draw_Init();
        GL_Main_Init();
        GL_Models_Init();
@@ -388,6 +387,7 @@ static void R_MarkEntities (void)
 {
        int i;
        vec3_t v;
+       entity_render_t *ent;
 
        R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
 
@@ -396,45 +396,45 @@ static void R_MarkEntities (void)
 
        for (i = 0;i < r_refdef.numentities;i++)
        {
-               currentrenderentity = r_refdef.entities[i];
-               Mod_CheckLoaded(currentrenderentity->model);
+               ent = r_refdef.entities[i];
+               Mod_CheckLoaded(ent->model);
 
                // move view-relative models to where they should be
-               if (currentrenderentity->flags & RENDER_VIEWMODEL)
+               if (ent->flags & RENDER_VIEWMODEL)
                {
                        // remove flag so it will not be repeated incase RelinkEntities is not called again for a while
-                       currentrenderentity->flags -= RENDER_VIEWMODEL;
+                       ent->flags -= RENDER_VIEWMODEL;
                        // transform origin
-                       VectorCopy(currentrenderentity->origin, v);
-                       currentrenderentity->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0];
-                       currentrenderentity->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1];
-                       currentrenderentity->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2];
+                       VectorCopy(ent->origin, v);
+                       ent->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0];
+                       ent->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1];
+                       ent->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2];
                        // adjust angles
-                       VectorAdd(currentrenderentity->angles, r_refdef.viewangles, currentrenderentity->angles);
+                       VectorAdd(ent->angles, r_refdef.viewangles, ent->angles);
                }
 
-               if (currentrenderentity->angles[0] || currentrenderentity->angles[2])
+               if (ent->angles[0] || ent->angles[2])
                {
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmins, currentrenderentity->mins);
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmaxs, currentrenderentity->maxs);
+                       VectorMA(ent->origin, ent->scale, ent->model->rotatedmins, ent->mins);
+                       VectorMA(ent->origin, ent->scale, ent->model->rotatedmaxs, ent->maxs);
                }
-               else if (currentrenderentity->angles[1])
+               else if (ent->angles[1])
                {
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmins, currentrenderentity->mins);
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmaxs, currentrenderentity->maxs);
+                       VectorMA(ent->origin, ent->scale, ent->model->yawmins, ent->mins);
+                       VectorMA(ent->origin, ent->scale, ent->model->yawmaxs, ent->maxs);
                }
                else
                {
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmins, currentrenderentity->mins);
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmaxs, currentrenderentity->maxs);
+                       VectorMA(ent->origin, ent->scale, ent->model->normalmins, ent->mins);
+                       VectorMA(ent->origin, ent->scale, ent->model->normalmaxs, ent->maxs);
                }
-               if (R_VisibleCullBox(currentrenderentity->mins, currentrenderentity->maxs))
+               if (R_VisibleCullBox(ent->mins, ent->maxs))
                        continue;
 
-               R_LerpAnimation(currentrenderentity);
-               currentrenderentity->visframe = r_framecount;
+               R_LerpAnimation(ent);
+               ent->visframe = r_framecount;
 
-               R_FarClip_Box(currentrenderentity->mins, currentrenderentity->maxs);
+               R_FarClip_Box(ent->mins, ent->maxs);
        }
 }
 
@@ -442,6 +442,7 @@ static void R_MarkEntities (void)
 int R_DrawBModelSky (void)
 {
        int i, sky;
+       entity_render_t *ent;
 
        if (!r_drawentities.integer)
                return false;
@@ -449,10 +450,10 @@ int R_DrawBModelSky (void)
        sky = false;
        for (i = 0;i < r_refdef.numentities;i++)
        {
-               currentrenderentity = r_refdef.entities[i];
-               if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->DrawSky)
+               ent = r_refdef.entities[i];
+               if (ent->visframe == r_framecount && ent->model->DrawSky)
                {
-                       currentrenderentity->model->DrawSky();
+                       ent->model->DrawSky(ent);
                        sky = true;
                }
        }
@@ -462,15 +463,16 @@ int R_DrawBModelSky (void)
 void R_DrawModels (void)
 {
        int i;
+       entity_render_t *ent;
 
        if (!r_drawentities.integer)
                return;
 
        for (i = 0;i < r_refdef.numentities;i++)
        {
-               currentrenderentity = r_refdef.entities[i];
-               if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->Draw)
-                       currentrenderentity->model->Draw();
+               ent = r_refdef.entities[i];
+               if (ent->visframe == r_framecount && ent->model->Draw)
+                       ent->model->Draw(ent);
        }
 }
 
@@ -481,16 +483,18 @@ R_DrawViewModel
 */
 void R_DrawViewModel (void)
 {
+       entity_render_t *ent;
+
        // FIXME: move these checks to client
        if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model)
                return;
 
-       currentrenderentity = &cl.viewent.render;
-       Mod_CheckLoaded(currentrenderentity->model);
+       ent = &cl.viewent.render;
+       Mod_CheckLoaded(ent->model);
 
-       R_LerpAnimation(currentrenderentity);
+       R_LerpAnimation(ent);
 
-       currentrenderentity->model->Draw();
+       ent->model->Draw(ent);
 }
 
 static void R_SetFrustum (void)
@@ -596,6 +600,7 @@ r_refdef must be set before the first call
 */
 void R_RenderView (void)
 {
+       entity_render_t *world = &cl_entities[0].render;
        if (!cl.worldmodel)
                return; //Host_Error ("R_RenderView: NULL worldmodel");
 
@@ -609,23 +614,26 @@ void R_RenderView (void)
        R_SkyStartFrame();
        R_BuildLightList();
 
+       R_MeshQueue_BeginScene();
+
        R_FarClip_Start(r_origin, vpn, 768.0f);
 
        R_TimeReport("setup");
 
-       R_DrawWorld();
+       R_DrawWorld(world);
        R_TimeReport("worldnode");
 
        R_MarkEntities();
        R_TimeReport("markentity");
 
-       R_MarkWorldLights();
+       R_MarkWorldLights(world);
        R_TimeReport("marklights");
 
        r_farclip = R_FarClip_Finish() + 256.0f;
 
        R_Mesh_Start(r_farclip);
 
+
        if (skyrendermasked)
        {
                if (R_DrawBModelSky())
@@ -637,17 +645,17 @@ void R_RenderView (void)
                R_TimeReport("viewmodel");
        }
 
-       R_SetupForWorldRendering();
-       R_PrepareSurfaces();
+       R_SetupForWorldRendering(world);
+       R_PrepareSurfaces(world);
        R_TimeReport("surfprep");
 
-       R_DrawSurfaces(SHADERSTAGE_SKY);
-       R_DrawSurfaces(SHADERSTAGE_NORMAL);
+       R_DrawSurfaces(world, SHADERSTAGE_SKY);
+       R_DrawSurfaces(world, SHADERSTAGE_NORMAL);
        R_TimeReport("surfdraw");
 
        if (r_drawportals.integer)
        {
-               R_DrawPortals();
+               R_DrawPortals(world);
                R_TimeReport("portals");
        }
 
@@ -670,6 +678,8 @@ void R_RenderView (void)
        R_DrawExplosions();
        R_TimeReport("explosions");
 
+       R_MeshQueue_EndScene();
+
        // draw transparent meshs
        R_Mesh_AddTransparent();
        R_TimeReport("addtrans");
@@ -677,13 +687,12 @@ void R_RenderView (void)
        R_DrawCoronas();
        R_TimeReport("coronas");
 
-       R_BlendView();
-       R_TimeReport("blendview");
-
        R_DrawCrosshair();
        R_TimeReport("crosshair");
 
-       // render any queued meshs
+       R_BlendView();
+       R_TimeReport("blendview");
+
        R_Mesh_Finish();
        R_TimeReport("meshfinish");
 }
index c9ce94c..c0dbab4 100644 (file)
@@ -236,7 +236,7 @@ R_BuildLightMap
 Combine and scale multiple lightmaps into the 8.8 format in blocklights
 ===============
 */
-static void R_BuildLightMap (msurface_t *surf, int dlightchanged)
+static void R_BuildLightMap (entity_render_t *ent, msurface_t *surf, int dlightchanged)
 {
        if (!r_floatbuildlightmap.integer)
        {
@@ -261,7 +261,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged)
 
        // set to full bright if no light data
                bl = intblocklights;
-               if ((currentrenderentity->effects & EF_FULLBRIGHT) || !currentrenderentity->model->lightdata)
+               if ((ent->effects & EF_FULLBRIGHT) || !ent->model->lightdata)
                {
                        for (i = 0;i < size3;i++)
                                bl[i] = 255*256;
@@ -302,7 +302,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged)
                out = templight;
                // deal with lightmap brightness scale
                shift = 7 + lightscalebit + 8;
-               if (currentrenderentity->model->lightmaprgba)
+               if (ent->model->lightmaprgba)
                {
                        stride = (surf->lightmaptexturestride - smax) * 4;
                        for (i = 0;i < tmax;i++, out += stride)
@@ -355,7 +355,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged)
 
        // set to full bright if no light data
                bl = floatblocklights;
-               if ((currentrenderentity->effects & EF_FULLBRIGHT) || !currentrenderentity->model->lightdata)
+               if ((ent->effects & EF_FULLBRIGHT) || !ent->model->lightdata)
                        j = 255*256;
                else
                        j = r_ambient.value * 512.0f; // would be 128.0f logically, but using 512.0f to match winquake style
@@ -392,7 +392,7 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged)
                out = templight;
                // deal with lightmap brightness scale
                scale = 1.0f / (1 << (7 + lightscalebit + 8));
-               if (currentrenderentity->model->lightmaprgba)
+               if (ent->model->lightmaprgba)
                {
                        stride = (surf->lightmaptexturestride - smax) * 4;
                        for (i = 0;i < tmax;i++, out += stride)
@@ -617,7 +617,7 @@ void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, i
 =============================================================
 */
 
-static void RSurfShader_Sky(msurface_t *firstsurf)
+static void RSurfShader_Sky(entity_render_t *ent, msurface_t *firstsurf)
 {
        msurface_t *surf;
        int i;
@@ -628,7 +628,7 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
        float *outv, *outc;
 
        // LordHavoc: HalfLife maps have freaky skypolys...
-       if (currentrenderentity->model->ishlbsp)
+       if (ent->model->ishlbsp)
                return;
 
        if (skyrendernow)
@@ -732,7 +732,7 @@ static int RSurf_LightCheck(int *dlightbits, surfmesh_t *mesh)
        return false;
 }
 
-static void RSurfShader_Water_Pass_Base(msurface_t *surf)
+static void RSurfShader_Water_Pass_Base(entity_render_t *ent, msurface_t *surf)
 {
        int i, size3;
        surfvertex_t *v;
@@ -741,9 +741,9 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf)
        qbyte *lm;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
-       float alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
+       float alpha = ent->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
        memset(&m, 0, sizeof(m));
-       if (currentrenderentity->effects & EF_ADDITIVE)
+       if (ent->effects & EF_ADDITIVE)
        {
                m.transparent = true;
                m.blendfunc1 = GL_SRC_ALPHA;
@@ -764,7 +764,7 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf)
        m.depthwrite = false;
        m.depthdisable = false;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       if (surf->flags & SURF_DRAWFULLBRIGHT || currentrenderentity->effects & EF_FULLBRIGHT)
+       if (surf->flags & SURF_DRAWFULLBRIGHT || ent->effects & EF_FULLBRIGHT)
        {
                for (mesh = surf->mesh;mesh;mesh = mesh->chain)
                {
@@ -858,7 +858,7 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf)
        }
 }
 
-static void RSurfShader_Water_Pass_Fog(msurface_t *surf)
+static void RSurfShader_Water_Pass_Fog(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -866,9 +866,9 @@ static void RSurfShader_Water_Pass_Fog(msurface_t *surf)
        float base[3], f;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
-       float alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
+       float alpha = ent->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
        memset(&m, 0, sizeof(m));
-       m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || alpha < 1;
+       m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || alpha < 1;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
        m.depthwrite = false;
@@ -904,17 +904,17 @@ static void RSurfShader_Water_Pass_Fog(msurface_t *surf)
        }
 }
 
-static void RSurfShader_Water(msurface_t *firstsurf)
+static void RSurfShader_Water(entity_render_t *ent, msurface_t *firstsurf)
 {
        msurface_t *surf;
        for (surf = firstsurf;surf;surf = surf->chain)
-               RSurfShader_Water_Pass_Base(surf);
+               RSurfShader_Water_Pass_Base(ent, surf);
        if (fogenabled)
                for (surf = firstsurf;surf;surf = surf->chain)
-                       RSurfShader_Water_Pass_Fog(surf);
+                       RSurfShader_Water_Pass_Fog(ent, surf);
 }
 
-static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseVertex(entity_render_t *ent, msurface_t *surf)
 {
        int i, size3;
        surfvertex_t *v;
@@ -924,13 +924,13 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       if (currentrenderentity->effects & EF_ADDITIVE)
+       if (ent->effects & EF_ADDITIVE)
        {
                m.transparent = true;
                m.blendfunc1 = GL_SRC_ALPHA;
                m.blendfunc2 = GL_ONE;
        }
-       else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)
+       else if (surf->currenttexture->fogtexture != NULL || ent->alpha != 1)
        {
                m.transparent = true;
                m.blendfunc1 = GL_SRC_ALPHA;
@@ -948,9 +948,9 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
 
        size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3;
 
-       base[0] = base[1] = base[2] = currentrenderentity->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
+       base[0] = base[1] = base[2] = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
 
-       ca = currentrenderentity->alpha;
+       ca = ent->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
@@ -961,7 +961,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
                        cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
 
-                       if (currentrenderentity->effects & EF_FULLBRIGHT)
+                       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)
                                {
@@ -1030,7 +1030,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
        }
 }
 
-static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseFullbright(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1038,13 +1038,13 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       if (currentrenderentity->effects & EF_ADDITIVE)
+       if (ent->effects & EF_ADDITIVE)
        {
                m.transparent = true;
                m.blendfunc1 = GL_SRC_ALPHA;
                m.blendfunc2 = GL_ONE;
        }
-       else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)
+       else if (surf->currenttexture->fogtexture != NULL || ent->alpha != 1)
        {
                m.transparent = true;
                m.blendfunc1 = GL_SRC_ALPHA;
@@ -1059,7 +1059,7 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
        m.depthwrite = false;
        m.depthdisable = false;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       ca = currentrenderentity->alpha;
+       ca = ent->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
@@ -1089,7 +1089,7 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
        }
 }
 
-static void RSurfShader_Wall_Pass_Glow(msurface_t *surf)
+static void RSurfShader_Wall_Pass_Glow(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1097,11 +1097,11 @@ static void RSurfShader_Wall_Pass_Glow(msurface_t *surf)
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1;
+       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 = currentrenderentity->alpha;
+       ca = ent->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
@@ -1131,7 +1131,7 @@ static void RSurfShader_Wall_Pass_Glow(msurface_t *surf)
        }
 }
 
-static void RSurfShader_Wall_Pass_Fog(msurface_t *surf)
+static void RSurfShader_Wall_Pass_Fog(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1139,10 +1139,10 @@ static void RSurfShader_Wall_Pass_Fog(msurface_t *surf)
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1;
+       m.transparent = ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || ent->alpha != 1;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       ca = currentrenderentity->alpha;
+       ca = ent->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
@@ -1168,7 +1168,7 @@ static void RSurfShader_Wall_Pass_Fog(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1214,7 +1214,7 @@ static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseMTex(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseMTex(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1254,7 +1254,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseMTex(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseTexture(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseTexture(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1291,7 +1291,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseTexture(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseLightmap(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseLightmap(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1328,7 +1328,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseLightmap(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_Light(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Light(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1338,7 +1338,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(msurface_t *surf)
 
        if (surf->dlightframe != r_framecount)
                return;
-       if (currentrenderentity->effects & EF_FULLBRIGHT)
+       if (ent->effects & EF_FULLBRIGHT)
                return;
 
        memset(&m, 0, sizeof(m));
@@ -1378,7 +1378,7 @@ static void RSurfShader_OpaqueWall_Pass_Light(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_Fog(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Fog(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1412,7 +1412,7 @@ static void RSurfShader_OpaqueWall_Pass_Fog(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_BaseDetail(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseDetail(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1447,7 +1447,7 @@ static void RSurfShader_OpaqueWall_Pass_BaseDetail(msurface_t *surf)
        }
 }
 
-static void RSurfShader_OpaqueWall_Pass_Glow(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Glow(entity_render_t *ent, msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
@@ -1482,54 +1482,54 @@ static void RSurfShader_OpaqueWall_Pass_Glow(msurface_t *surf)
        }
 }
 
-static void RSurfShader_Wall_Fullbright(msurface_t *firstsurf)
+static void RSurfShader_Wall_Fullbright(entity_render_t *ent, msurface_t *firstsurf)
 {
        msurface_t *surf;
        for (surf = firstsurf;surf;surf = surf->chain)
        {
                c_brush_polys++;
-               RSurfShader_Wall_Pass_BaseFullbright(surf);
+               RSurfShader_Wall_Pass_BaseFullbright(ent, surf);
        }
        for (surf = firstsurf;surf;surf = surf->chain)
                if (surf->currenttexture->glowtexture)
-                       RSurfShader_Wall_Pass_Glow(surf);
+                       RSurfShader_Wall_Pass_Glow(ent, surf);
        if (fogenabled)
                for (surf = firstsurf;surf;surf = surf->chain)
-                       RSurfShader_Wall_Pass_Fog(surf);
+                       RSurfShader_Wall_Pass_Fog(ent, surf);
 }
 
-static void RSurfShader_Wall_Vertex(msurface_t *firstsurf)
+static void RSurfShader_Wall_Vertex(entity_render_t *ent, msurface_t *firstsurf)
 {
        msurface_t *surf;
        for (surf = firstsurf;surf;surf = surf->chain)
        {
                c_brush_polys++;
-               RSurfShader_Wall_Pass_BaseVertex(surf);
+               RSurfShader_Wall_Pass_BaseVertex(ent, surf);
        }
        for (surf = firstsurf;surf;surf = surf->chain)
                if (surf->currenttexture->glowtexture)
-                       RSurfShader_Wall_Pass_Glow(surf);
+                       RSurfShader_Wall_Pass_Glow(ent, surf);
        if (fogenabled)
                for (surf = firstsurf;surf;surf = surf->chain)
-                       RSurfShader_Wall_Pass_Fog(surf);
+                       RSurfShader_Wall_Pass_Fog(ent, surf);
 }
 
-static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf)
+static void RSurfShader_Wall_Lightmap(entity_render_t *ent, msurface_t *firstsurf)
 {
        msurface_t *surf;
-       if (r_vertexsurfaces.integer || firstsurf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1 || currentrenderentity->effects & EF_ADDITIVE)
+       if (r_vertexsurfaces.integer || firstsurf->currenttexture->fogtexture != NULL || ent->alpha != 1 || ent->effects & EF_ADDITIVE)
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
                        c_brush_polys++;
-                       RSurfShader_Wall_Pass_BaseVertex(surf);
+                       RSurfShader_Wall_Pass_BaseVertex(ent, surf);
                }
                for (surf = firstsurf;surf;surf = surf->chain)
                        if (surf->currenttexture->glowtexture)
-                               RSurfShader_Wall_Pass_Glow(surf);
+                               RSurfShader_Wall_Pass_Glow(ent, surf);
                if (fogenabled)
                        for (surf = firstsurf;surf;surf = surf->chain)
-                               RSurfShader_Wall_Pass_Fog(surf);
+                               RSurfShader_Wall_Pass_Fog(ent, surf);
        }
        else
        {
@@ -1540,7 +1540,7 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf)
                                for (surf = firstsurf;surf;surf = surf->chain)
                                {
                                        c_brush_polys++;
-                                       RSurfShader_OpaqueWall_Pass_TripleTexCombine(surf);
+                                       RSurfShader_OpaqueWall_Pass_TripleTexCombine(ent, surf);
                                }
                        }
                        else
@@ -1548,11 +1548,11 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf)
                                for (surf = firstsurf;surf;surf = surf->chain)
                                {
                                        c_brush_polys++;
-                                       RSurfShader_OpaqueWall_Pass_BaseMTex(surf);
+                                       RSurfShader_OpaqueWall_Pass_BaseMTex(ent, surf);
                                }
                                if (r_detailtextures.integer)
                                        for (surf = firstsurf;surf;surf = surf->chain)
-                                               RSurfShader_OpaqueWall_Pass_BaseDetail(surf);
+                                               RSurfShader_OpaqueWall_Pass_BaseDetail(ent, surf);
                        }
                }
                else
@@ -1560,24 +1560,24 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf)
                        for (surf = firstsurf;surf;surf = surf->chain)
                        {
                                c_brush_polys++;
-                               RSurfShader_OpaqueWall_Pass_BaseTexture(surf);
+                               RSurfShader_OpaqueWall_Pass_BaseTexture(ent, surf);
                        }
                        for (surf = firstsurf;surf;surf = surf->chain)
-                               RSurfShader_OpaqueWall_Pass_BaseLightmap(surf);
+                               RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, surf);
                        if (r_detailtextures.integer)
                                for (surf = firstsurf;surf;surf = surf->chain)
-                                       RSurfShader_OpaqueWall_Pass_BaseDetail(surf);
+                                       RSurfShader_OpaqueWall_Pass_BaseDetail(ent, surf);
                }
                if (!r_dlightmap.integer)
                        for (surf = firstsurf;surf;surf = surf->chain)
                                if (surf->dlightframe == r_framecount)
-                                       RSurfShader_OpaqueWall_Pass_Light(surf);
+                                       RSurfShader_OpaqueWall_Pass_Light(ent, surf);
                for (surf = firstsurf;surf;surf = surf->chain)
                        if (surf->currenttexture->glowtexture)
-                               RSurfShader_OpaqueWall_Pass_Glow(surf);
+                               RSurfShader_OpaqueWall_Pass_Glow(ent, surf);
                if (fogenabled)
                        for (surf = firstsurf;surf;surf = surf->chain)
-                               RSurfShader_OpaqueWall_Pass_Fog(surf);
+                               RSurfShader_OpaqueWall_Pass_Fog(ent, surf);
        }
 }
 
@@ -1589,7 +1589,7 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf)
 =============================================================
 */
 
-static void R_SolidWorldNode (void)
+static void R_SolidWorldNode (entity_render_t *ent)
 {
        if (r_viewleaf->contents != CONTENTS_SOLID)
        {
@@ -1829,7 +1829,7 @@ Cshader_t *Cshaders[5] =
        &Cshader_sky
 };
 
-void R_PrepareSurfaces(void)
+void R_PrepareSurfaces(entity_render_t *ent)
 {
        int i, alttextures, texframe, framecount;
        texture_t *t;
@@ -1839,8 +1839,8 @@ void R_PrepareSurfaces(void)
        for (i = 0;i < Cshader_count;i++)
                Cshaders[i]->chain = NULL;
 
-       model = currentrenderentity->model;
-       alttextures = currentrenderentity->frame != 0;
+       model = ent->model;
+       alttextures = ent->frame != 0;
        texframe = (int)(cl.time * 5.0f);
 
        for (i = 0;i < model->nummodelsurfaces;i++)
@@ -1871,7 +1871,7 @@ void R_PrepareSurfaces(void)
        }
 }
 
-void R_DrawSurfaces (int type)
+void R_DrawSurfaces (entity_render_t *ent, int type)
 {
        int                     i;
        Cshader_t       *shader;
@@ -1880,11 +1880,11 @@ void R_DrawSurfaces (int type)
        {
                shader = Cshaders[i];
                if (shader->chain && shader->shaderfunc[type])
-                       shader->shaderfunc[type](shader->chain);
+                       shader->shaderfunc[type](ent, shader->chain);
        }
 }
 
-void R_DrawPortals(void)
+void R_DrawPortals(entity_render_t *ent)
 {
        int drawportals, i;
        float *v;
@@ -1933,7 +1933,7 @@ void R_DrawPortals(void)
        }
 }
 
-void R_SetupForBModelRendering(void)
+void R_SetupForBModelRendering(entity_render_t *ent)
 {
        int                     i;
        msurface_t      *surf;
@@ -1943,9 +1943,9 @@ void R_SetupForBModelRendering(void)
        // because bmodels can be reused, we have to decide which things to render
        // from scratch every time
 
-       model = currentrenderentity->model;
+       model = ent->model;
 
-       softwaretransformforentity (currentrenderentity);
+       softwaretransformforentity (ent);
        softwareuntransform(r_origin, modelorg);
 
        for (i = 0;i < model->nummodelsurfaces;i++)
@@ -1962,53 +1962,51 @@ void R_SetupForBModelRendering(void)
        }
 }
 
-void R_SetupForWorldRendering(void)
+void R_SetupForWorldRendering(entity_render_t *ent)
 {
        // there is only one instance of the world, but it can be rendered in
        // multiple stages
-
-       currentrenderentity = &cl_entities[0].render;
        softwaretransformidentity();
 }
 
-static void R_SurfMarkLights (void)
+static void R_SurfMarkLights (entity_render_t *ent)
 {
        int                     i;
        msurface_t      *surf;
 
        if (r_dynamic.integer)
-               R_MarkLights();
+               R_MarkLights(ent);
 
        if (!r_vertexsurfaces.integer)
        {
-               for (i = 0;i < currentrenderentity->model->nummodelsurfaces;i++)
+               for (i = 0;i < ent->model->nummodelsurfaces;i++)
                {
-                       surf = currentrenderentity->model->modelsortedsurfaces[i];
+                       surf = ent->model->modelsortedsurfaces[i];
                        if (surf->visframe == r_framecount && surf->lightmaptexture != NULL)
                        {
                                if (surf->cached_dlight
                                 || surf->cached_ambient != r_ambient.value
                                 || surf->cached_lightscalebit != lightscalebit)
-                                       R_BuildLightMap(surf, false); // base lighting changed
+                                       R_BuildLightMap(ent, surf, false); // base lighting changed
                                else if (r_dynamic.integer)
                                {
                                        if  (surf->styles[0] != 255 && (d_lightstylevalue[surf->styles[0]] != surf->cached_light[0]
                                         || (surf->styles[1] != 255 && (d_lightstylevalue[surf->styles[1]] != surf->cached_light[1]
                                         || (surf->styles[2] != 255 && (d_lightstylevalue[surf->styles[2]] != surf->cached_light[2]
                                         || (surf->styles[3] != 255 && (d_lightstylevalue[surf->styles[3]] != surf->cached_light[3]))))))))
-                                               R_BuildLightMap(surf, false); // base lighting changed
+                                               R_BuildLightMap(ent, surf, false); // base lighting changed
                                        else if (surf->dlightframe == r_framecount && r_dlightmap.integer)
-                                               R_BuildLightMap(surf, true); // only dlights
+                                               R_BuildLightMap(ent, surf, true); // only dlights
                                }
                        }
                }
        }
 }
 
-void R_MarkWorldLights(void)
+void R_MarkWorldLights(entity_render_t *ent)
 {
-       R_SetupForWorldRendering();
-       R_SurfMarkLights();
+       R_SetupForWorldRendering(ent);
+       R_SurfMarkLights(ent);
 }
 
 /*
@@ -2016,14 +2014,14 @@ void R_MarkWorldLights(void)
 R_DrawWorld
 =============
 */
-void R_DrawWorld (void)
+void R_DrawWorld (entity_render_t *ent)
 {
-       R_SetupForWorldRendering();
+       R_SetupForWorldRendering(ent);
 
        if (r_viewleaf->contents == CONTENTS_SOLID || r_novis.integer || r_viewleaf->compressed_vis == NULL)
-               R_SolidWorldNode ();
+               R_SolidWorldNode (ent);
        else
-               R_PVSWorldNode ();
+               R_PVSWorldNode (ent);
 }
 
 /*
@@ -2031,30 +2029,30 @@ void R_DrawWorld (void)
 R_DrawBrushModel
 =================
 */
-void R_DrawBrushModelSky (void)
+void R_DrawBrushModelSky (entity_render_t *ent)
 {
-       R_SetupForBModelRendering();
+       R_SetupForBModelRendering(ent);
 
-       R_PrepareSurfaces();
-       R_DrawSurfaces(SHADERSTAGE_SKY);
+       R_PrepareSurfaces(ent);
+       R_DrawSurfaces(ent, SHADERSTAGE_SKY);
 }
 
-void R_DrawBrushModelNormal (void)
+void R_DrawBrushModelNormal (entity_render_t *ent)
 {
        c_bmodels++;
 
        // have to flush queue because of possible lightmap reuse
        R_Mesh_Render();
 
-       R_SetupForBModelRendering();
+       R_SetupForBModelRendering(ent);
 
-       R_SurfMarkLights();
+       R_SurfMarkLights(ent);
 
-       R_PrepareSurfaces();
+       R_PrepareSurfaces(ent);
 
        if (!skyrendermasked)
-               R_DrawSurfaces(SHADERSTAGE_SKY);
-       R_DrawSurfaces(SHADERSTAGE_NORMAL);
+               R_DrawSurfaces(ent, SHADERSTAGE_SKY);
+       R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
 }
 
 static void gl_surf_start(void)
index 6247e5b..baf58a1 100644 (file)
@@ -492,7 +492,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
        loadmodel->yawmins[2] = loadmodel->normalmins[2];
        loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2];
 
-       loadmodel->Draw = R_DrawAliasModel;
+       loadmodel->Draw = R_DrawQ1Q2AliasModel;
        loadmodel->DrawSky = NULL;
        loadmodel->DrawShadow = NULL;
 }
@@ -566,7 +566,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer)
 
        loadmodel->type = mod_alias;
        loadmodel->aliastype = ALIASTYPE_MDLMD2;
-       loadmodel->Draw = R_DrawAliasModel;
+       loadmodel->Draw = R_DrawQ1Q2AliasModel;
        loadmodel->DrawSky = NULL;
        loadmodel->DrawShadow = NULL;
 
@@ -952,7 +952,7 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
        loadmodel->yawmins[2] = loadmodel->normalmins[2];
        loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2];
 
-       loadmodel->Draw = R_DrawAliasModel;
+       loadmodel->Draw = R_DrawZymoticModel;
        loadmodel->DrawSky = NULL;
        loadmodel->DrawShadow = NULL;
 }
index 05d8105..9d6ffc6 100644 (file)
@@ -204,10 +204,11 @@ msurface_t;
 #define SHADERSTAGE_NORMAL 1
 #define SHADERSTAGE_COUNT 2
 
+struct entity_render_s;
 // change this stuff when real shaders are added
 typedef struct Cshader_s
 {
-       void (*shaderfunc[SHADERSTAGE_COUNT])(msurface_t *firstsurf);
+       void (*shaderfunc[SHADERSTAGE_COUNT])(struct entity_render_s *ent, msurface_t *firstsurf);
        // list of surfaces using this shader (used during surface rendering)
        msurface_t *chain;
 }
index 90657ed..6fc568c 100644 (file)
@@ -193,11 +193,11 @@ typedef struct model_s
        mspriteframe_t  *sprdata_frames;
 
        // draw the model
-       void(*Draw)(void);
+       void(*Draw)(struct entity_render_s *ent);
        // draw the model's sky polygons (only used by brush models)
-       void(*DrawSky)(void);
+       void(*DrawSky)(struct entity_render_s *ent);
        // draw the model's shadows
-       void(*DrawShadow)(void);
+       void(*DrawShadow)(struct entity_render_s *ent);
 
        // memory pool for allocations
        mempool_t               *mempool;
index 507f1f7..da305b9 100644 (file)
@@ -173,14 +173,16 @@ void R_NewExplosion(vec3_t org)
        }
 }
 
-void R_DrawExplosion(explosion_t *e)
+void R_DrawExplosionCallback(void *calldata1, int calldata2)
 {
        int i;
        float *c, *v, diff[3], centerdir[3], ifog, alpha, dist;
        rmeshbufferinfo_t m;
+       explosion_t *e;
+       e = calldata1;
 
        memset(&m, 0, sizeof(m));
-       m.transparent = true;
+       m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
        m.numtriangles = EXPLOSIONTRIS;
@@ -303,6 +305,6 @@ void R_DrawExplosions(void)
                return;
        for (i = 0;i < MAX_EXPLOSIONS;i++)
                if (explosion[i].alpha > 0.01f)
-                       R_DrawExplosion(&explosion[i]);
+                       R_MeshQueue_AddTransparent(explosion[i].origin, R_DrawExplosionCallback, &explosion[i], 0);
 }
 
index e1207de..f801562 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -212,7 +212,7 @@ DYNAMIC LIGHTS
 R_MarkLights
 =============
 */
-static void R_OldMarkLights (vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node)
+static void R_OldMarkLights (entity_render_t *ent, vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node)
 {
        float ndist, maxdist;
        msurface_t *surf;
@@ -255,7 +255,7 @@ loc0:
        }
 
 // mark the polygons
-       surf = currentrenderentity->model->surfaces + node->firstsurface;
+       surf = ent->model->surfaces + node->firstsurface;
        for (i=0 ; i<node->numsurfaces ; i++, surf++)
        {
                int d, impacts, impactt;
@@ -311,7 +311,7 @@ loc0:
        {
                if (node->children[1]->contents >= 0)
                {
-                       R_OldMarkLights (lightorigin, rd, bit, bitindex, node->children[0]);
+                       R_OldMarkLights (ent, lightorigin, rd, bit, bitindex, node->children[0]);
                        node = node->children[1];
                        goto loc0;
                }
@@ -329,7 +329,7 @@ loc0:
 }
 
 
-static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex)
+static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int bitindex)
 {
        static int lightframe = 0;
        mleaf_t *pvsleaf;
@@ -345,12 +345,12 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex)
        if (!r_dynamic.integer)
                return;
 
-       model = currentrenderentity->model;
+       model = ent->model;
        softwareuntransform(rd->origin, lightorigin);
 
        if (!r_vismarklights.integer)
        {
-               R_OldMarkLights(lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
+               R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
                return;
        }
 
@@ -358,7 +358,7 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex)
        if (pvsleaf == NULL)
        {
                Con_Printf("R_VisMarkLights: NULL leaf??\n");
-               R_OldMarkLights(lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
+               R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
                return;
        }
 
@@ -366,7 +366,7 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex)
        if (!in)
        {
                // no vis info, so make all visible
-               R_OldMarkLights(lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
+               R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
                return;
        }
 
@@ -476,11 +476,11 @@ static void R_VisMarkLights (rdlight_t *rd, int bit, int bitindex)
        }
 }
 
-void R_MarkLights(void)
+void R_MarkLights(entity_render_t *ent)
 {
        int i;
        for (i = 0;i < r_numdlights;i++)
-               R_VisMarkLights (r_dlight + i, 1 << (i & 31), i >> 5);
+               R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5);
 }
 
 /*
@@ -693,7 +693,7 @@ void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf)
        }
 }
 
-void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits)
+void R_ModelLightPoint (entity_render_t *ent, vec3_t color, vec3_t p, int *dlightbits)
 {
        mleaf_t *leaf;
        leaf = Mod_PointInLeaf(p, cl.worldmodel);
@@ -704,7 +704,7 @@ void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits)
                return;
        }
 
-       if (r_fullbright.integer || !cl.worldmodel->lightdata || currentrenderentity->effects & EF_FULLBRIGHT)
+       if (r_fullbright.integer || !cl.worldmodel->lightdata || ent->effects & EF_FULLBRIGHT)
        {
                color[0] = color[1] = color[2] = 2;
                dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
@@ -730,7 +730,7 @@ void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits)
                dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
 }
 
-void R_LightModel(int numverts, float colorr, float colorg, float colorb, int worldcoords)
+void R_LightModel(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];
@@ -751,30 +751,30 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo
        int modeldlightbits[8];
        mlight_t *sl;
        rdlight_t *rd;
-       a = currentrenderentity->alpha;
+       a = ent->alpha;
        // scale of the model's coordinate space, to alter light attenuation to match
        // make the mscale squared so it can scale the squared distance results
-       mscale = currentrenderentity->scale * currentrenderentity->scale;
-       if ((maxnearlights != 0) && !r_fullbright.integer && !(currentrenderentity->effects & EF_FULLBRIGHT))
+       mscale = ent->scale * ent->scale;
+       if ((maxnearlights != 0) && !r_fullbright.integer && !(ent->effects & EF_FULLBRIGHT))
        {
-               R_ModelLightPoint(basecolor, currentrenderentity->origin, modeldlightbits);
+               R_ModelLightPoint(ent, basecolor, ent->origin, modeldlightbits);
 
                nl = &nearlight[0];
-               VectorSubtract(currentrenderentity->origin, currentrenderentity->entlightsorigin, v);
-               if ((realtime > currentrenderentity->entlightstime && DotProduct(v,v) >= 1.0f))
+               VectorSubtract(ent->origin, ent->entlightsorigin, v);
+               if ((realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
                {
-                       currentrenderentity->numentlights = 0;
-                       currentrenderentity->entlightstime = realtime + 0.2;
-                       VectorCopy(currentrenderentity->origin, currentrenderentity->entlightsorigin);
-                       for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && currentrenderentity->numentlights < MAXENTLIGHTS;i++, sl++)
-                               if (CL_TraceLine(currentrenderentity->origin, sl->origin, NULL, NULL, 0, false) == 1)
-                                       currentrenderentity->entlights[currentrenderentity->numentlights++] = i;
+                       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 < currentrenderentity->numentlights;i++)
+               for (i = 0;i < ent->numentlights;i++)
                {
-                       sl = cl.worldmodel->lights + currentrenderentity->entlights[i];
+                       sl = cl.worldmodel->lights + ent->entlights[i];
                        stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
-                       VectorSubtract (currentrenderentity->origin, sl->origin, v);
+                       VectorSubtract (ent->origin, sl->origin, v);
                        f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale;
                        VectorScale(sl->light, f, ambientcolor);
                        intensity = DotProduct(ambientcolor, ambientcolor);
@@ -825,7 +825,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo
                        if (!(modeldlightbits[i >> 5] & (1 << (i & 31))))
                                continue;
                        rd = r_dlight + i;
-                       VectorSubtract (currentrenderentity->origin, rd->origin, v);
+                       VectorSubtract (ent->origin, rd->origin, v);
                        f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
                        VectorScale(rd->light, f, ambientcolor);
                        intensity = DotProduct(ambientcolor, ambientcolor);
@@ -874,7 +874,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo
        }
        else
        {
-               R_CompleteLightPoint (basecolor, currentrenderentity->origin, true, NULL);
+               R_CompleteLightPoint (basecolor, ent->origin, true, NULL);
        }
        basecolor[0] *= colorr;
        basecolor[1] *= colorg;
index cc63e8b..026a4ec 100644 (file)
--- a/r_light.h
+++ b/r_light.h
@@ -18,10 +18,10 @@ extern rdlight_t r_dlight[MAX_DLIGHTS];
 
 void R_BuildLightList(void);
 void R_AnimateLight(void);
-void R_MarkLights(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(int numverts, float colorr, float colorg, float colorb, int worldcoords);
+void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords);
 
 #endif
 
index f6ca3a4..40abcef 100644 (file)
@@ -3,11 +3,11 @@
 
 #define LERPSPRITES
 
-static int R_SpriteSetup (int type, float org[3], float left[3], float up[3])
+static int R_SpriteSetup (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];
 
-       VectorCopy(currentrenderentity->origin, org);
+       VectorCopy(ent->origin, org);
        switch(type)
        {
        case SPR_VP_PARALLEL_UPRIGHT:
@@ -26,7 +26,7 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3])
        case SPR_FACING_UPRIGHT:
                // flames and such
                // vertical beam sprite, faces viewer's origin (not the view plane)
-               VectorSubtract(currentrenderentity->origin, r_origin, matrix3[0]);
+               VectorSubtract(ent->origin, r_origin, matrix3[0]);
                matrix3[0][2] = 0;
                VectorNormalizeFast(matrix3[0]);
                matrix3[1][0] = matrix3[0][1];
@@ -49,7 +49,7 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3])
        case SPR_ORIENTED:
                // bullet marks on walls
                // ignores viewer entirely
-               AngleVectorsFLU (currentrenderentity->angles, matrix3[0], matrix3[1], matrix3[2]);
+               AngleVectorsFLU (ent->angles, matrix3[0], matrix3[1], matrix3[2]);
                // nudge it toward the view, so it will be infront of the wall
                VectorSubtract(org, vpn, org);
                break;
@@ -57,7 +57,7 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3])
                // I have no idea what people would use this for
                // oriented relative to view space
                // FIXME: test this and make sure it mimicks software
-               AngleVectorsFLU (currentrenderentity->angles, matrix1[0], matrix1[1], matrix1[2]);
+               AngleVectorsFLU (ent->angles, matrix1[0], matrix1[1], matrix1[2]);
                VectorCopy(vpn, matrix2[0]);
                VectorNegate(vright, matrix2[1]);
                VectorCopy(vup, matrix2[2]);
@@ -65,10 +65,10 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3])
                break;
        }
 
-       if (currentrenderentity->scale != 1)
+       if (ent->scale != 1)
        {
-               VectorScale(matrix3[1], currentrenderentity->scale, left);
-               VectorScale(matrix3[2], currentrenderentity->scale, up);
+               VectorScale(matrix3[1], ent->scale, left);
+               VectorScale(matrix3[2], ent->scale, up);
        }
        else
        {
@@ -78,21 +78,20 @@ static int R_SpriteSetup (int type, float org[3], float left[3], float up[3])
        return false;
 }
 
-static void GL_DrawSpriteImage (int fog, mspriteframe_t *frame, int texture, vec3_t origin, vec3_t up, vec3_t left, float red, float green, float blue, float alpha)
+static void R_DrawSpriteImage (int wantoverbright, int additive, mspriteframe_t *frame, int texture, vec3_t origin, vec3_t up, vec3_t left, float red, float green, float blue, float alpha)
 {
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       m.transparent = true;
+       // the mesh was sorted already, so don't transparent sort
+       m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-       if ((currentrenderentity->effects & EF_ADDITIVE)
-        || (currentrenderentity->model->flags & EF_ADDITIVE)
-        || fog)
+       if (additive)
                m.blendfunc2 = GL_ONE;
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = texture;
-       if (R_Mesh_Draw_GetBuffer(&m, !(currentrenderentity->model->flags & EF_FULLBRIGHT || currentrenderentity->effects & EF_FULLBRIGHT)))
+       if (R_Mesh_Draw_GetBuffer(&m, wantoverbright))
        {
                m.index[0] = 0;
                m.index[1] = 1;
@@ -125,38 +124,37 @@ static void GL_DrawSpriteImage (int fog, mspriteframe_t *frame, int texture, vec
                m.vertex[12] = origin[0] + frame->down * up[0] - frame->right * left[0];
                m.vertex[13] = origin[1] + frame->down * up[1] - frame->right * left[1];
                m.vertex[14] = origin[2] + frame->down * up[2] - frame->right * left[2];
+               R_Mesh_Render();
        }
 }
 
-/*
-=================
-R_DrawSpriteModel
-=================
-*/
-void R_DrawSpriteModel ()
+void R_DrawSpriteModelCallback(void *calldata1, int calldata2)
 {
-       int                     i;
-       vec3_t          left, up, org, color;
+       entity_render_t *ent;
+       int i, wantoverbright;
+       vec3_t left, up, org, color;
        mspriteframe_t *frame;
        vec3_t diff;
-       float           fog, ifog;
-
-       if (currentrenderentity->frameblend[0].frame < 0)
-               return;
+       float fog, ifog;
 
-       if (R_SpriteSetup(currentrenderentity->model->sprnum_type, org, left, up))
+       ent = calldata1;
+       if (R_SpriteSetup(ent, ent->model->sprnum_type, org, left, up))
                return;
 
-       c_sprites++;
-
-       if ((currentrenderentity->model->flags & EF_FULLBRIGHT) || (currentrenderentity->effects & EF_FULLBRIGHT))
+       if ((ent->model->flags & EF_FULLBRIGHT) || (ent->effects & EF_FULLBRIGHT))
+       {
                color[0] = color[1] = color[2] = 1;
+               wantoverbright = false;
+       }
        else
-               R_CompleteLightPoint(color, currentrenderentity->origin, true, NULL);
+       {
+               R_CompleteLightPoint(color, ent->origin, true, NULL);
+               wantoverbright = color[0] > 1 || color[1] > 1 || color[2] > 1;
+       }
 
        if (fogenabled)
        {
-               VectorSubtract(currentrenderentity->origin, r_origin, diff);
+               VectorSubtract(ent->origin, r_origin, diff);
                fog = exp(fogdensity/DotProduct(diff,diff));
                if (fog > 1)
                        fog = 1;
@@ -169,23 +167,38 @@ void R_DrawSpriteModel ()
        // LordHavoc: interpolated sprite rendering
        for (i = 0;i < 4;i++)
        {
-               if (currentrenderentity->frameblend[i].lerp >= 0.01f)
+               if (ent->frameblend[i].lerp >= 0.01f)
                {
-                       frame = currentrenderentity->model->sprdata_frames + currentrenderentity->frameblend[i].frame;
-                       GL_DrawSpriteImage(false, frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, currentrenderentity->alpha * currentrenderentity->frameblend[i].lerp);
-                       if (fog * currentrenderentity->frameblend[i].lerp >= 0.01f)
-                               GL_DrawSpriteImage(true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * currentrenderentity->alpha * currentrenderentity->frameblend[i].lerp);
+                       frame = ent->model->sprdata_frames + ent->frameblend[i].frame;
+                       R_DrawSpriteImage(wantoverbright, (ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha * ent->frameblend[i].lerp);
+                       if (fog * ent->frameblend[i].lerp >= 0.01f)
+                               R_DrawSpriteImage(false, true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha * ent->frameblend[i].lerp);
                }
        }
 #else
        // LordHavoc: no interpolation
        frame = NULL;
-       for (i = 0;i < 4 && currentrenderentity->frameblend[i].lerp;i++)
-               frame = currentrenderentity->model->sprdata_frames + currentrenderentity->frameblend[i].frame;
+       for (i = 0;i < 4 && ent->frameblend[i].lerp;i++)
+               frame = ent->model->sprdata_frames + ent->frameblend[i].frame;
 
-       GL_DrawSpriteImage(false, frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, currentrenderentity->alpha);
-       if (fog * currentrenderentity->frameblend[i].lerp >= 0.01f)
-               GL_DrawSpriteImage(true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * currentrenderentity->alpha);
+       R_DrawSpriteImage(wantoverbright, (ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, R_GetTexture(frame->texture), org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha);
+       if (fog * ent->frameblend[i].lerp >= 0.01f)
+               R_DrawSpriteImage(false, true, frame, R_GetTexture(frame->fogtexture), org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha);
 #endif
 }
 
+/*
+=================
+R_DrawSpriteModel
+=================
+*/
+void R_DrawSpriteModel (entity_render_t *ent)
+{
+       if (ent->frameblend[0].frame < 0)
+               return;
+
+       c_sprites++;
+
+       R_MeshQueue_AddTransparent(ent->origin, R_DrawSpriteModelCallback, ent, 0);
+}
+
index 394cc41..c3a5e09 100644 (file)
--- a/render.h
+++ b/render.h
@@ -77,7 +77,6 @@ void R_FillColors(float *out, int verts, float r, float g, float b, float a);
 
 //=============================================================================
 
-extern entity_render_t *currentrenderentity;
 extern int                     r_framecount;
 extern mplane_t        frustum[4];
 extern int             c_brush_polys, c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
@@ -111,14 +110,19 @@ void R_InitSky (qbyte *src, int bytesperpixel); // called at level load
 
 void R_NewMap (void);
 
-void R_DrawWorld(void);
-void R_SetupForWorldRendering(void);
-void R_MarkWorldLights(void);
-void R_PrepareSurfaces(void);
-void R_DrawSurfaces(int type);
-void R_DrawPortals(void);
+void R_DrawWorld(entity_render_t *ent);
+void R_SetupForWorldRendering(entity_render_t *ent);
+void R_MarkWorldLights(entity_render_t *ent);
+void R_PrepareSurfaces(entity_render_t *ent);
+void R_DrawSurfaces(entity_render_t *ent, int type);
+void R_DrawPortals(entity_render_t *ent);
 void R_DrawParticles(void);
 void R_DrawExplosions(void);
+void R_DrawBrushModelSky (entity_render_t *ent);
+void R_DrawBrushModelNormal (entity_render_t *ent);
+void R_DrawZymoticModel (entity_render_t *ent);
+void R_DrawQ1Q2AliasModel(entity_render_t *ent);
+void R_DrawSpriteModel (entity_render_t *ent);
 
 // LordHavoc: vertex transform
 #include "transform.h"
@@ -151,15 +155,12 @@ void R_Mesh_EnlargeFarClipBBox(vec3_t mins, vec3_t maxs);
 
 #include "r_modules.h"
 
+#include "meshqueue.h"
+
 extern float overbrightscale;
 
 #include "r_lerpanim.h"
 
-void R_DrawBrushModelSky (void);
-void R_DrawBrushModelNormal (void);
-void R_DrawAliasModel (void);
-void R_DrawSpriteModel (void);
-
 extern cvar_t r_render;
 #include "image.h"