CSQC polygonbegin functionality now uses the CL_MeshEntities system, this finally...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 13 Apr 2018 02:23:34 +0000 (02:23 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 13 Apr 2018 02:23:34 +0000 (02:23 +0000)
UI elements (DrawQ_ system) now use the CL_MeshEntities system, but still renders the mesh the old way, shader support is planned.

DrawQ_Line no longer uses GL_LINES, it now produces a polygon in the CL_MeshEntities system, so shownetgraph and r_speeds_graph features now work on D3D9/DPSOFTRAST/GLES2 render paths.

Added MATERIALFLAG_VERTEXCOLOR as a special case for rgbgen vertex shaders that are being used by CL_MeshEntities meshes, currently this is an unlit type of material but lighting support for it is planned.

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

16 files changed:
cl_main.c
cl_screen.c
clvm_cmds.c
csprogs.h
draw.h
gl_draw.c
gl_rmain.c
model_alias.c
model_brush.c
model_brush.h
model_shared.c
model_shared.h
mvm_cmds.c
progsvm.h
r_lightning.c
render.h

index 8753a5e..f70aeb8 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -2406,7 +2406,7 @@ void CL_MeshEntities_Init(void)
                ent->state_current.active = true;
                ent->render.model = cl_meshentitymodels + i;
                ent->render.alpha = 1;
-               ent->render.flags = RENDER_SHADOW | RENDER_LIGHT | RENDER_CUSTOMIZEDMODELLIGHT;
+               ent->render.flags = RENDER_SHADOW | RENDER_LIGHT;
                ent->render.framegroupblend[0].lerp = 1;
                ent->render.frameblend[0].lerp = 1;
                VectorSet(ent->render.colormod, 1, 1, 1);
index b62fa45..733aca0 100644 (file)
@@ -252,14 +252,12 @@ static void SCR_CheckDrawCenterString (void)
 static void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth, int graphheight, float graphscale, int graphlimit, const char *label, float textsize, int packetcounter, netgraphitem_t *netgraph)
 {
        netgraphitem_t *graph;
-       int j, x, y, numlines;
+       int j, x, y;
        int totalbytes = 0;
        char bytesstring[128];
        float g[NETGRAPH_PACKETS][7];
        float *a;
        float *b;
-       r_vertexgeneric_t vertex[(NETGRAPH_PACKETS+2)*6*2];
-       r_vertexgeneric_t *v;
        DrawQ_Fill(graphx, graphy, graphwidth, graphheight + textsize * 2, 0, 0, 0, 0.5, 0);
        // draw the bar graph itself
        memset(g, 0, sizeof(g));
@@ -299,38 +297,18 @@ static void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth,
                g[j][6] = bound(0.0f, g[j][6], 1.0f);
        }
        // render the lines for the graph
