-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 */
-}
-