got rid of R_Mesh_Draw and R_Mesh_DrawPolygon, now all 3D geometry is drawn using...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 25 Aug 2002 15:45:41 +0000 (15:45 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 25 Aug 2002 15:45:41 +0000 (15:45 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2285 d7cf8633-e32d-0410-b094-e92efae38249

gl_backend.c
gl_backend.h
gl_models.c
gl_rmain.c
gl_rsurf.c
render.h

index 1dff96e..0c7c315 100644 (file)
@@ -70,8 +70,6 @@ void GL_PrintError(int errornumber, char *filename, int linenumber)
 
 float r_mesh_farclip;
 
 
 float r_mesh_farclip;
 
-int polyindexarray[768];
-
 static float viewdist;
 // sign bits (true if negative) for vpn[] entries, so quick integer compares can be used instead of float compares
 static int vpnbit0, vpnbit1, vpnbit2;
 static float viewdist;
 // sign bits (true if negative) for vpn[] entries, so quick integer compares can be used instead of float compares
 static int vpnbit0, vpnbit1, vpnbit2;
@@ -293,8 +291,6 @@ static void gl_backend_newmap(void)
 
 void gl_backend_init(void)
 {
 
 void gl_backend_init(void)
 {
-       int i;
-
        Cvar_RegisterVariable(&r_render);
        Cvar_RegisterVariable(&gl_dither);
        Cvar_RegisterVariable(&gl_lockarrays);
        Cvar_RegisterVariable(&r_render);
        Cvar_RegisterVariable(&gl_dither);
        Cvar_RegisterVariable(&gl_lockarrays);
@@ -308,12 +304,6 @@ void gl_backend_init(void)
        Cvar_RegisterVariable(&gl_mesh_drawmode);
        R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
        gl_backend_bufferchanges(true);
        Cvar_RegisterVariable(&gl_mesh_drawmode);
        R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
        gl_backend_bufferchanges(true);
-       for (i = 0;i < 256;i++)
-       {
-               polyindexarray[i*3+0] = 0;
-               polyindexarray[i*3+1] = i + 1;
-               polyindexarray[i*3+2] = i + 2;
-       }
 }
 
 int arraylocked = false;
 }
 
 int arraylocked = false;
@@ -1000,219 +990,6 @@ void R_Mesh_AddTransparent(void)
        currenttransvertex = 0;
 }
 
        currenttransvertex = 0;
 }
 