-       numlines = 0;
-       v = vertex;
        for (j = 0;j < NETGRAPH_PACKETS;j++)
        {
                a = g[j];
                b = g[(j+1)%NETGRAPH_PACKETS];
                if (a[0] < 0.0f || b[0] > 1.0f || b[0] < a[0])
                        continue;
-               VectorSet(v->vertex3f, graphx + graphwidth * a[0], graphy + graphheight * a[2], 0.0f);Vector4Set(v->color4f, 1.0f, 1.0f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-               VectorSet(v->vertex3f, graphx + graphwidth * b[0], graphy + graphheight * b[2], 0.0f);Vector4Set(v->color4f, 1.0f, 1.0f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-
-               VectorSet(v->vertex3f, graphx + graphwidth * a[0], graphy + graphheight * a[1], 0.0f);Vector4Set(v->color4f, 1.0f, 0.0f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-               VectorSet(v->vertex3f, graphx + graphwidth * b[0], graphy + graphheight * b[1], 0.0f);Vector4Set(v->color4f, 1.0f, 0.0f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-
-               VectorSet(v->vertex3f, graphx + graphwidth * a[0], graphy + graphheight * a[5], 0.0f);Vector4Set(v->color4f, 0.0f, 1.0f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-               VectorSet(v->vertex3f, graphx + graphwidth * b[0], graphy + graphheight * b[5], 0.0f);Vector4Set(v->color4f, 0.0f, 1.0f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-
-               VectorSet(v->vertex3f, graphx + graphwidth * a[0], graphy + graphheight * a[4], 0.0f);Vector4Set(v->color4f, 1.0f, 1.0f, 1.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-               VectorSet(v->vertex3f, graphx + graphwidth * b[0], graphy + graphheight * b[4], 0.0f);Vector4Set(v->color4f, 1.0f, 1.0f, 1.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-
-               VectorSet(v->vertex3f, graphx + graphwidth * a[0], graphy + graphheight * a[3], 0.0f);Vector4Set(v->color4f, 1.0f, 0.5f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-               VectorSet(v->vertex3f, graphx + graphwidth * b[0], graphy + graphheight * b[3], 0.0f);Vector4Set(v->color4f, 1.0f, 0.5f, 0.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-
-               VectorSet(v->vertex3f, graphx + graphwidth * a[0], graphy + graphheight * a[6], 0.0f);Vector4Set(v->color4f, 0.0f, 0.0f, 1.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-               VectorSet(v->vertex3f, graphx + graphwidth * b[0], graphy + graphheight * b[6], 0.0f);Vector4Set(v->color4f, 0.0f, 0.0f, 1.0f, 1.0f);Vector2Set(v->texcoord2f, 0.0f, 0.0f);v++;
-
-               numlines += 6;
-       }
-       if (numlines > 0)
-       {
-               R_Mesh_PrepareVertices_Generic(numlines*2, vertex, NULL, 0);
-               DrawQ_Lines(0.0f, numlines, 0, false);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[2], graphx + graphwidth * b[0], graphy + graphheight * b[2], 1.0f, 1.0f, 1.0f, 1.0f, 0);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[1], graphx + graphwidth * b[0], graphy + graphheight * b[1], 1.0f, 0.0f, 0.0f, 1.0f, 0);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[5], graphx + graphwidth * b[0], graphy + graphheight * b[5], 0.0f, 1.0f, 0.0f, 1.0f, 0);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[4], graphx + graphwidth * b[0], graphy + graphheight * b[4], 1.0f, 1.0f, 1.0f, 1.0f, 0);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[3], graphx + graphwidth * b[0], graphy + graphheight * b[3], 1.0f, 0.5f, 0.0f, 1.0f, 0);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[6], graphx + graphwidth * b[0], graphy + graphheight * b[6], 0.0f, 0.0f, 1.0f, 1.0f, 0);
        }
        x = graphx;
        y = graphy + graphheight;
@@ -1134,8 +1112,7 @@ static void R_TimeReport_EndFrame(void)
        if (cls.r_speeds_graph_length)
        {
                char legend[128];
-               r_vertexgeneric_t *v;
-               int i, numlines;
+               int i;
                const int *data;
                float x, y, width, height, scalex, scaley;
                int range_default = max(r_speeds_graph_maxdefault.integer, 1);
@@ -1215,9 +1192,6 @@ static void R_TimeReport_EndFrame(void)
                        // legend text is drawn after the graphs
                        // render the graph lines, we'll go back and render the legend text later
                        scalex = (float)width / (1000000.0 * r_speeds_graph_seconds.value);
-                       // get space in a vertex buffer to draw this
-                       numlines = stats * (graph_length - 1);
-                       v = R_Mesh_PrepareVertices_Generic_Lock(numlines * 2);
                        stats = 0;
                        for (color = 0;color < R_SPEEDS_GRAPH_COLORS;color++)
                        {
@@ -1240,39 +1214,19 @@ static void R_TimeReport_EndFrame(void)
                                sum = 0;
                                for (i = 0;i < graph_length - 1;)
                                {
-                                       v->vertex3f[0] = x + width - sum * scalex;
-                                       if (v->vertex3f[0] < x)
-                                               v->vertex3f[0] = x;
-                                       v->vertex3f[1] = y + height - (data[index] - range_min) * scaley;
-                                       v->vertex3f[2] = 0;
-                                       v->color4f[0] = r_speeds_graph_colors[color][0];
-                                       v->color4f[1] = r_speeds_graph_colors[color][1];
-                                       v->color4f[2] = r_speeds_graph_colors[color][2];
-                                       v->color4f[3] = r_speeds_graph_colors[color][3];
-                                       v->texcoord2f[0] = 0;
-                                       v->texcoord2f[1] = 0;
-                                       v++;
+                                       float x1, y1, x2, y2;
+                                       x1 = max(x, x + width - sum * scalex);
+                                       y1 = y + height - (data[index] - range_min) * scaley;
                                        sum += graph_data[r_stat_timedelta * graph_length + index];
                                        index--;
                                        if (index < 0)
                                                index = graph_length - 1;
                                        i++;
-                                       v->vertex3f[0] = x + width - sum * scalex;
-                                       if (v->vertex3f[0] < x)
-                                               v->vertex3f[0] = x;
-                                       v->vertex3f[1] = y + height - (data[index] - range_min) * scaley;
-                                       v->vertex3f[2] = 0;
-                                       v->color4f[0] = r_speeds_graph_colors[color][0];
-                                       v->color4f[1] = r_speeds_graph_colors[color][1];
-                                       v->color4f[2] = r_speeds_graph_colors[color][2];
-                                       v->color4f[3] = r_speeds_graph_colors[color][3];
-                                       v->texcoord2f[0] = 0;
-                                       v->texcoord2f[1] = 0;
-                                       v++;
+                                       x2 = max(x, x + width - sum * scalex);
+                                       y2 = y + height - (data[index] - range_min) * scaley;
+                                       DrawQ_Line(1, x1, y1, x2, y2, r_speeds_graph_colors[color][0], r_speeds_graph_colors[color][1], r_speeds_graph_colors[color][2], r_speeds_graph_colors[color][3], 0);
                                }
                        }
-                       R_Mesh_PrepareVertices_Generic_Unlock();
-                       DrawQ_Lines(0.0f, numlines, 0, false);
                }
 
                // return to not drawing anything if r_render is 0
index 27d247f..02f1607 100644 (file)
@@ -3252,7 +3252,6 @@ static void VM_CL_GetEntity (prvm_prog_t *prog)
 static void VM_CL_R_RenderScene (prvm_prog_t *prog)
 {
        double t = Sys_DirtyTime();
-       vmpolygons_t *polys = &prog->vmpolygons;
        VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
 
        // update the views
@@ -3269,275 +3268,88 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog)
        // we need to update any RENDER_VIEWMODEL entities at this point because
        // csqc supplies its own view matrix
        CL_UpdateViewEntities();
+       CL_MeshEntities_AddToScene();
        CL_UpdateEntityShading();
 
        // now draw stuff!
        R_RenderView();
 
-       polys->num_vertices = polys->num_triangles = 0;
+       Mod_Mesh_Reset(CL_Mesh_CSQC());
 
        // callprofile fixing hack: do not include this time in what is counted for CSQC_UpdateView
        t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
        prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
 }
 
-static void VM_ResizePolygons(vmpolygons_t *polys)
-{
-       float *oldvertex3f = polys->data_vertex3f;
-       float *oldcolor4f = polys->data_color4f;
-       float *oldtexcoord2f = polys->data_texcoord2f;
-       vmpolygons_triangle_t *oldtriangles = polys->data_triangles;
-       unsigned short *oldsortedelement3s = polys->data_sortedelement3s;
-       polys->max_vertices = min(polys->max_triangles*3, 65536);
-       polys->data_vertex3f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[3]));
-       polys->data_color4f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[4]));
-       polys->data_texcoord2f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[2]));
-       polys->data_triangles = (vmpolygons_triangle_t *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(vmpolygons_triangle_t));
-       polys->data_sortedelement3s = (unsigned short *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(unsigned short[3]));
-       if (polys->num_vertices)
-       {
-               memcpy(polys->data_vertex3f, oldvertex3f, polys->num_vertices*sizeof(float[3]));
-               memcpy(polys->data_color4f, oldcolor4f, polys->num_vertices*sizeof(float[4]));
-               memcpy(polys->data_texcoord2f, oldtexcoord2f, polys->num_vertices*sizeof(float[2]));
-       }
-       if (polys->num_triangles)
-       {
-               memcpy(polys->data_triangles, oldtriangles, polys->num_triangles*sizeof(vmpolygons_triangle_t));
-               memcpy(polys->data_sortedelement3s, oldsortedelement3s, polys->num_triangles*sizeof(unsigned short[3]));
-       }
-       if (oldvertex3f)
-               Mem_Free(oldvertex3f);
-       if (oldcolor4f)
-               Mem_Free(oldcolor4f);
-       if (oldtexcoord2f)
-               Mem_Free(oldtexcoord2f);
-       if (oldtriangles)
-               Mem_Free(oldtriangles);
-       if (oldsortedelement3s)
-               Mem_Free(oldsortedelement3s);
-}
-
-static void VM_InitPolygons (vmpolygons_t* polys)
-{
-       memset(polys, 0, sizeof(*polys));
-       polys->pool = Mem_AllocPool("VMPOLY", 0, NULL);
-       polys->max_triangles = 1024;
-       VM_ResizePolygons(polys);
-       polys->initialized = true;
-}
-
-static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
-{
-       int surfacelistindex;
-       vmpolygons_t *polys = (vmpolygons_t *)ent;
-//     R_Mesh_ResetTextureState();
-       R_EntityMatrix(&identitymatrix);
-       GL_CullFace(GL_NONE);
-       GL_DepthTest(true); // polys in 3D space shall always have depth test
-       GL_DepthRange(0, 1);
-       R_Mesh_PrepareVertices_Generic_Arrays(polys->num_vertices, polys->data_vertex3f, polys->data_color4f, polys->data_texcoord2f);
-
-       for (surfacelistindex = 0;surfacelistindex < numsurfaces;)
-       {
-               int numtriangles = 0;
-               rtexture_t *tex = polys->data_triangles[surfacelist[surfacelistindex]].texture;
-               int drawflag = polys->data_triangles[surfacelist[surfacelistindex]].drawflag;
-               DrawQ_ProcessDrawFlag(drawflag, polys->data_triangles[surfacelist[surfacelistindex]].hasalpha);
-               R_SetupShader_Generic(tex, NULL, GL_MODULATE, 1, false, false, false);
-               numtriangles = 0;
-               for (;surfacelistindex < numsurfaces;surfacelistindex++)
-               {
-                       if (polys->data_triangles[surfacelist[surfacelistindex]].texture != tex || polys->data_triangles[surfacelist[surfacelistindex]].drawflag != drawflag)
-                               break;
-                       VectorCopy(polys->data_triangles[surfacelist[surfacelistindex]].elements, polys->data_sortedelement3s + 3*numtriangles);
-                       numtriangles++;
-               }
-               R_Mesh_Draw(0, polys->num_vertices, 0, numtriangles, NULL, NULL, 0, polys->data_sortedelement3s, NULL, 0);
-       }
-}
-
-static void VMPolygons_Store(vmpolygons_t *polys)
-{
-       qboolean hasalpha;
-       int i;
-
-       // detect if we have alpha
-       hasalpha = polys->begin_texture_hasalpha;
-       for(i = 0; !hasalpha && (i < polys->begin_vertices); ++i)
-               if(polys->begin_color[i][3] < 1)
-                       hasalpha = true;
-
-       if (polys->begin_draw2d)
-       {
-               // draw the polygon as 2D immediately
-               drawqueuemesh_t mesh;
-               mesh.texture = polys->begin_texture;
-               mesh.num_vertices = polys->begin_vertices;
-               mesh.num_triangles = polys->begin_vertices-2;
-               mesh.data_element3i = polygonelement3i;
-               mesh.data_element3s = polygonelement3s;
-               mesh.data_vertex3f = polys->begin_vertex[0];
-               mesh.data_color4f = polys->begin_color[0];
-               mesh.data_texcoord2f = polys->begin_texcoord[0];
-               DrawQ_Mesh(&mesh, polys->begin_drawflag, hasalpha);
-       }
-       else
-       {
-               // queue the polygon as 3D for sorted transparent rendering later
-               if (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
-               {
-                       while (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
-                               polys->max_triangles *= 2;
-                       VM_ResizePolygons(polys);
-               }
-               if (polys->num_vertices + polys->begin_vertices <= polys->max_vertices)
-               {
-                       // needle in a haystack!
-                       // polys->num_vertices was used for copying where we actually want to copy begin_vertices
-                       // that also caused it to not render the first polygon that is added
-                       // --blub
-                       memcpy(polys->data_vertex3f + polys->num_vertices * 3, polys->begin_vertex[0], polys->begin_vertices * sizeof(float[3]));
-                       memcpy(polys->data_color4f + polys->num_vertices * 4, polys->begin_color[0], polys->begin_vertices * sizeof(float[4]));
-                       memcpy(polys->data_texcoord2f + polys->num_vertices * 2, polys->begin_texcoord[0], polys->begin_vertices * sizeof(float[2]));
-                       for (i = 0;i < polys->begin_vertices-2;i++)
-                       {
-                               polys->data_triangles[polys->num_triangles].texture = polys->begin_texture;
-                               polys->data_triangles[polys->num_triangles].drawflag = polys->begin_drawflag;
-                               polys->data_triangles[polys->num_triangles].elements[0] = polys->num_vertices;
-                               polys->data_triangles[polys->num_triangles].elements[1] = polys->num_vertices + i+1;
-                               polys->data_triangles[polys->num_triangles].elements[2] = polys->num_vertices + i+2;
-                               polys->data_triangles[polys->num_triangles].hasalpha = hasalpha;
-                               polys->num_triangles++;
-                       }
-                       polys->num_vertices += polys->begin_vertices;
-               }
-       }
-       polys->begin_active = false;
-}
-
-// TODO: move this into the client code and clean-up everything else, too! [1/6/2008 Black]
-// LordHavoc: agreed, this is a mess
-void VM_CL_AddPolygonsToMeshQueue (prvm_prog_t *prog)
-{
-       int i;
-       vmpolygons_t *polys = &prog->vmpolygons;
-       vec3_t center;
-
-       // only add polygons of the currently active prog to the queue - if there is none, we're done
-       if( !prog )
-               return;
-
-       if (!polys->num_triangles)
-               return;
-
-       for (i = 0;i < polys->num_triangles;i++)
-       {
-               VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[2], center);
-               R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL);
-       }
-
-       /*polys->num_triangles = 0; // now done after rendering the scene,
-         polys->num_vertices = 0;  // otherwise it's not rendered at all and prints an error message --blub */
-}
-
 //void(string texturename, float flag[, float is2d]) R_BeginPolygon
 static void VM_CL_R_PolygonBegin (prvm_prog_t *prog)
 {
-       const char              *picname;
-       skinframe_t     *sf;
-       vmpolygons_t *polys = &prog->vmpolygons;
-       int tf;
-
-       // TODO instead of using skinframes here (which provides the benefit of
-       // better management of flags, and is more suited for 3D rendering), what
-       // about supporting Q3 shaders?
+       const char *texname;
+       int drawflags;
+       qboolean draw2d;
+       dp_model_t *mod;
 
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_PolygonBegin);
 
