- prog->functions[prog->funcoffsets.CSQC_UpdateView].totaltime -= Sys_DoubleTime() - 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 + PRVM_GetProgNr();
- if(polys->progstarttime != prog->starttime) // from other progs? won't draw these (this can cause crashes!)
- return;
- R_Mesh_ResetTextureState();
- R_EntityMatrix(&identitymatrix);
- GL_CullFace(GL_NONE);
- R_Mesh_VertexPointer(polys->data_vertex3f, 0, 0);
- R_Mesh_ColorPointer(polys->data_color4f, 0, 0);
- R_Mesh_TexCoordPointer(0, 2, polys->data_texcoord2f, 0, 0);
-
- 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;
- // this can't call _DrawQ_ProcessDrawFlag, but should be in sync with it
- // FIXME factor this out
- if(drawflag == DRAWFLAG_ADDITIVE)
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- else if(drawflag == DRAWFLAG_MODULATE)
- GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
- else if(drawflag == DRAWFLAG_2XMODULATE)
- GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
- else if(drawflag == DRAWFLAG_SCREEN)
- GL_BlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE);
- else
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- R_SetupShader_Generic(tex, NULL, GL_MODULATE, 1);
- 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, polys->data_sortedelement3s, 0, 0);
- }
-}
-
-void VMPolygons_Store(vmpolygons_t *polys)
-{
- if (r_refdef.draw2dstage)
- {
- // 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);
- }
- else
- {
- // queue the polygon as 3D for sorted transparent rendering later
- int i;
- if (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->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 (void)
-{
- int i;
- vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
- vec3_t center;
-
- // only add polygons of the currently active prog to the queue - if there is none, we're done
- if( !prog )
- return;