-void R_Mesh_Draw(const rmeshinfo_t *m)
-{
-       // these are static because gcc runs out of virtual registers otherwise
-       static int i, j, overbright, *index;
-       static float *in, scaler;
-       static float cr, cg, cb, ca;
-       static buf_mesh_t *mesh;
-       static buf_vertex_t *vert;
-       static buf_fcolor_t *fcolor;
-       static buf_texcoord_t *texcoord[MAX_TEXTUREUNITS];
-
-       if (!backendactive)
-               Sys_Error("R_Mesh_Draw: called when backend is not active\n");
-
-       if (m->index == NULL
-        || !m->numtriangles
-        || m->vertex == NULL
-        || !m->numverts)
-               Host_Error("R_Mesh_Draw: no triangles or verts\n");
-
-       // ignore meaningless alpha meshs
-       if (!m->depthwrite && m->blendfunc1 == GL_SRC_ALPHA && (m->blendfunc2 == GL_ONE || m->blendfunc2 == GL_ONE_MINUS_SRC_ALPHA))
-       {
-               if (m->color)
-               {
-                       for (i = 0, in = m->color + 3;i < m->numverts;i++, (int)in += m->colorstep)
-                               if (*in >= 0.01f)
-                                       break;
-                       if (i == m->numverts)
-                               return;
-               }
-               else if (m->ca < 0.01f)
-                       return;
-       }
-
-       if (!backendactive)
-               Sys_Error("R_Mesh_Draw: called when backend is not active\n");
-
-#ifdef DEBUGGL
-       for (i = 0;i < m->numtriangles * 3;i++)
-               if ((unsigned int) m->index[i] >= (unsigned int) m->numverts)
-                       Host_Error("R_Mesh_Draw: invalid index (%i of %i verts)\n", m->index, m->numverts);
-#endif
-
-       // LordHavoc: removed this error condition because with floatcolors 0,
-       // the 3DFX driver works with very large meshs
-       // FIXME: we can work around this by falling back on non-array renderer if buffers are too big
-       //if (m->numtriangles > 1024 || m->numverts > 3072)
-       //{
-       //      Con_Printf("R_Mesh_Draw: mesh too big for 3DFX drivers, rejected\n");
-       //      return;
-       //}
-
-       i = max(m->numtriangles * 3, m->numverts);
-       if (overflowedverts < i)
-               overflowedverts = i;
-
-       if (m->numtriangles > max_meshs || m->numverts > max_verts)
-       {
-               Con_Printf("R_Mesh_Draw: mesh too big for current gl_mesh_maxtriangles setting, increasing limits\n");
-               return;
-       }
-
-       if (m->transparent)
-       {
-               overflowedtransverts += max(m->numtriangles * 3, m->numverts);
-               if (currenttransmesh >= max_transmeshs || (currenttranstriangle + m->numtriangles) > max_transmeshs || (currenttransvertex + m->numverts) > max_transverts)
-               {
-                       if (!transranout)
-                       {
-                               Con_Printf("R_Mesh_Draw: ran out of room for transparent meshs\n");
-                               transranout = true;
-                       }
-                       return;
-               }
-
-               c_transmeshs++;
-               c_transtris += m->numtriangles;
-               vert = &buf_transvertex[currenttransvertex];
-               fcolor = &buf_transfcolor[currenttransvertex];
-               for (i = 0;i < backendunits;i++)
-                       texcoord[i] = &buf_transtexcoord[i][currenttransvertex];
-
-               // transmesh is only for storage of transparent meshs until they
-               // are inserted into the main mesh array
-               mesh = &buf_transmesh[currenttransmesh++];
-               mesh->firsttriangle = currenttranstriangle;
-               mesh->firstvert = currenttransvertex;
-               index = &buf_transtri[currenttranstriangle].index[0];
-
-               currenttranstriangle += m->numtriangles;
-               currenttransvertex += m->numverts;
-       }
-       else
-       {
-               if (currentmesh)
-               {
-                       R_Mesh_Render();
-                       Con_Printf("mesh queue not empty, flushing.\n");
-               }
-
-               c_meshs++;
-               c_meshtris += m->numtriangles;
-               vert = &buf_vertex[currentvertex];
-               fcolor = &buf_fcolor[currentvertex];
-               for (i = 0;i < backendunits;i++)
-                       texcoord[i] = &buf_texcoord[i][currentvertex];
-
-               // opaque meshs are rendered directly
-               mesh = &buf_mesh[currentmesh++];
-               mesh->firsttriangle = currenttriangle;
-               mesh->firstvert = currentvertex;
-               index = &buf_tri[currenttriangle].index[0];
-
-               currenttriangle += m->numtriangles;
-               currentvertex += m->numverts;
-       }
-
-       // code shared for transparent and opaque meshs
-       memcpy(index, m->index, sizeof(int[3]) * m->numtriangles);
-       mesh->blendfunc1 = m->blendfunc1;
-       mesh->blendfunc2 = m->blendfunc2;
-       mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite);
-       mesh->depthtest = !m->depthdisable;
-       mesh->triangles = m->numtriangles;
-       mesh->verts = m->numverts;
-
-       overbright = false;
-       scaler = 1;
-       if (m->blendfunc1 == GL_DST_COLOR)
-       {
-               // check if it is a 2x modulate with framebuffer
-               if (m->blendfunc2 == GL_SRC_COLOR)
-                       scaler *= 0.5f;
-       }
-       else if (m->blendfunc2 != GL_SRC_COLOR)
-       {
-               if (m->tex[0])
-               {
-                       overbright = gl_combine.integer;
-                       if (overbright)
-                               scaler *= 0.25f;
-               }
-               scaler *= overbrightscale;
-       }
-
-
-       j = -1;
-       for (i = 0;i < backendunits;i++)
-       {
-               if ((mesh->textures[i] = m->tex[i]))
-                       j = i;
-               mesh->texturergbscale[i] = m->texrgbscale[i];
-               if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4)
-                       mesh->texturergbscale[i] = 1;
-       }
-       if (overbright && j >= 0)
-               mesh->texturergbscale[j] = 4;
-
-       if (m->vertexstep != sizeof(buf_vertex_t))
-       {
-               for (i = 0, in = m->vertex;i < m->numverts;i++, (int)in += m->vertexstep)
-               {
-                       vert[i].v[0] = in[0];
-                       vert[i].v[1] = in[1];
-                       vert[i].v[2] = in[2];
-               }
-       }
-       else
-               memcpy(vert, m->vertex, m->numverts * sizeof(buf_vertex_t));
-
-       if (m->color)
-       {
-               for (i = 0, in = m->color;i < m->numverts;i++, (int)in += m->colorstep)
-               {
-                       fcolor[i].c[0] = in[0] * scaler;
-                       fcolor[i].c[1] = in[1] * scaler;
-                       fcolor[i].c[2] = in[2] * scaler;
-                       fcolor[i].c[3] = in[3];
-               }
-       }
-       else
-       {
-               cr = m->cr * scaler;
-               cg = m->cg * scaler;
-               cb = m->cb * scaler;
-               ca = m->ca;
-               for (i = 0;i < m->numverts;i++)
-               {
-                       fcolor[i].c[0] = cr;
-                       fcolor[i].c[1] = cg;
-                       fcolor[i].c[2] = cb;
-                       fcolor[i].c[3] = ca;
-               }
-       }
-
-       for (j = 0;j < MAX_TEXTUREUNITS && m->tex[j];j++)
-       {
-               if (j >= backendunits)
-                       Sys_Error("R_Mesh_Draw: texture %i supplied when there are only %i texture units\n", j + 1, backendunits);
-               if (m->texcoordstep[j] != sizeof(buf_texcoord_t))
-               {
-                       for (i = 0, in = m->texcoords[j];i < m->numverts;i++, (int)in += m->texcoordstep[j])
-                       {
-                               texcoord[j][i].t[0] = in[0];
-                               texcoord[j][i].t[1] = in[1];
-                       }
-               }
-               else
-                       memcpy(&texcoord[j][0].t[0], m->texcoords[j], m->numverts * sizeof(buf_texcoord_t));
-       }
-}
-
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
 // (this is used for very high speed rendering, no copying)
 int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
 // (this is used for very high speed rendering, no copying)
 int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