-       if (!polys->initialized)
-               VM_InitPolygons(polys);
-       if (polys->begin_active)
-       {
-               VM_Warning(prog, "VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonBegin after first\n");
-               return;
-       }
-       picname = PRVM_G_STRING(OFS_PARM0);
-
-       sf = NULL;
-       if(*picname)
-       {
-               tf = TEXF_ALPHA;
-               if((int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MIPMAP)
-                       tf |= TEXF_MIPMAP;
+       texname = PRVM_G_STRING(OFS_PARM0);
+       drawflags = (int)PRVM_G_FLOAT(OFS_PARM1);
+       // weird hacky way to figure out if this is a 2D HUD polygon or a scene polygon
+       draw2d = (prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : r_refdef.draw2dstage);
 
-               do
-               {
-                       sf = R_SkinFrame_FindNextByName(sf, picname);
-               }
-               while(sf && sf->textureflags != tf);
-
-               if(!sf || !sf->base)
-                       sf = R_SkinFrame_LoadExternal(picname, tf, true, true);
-
-               if(sf)
-                       R_SkinFrame_MarkUsed(sf);
-       }
-
-       polys->begin_texture = (sf && sf->base) ? sf->base : r_texture_white;
-       polys->begin_texture_hasalpha = (sf && sf->base) ? sf->hasalpha : false;
-       polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MASK;
-       polys->begin_vertices = 0;
-       polys->begin_active = true;
-       polys->begin_draw2d = (prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : r_refdef.draw2dstage);
+       // we need to remember whether this is a 2D or 3D mesh we're adding to
+       mod = draw2d ? CL_Mesh_UI() : CL_Mesh_CSQC();
+       prog->polygonbegin_model = mod;
+       Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, texname, drawflags, TEXF_ALPHA, MATERIALFLAG_VERTEXCOLOR), draw2d);
 }
 
 //void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
 static void VM_CL_R_PolygonVertex (prvm_prog_t *prog)
 {
-       vmpolygons_t *polys = &prog->vmpolygons;
+       const prvm_vec_t *v = PRVM_G_VECTOR(OFS_PARM0);
+       const prvm_vec_t *tc = PRVM_G_VECTOR(OFS_PARM1);
+       const prvm_vec_t *c = PRVM_G_VECTOR(OFS_PARM2);
+       const prvm_vec_t a = PRVM_G_FLOAT(OFS_PARM3);
+       dp_model_t *mod = prog->polygonbegin_model;
+       int e0, e1, e2;
+       msurface_t *surf;
 
        VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex);
 
-       if (!polys->begin_active)
+       if (!mod || mod->num_surfaces == 0)
        {
                VM_Warning(prog, "VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
                return;
        }
 
-       if (polys->begin_vertices >= VMPOLYGONS_MAXPOINTS)
+       surf = &mod->data_surfaces[mod->num_surfaces - 1];
+       e2 = Mod_Mesh_IndexForVertex(mod, surf, v[0], v[1], v[2], 0, 0, 0, tc[0], tc[1], 0, 0, c[0], c[1], c[2], a);
+       if (surf->num_vertices >= 3)
        {
-               VM_Warning(prog, "VM_CL_R_PolygonVertex: may have %i vertices max\n", VMPOLYGONS_MAXPOINTS);
-               return;
+               // the first element is the start of the triangle fan
+               e0 = surf->num_firstvertex;
+               // the second element is the previous vertex
+               e1 = e0 + 1;
+               if (surf->num_triangles > 0)
+                       e1 = mod->surfmesh.data_element3i[(surf->num_firsttriangle + surf->num_triangles) * 3 - 1];
+               Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
        }
-
-       polys->begin_vertex[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM0)[0];
-       polys->begin_vertex[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM0)[1];
-       polys->begin_vertex[polys->begin_vertices][2] = PRVM_G_VECTOR(OFS_PARM0)[2];
-       polys->begin_texcoord[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM1)[0];
-       polys->begin_texcoord[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM1)[1];
-       polys->begin_color[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM2)[0];
-       polys->begin_color[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM2)[1];
-       polys->begin_color[polys->begin_vertices][2] = PRVM_G_VECTOR(OFS_PARM2)[2];
-       polys->begin_color[polys->begin_vertices][3] = PRVM_G_FLOAT(OFS_PARM3);
-       polys->begin_vertices++;
 }
 
 //void() R_EndPolygon
 static void VM_CL_R_PolygonEnd (prvm_prog_t *prog)
 {
-       vmpolygons_t *polys = &prog->vmpolygons;
+       dp_model_t *mod = prog->polygonbegin_model;
+       msurface_t *surf;
 
        VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd);
-       if (!polys->begin_active)
+       if (!mod || mod->num_surfaces == 0)
        {
                VM_Warning(prog, "VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
                return;
        }
-       polys->begin_active = false;
-       if (polys->begin_vertices >= 3)
-               VMPolygons_Store(polys);
-       else
-               VM_Warning(prog, "VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->begin_vertices);
+       surf = &mod->data_surfaces[mod->num_surfaces - 1];
+       Mod_BuildNormals(surf->num_firstvertex, surf->num_vertices, surf->num_triangles, mod->surfmesh.data_vertex3f, mod->surfmesh.data_element3i + 3 * surf->num_firsttriangle, mod->surfmesh.data_normal3f, true);
+       prog->polygonbegin_model = NULL;
 }
 
 /*
@@ -4934,27 +4746,15 @@ NULL
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
 
-void VM_Polygons_Reset(prvm_prog_t *prog)
-{
-       vmpolygons_t *polys = &prog->vmpolygons;
-
-       // TODO: replace vm_polygons stuff with a more general debugging polygon system, and make vm_polygons functions use that system
-       if(polys->initialized)
-       {
-               Mem_FreePool(&polys->pool);
-               polys->initialized = false;
-       }
-}
-
 void CLVM_init_cmd(prvm_prog_t *prog)
 {
        VM_Cmd_Init(prog);
-       VM_Polygons_Reset(prog);
+       prog->polygonbegin_model = NULL;
 }
 
 void CLVM_reset_cmd(prvm_prog_t *prog)
 {
        World_End(&cl.world);
        VM_Cmd_Reset(prog);
-       VM_Polygons_Reset(prog);
+       prog->polygonbegin_model = NULL;
 }
index 226cf96..bb05e38 100644 (file)
--- a/csprogs.h
+++ b/csprogs.h
@@ -100,8 +100,6 @@ void CL_VM_Parse_CenterPrint(const char *msg);
 int CL_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent);
 int CL_GetTagMatrix(prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex, prvm_vec_t *shadingorigin);
 void CL_GetEntityMatrix(prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix);
-/* VMs exposing the polygon calls must call this on Init/Reset */
-void VM_Polygons_Reset(prvm_prog_t *prog);
 void QW_CL_StartUpload(unsigned char *data, int size);
 
 void CSQC_UpdateNetworkTimes(double newtime, double oldtime);
diff --git a/draw.h b/draw.h
index 59470b6..bbd964e 100644 (file)
--- a/draw.h
+++ b/draw.h
@@ -157,23 +157,18 @@ float DrawQ_TextWidth_UntilWidth_TrackColors(const char *text, size_t *maxlen, f
 float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *maxlen, float w, float h, float sw, float sh, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth);
 // draw a very fancy pic (per corner texcoord/color control), the order is tl, tr, bl, br
 void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags);
-// draw a triangle mesh
-void DrawQ_Mesh(drawqueuemesh_t *mesh, int flags, qboolean hasalpha);
 // set the clipping area
 void DrawQ_SetClipArea(float x, float y, float width, float height);
 // reset the clipping area
 void DrawQ_ResetClipArea(void);
 // draw a line
 void DrawQ_Line(float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags);
-// draw a lot of lines (call R_Mesh_PrepareVertices_Generic first)
-void DrawQ_Lines(float width, int numlines, int flags, qboolean hasalpha);
-// draw a line loop
-void DrawQ_LineLoop(drawqueuemesh_t *mesh, int flags);
 // resets r_refdef.draw2dstage
 void DrawQ_Finish(void);
-void DrawQ_ProcessDrawFlag(int flags, qboolean alpha); // sets GL_DepthMask and GL_BlendFunc
 void DrawQ_RecalcView(void); // use this when changing r_refdef.view.* from e.g. csqc
-
+// batch draw the pending geometry in the CL_Mesh_UI() model and reset the model,
+// to be called by things like DrawQ_SetClipArea which make disruptive state changes.
+void DrawQ_FlushUI(void);
 
 const char *Draw_GetPicName(cachepic_t *pic);
 int Draw_GetPicWidth(cachepic_t *pic);
index 4e0bfd6..5f8a358 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -748,188 +748,64 @@ static void _DrawQ_Setup(void) // see R_ResetViewRendering2D
 {
        if (r_refdef.draw2dstage == 1)
                return;
+       DrawQ_FlushUI();
        r_refdef.draw2dstage = 1;
-
        R_ResetViewRendering2D_Common(0, NULL, NULL, vid_conwidth.integer, vid_conheight.integer);
 }
 
 qboolean r_draw2d_force = false;
-static void _DrawQ_SetupAndProcessDrawFlag(int flags, cachepic_t *pic, float alpha)
-{
-       _DrawQ_Setup();
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-       DrawQ_ProcessDrawFlag(flags, (alpha < 1) || (pic && pic->skinframe && pic->skinframe->hasalpha));
-}
-void DrawQ_ProcessDrawFlag(int flags, qboolean alpha)
-{
-       if(flags == DRAWFLAG_ADDITIVE)
-       {
-               GL_DepthMask(false);
-               GL_BlendFunc(alpha ? GL_SRC_ALPHA : GL_ONE, GL_ONE);
-       }
-       else if(flags == DRAWFLAG_MODULATE)
-       {
-               GL_DepthMask(false);
-               GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
-       }
-       else if(flags == DRAWFLAG_2XMODULATE)
-       {
-               GL_DepthMask(false);
-               GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
-       }
-       else if(flags == DRAWFLAG_SCREEN)
-       {
-               GL_DepthMask(false);
-               GL_BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
-       }
-       else if(alpha)
-       {
-               GL_DepthMask(false);
-               GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       }
-       else
-       {
-               GL_DepthMask(true);
-               GL_BlendFunc(GL_ONE, GL_ZERO);
-       }
-}
 
 void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags)
 {
-       float floats[36];
-
-       _DrawQ_SetupAndProcessDrawFlag(flags, pic, alpha);
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-
-//     R_Mesh_ResetTextureState();
-       floats[12] = 0.0f;floats[13] = 0.0f;
-       floats[14] = 1.0f;floats[15] = 0.0f;
-       floats[16] = 1.0f;floats[17] = 1.0f;
-       floats[18] = 0.0f;floats[19] = 1.0f;
-       floats[20] = floats[24] = floats[28] = floats[32] = red;
-       floats[21] = floats[25] = floats[29] = floats[33] = green;
-       floats[22] = floats[26] = floats[30] = floats[34] = blue;
-       floats[23] = floats[27] = floats[31] = floats[35] = alpha;
-       if (pic)
-       {
-               if (width == 0)
-                       width = pic->width;
-               if (height == 0)
-                       height = pic->height;
-               R_SetupShader_Generic(Draw_GetPicTexture(pic), NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
-
-#if 0
-      // AK07: lets be texel correct on the corners
-      {
-         float horz_offset = 0.5f / pic->width;
-         float vert_offset = 0.5f / pic->height;
-
-                  floats[12] = 0.0f + horz_offset;floats[13] = 0.0f + vert_offset;
-                  floats[14] = 1.0f - horz_offset;floats[15] = 0.0f + vert_offset;
-                  floats[16] = 1.0f - horz_offset;floats[17] = 1.0f - vert_offset;
-                  floats[18] = 0.0f + horz_offset;floats[19] = 1.0f - vert_offset;
-      }
-#endif
-       }
-       else
-               R_SetupShader_Generic_NoTexture((flags & DRAWFLAGS_BLEND) ? false : true, true);
-
-       floats[2] = floats[5] = floats[8] = floats[11] = 0;
-       floats[0] = floats[9] = x;
-       floats[1] = floats[4] = y;
-       floats[3] = floats[6] = x + width;
-       floats[7] = floats[10] = y + height;
-
-       R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12);
-       R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+       dp_model_t *mod = CL_Mesh_UI();
+       msurface_t *surf;
+       int e0, e1, e2, e3;
+       _DrawQ_Setup();
+       if (!pic)
+               pic = Draw_CachePic("white");
+       if (width == 0)
+               width = pic->width;
+       if (height == 0)
+               height = pic->height;
+       surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_VERTEXCOLOR), true);
+       e0 = Mod_Mesh_IndexForVertex(mod, surf, x        , y         , 0, 0, 0, -1, 0, 0, 0, 0, red, green, blue, alpha);
+       e1 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y         , 0, 0, 0, -1, 1, 0, 0, 0, red, green, blue, alpha);
+       e2 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y + height, 0, 0, 0, -1, 1, 1, 0, 0, red, green, blue, alpha);
+       e3 = Mod_Mesh_IndexForVertex(mod, surf, x        , y + height, 0, 0, 0, -1, 0, 1, 0, 0, red, green, blue, alpha);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
 }
 
 void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, float org_x, float org_y, float angle, float red, float green, float blue, float alpha, int flags)
 {
-       float floats[36];
        float af = DEG2RAD(-angle); // forward
        float ar = DEG2RAD(-angle + 90); // right
        float sinaf = sin(af);
        float cosaf = cos(af);
        float sinar = sin(ar);
        float cosar = cos(ar);
-
-       _DrawQ_SetupAndProcessDrawFlag(flags, pic, alpha);
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-
-//     R_Mesh_ResetTextureState();
-       if (pic)
-       {
-               if (width == 0)
-                       width = pic->width;
-               if (height == 0)
-                       height = pic->height;
-               R_SetupShader_Generic(Draw_GetPicTexture(pic), NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
-       }
-       else
-               R_SetupShader_Generic_NoTexture((flags & DRAWFLAGS_BLEND) ? false : true, true);
-
-       floats[2] = floats[5] = floats[8] = floats[11] = 0;
-
-// top left
-       floats[0] = x - cosaf*org_x - cosar*org_y;
-       floats[1] = y - sinaf*org_x - sinar*org_y;
-
-// top right
-       floats[3] = x + cosaf*(width-org_x) - cosar*org_y;
-       floats[4] = y + sinaf*(width-org_x) - sinar*org_y;
-
-// bottom right
-       floats[6] = x + cosaf*(width-org_x) + cosar*(height-org_y);
-       floats[7] = y + sinaf*(width-org_x) + sinar*(height-org_y);
-
-// bottom left
-       floats[9]  = x - cosaf*org_x + cosar*(height-org_y);
-       floats[10] = y - sinaf*org_x + sinar*(height-org_y);
-
-       floats[12] = 0.0f;floats[13] = 0.0f;
-       floats[14] = 1.0f;floats[15] = 0.0f;
-       floats[16] = 1.0f;floats[17] = 1.0f;
-       floats[18] = 0.0f;floats[19] = 1.0f;
-       floats[20] = floats[24] = floats[28] = floats[32] = red;
-       floats[21] = floats[25] = floats[29] = floats[33] = green;
-       floats[22] = floats[26] = floats[30] = floats[34] = blue;
-       floats[23] = floats[27] = floats[31] = floats[35] = alpha;
-
-       R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12);
-       R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+       dp_model_t *mod = CL_Mesh_UI();
+       msurface_t *surf;
+       int e0, e1, e2, e3;
+       _DrawQ_Setup();
+       if (!pic)
+               pic = Draw_CachePic("white");
+       if (width == 0)
+               width = pic->width;
+       if (height == 0)
+               height = pic->height;
+       surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_VERTEXCOLOR), true);
+       e0 = Mod_Mesh_IndexForVertex(mod, surf, x - cosaf * org_x - cosar * org_y, y - sinaf * org_x - sinar * org_y, 0, 0, 0, -1, 0, 0, 0, 0, red, green, blue, alpha);
+       e1 = Mod_Mesh_IndexForVertex(mod, surf, x + cosaf * (width - org_x) - cosar * org_y, y + sinaf * (width - org_x) - sinar * org_y, 0, 0, 0, -1, 1, 0, 0, 0, red, green, blue, alpha);
+       e2 = Mod_Mesh_IndexForVertex(mod, surf, x + cosaf * (width - org_x) + cosar * (height - org_y), sinaf*(width - org_x) + sinar * (height - org_y), 0, 0, 0, -1, 1, 1, 0, 0, red, green, blue, alpha);
+       e3 = Mod_Mesh_IndexForVertex(mod, surf, x - cosaf * org_x + cosar * (height - org_y), y - sinaf * org_x + sinar * (height - org_y), 0, 0, 0, -1, 0, 1, 0, 0, red, green, blue, alpha);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
 }
 
 void DrawQ_Fill(float x, float y, float width, float height, float red, float green, float blue, float alpha, int flags)
 {
-       float floats[36];
-
-       _DrawQ_SetupAndProcessDrawFlag(flags, NULL, alpha);
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-
-//     R_Mesh_ResetTextureState();
-       R_SetupShader_Generic_NoTexture((flags & DRAWFLAGS_BLEND) ? false : true, true);
-
-       floats[2] = floats[5] = floats[8] = floats[11] = 0;
-       floats[0] = floats[9] = x;
-       floats[1] = floats[4] = y;
-       floats[3] = floats[6] = x + width;
-       floats[7] = floats[10] = y + height;
-       floats[12] = 0.0f;floats[13] = 0.0f;
-       floats[14] = 1.0f;floats[15] = 0.0f;
-       floats[16] = 1.0f;floats[17] = 1.0f;
-       floats[18] = 0.0f;floats[19] = 1.0f;
-       floats[20] = floats[24] = floats[28] = floats[32] = red;
-       floats[21] = floats[25] = floats[29] = floats[33] = green;
-       floats[22] = floats[26] = floats[30] = floats[34] = blue;
-       floats[23] = floats[27] = floats[31] = floats[35] = alpha;
-
-       R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12);
-       R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+       DrawQ_Pic(x, y, Draw_CachePic("white"), width, height, red, green, blue, alpha, flags);
 }
 
 /// color tag printing
@@ -1178,11 +1054,6 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma
        int shadow, colorindex = STRING_COLOR_DEFAULT;
        size_t i;
        float x = startx, y, s, t, u, v, thisw;
-       float *av, *at, *ac;
-       int batchcount;
-       static float vertex3f[QUADELEMENTS_MAXQUADS*4*3];
-       static float texcoord2f[QUADELEMENTS_MAXQUADS*4*2];
-       static float color4f[QUADELEMENTS_MAXQUADS*4*4];
        Uchar ch, mapch, nextch;
        Uchar prevch = 0; // used for kerning
        int tempcolorindex;
@@ -1199,11 +1070,15 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma
        size_t bytes_left;
        float dw, dh;
        const float *width_of;
-
+       dp_model_t *mod = CL_Mesh_UI();
+       msurface_t *surf = NULL;
+       int e0, e1, e2, e3;
        int tw, th;
        tw = Draw_GetPicWidth(fnt->pic);
        th = Draw_GetPicHeight(fnt->pic);
 