@@ -1223,11 +1000,11 @@ int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
        buf_mesh_t *mesh;
 
        if (!backendactive)
        buf_mesh_t *mesh;
 
        if (!backendactive)
-               Sys_Error("R_Mesh_Draw: called when backend is not active\n");
+               Sys_Error("R_Mesh_Draw_GetBuffer: called when backend is not active\n");
 
        if (!m->numtriangles
         || !m->numverts)
 
        if (!m->numtriangles
         || !m->numverts)
-               Host_Error("R_Mesh_Draw: no triangles or verts\n");
+               Host_Error("R_Mesh_Draw_GetBuffer: no triangles or verts\n");
 
        // LordHavoc: removed this error condition because with floatcolors 0,
        // the 3DFX driver works with very large meshs
 
        // LordHavoc: removed this error condition because with floatcolors 0,
        // the 3DFX driver works with very large meshs
@@ -1255,7 +1032,7 @@ int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
                {
                        if (!transranout)
                        {
                {
                        if (!transranout)
                        {
-                               Con_Printf("R_Mesh_Draw: ran out of room for transparent meshs\n");
+                               Con_Printf("R_Mesh_Draw_GetBuffer: ran out of room for transparent meshs\n");
                                transranout = true;
                        }
                        return false;
                                transranout = true;
                        }
                        return false;
@@ -1348,24 +1125,6 @@ int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
        return true;
 }
 
        return true;
 }
 