+       _DrawQ_Setup();
+
        if (!h) h = w;
        if (!h) {
                h = w = 1;
@@ -1233,20 +1108,9 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma
        if (maxlen < 1)
                maxlen = 1<<30;
 
-       _DrawQ_SetupAndProcessDrawFlag(flags, NULL, 0);
        if(!r_draw2d.integer && !r_draw2d_force)
                return startx + DrawQ_TextWidth_UntilWidth_TrackColors_Scale(text, &maxlen, w, h, sw, sh, NULL, ignorecolorcodes, fnt, 1000000000);
 
-//     R_Mesh_ResetTextureState();
-       if (!fontmap)
-               R_Mesh_TexBind(0, Draw_GetPicTexture(fnt->pic));
-       R_SetupShader_Generic(Draw_GetPicTexture(fnt->pic), NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
-
-       ac = color4f;
-       at = texcoord2f;
-       av = vertex3f;
-       batchcount = 0;
-
        //ftbase_x = snap_to_pixel_x(ftbase_x);
        if(snap)
        {
@@ -1363,23 +1227,7 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma
                                if (ch > 0xFF)
                                        goto out;
                                if (fontmap)
-                               {
-                                       if (map != ft2_oldstyle_map)
-                                       {
-                                               if (batchcount)
-                                               {
-                                                       // switching from freetype to non-freetype rendering
-                                                       R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
-                                                       R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
-                                                       batchcount = 0;
-                                                       ac = color4f;
-                                                       at = texcoord2f;
-                                                       av = vertex3f;
-                                               }
-                                               R_SetupShader_Generic(Draw_GetPicTexture(fnt->pic), NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
-                                               map = ft2_oldstyle_map;
-                                       }
-                               }
+                                       map = ft2_oldstyle_map;
                                prevch = 0;
                                //num = (unsigned char) text[i];
                                //thisw = fnt->width_of[num];
@@ -1399,46 +1247,17 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma
                                        u = 0.0625f * thisw - (1.0f / tw);
                                        v = 0.0625f - (1.0f / th);
                                }
-                               ac[ 0] = DrawQ_Color[0];ac[ 1] = DrawQ_Color[1];ac[ 2] = DrawQ_Color[2];ac[ 3] = DrawQ_Color[3];
-                               ac[ 4] = DrawQ_Color[0];ac[ 5] = DrawQ_Color[1];ac[ 6] = DrawQ_Color[2];ac[ 7] = DrawQ_Color[3];
-                               ac[ 8] = DrawQ_Color[0];ac[ 9] = DrawQ_Color[1];ac[10] = DrawQ_Color[2];ac[11] = DrawQ_Color[3];
-                               ac[12] = DrawQ_Color[0];ac[13] = DrawQ_Color[1];ac[14] = DrawQ_Color[2];ac[15] = DrawQ_Color[3];
-                               at[ 0] = s              ; at[ 1] = t    ;
-                               at[ 2] = s+u    ; at[ 3] = t    ;
-                               at[ 4] = s+u    ; at[ 5] = t+v  ;
-                               at[ 6] = s              ; at[ 7] = t+v  ;
-                               av[ 0] = x                      ; av[ 1] = y    ; av[ 2] = 10;
-                               av[ 3] = x+dw*thisw     ; av[ 4] = y    ; av[ 5] = 10;
-                               av[ 6] = x+dw*thisw     ; av[ 7] = y+dh ; av[ 8] = 10;
-                               av[ 9] = x                      ; av[10] = y+dh ; av[11] = 10;
-                               ac += 16;
-                               at += 8;
-                               av += 12;
-                               batchcount++;
-                               if (batchcount >= QUADELEMENTS_MAXQUADS)
-                               {
-                                       R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
-                                       R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
-                                       batchcount = 0;
-                                       ac = color4f;
-                                       at = texcoord2f;
-                                       av = vertex3f;
-                               }
+                               surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, fnt->pic->name, flags, TEXF_ALPHA | TEXF_CLAMP, MATERIALFLAG_VERTEXCOLOR), true);
+                               e0 = Mod_Mesh_IndexForVertex(mod, surf, x         , y   , 10, 0, 0, -1, s  , t  , 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               e1 = Mod_Mesh_IndexForVertex(mod, surf, x+dw*thisw, y   , 10, 0, 0, -1, s+u, t  , 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               e2 = Mod_Mesh_IndexForVertex(mod, surf, x+dw*thisw, y+dh, 10, 0, 0, -1, s+u, t+v, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               e3 = Mod_Mesh_IndexForVertex(mod, surf, x         , y+dh, 10, 0, 0, -1, s  , t+v, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
+                               Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
                                x += width_of[ch] * dw;
                        } else {
                                if (!map || map == ft2_oldstyle_map || ch < map->start || ch >= map->start + FONT_CHARS_PER_MAP)
                                {
-                                       // new charmap - need to render
-                                       if (batchcount)
-                                       {
-                                               // we need a different character map, render what we currently have:
-                                               R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
-                                               R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
-                                               batchcount = 0;
-                                               ac = color4f;
-                                               at = texcoord2f;
-                                               av = vertex3f;
-                                       }
                                        // find the new map
                                        map = FontMap_FindForChar(fontmap, ch);
                                        if (!map)
@@ -1455,7 +1274,6 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma
                                                        break;
                                                }
                                        }
-                                       R_SetupShader_Generic(Draw_GetPicTexture(map->pic), NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
                                }
 
                                mapch = ch - map->start;
@@ -1470,35 +1288,17 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma
                                }
                                else
                                        kx = ky = 0;
-                               ac[ 0] = DrawQ_Color[0]; ac[ 1] = DrawQ_Color[1]; ac[ 2] = DrawQ_Color[2]; ac[ 3] = DrawQ_Color[3];
-                               ac[ 4] = DrawQ_Color[0]; ac[ 5] = DrawQ_Color[1]; ac[ 6] = DrawQ_Color[2]; ac[ 7] = DrawQ_Color[3];
-                               ac[ 8] = DrawQ_Color[0]; ac[ 9] = DrawQ_Color[1]; ac[10] = DrawQ_Color[2]; ac[11] = DrawQ_Color[3];
-                               ac[12] = DrawQ_Color[0]; ac[13] = DrawQ_Color[1]; ac[14] = DrawQ_Color[2]; ac[15] = DrawQ_Color[3];
-                               at[0] = map->glyphs[mapch].txmin; at[1] = map->glyphs[mapch].tymin;
-                               at[2] = map->glyphs[mapch].txmax; at[3] = map->glyphs[mapch].tymin;
-                               at[4] = map->glyphs[mapch].txmax; at[5] = map->glyphs[mapch].tymax;
-                               at[6] = map->glyphs[mapch].txmin; at[7] = map->glyphs[mapch].tymax;
-                               av[ 0] = x + dw * map->glyphs[mapch].vxmin; av[ 1] = y + dh * map->glyphs[mapch].vymin; av[ 2] = 10;
-                               av[ 3] = x + dw * map->glyphs[mapch].vxmax; av[ 4] = y + dh * map->glyphs[mapch].vymin; av[ 5] = 10;
-                               av[ 6] = x + dw * map->glyphs[mapch].vxmax; av[ 7] = y + dh * map->glyphs[mapch].vymax; av[ 8] = 10;
-                               av[ 9] = x + dw * map->glyphs[mapch].vxmin; av[10] = y + dh * map->glyphs[mapch].vymax; av[11] = 10;
+                               surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, map->pic->name, flags, TEXF_ALPHA | TEXF_CLAMP, MATERIALFLAG_VERTEXCOLOR), true);
+                               e0 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmin, y + dh * map->glyphs[mapch].vymin, 10, 0, 0, -1, map->glyphs[mapch].txmin, map->glyphs[mapch].tymin, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               e1 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmax, y + dh * map->glyphs[mapch].vymin, 10, 0, 0, -1, map->glyphs[mapch].txmax, map->glyphs[mapch].tymin, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               e2 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmax, y + dh * map->glyphs[mapch].vymax, 10, 0, 0, -1, map->glyphs[mapch].txmax, map->glyphs[mapch].tymax, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               e3 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmin, y + dh * map->glyphs[mapch].vymax, 10, 0, 0, -1, map->glyphs[mapch].txmin, map->glyphs[mapch].tymax, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
+                               Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
+                               Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
                                //x -= ftbase_x;
                                y -= ftbase_y;
 
                                x += thisw * dw;
-                               ac += 16;
-                               at += 8;
-                               av += 12;
-                               batchcount++;
-                               if (batchcount >= QUADELEMENTS_MAXQUADS)
-                               {
-                                       R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
-                                       R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
-                                       batchcount = 0;
-                                       ac = color4f;
-                                       at = texcoord2f;
-                                       av = vertex3f;
-                               }
 
                                //prevmap = map;
                                prevch = ch;
@@ -1511,11 +1311,6 @@ out:
                        }
                }
        }
-       if (batchcount > 0)
-       {
-               R_Mesh_PrepareVertices_Generic_Arrays(batchcount * 4, vertex3f, color4f, texcoord2f);
-               R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, quadelement3i, NULL, 0, quadelement3s, NULL, 0);
-       }
 
        if (outcolor)
                *outcolor = colorindex;
@@ -1586,195 +1381,57 @@ static int DrawQ_BuildColoredText(char *output2c, size_t maxoutchars, const char
 
 void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags)
 {
-       float floats[36];
-
-       _DrawQ_SetupAndProcessDrawFlag(flags, pic, a1*a2*a3*a4);
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-
-//     R_Mesh_ResetTextureState();
-       if (pic)
-       {
-               if (width == 0)
-                       width = pic->width;
-               if (height == 0)
-                       height = pic->height;
-               R_SetupShader_Generic(Draw_GetPicTexture(pic), NULL, GL_MODULATE, 1, (flags & (DRAWFLAGS_BLEND | DRAWFLAG_NOGAMMA)) ? false : true, true, false);
-       }
-       else
-               R_SetupShader_Generic_NoTexture((flags & (DRAWFLAGS_BLEND | DRAWFLAG_NOGAMMA)) ? false : true, true);
-
-       floats[2] = floats[5] = floats[8] = floats[11] = 0;
-       floats[0] = floats[9] = x;
-       floats[1] = floats[4] = y;
-       floats[3] = floats[6] = x + width;
-       floats[7] = floats[10] = y + height;
-       floats[12] = s1;floats[13] = t1;
-       floats[14] = s2;floats[15] = t2;
-       floats[16] = s4;floats[17] = t4;
-       floats[18] = s3;floats[19] = t3;
-       floats[20] = r1;floats[21] = g1;floats[22] = b1;floats[23] = a1;
-       floats[24] = r2;floats[25] = g2;floats[26] = b2;floats[27] = a2;
-       floats[28] = r4;floats[29] = g4;floats[30] = b4;floats[31] = a4;
-       floats[32] = r3;floats[33] = g3;floats[34] = b3;floats[35] = a3;
-
-       R_Mesh_PrepareVertices_Generic_Arrays(4, floats, floats + 20, floats + 12);
-       R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
-}
-
-void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags, qboolean hasalpha)
-{
+       dp_model_t *mod = CL_Mesh_UI();
+       msurface_t *surf;
+       int e0, e1, e2, e3;
        _DrawQ_Setup();
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-       DrawQ_ProcessDrawFlag(flags, hasalpha);
-
-//     R_Mesh_ResetTextureState();
-       R_SetupShader_Generic(mesh->texture, NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
-
-       R_Mesh_PrepareVertices_Generic_Arrays(mesh->num_vertices, mesh->data_vertex3f, mesh->data_color4f, mesh->data_texcoord2f);
-       R_Mesh_Draw(0, mesh->num_vertices, 0, mesh->num_triangles, mesh->data_element3i, NULL, 0, mesh->data_element3s, NULL, 0);
-}
-
-void DrawQ_LineLoop (drawqueuemesh_t *mesh, int flags)
-{
-       _DrawQ_SetupAndProcessDrawFlag(flags, NULL, 1);
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-
-       GL_Color(1,1,1,1);
-       switch(vid.renderpath)
-       {
-       case RENDERPATH_GL11:
-       case RENDERPATH_GL13:
-       case RENDERPATH_GL20:
-#ifndef USE_GLES2
-               {
-                       int num;
-                       CHECKGLERROR
-                       qglBegin(GL_LINE_LOOP);
-                       for (num = 0;num < mesh->num_vertices;num++)
-                       {
-                               if (mesh->data_color4f)
-                                       GL_Color(mesh->data_color4f[num*4+0], mesh->data_color4f[num*4+1], mesh->data_color4f[num*4+2], mesh->data_color4f[num*4+3]);
-                               qglVertex2f(mesh->data_vertex3f[num*3+0], mesh->data_vertex3f[num*3+1]);
-                       }
-                       qglEnd();
-                       CHECKGLERROR
-               }
-#endif
-               break;
-       case RENDERPATH_D3D9:
-               //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_D3D10:
-               Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_D3D11:
-               Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_SOFT:
-               //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_GLES1:
-       case RENDERPATH_GLES2:
-               //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               return;
-       }
+       if (!pic)
+               pic = Draw_CachePic("white");
+       if (width == 0)
+               width = pic->width;
+       if (height == 0)
+               height = pic->height;
+       surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, pic->name, flags, pic->texflags, MATERIALFLAG_VERTEXCOLOR), true);
+       e0 = Mod_Mesh_IndexForVertex(mod, surf, x        , y         , 0, 0, 0, -1, s1, t1, 0, 0, r1, g1, b1, a1);
+       e1 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y         , 0, 0, 0, -1, s2, t2, 0, 0, r2, g2, b2, a2);
+       e2 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y + height, 0, 0, 0, -1, s4, t4, 0, 0, r4, g4, b4, a4);
+       e3 = Mod_Mesh_IndexForVertex(mod, surf, x        , y + height, 0, 0, 0, -1, s3, t3, 0, 0, r3, g3, b3, a3);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
 }
 
-//[515]: this is old, delete
 void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags)
 {
-       _DrawQ_SetupAndProcessDrawFlag(flags, NULL, alpha);
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-
-       R_SetupShader_Generic_NoTexture((flags & DRAWFLAGS_BLEND) ? false : true, true);
-
-       switch(vid.renderpath)
+       dp_model_t *mod = CL_Mesh_UI();
+       msurface_t *surf;
+       int e0, e1, e2, e3;
+       float offsetx, offsety;
+       _DrawQ_Setup();
+       // width is measured in real pixels
+       if (fabs(x2 - x1) > fabs(y2 - y1))
        {
-       case RENDERPATH_GL11:
-       case RENDERPATH_GL13:
-       case RENDERPATH_GL20:
-#ifndef USE_GLES2
-               CHECKGLERROR
-
-               //qglLineWidth(width);CHECKGLERROR
-
-               GL_Color(r,g,b,alpha);
-               CHECKGLERROR
-               qglBegin(GL_LINES);
-               qglVertex2f(x1, y1);
-               qglVertex2f(x2, y2);
-               qglEnd();
-               CHECKGLERROR
-#endif
-               break;
-       case RENDERPATH_D3D9:
-               //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_D3D10:
-               Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_D3D11:
-               Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_SOFT:
-               //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_GLES1:
-       case RENDERPATH_GLES2:
-               //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               return;
+               offsetx = 0;
+               offsety = width * vid_conheight.value / vid.height;
        }
-}
-
-void DrawQ_Lines (float width, int numlines, int flags, qboolean hasalpha)
-{
-       _DrawQ_SetupAndProcessDrawFlag(flags, NULL, hasalpha ? 0.5f : 1.0f);
-
-       if(!r_draw2d.integer && !r_draw2d_force)
-               return;
-
-       switch(vid.renderpath)
+       else
        {
-       case RENDERPATH_GL11:
-       case RENDERPATH_GL13:
-       case RENDERPATH_GL20:
-               CHECKGLERROR
-
-               R_SetupShader_Generic_NoTexture((flags & DRAWFLAGS_BLEND) ? false : true, true);
-
-               //qglLineWidth(width);CHECKGLERROR
-
-               CHECKGLERROR
-               qglDrawArrays(GL_LINES, 0, numlines*2);
-               CHECKGLERROR
-               break;
-       case RENDERPATH_D3D9:
-               //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_D3D10:
-               Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_D3D11:
-               Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_SOFT:
-               //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               break;
-       case RENDERPATH_GLES1:
-       case RENDERPATH_GLES2:
-               //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-               return;
+               offsetx = width * vid_conwidth.value / vid.width;
+               offsety = 0;
        }
+       surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_VERTEXCOLOR), true);
+       e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+       e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+       e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+       e3 = Mod_Mesh_IndexForVertex(mod, surf, x1 + offsetx, y1 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
+       Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
 }
 
 void DrawQ_SetClipArea(float x, float y, float width, float height)
 {
        int ix, iy, iw, ih;
        _DrawQ_Setup();
+       DrawQ_FlushUI();
 
        // We have to convert the con coords into real coords
        // OGL uses bottom to top (origin is in bottom left)
@@ -1808,18 +1465,55 @@ void DrawQ_SetClipArea(float x, float y, float width, float height)
 
 void DrawQ_ResetClipArea(void)
 {
+       DrawQ_FlushUI();
        _DrawQ_Setup();
        GL_ScissorTest(false);
 }
 
 void DrawQ_Finish(void)
 {
+       DrawQ_FlushUI();
        r_refdef.draw2dstage = 0;
 }
 
 void DrawQ_RecalcView(void)
 {
+       DrawQ_FlushUI();
        if(r_refdef.draw2dstage)
                r_refdef.draw2dstage = -1; // next draw call will set viewport etc. again
 }
 
+void DrawQ_FlushUI(void)
+{
+       int i;
+       dp_model_t *mod = CL_Mesh_UI();
+       if (mod->num_surfaces == 0)
+               return;
+
+       if (!r_draw2d.integer && !r_draw2d_force)
+       {
+               Mod_Mesh_Reset(mod);
+               return;
+       }
+
+       // TODO: render the mesh using R_Q1BSP_Draw or similar, for full material support.
+       GL_DepthMask(false);
+       R_Mesh_PrepareVertices_Generic_Arrays(mod->surfmesh.num_vertices, mod->surfmesh.data_vertex3f, mod->surfmesh.data_lightmapcolor4f, mod->surfmesh.data_texcoordtexture2f);
+       for (i = 0; i < mod->num_surfaces; i++)
+       {
+               msurface_t *surf = mod->data_surfaces + i;
+               texture_t *tex = surf->texture;
+               if (tex->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
+                       GL_BlendFunc(tex->customblendfunc[0], tex->customblendfunc[1]);
+               else if (tex->currentmaterialflags & MATERIALFLAG_ADD)
+                       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+               else if (tex->currentmaterialflags & MATERIALFLAG_ALPHA)
+                       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               else
+                       GL_BlendFunc(GL_ONE, GL_ZERO);
+               R_SetupShader_Generic(tex->currentskinframe->base, NULL, GL_MODULATE, 1, (tex->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) ? false : true, true, false);
+               R_Mesh_Draw(surf->num_firstvertex, surf->num_vertices, surf->num_firsttriangle, surf->num_triangles, mod->surfmesh.data_element3i, NULL, 0, mod->surfmesh.data_element3s, NULL, 0);
+       }
+
+       Mod_Mesh_Reset(mod);
+}
index 36a45b0..938d97f 100644 (file)
@@ -7438,9 +7438,6 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
                        R_TimeReport("explosions");
        }
 
-       if (cl.csqc_loaded)
-               VM_CL_AddPolygonsToMeshQueue(CLVM_prog);
-
        if (r_refdef.view.showdebug)
        {
                if (cl_locs_show.integer)
@@ -8169,8 +8166,8 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                t->currentmaterialflags |= MATERIALFLAG_NORTLIGHT;
        if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND && !(R_BlendFuncFlags(t->customblendfunc[0], t->customblendfunc[1]) & BLENDFUNC_ALLOWS_COLORMOD))
        {
-               // some CUSTOMBLEND blendfuncs are too weird for anything but fullbright rendering, and even then we have to ignore colormod and view colorscale
-               t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_NORTLIGHT;
+               // some CUSTOMBLEND blendfuncs are too weird, we have to ignore colormod and view colorscale
+               t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_NORTLIGHT;
                for (q = 0; q < 3; q++)
                {
                        t->render_glowmod[q] = rsurface.entity->glowmod[q];
@@ -8245,8 +8242,8 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                for (q = 0; q < 3; q++)
                {
                        t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
-                       t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q] * r_refdef.view.colorscale;
-                       t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale;
+                       t->render_modellight_lightdir[q] = q == 2;
+                       t->render_modellight_ambient[q] = 0;
                        t->render_modellight_diffuse[q] = 0;
                        t->render_modellight_specular[q] = 0;
                        t->render_lightmap_ambient[q] = rsurface.entity->render_lightmap_ambient[q] * r_refdef.view.colorscale;
@@ -8257,6 +8254,30 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                }
        }
 
+       if (t->currentmaterialflags & MATERIALFLAG_VERTEXCOLOR)
+       {
+               // since MATERIALFLAG_VERTEXCOLOR uses the lightmapcolor4f vertex
+               // attribute, we punt it to the lightmap path and hope for the best,
+               // but lighting doesn't work.
+               //
+               // FIXME: this is fine for effects but CSQC polygons should be subject
+               // to lighting.
+               t->currentmaterialflags &= ~MATERIALFLAG_MODELLIGHT;
+               for (q = 0; q < 3; q++)
+               {
+                       t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
+                       t->render_modellight_lightdir[q] = q == 2;
+                       t->render_modellight_ambient[q] = 0;
+                       t->render_modellight_diffuse[q] = 0;
+                       t->render_modellight_specular[q] = 0;
+                       t->render_lightmap_ambient[q] = 0;
+                       t->render_lightmap_diffuse[q] = rsurface.entity->render_fullbright[q] * r_refdef.view.colorscale;
+                       t->render_lightmap_specular[q] = 0;
+                       t->render_rtlight_diffuse[q] = 0;
+                       t->render_rtlight_specular[q] = 0;
+               }
+       }
+
        for (q = 0; q < 3; q++)
        {
                t->render_colormap_pants[q] = rsurface.entity->colormap_pantscolor[q];
index 9fdc080..cdf0ede 100644 (file)
@@ -944,7 +944,7 @@ void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, con
                                        Image_StripImageExtension(skinfileitem->replacement, stripbuf, sizeof(stripbuf));
                                        if(developer_extra.integer)
                                                Con_DPrintf("--> got %s from skin file\n", stripbuf);
-                                       Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS);
+                                       Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL);
                                        break;
                                }
                        }