-void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts)
-{
-       m->index = polyindexarray;
-       m->numverts = numverts;
-       m->numtriangles = numverts - 2;
-       if (m->numtriangles < 1)
-       {
-               Con_Printf("R_Mesh_DrawPolygon: invalid vertex count\n");
-               return;
-       }
-       if (m->numtriangles >= 256)
-       {
-               Con_Printf("R_Mesh_DrawPolygon: only up to 256 triangles (258 verts) supported\n");
-               return;
-       }
-       R_Mesh_Draw(m);
-}
-
 /*
 ==============================================================================
 
 /*
 ==============================================================================
 
index 01dc106..2efbd9a 100644 (file)
@@ -68,20 +68,13 @@ void R_Mesh_ClearDepth(void);
 // (only valid between R_Mesh_Start and R_Mesh_Finish)
 void R_Mesh_Render(void);
 
 // (only valid between R_Mesh_Start and R_Mesh_Finish)
 void R_Mesh_Render(void);
 
-// queues a mesh to be rendered (invokes Render if queue is full)
-// (only valid between R_Mesh_Start and R_Mesh_Finish)
-void R_Mesh_Draw(const rmeshinfo_t *m);
-
 // renders the queued transparent meshs
 // (only valid between R_Mesh_Start and R_Mesh_Finish)
 void R_Mesh_AddTransparent(void);
 
 // renders the queued transparent meshs
 // (only valid between R_Mesh_Start and R_Mesh_Finish)
 void R_Mesh_AddTransparent(void);
 
-// ease-of-use frontend to R_Mesh_Draw, set up meshinfo, except for index and numtriangles and numverts, then call this
-// (only valid between R_Mesh_Start and R_Mesh_Finish)
-void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts);
-
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
-// (this is used for very high speed rendering, no copying)
+// (it is up to the caller to fill in the geometry data)
+// (make sure you scale your colors by the colorscale field)
 // (only valid between R_Mesh_Start and R_Mesh_Finish)
 int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright);
 
 // (only valid between R_Mesh_Start and R_Mesh_Finish)
 int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright);
 
index 47efa6d..8b40edd 100644 (file)
@@ -20,8 +20,6 @@ float *aliasvertnorm;
 int *aliasvertusage;
 zymbonematrix *zymbonepose;
 
 int *aliasvertusage;
 zymbonematrix *zymbonepose;
 
-rmeshinfo_t aliasmeshinfo;
-
 mempool_t *gl_models_mempool;
 
 void gl_models_start(void)
 mempool_t *gl_models_mempool;
 
 void gl_models_start(void)
@@ -200,41 +198,6 @@ void R_AliasLerpVerts(int vertcount,
        }
 }
 
        }
 }
 
-void R_DrawModelMesh(rtexture_t *skin, float *colors, float cred, float cgreen, float cblue)
-{
-       aliasmeshinfo.tex[0] = R_GetTexture(skin);
-       aliasmeshinfo.color = colors;
-       if (colors == NULL)
-       {
-               aliasmeshinfo.cr = cred;
-               aliasmeshinfo.cg = cgreen;
-               aliasmeshinfo.cb = cblue;
-               aliasmeshinfo.ca = currentrenderentity->alpha;
-       }
-
-       c_alias_polys += aliasmeshinfo.numtriangles;
-       R_Mesh_Draw(&aliasmeshinfo);
-       R_Mesh_Render();
-
-       // leave it in a state for additional passes
-       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-       aliasmeshinfo.blendfunc2 = GL_ONE;
-}
-
-void R_TintModel(float *in, float *out, int verts, float r, float g, float b)
-{
-       int i;
-       for (i = 0;i < verts;i++)
-       {
-               out[0] = in[0] * r;
-               out[1] = in[1] * g;
-               out[2] = in[2] * b;
-               out[3] = in[3];
-               in += 4;
-               out += 4;
-       }
-}
-
 skinframe_t *R_FetchSkinFrame(void)
 {
        model_t *model = currentrenderentity->model;
 skinframe_t *R_FetchSkinFrame(void)
 {
        model_t *model = currentrenderentity->model;
@@ -272,231 +235,197 @@ void R_SetupMDLMD2Frames(float colorr, float colorg, float colorb)
 
 void R_DrawQ1Q2AliasModel (float fog)
 {
 
 void R_DrawQ1Q2AliasModel (float fog)
 {
+       int c, pantsfullbright, shirtfullbright, colormapped;
+       float pantscolor[3], shirtcolor[3];
+       qbyte *bcolor;
+       rmeshbufferinfo_t m;
        model_t *model;
        skinframe_t *skinframe;
 
        model = currentrenderentity->model;
 
        skinframe = R_FetchSkinFrame();
        model_t *model;
        skinframe_t *skinframe;
 
        model = currentrenderentity->model;
 
        skinframe = R_FetchSkinFrame();
-       if (fog && !(currentrenderentity->effects & EF_ADDITIVE))
-       {
-               R_SetupMDLMD2Frames(1 - fog, 1 - fog, 1 - fog);
-
-               memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
-
-               aliasmeshinfo.vertex = aliasvert;
-               aliasmeshinfo.vertexstep = sizeof(float[4]);
-               aliasmeshinfo.numverts = model->numverts;
-               aliasmeshinfo.numtriangles = model->numtris;
-               aliasmeshinfo.index = model->mdlmd2data_indices;
-               aliasmeshinfo.colorstep = sizeof(float[4]);
-               aliasmeshinfo.texcoords[0] = model->mdlmd2data_texcoords;
-               aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
 
 
+       colormapped = !skinframe->merged || (currentrenderentity->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 (currentrenderentity->effects & EF_ADDITIVE)
                {
-                       aliasmeshinfo.transparent = true;
-                       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-                       aliasmeshinfo.blendfunc2 = GL_ONE;
+                       m.transparent = true;
+                       m.blendfunc1 = GL_SRC_ALPHA;
+                       m.blendfunc2 = GL_ONE;
                }
                else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
                {
                }
                else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
                {
-                       aliasmeshinfo.transparent = true;
-                       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-                       aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+                       m.transparent = true;
+                       m.blendfunc1 = GL_SRC_ALPHA;
+                       m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
                }
                else
                {
                }
                else
                {
-                       aliasmeshinfo.transparent = false;
-                       aliasmeshinfo.blendfunc1 = GL_ONE;
-                       aliasmeshinfo.blendfunc2 = GL_ZERO;
+                       m.transparent = false;
+                       m.blendfunc1 = GL_ONE;
+                       m.blendfunc2 = GL_ZERO;
                }
                }
+               m.numtriangles = model->numtris;
+               m.numverts = model->numverts;
+               m.tex[0] = R_GetTexture(skinframe->merged);
 
 
-               if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged)
+               c_alias_polys += m.numtriangles;
+               if (R_Mesh_Draw_GetBuffer(&m, true))
                {
                {
-                       if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt))
-                       {
-                               int c;
-                               qbyte *color;
-                               if (skinframe->base)
-                                       R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
-                               if (skinframe->pants)
-                               {
-                                       c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
-                                       color = (qbyte *) (&d_8to24table[c]);
-                                       if (c >= 224) // fullbright ranges
-                                               R_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                       else
-                                       {
-                                               R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                               R_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0);
-                                       }
-                               }
-                               if (skinframe->shirt)
-                               {
-                                       c = currentrenderentity->colormap & 0xF0      ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
-                                       color = (qbyte *) (&d_8to24table[c]);
-                                       if (c >= 224) // fullbright ranges
-                                               R_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                       else
-                                       {
-                                               R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                               R_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0);
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               if (skinframe->merged)
-                                       R_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0);
-                               else
-                               {
-                                       if (skinframe->base) R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
-                                       if (skinframe->pants) R_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0);
-                                       if (skinframe->shirt) R_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0);
-                               }
-                       }
-                       if (skinframe->glow) R_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog);
-               }
-               else
-                       R_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog);
-
-               aliasmeshinfo.tex[0] = R_GetTexture(skinframe->fog);
-               aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-               aliasmeshinfo.blendfunc2 = GL_ONE;
-               aliasmeshinfo.color = NULL;
+                       memcpy(m.index, model->mdlmd2data_indices, m.numtriangles * sizeof(int[3]));
+                       memcpy(m.texcoords[0], model->mdlmd2data_texcoords, m.numverts * sizeof(float[2]));
 
 
-               aliasmeshinfo.cr = fogcolor[0];
-               aliasmeshinfo.cg = fogcolor[1];
-               aliasmeshinfo.cb = fogcolor[2];
-               aliasmeshinfo.ca = currentrenderentity->alpha * fog;
+                       aliasvert = m.vertex;
+                       aliasvertcolor = m.color;
+                       R_SetupMDLMD2Frames(m.colorscale * (1 - fog), m.colorscale * (1 - fog), m.colorscale * (1 - fog));
+                       aliasvert = aliasvertbuf;
+                       aliasvertcolor = aliasvertcolorbuf;
 
 
-               c_alias_polys += aliasmeshinfo.numtriangles;
-               R_Mesh_Draw(&aliasmeshinfo);
-               R_Mesh_Render();
+                       R_Mesh_Render();
+               }
+               return;
        }
        }
-       else if (currentrenderentity->colormap >= 0 || !skinframe->merged || skinframe->glow || !r_quickmodels.integer)
-       {
-               R_SetupMDLMD2Frames(1 - fog, 1 - fog, 1 - fog);
 
 
-               memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
+       R_SetupMDLMD2Frames(1 - fog, 1 - fog, 1 - fog);
 
 
-               aliasmeshinfo.vertex = aliasvert;
-               aliasmeshinfo.vertexstep = sizeof(float[4]);
-               aliasmeshinfo.numverts = model->numverts;
-               aliasmeshinfo.numtriangles = model->numtris;
-               aliasmeshinfo.index = model->mdlmd2data_indices;
-               aliasmeshinfo.colorstep = sizeof(float[4]);
-               aliasmeshinfo.texcoords[0] = model->mdlmd2data_texcoords;
-               aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
+       if (colormapped)
+       {
+               // 128-224 are backwards ranges
+               c = (currentrenderentity->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;
+               bcolor = (qbyte *) (&d_8to24table[c]);
+               shirtfullbright = c >= 224;
+               VectorScale(bcolor, (1.0f / 255.0f), shirtcolor);
+       }
+       else
+       {
+               pantscolor[0] = pantscolor[1] = pantscolor[2] = shirtcolor[0] = shirtcolor[1] = shirtcolor[2] = 1;
+               pantsfullbright = shirtfullbright = false;
+       }
 
 
-               if (currentrenderentity->effects & EF_ADDITIVE)
-               {
-                       aliasmeshinfo.transparent = true;
-                       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-                       aliasmeshinfo.blendfunc2 = GL_ONE;
-               }
-               else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
-               {
-                       aliasmeshinfo.transparent = true;
-                       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-                       aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-               }
-               else
-               {
-                       aliasmeshinfo.transparent = false;
-                       aliasmeshinfo.blendfunc1 = GL_ONE;
-                       aliasmeshinfo.blendfunc2 = GL_ZERO;
-               }
+       memset(&m, 0, sizeof(m));
+       if (currentrenderentity->effects & EF_ADDITIVE)
+       {
+               m.transparent = true;
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE;
+       }
+       else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
+       {
+               m.transparent = true;
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       }
+       else
+       {
+               m.transparent = false;
+               m.blendfunc1 = GL_ONE;
+               m.blendfunc2 = GL_ZERO;
+       }
+       m.numtriangles = model->numtris;
+       m.numverts = model->numverts;
+       m.tex[0] = colormapped ? R_GetTexture(skinframe->base) : R_GetTexture(skinframe->merged);
+       if (R_Mesh_Draw_GetBuffer(&m, true))
+       {
+               c_alias_polys += m.numtriangles;
+               R_ModulateColors(aliasvertcolor, m.color, m.numverts, m.colorscale, m.colorscale, m.colorscale);
+               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]));
+               R_Mesh_Render();
+       }
 
 
-               if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged)
+       if (colormapped)
+       {
+               if (skinframe->pants)
                {
                {
-                       if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt))
+                       memset(&m, 0, sizeof(m));
+                       m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+                       m.blendfunc1 = GL_SRC_ALPHA;
+                       m.blendfunc2 = GL_ONE;
+                       m.numtriangles = model->numtris;
+                       m.numverts = model->numverts;
+                       m.tex[0] = R_GetTexture(skinframe->pants);
+                       if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
                        {
-                               int c;
-                               qbyte *color;
-                               if (skinframe->base)
-                                       R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
-                               if (skinframe->pants)
-                               {
-                                       c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
-                                       color = (qbyte *) (&d_8to24table[c]);
-                                       if (c >= 224) // fullbright ranges
-                                               R_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                       else
-                                       {
-                                               R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                               R_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0);
-                                       }
-                               }
-                               if (skinframe->shirt)
-                               {
-                                       c = currentrenderentity->colormap & 0xF0      ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
-                                       color = (qbyte *) (&d_8to24table[c]);
-                                       if (c >= 224) // fullbright ranges
-                                               R_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                       else
-                                       {
-                                               R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
-                                               R_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0);
-                                       }
-                               }
+                               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);
+                               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]));
+                               memcpy(m.vertex, aliasvert, m.numverts * sizeof(float[4]));
+                               memcpy(m.texcoords[0], model->mdlmd2data_texcoords, m.numverts * sizeof(float[2]));
+                               R_Mesh_Render();
                        }
                        }
-                       else
+               }
+               if (skinframe->shirt)
+               {
+                       memset(&m, 0, sizeof(m));
+                       m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+                       m.blendfunc1 = GL_SRC_ALPHA;
+                       m.blendfunc2 = GL_ONE;
+                       m.numtriangles = model->numtris;
+                       m.numverts = model->numverts;
+                       m.tex[0] = R_GetTexture(skinframe->shirt);
+                       if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
                        {
-                               if (skinframe->merged)
-                                       R_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0);
+                               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);
                                else
                                else
-                               {
-                                       if (skinframe->base) R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
-                                       if (skinframe->pants) R_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0);
-                                       if (skinframe->shirt) R_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0);
-                               }
+                                       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]));
+                               memcpy(m.vertex, aliasvert, m.numverts * sizeof(float[4]));
+                               memcpy(m.texcoords[0], model->mdlmd2data_texcoords, m.numverts * sizeof(float[2]));
+                               R_Mesh_Render();
                        }
                        }
-                       if (skinframe->glow) R_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog);
                }
                }
-               else
-                       R_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog);
        }
        }
-       else
+       if (skinframe->glow)
        {
        {
-               rmeshbufferinfo_t bufmesh;
-               memset(&bufmesh, 0, sizeof(bufmesh));
-               if (currentrenderentity->effects & EF_ADDITIVE)
-               {
-                       bufmesh.transparent = true;
-                       bufmesh.blendfunc1 = GL_SRC_ALPHA;
-                       bufmesh.blendfunc2 = GL_ONE;
-               }
-               else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
+               memset(&m, 0, sizeof(m));
+               m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE;
+               m.numtriangles = model->numtris;
+               m.numverts = model->numverts;
+               m.tex[0] = R_GetTexture(skinframe->glow);
+               if (R_Mesh_Draw_GetBuffer(&m, true))
                {
                {
-                       bufmesh.transparent = true;
-                       bufmesh.blendfunc1 = GL_SRC_ALPHA;
-                       bufmesh.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+                       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);
+                       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]));
+                       R_Mesh_Render();
                }
                }
-               else
+       }
+       if (fog)
+       {
+               memset(&m, 0, sizeof(m));
+               m.transparent = currentrenderentity->effects & EF_ADDITIVE || currentrenderentity->alpha != 1.0 || skinframe->fog != NULL;
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE;
+               m.numtriangles = model->numtris;
+               m.numverts = model->numverts;
+               m.tex[0] = R_GetTexture(skinframe->fog);
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                {
-                       bufmesh.transparent = false;
-                       bufmesh.blendfunc1 = GL_ONE;
-                       bufmesh.blendfunc2 = GL_ZERO;
+                       c_alias_polys += m.numtriangles;
+                       R_FillColors(m.color, m.numverts, fog * m.colorscale, fog * m.colorscale, fog * m.colorscale, currentrenderentity->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]));
+                       R_Mesh_Render();
                }
                }
-               bufmesh.numtriangles = model->numtris;
-               bufmesh.numverts = model->numverts;
-               bufmesh.tex[0] = R_GetTexture(skinframe->merged);
-
-               R_Mesh_Draw_GetBuffer(&bufmesh, true);
-
-               aliasvert = bufmesh.vertex;
-               aliasvertcolor = bufmesh.color;
-               memcpy(bufmesh.index, model->mdlmd2data_indices, bufmesh.numtriangles * sizeof(int[3]));
-               memcpy(bufmesh.texcoords[0], model->mdlmd2data_texcoords, bufmesh.numverts * sizeof(float[2]));
-
-               fog = bufmesh.colorscale * (1 - fog);
-               R_SetupMDLMD2Frames(fog, fog, fog);
-
-               aliasvert = aliasvertbuf;
-               aliasvertcolor = aliasvertcolorbuf;
-               R_Mesh_Render();
        }
 }
 
        }
 }
 
@@ -760,76 +689,76 @@ void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
        }
 }
 
        }
 }
 
-void R_DrawZymoticModelMesh(zymtype1header_t *m)
+void R_DrawZymoticModelMesh(zymtype1header_t *m, float fog)
 {
 {
+       rmeshbufferinfo_t mbuf;
        int i, *renderlist;
        rtexture_t **texture;
 
        int i, *renderlist;
        rtexture_t **texture;
 
-       // FIXME: do better fog
-       renderlist = (int *)(m->lump_render.start + (int) m);
        texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
 
        texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
 
-       aliasmeshinfo.vertex = aliasvert;
-       aliasmeshinfo.vertexstep = sizeof(float[4]);
-       aliasmeshinfo.color = aliasvertcolor;
-       aliasmeshinfo.colorstep = sizeof(float[4]);
-       aliasmeshinfo.texcoords[0] = (float *)(m->lump_texcoords.start + (int) m);
-       aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
-
+       renderlist = (int *)(m->lump_render.start + (int) m);
        for (i = 0;i < m->numshaders;i++)
        {
        for (i = 0;i < m->numshaders;i++)
        {
-               aliasmeshinfo.tex[0] = R_GetTexture(texture[i]);
+               memset(&mbuf, 0, sizeof(mbuf));
+               mbuf.numverts = m->numverts;
+               mbuf.numtriangles = *renderlist++;
                if (currentrenderentity->effects & EF_ADDITIVE)
                {
                if (currentrenderentity->effects & EF_ADDITIVE)
                {
-                       aliasmeshinfo.transparent = true;
-                       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-                       aliasmeshinfo.blendfunc2 = GL_ONE;
+                       mbuf.transparent = true;
+                       mbuf.blendfunc1 = GL_SRC_ALPHA;
+                       mbuf.blendfunc2 = GL_ONE;
                }
                else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i]))
                {
                }
                else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i]))
                {
-                       aliasmeshinfo.transparent = true;
-                       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-                       aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+                       mbuf.transparent = true;
+                       mbuf.blendfunc1 = GL_SRC_ALPHA;
+                       mbuf.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
                }
                else
                {
                }
                else
                {
-                       aliasmeshinfo.transparent = false;
-                       aliasmeshinfo.blendfunc1 = GL_ONE;
-                       aliasmeshinfo.blendfunc2 = GL_ZERO;
+                       mbuf.transparent = false;
+                       mbuf.blendfunc1 = GL_ONE;
+                       mbuf.blendfunc2 = GL_ZERO;
                }
                }
-               aliasmeshinfo.numtriangles = *renderlist++;
-               aliasmeshinfo.index = renderlist;
-               c_alias_polys += aliasmeshinfo.numtriangles;
-               R_Mesh_Draw(&aliasmeshinfo);
-               R_Mesh_Render();
-               renderlist += aliasmeshinfo.numtriangles * 3;
+               mbuf.tex[0] = R_GetTexture(texture[i]);
+               if (R_Mesh_Draw_GetBuffer(&mbuf, true))
+               {
+                       c_alias_polys += mbuf.numtriangles;
+                       memcpy(mbuf.index, renderlist, 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();
+               }
+               renderlist += mbuf.numtriangles * 3;
        }
        }
-}
 
 
-void R_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m, float fog)
-{
-       int i, *renderlist;
-
-       // FIXME: do better fog
-       renderlist = (int *)(m->lump_render.start + (int) m);
-
-       aliasmeshinfo.tex[0] = 0;
-       aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
-       aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-
-       aliasmeshinfo.cr = fogcolor[0];
-       aliasmeshinfo.cg = fogcolor[1];
-       aliasmeshinfo.cb = fogcolor[2];
-       aliasmeshinfo.ca = currentrenderentity->alpha * fog;
-
-       for (i = 0;i < m->numshaders;i++)
+       if (fog)
        {
        {
-               aliasmeshinfo.numtriangles = *renderlist++;
-               aliasmeshinfo.index = renderlist;
-               c_alias_polys += aliasmeshinfo.numtriangles;
-               R_Mesh_Draw(&aliasmeshinfo);
-               R_Mesh_Render();
-               renderlist += aliasmeshinfo.numtriangles * 3;
+               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;
+               }
        }
 }
 
        }
 }
 
@@ -845,13 +774,7 @@ void R_DrawZymoticModel (float fog)
 
        R_LightModel(m->numverts, 1 - fog, 1 - fog, 1 - fog, true);
 
 
        R_LightModel(m->numverts, 1 - fog, 1 - fog, 1 - fog, true);
 
-       memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
-       aliasmeshinfo.numverts = m->numverts;
-
-       R_DrawZymoticModelMesh(m);
-
-       if (fog)
-               R_DrawZymoticModelMeshFog(currentrenderentity->origin, m, fog);
+       R_DrawZymoticModelMesh(m, fog);
 }
 
 void R_DrawAliasModel (void)
 }
 
 void R_DrawAliasModel (void)
index ad66314..7640985 100644 (file)
@@ -69,6 +69,33 @@ cvar_t gl_fogend = {0, "gl_fogend","0"};
 
 cvar_t r_textureunits = {0, "r_textureunits", "32"};
 
 
 cvar_t r_textureunits = {0, "r_textureunits", "32"};
 
+void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
+{
+       int i;
+       for (i = 0;i < verts;i++)
+       {
+               out[0] = in[0] * r;
+               out[1] = in[1] * g;
+               out[2] = in[2] * b;
+               out[3] = in[3];
+               in += 4;
+               out += 4;
+       }
+}
+
+void R_FillColors(float *out, int verts, float r, float g, float b, float a)
+{
+       int i;
+       for (i = 0;i < verts;i++)
+       {
+               out[0] = r;
+               out[1] = g;
+               out[2] = b;
+               out[3] = a;
+               out += 4;
+       }
+}
+
 /*
 ====================
 R_TimeRefresh_f
 /*
 ====================
 R_TimeRefresh_f
index dbe515c..c9ce94c 100644 (file)
@@ -1884,48 +1884,49 @@ void R_DrawSurfaces (int type)
        }
 }
 
        }
 }
 
-static float portalpointbuffer[256][3];
-
 void R_DrawPortals(void)
 {
        int drawportals, i;
 void R_DrawPortals(void)
 {
        int drawportals, i;
+       float *v;
        mportal_t *portal, *endportal;
        mportal_t *portal, *endportal;
-       mvertex_t *point;
-       rmeshinfo_t m;
+       rmeshbufferinfo_t m;
        drawportals = r_drawportals.integer;
 
        if (drawportals < 1)
                return;
 
        drawportals = r_drawportals.integer;
 
        if (drawportals < 1)
                return;
 
-       memset(&m, 0, sizeof(m));
-       m.transparent = true;
-       m.blendfunc1 = GL_SRC_ALPHA;
-       m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-       m.vertex = &portalpointbuffer[0][0];
-       m.vertexstep = sizeof(float[3]);
-       m.ca = 0.125;
        for (portal = cl.worldmodel->portals, endportal = portal + cl.worldmodel->numportals;portal < endportal;portal++)
        {
                if (portal->visframe == r_portalframecount)
                {
        for (portal = cl.worldmodel->portals, endportal = portal + cl.worldmodel->numportals;portal < endportal;portal++)
        {
                if (portal->visframe == r_portalframecount)
                {
-                       if (portal->numpoints <= 256)
+                       memset(&m, 0, sizeof(m));
+                       m.transparent = true;
+                       m.blendfunc1 = GL_SRC_ALPHA;
+                       m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+                       m.numverts = portal->numpoints;
+                       m.numtriangles = portal->numpoints - 2;
+                       if (R_Mesh_Draw_GetBuffer(&m, false))
                        {
                        {
+                               for (i = 0;i < m.numtriangles;i++)
+                               {
+                                       m.index[i * 3 + 0] = 0;
+                                       m.index[i * 3 + 1] = i + 1;
+                                       m.index[i * 3 + 2] = i + 2;
+                               }
                                i = portal - cl.worldmodel->portals;
                                i = portal - cl.worldmodel->portals;
-                               m.cr = ((i & 0x0007) >> 0) * (1.0f / 7.0f);
-                               m.cg = ((i & 0x0038) >> 3) * (1.0f / 7.0f);
-                               m.cb = ((i & 0x01C0) >> 6) * (1.0f / 7.0f);
-                               point = portal->points;
+                               R_FillColors(m.color, m.numverts,
+                                       ((i & 0x0007) >> 0) * (1.0f / 7.0f) * m.colorscale,
+                                       ((i & 0x0038) >> 3) * (1.0f / 7.0f) * m.colorscale,
+                                       ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * m.colorscale,
+                                       0.125f);
                                if (PlaneDiff(r_origin, (&portal->plane)) > 0)
                                {
                                if (PlaneDiff(r_origin, (&portal->plane)) > 0)
                                {
-                                       for (i = portal->numpoints - 1;i >= 0;i--)
-                                               VectorCopy(point[i].position, portalpointbuffer[i]);
+                                       for (i = portal->numpoints - 1, v = m.vertex;i >= 0;i--, v += 4)
+                                               VectorCopy(portal->points[i].position, v);
                                }
                                else
                                }
                                else
-                               {
-                                       for (i = 0;i < portal->numpoints;i++)
-                                               VectorCopy(point[i].position, portalpointbuffer[i]);
-                               }
-                               R_Mesh_DrawPolygon(&m, portal->numpoints);
+                                       for (i = 0, v = m.vertex;i < portal->numpoints;i++, v += 4)
+                                               VectorCopy(portal->points[i].position, v);
                                R_Mesh_Render();
                        }
                }
                                R_Mesh_Render();
                        }
                }
index 16c158b..394cc41 100644 (file)
--- a/render.h
+++ b/render.h
@@ -68,6 +68,10 @@ extern cvar_t r_novis;
 // detail texture stuff
 extern cvar_t r_detailtextures;
 
 // detail texture stuff
 extern cvar_t r_detailtextures;
 
+// useful functions for rendering
+void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b);
+void R_FillColors(float *out, int verts, float r, float g, float b, float a);
+
 #define        TOP_RANGE               16                      // soldier uniform colors
 #define        BOTTOM_RANGE    96
 
 #define        TOP_RANGE               16                      // soldier uniform colors
 #define        BOTTOM_RANGE    96