@@ -963,7 +963,7 @@ void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, con
                if(developer_extra.integer)
                        Con_DPrintf("--> using default\n");
                Image_StripImageExtension(shadername, stripbuf, sizeof(stripbuf));
-               Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS);
+               Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL);
        }
 }
 
@@ -1259,7 +1259,7 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend)
                                        dpsnprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i, j);
                                else
                                        dpsnprintf (name, sizeof(name), "%s_%i", loadmodel->name, i);
-                               if (!Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, false, false, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS))
+                               if (!Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, false, false, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL))
                                        Mod_LoadCustomMaterial(loadmodel->mempool, loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, SUPERCONTENTS_SOLID, MATERIALFLAG_WALL, R_SkinFrame_LoadInternalQuake(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight));
                                datapointer += skinwidth * skinheight;
                                totalskins++;
@@ -1451,7 +1451,7 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend)
                loadmodel->num_texturesperskin = loadmodel->num_surfaces;
                loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
                for (i = 0;i < loadmodel->numskins;i++, inskin += MD2_SKINNAME)
-                       Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS);
+                       Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL);
        }
        else
        {
index e6451a0..eb37da1 100644 (file)
@@ -1826,7 +1826,7 @@ static void Mod_Q1BSP_LoadTextures(sizebuf_t *sb)
 
                // LordHavoc: backup the texture_t because q3 shader loading overwrites it
                backuptex = loadmodel->data_textures[i];
-               if (name[0] && Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + i, name, false, false, 0))
+               if (name[0] && Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + i, name, false, false, 0, MATERIALFLAG_WALL))
                        continue;
                loadmodel->data_textures[i] = backuptex;
 
@@ -4439,7 +4439,7 @@ static void Mod_Q2BSP_LoadTexinfo(sizebuf_t *sb)
                                int q2flags = out->q2flags;
                                unsigned char *walfile = NULL;
                                fs_offset_t walfilesize = 0;
-                               Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, tx, filename, true, true, TEXF_ALPHA | TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS);
+                               Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, tx, filename, true, true, TEXF_ALPHA | TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL);
                                // now read the .wal file to get metadata (even if a .tga was overriding it, we still need the wal data)
                                walfile = FS_LoadFile(filename, tempmempool, true, &walfilesize);
                                if (walfile)
@@ -5309,7 +5309,7 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l)
        {
                out[i].surfaceflags = LittleLong(in[i].surfaceflags);
                out[i].supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(LittleLong(in[i].contents));
-               Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, out + i, in[i].name, true, true, TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS);
+               Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, out + i, in[i].name, true, true, TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL);
                // restore the surfaceflags and supercontents
                out[i].surfaceflags = LittleLong(in[i].surfaceflags);
                out[i].supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(LittleLong(in[i].contents));
index 2eb3847..3b1d616 100644 (file)
@@ -127,6 +127,8 @@ mplane_t;
 #define MATERIALFLAG_ALPHAGEN_VERTEX 0x08000000
 // use occlusion buffer for corona
 #define MATERIALFLAG_OCCLUDE 0x10000000
+// use vertex color instead of lighting (e.g. particles and other glowy stuff), use with MATERIALFLAG_FULLBRIGHT
+#define MATERIALFLAG_VERTEXCOLOR 0x20000000
 // combined mask of all attributes that require depth sorted rendering
 #define MATERIALFLAGMASK_DEPTHSORTED (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)
 // combined mask of all attributes that cause some sort of transparency
index 9d7d449..5fea229 100644 (file)
@@ -2446,7 +2446,7 @@ texture_shaderpass_t *Mod_CreateShaderPassFromQ3ShaderLayer(mempool_t *mempool,
        return shaderpass;
 }
 
-qboolean Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qboolean warnmissing, qboolean fallback, int defaulttexflags)
+qboolean Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qboolean warnmissing, qboolean fallback, int defaulttexflags, int defaultmaterialflags)
 {
        int texflagsmask, texflagsor;
        qboolean success = true;
@@ -2613,6 +2613,9 @@ nothing                GL_ZERO GL_ONE
                                materiallayer = rgbgenvertexlayer;
                                endofprelayers = rgbgenvertexlayer;
                                firstpostlayer = rgbgenvertexlayer + 1;
+                               // special case for rgbgen vertex if MATERIALFLAG_VERTEXCOLOR is expected on this material
+                               if (defaultmaterialflags & MATERIALFLAG_VERTEXCOLOR)
+                                       texture->basematerialflags |= MATERIALFLAG_VERTEXCOLOR;
                        }
                        else if (rgbgendiffuselayer >= 0)
                        {
@@ -2777,17 +2780,17 @@ nothing                GL_ZERO GL_ONE
                        Con_DPrintf("^1%s:^7 No shader found for texture ^3\"%s\"\n", modelname, texture->name);
                if (texture->surfaceflags & Q3SURFACEFLAG_NODRAW)
                {
-                       texture->basematerialflags |= MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
+                       texture->basematerialflags = MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
                        texture->supercontents = SUPERCONTENTS_SOLID;
                }
                else if (texture->surfaceflags & Q3SURFACEFLAG_SKY)
                {
-                       texture->basematerialflags |= MATERIALFLAG_SKY;
+                       texture->basematerialflags = MATERIALFLAG_SKY;
                        texture->supercontents = SUPERCONTENTS_SKY;
                }
                else
                {
-                       texture->basematerialflags |= MATERIALFLAG_WALL;
+                       texture->basematerialflags = defaultmaterialflags;
                        texture->supercontents = SUPERCONTENTS_SOLID | SUPERCONTENTS_OPAQUE;
                }
                if(cls.state == ca_dedicated)
@@ -2797,9 +2800,10 @@ nothing                GL_ZERO GL_ONE
                }
                else
                {
-                       if (fallback)
+                       skinframe_t *skinframe = R_SkinFrame_LoadExternal(texture->name, defaulttexflags, false, fallback);
+                       if (skinframe)
                        {
-                               texture->materialshaderpass = texture->shaderpasses[0] = Mod_CreateShaderPass(mempool, R_SkinFrame_LoadExternal(texture->name, defaulttexflags, false, true));
+                               texture->materialshaderpass = texture->shaderpasses[0] = Mod_CreateShaderPass(mempool, skinframe);
                                if (texture->materialshaderpass->skinframes[0]->hasalpha)
                                        texture->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
                                if (texture->q2contents)
@@ -4614,7 +4618,7 @@ void Mod_Mesh_Reset(dp_model_t *mod)
        mod->DrawAddWaterPlanes = NULL; // will be set if a texture needs it
 }
 
-texture_t *Mod_Mesh_GetTexture(dp_model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int addmaterialflags)
+texture_t *Mod_Mesh_GetTexture(dp_model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags)
 {
        int i;
        texture_t *t;
@@ -4631,8 +4635,7 @@ texture_t *Mod_Mesh_GetTexture(dp_model_t *mod, const char *name, int defaultdra
                        mod->data_surfaces[i].texture = mod->data_textures + (mod->data_surfaces[i].texture - oldtextures);
        }
        t = &mod->data_textures[mod->num_textures++];
-       Mod_LoadTextureFromQ3Shader(mod->mempool, mod->name, t, name, false, true, defaulttexflags);
-       t->basematerialflags |= addmaterialflags;
+       Mod_LoadTextureFromQ3Shader(mod->mempool, mod->name, t, name, false, true, defaulttexflags, defaultmaterialflags);
        switch (defaultdrawflags & DRAWFLAG_MASK)
        {
        case DRAWFLAG_ADDITIVE:
index 0d3914e..9b5bf7b 100644 (file)
@@ -1183,7 +1183,7 @@ void Mod_CreateCollisionMesh(dp_model_t *mod);
 void Mod_FreeQ3Shaders(void);
 void Mod_LoadQ3Shaders(void);
 q3shaderinfo_t *Mod_LookupQ3Shader(const char *name);
-qboolean Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qboolean warnmissing, qboolean fallback, int defaulttexflags);
+qboolean Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qboolean warnmissing, qboolean fallback, int defaulttexflags, int defaultmaterialflags);
 texture_shaderpass_t *Mod_CreateShaderPass(mempool_t *mempool, skinframe_t *skinframe);
 texture_shaderpass_t *Mod_CreateShaderPassFromQ3ShaderLayer(mempool_t *mempool, const char *modelname, q3shaderinfo_layer_t *layer, int layerindex, int texflags, const char *texturename);
 /// Sets up a material to render the provided skinframe.  See also R_SkinFrame_LoadInternalBGRA.
index a310b0e..cc5d9c9 100644 (file)
@@ -1612,7 +1612,7 @@ void MVM_init_cmd(prvm_prog_t *prog)
        r_refdef_scene_t *scene;
 
        VM_Cmd_Init(prog);
-       VM_Polygons_Reset(prog);
+       prog->polygonbegin_model = NULL;
 
        scene = R_GetScenePointer( RST_MENU );
 
@@ -1634,5 +1634,5 @@ void MVM_reset_cmd(prvm_prog_t *prog)
 
        //VM_Cmd_Init();
        VM_Cmd_Reset(prog);
-       VM_Polygons_Reset(prog);
+       prog->polygonbegin_model = NULL;
 }
index 0a46d2a..4188a8f 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -116,43 +116,6 @@ typedef struct prvm_edict_s
        } fields;
 } prvm_edict_t;
 
-#define VMPOLYGONS_MAXPOINTS 64
-
-typedef struct vmpolygons_triangle_s
-{
-       rtexture_t              *texture;
-       int                             drawflag;
-       qboolean hasalpha;
-       unsigned short  elements[3];
-} vmpolygons_triangle_t;
-
-typedef struct vmpolygons_s
-{
-       mempool_t               *pool;
-       qboolean                initialized;
-
-       int                             max_vertices;
-       int                             num_vertices;
-       float                   *data_vertex3f;
-       float                   *data_color4f;
-       float                   *data_texcoord2f;
-
-       int                             max_triangles;
-       int                             num_triangles;
-       vmpolygons_triangle_t *data_triangles;
-       unsigned short  *data_sortedelement3s;
-
-       qboolean                begin_active;
-       int     begin_draw2d;
-       rtexture_t              *begin_texture;
-       int                             begin_drawflag;
-       int                             begin_vertices;
-       float                   begin_vertex[VMPOLYGONS_MAXPOINTS][3];
-       float                   begin_color[VMPOLYGONS_MAXPOINTS][4];
-       float                   begin_texcoord[VMPOLYGONS_MAXPOINTS][2];
-       qboolean                begin_texture_hasalpha;
-} vmpolygons_t;
-
 extern prvm_eval_t prvm_badvalue;
 
 #define PRVM_alledictfloat(ed, fieldname)    (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname))
@@ -634,9 +597,10 @@ typedef struct prvm_prog_s
        // buffer for storing all tempstrings created during one invocation of ExecuteProgram
        sizebuf_t                       tempstringsbuf;
 
-       // LordHavoc: moved this here to clean up things that relied on prvm_prog_list too much
-       // FIXME: make VM_CL_R_Polygon functions use Debug_Polygon functions?
-       vmpolygons_t            vmpolygons;
+       // in csqc the polygonbegin,polygonvertex,polygonend sequencing is
+       // stateful, so this tracks the last polygonbegin's choice of
+       // CL_Mesh_CSQC or CL_Mesh_UI for this polygon
+       dp_model_t                      *polygonbegin_model;
 
        // copies of some vars that were former read from sv
        int                                     num_edicts;
index 5373e63..e3d0501 100644 (file)
@@ -21,9 +21,7 @@ static void r_lightningbeams_start(void)
 
 static void CL_Beams_SetupExternalTexture(void)
 {
-       if (Mod_LoadTextureFromQ3Shader(r_main_mempool, "r_lightning.c", &cl_beams_externaltexture, "textures/particles/lightning", false, false, TEXF_ALPHA | TEXF_FORCELINEAR))
-               cl_beams_externaltexture.basematerialflags = cl_beams_externaltexture.currentmaterialflags = MATERIALFLAG_WALL | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOCULLFACE;
-       else
+       if (Mod_LoadTextureFromQ3Shader(r_main_mempool, "r_lightning.c", &cl_beams_externaltexture, "textures/particles/lightning", false, false, TEXF_ALPHA | TEXF_FORCELINEAR, MATERIALFLAG_WALL | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOCULLFACE))
                Cvar_SetValueQuick(&r_lightningbeam_qmbtexture, false);
 }
 
@@ -77,7 +75,7 @@ static void CL_Beams_SetupBuiltinTexture(void)
        }
 
        skinframe = R_SkinFrame_LoadInternalBGRA("lightningbeam", TEXF_FORCELINEAR, data, texwidth, texheight, false);
-       Mod_LoadCustomMaterial(r_main_mempool, &cl_beams_builtintexture, "cl_beams_builtintexture", 0, MATERIALFLAG_WALL | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOCULLFACE, skinframe);
+       Mod_LoadCustomMaterial(r_main_mempool, &cl_beams_builtintexture, "cl_beams_builtintexture", 0, MATERIALFLAG_WALL | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOCULLFACE | MATERIALFLAG_VERTEXCOLOR, skinframe);
        Mem_Free(data);
 }
 
index 3663834..d8fd034 100644 (file)
--- a/render.h
+++ b/render.h
@@ -458,30 +458,30 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q
 void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qboolean wantnormals, qboolean wanttangents);
 void RSurf_SetupDepthAndCulling(void);
 
-void R_Mesh_ResizeArrays(int newvertices);
-
 texture_t *R_GetCurrentTexture(texture_t *t);
 void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass);
 void R_AddWaterPlanes(entity_render_t *ent);
 void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass);
 void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass);
 
-#define BATCHNEED_VERTEXMESH_VERTEX      (1<< 1) // set up rsurface.batchvertexmesh
-#define BATCHNEED_VERTEXMESH_NORMAL      (1<< 2) // set up normals in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchnormal3f if BATCHNEED_ARRAYS
-#define BATCHNEED_VERTEXMESH_VECTOR      (1<< 3) // set up vectors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchsvector3f and rsurface.batchtvector3f if BATCHNEED_ARRAYS
-#define BATCHNEED_VERTEXMESH_VERTEXCOLOR (1<< 4) // set up vertex colors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchlightmapcolor4f if BATCHNEED_ARRAYS
-#define BATCHNEED_VERTEXMESH_TEXCOORD    (1<< 5) // set up vertex colors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchlightmapcolor4f if BATCHNEED_ARRAYS
-#define BATCHNEED_VERTEXMESH_LIGHTMAP    (1<< 6) // set up vertex colors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchlightmapcolor4f if BATCHNEED_ARRAYS
-#define BATCHNEED_VERTEXMESH_SKELETAL    (1<< 7) // set up skeletal index and weight data for vertex shader
-#define BATCHNEED_ARRAY_VERTEX           (1<< 8) // set up rsurface.batchvertex3f and optionally others
-#define BATCHNEED_ARRAY_NORMAL           (1<< 9) // set up normals in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchnormal3f if BATCHNEED_ARRAYS
-#define BATCHNEED_ARRAY_VECTOR           (1<<10) // set up vectors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchsvector3f and rsurface.batchtvector3f if BATCHNEED_ARRAYS
-#define BATCHNEED_ARRAY_VERTEXCOLOR      (1<<11) // set up vertex colors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchlightmapcolor4f if BATCHNEED_ARRAYS
-#define BATCHNEED_ARRAY_TEXCOORD         (1<<12) // set up vertex colors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchlightmapcolor4f if BATCHNEED_ARRAYS
-#define BATCHNEED_ARRAY_LIGHTMAP         (1<<13) // set up vertex colors in rsurface.batchvertexmesh if BATCHNEED_MESH, set up rsurface.batchlightmapcolor4f if BATCHNEED_ARRAYS
-#define BATCHNEED_ARRAY_SKELETAL         (1<<14) // set up skeletal index and weight data for vertex shader
-#define BATCHNEED_NOGAPS                 (1<<15) // force vertex copying if firstvertex is not zero or there are gaps
-#define BATCHNEED_ALLOWMULTIDRAW         (1<<16) // allow multiple draws
+#define BATCHNEED_VERTEXMESH_VERTEX           (1<< 0) // set up positions in rsurface.batchvertexmesh
+#define BATCHNEED_VERTEXMESH_NORMAL           (1<< 1) // set up normals in rsurface.batchvertexmesh
+#define BATCHNEED_VERTEXMESH_VECTOR           (1<< 2) // set up tangent vectors in rsurface.batchvertexmesh
+#define BATCHNEED_VERTEXMESH_VERTEXTINTCOLOR  (1<< 3) // set up vertex tint colors in rsurface.batchvertexmesh
+#define BATCHNEED_VERTEXMESH_VERTEXCOLOR      (1<< 4) // set up vertex light colors in rsurface.batchvertexmesh
+#define BATCHNEED_VERTEXMESH_TEXCOORD         (1<< 5) // set up surface texcoords in rsurface.batchvertexmesh
+#define BATCHNEED_VERTEXMESH_LIGHTMAP         (1<< 6) // set up lightmap texcoords in rsurface.batchvertexmesh
+#define BATCHNEED_VERTEXMESH_SKELETAL         (1<< 7) // set up skeletal index and weight data for vertex shader
+#define BATCHNEED_ARRAY_VERTEX                (1<< 8) // set up rsurface.batchvertex3f
+#define BATCHNEED_ARRAY_NORMAL                (1<< 9) // set up rsurface.batchnormal3f
+#define BATCHNEED_ARRAY_VECTOR                (1<<10) // set up rsurface.batchsvector3f and rsurface.batchtvector3f
+#define BATCHNEED_ARRAY_VERTEXTINTCOLOR       (1<<11) // set up rsurface.batchvertexcolor4f
+#define BATCHNEED_ARRAY_VERTEXCOLOR           (1<<12) // set up rsurface.batchlightmapcolor4f
+#define BATCHNEED_ARRAY_TEXCOORD              (1<<13) // set up rsurface.batchtexcoordtexture2f
+#define BATCHNEED_ARRAY_LIGHTMAP              (1<<14) // set up rsurface.batchtexcoordlightmap2f
+#define BATCHNEED_ARRAY_SKELETAL              (1<<15) // set up skeletal index and weight data for vertex shader
+#define BATCHNEED_NOGAPS                      (1<<16) // force vertex copying if firstvertex is not zero or there are gaps
+#define BATCHNEED_ALLOWMULTIDRAW              (1<<17) // allow multiple draws
 void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const msurface_t **texturesurfacelist);
 void RSurf_DrawBatch(void);
 
@@ -604,7 +604,6 @@ void SCR_DrawConsole(void);
 void R_Shadow_EditLights_DrawSelectedLightProperties(void);
 void R_DecalSystem_Reset(decalsystem_t *decalsystem);
 void R_Shadow_UpdateBounceGridTexture(void);
-void VM_CL_AddPolygonsToMeshQueue(struct prvm_prog_s *prog);
 void R_DrawPortals(void);
 void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
 void R_Water_AddWaterPlane(msurface_t *surface, int entno);