-//====================
-//QC POLYGON functions
-//====================
-
-typedef struct
-{
- rtexture_t *tex;
- float data[36]; //[515]: enough for polygons
- unsigned char flags; //[515]: + VM_POLYGON_2D and VM_POLYGON_FL4V flags
-}vm_polygon_t;
-
-//static float vm_polygon_linewidth = 1;
-static mempool_t *vm_polygons_pool = NULL;
-static unsigned char vm_current_vertices = 0;
-static qboolean vm_polygons_initialized = false;
-static vm_polygon_t *vm_polygons = NULL;
-static unsigned long vm_polygons_num = 0, vm_drawpolygons_num = 0; //[515]: ok long on 64bit ?
-static qboolean vm_polygonbegin = false; //[515]: for "no-crap-on-the-screen" check
-#define VM_DEFPOLYNUM 64 //[515]: enough for default ?
-
-#define VM_POLYGON_FL3V 16 //more than 2 vertices (used only for lines)
-#define VM_POLYGON_FLLINES 32
-#define VM_POLYGON_FL2D 64
-#define VM_POLYGON_FL4V 128 //4 vertices
-
-void VM_InitPolygons (void)
-{
- vm_polygons_pool = Mem_AllocPool("VMPOLY", 0, NULL);
- vm_polygons = Mem_Alloc(vm_polygons_pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- memset(vm_polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- vm_polygons_num = VM_DEFPOLYNUM;
- vm_polygonbegin = vm_drawpolygons_num = 0;
- vm_polygons_initialized = true;
-}
-
-void VM_DrawPolygonCallback (const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
-{
- const vm_polygon_t *p = &vm_polygons[surfacenumber];
- int flags = p->flags & 0x0f;
-
- if(flags == DRAWFLAG_ADDITIVE)
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- else if(flags == DRAWFLAG_MODULATE)
- GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
- else if(flags == DRAWFLAG_2XMODULATE)
- GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
- else
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- R_Mesh_TexBind(0, R_GetTexture(p->tex));
-
- //[515]: is speed is max ?
- if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
- {
- qglLineWidth(p->data[13]);
- qglBegin(GL_LINE_LOOP);
- qglTexCoord1f (p->data[12]);
- qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
- qglVertex3f (p->data[0] , p->data[1], p->data[2]);
-
- qglTexCoord1f (p->data[14]);
- qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
- qglVertex3f (p->data[3] , p->data[4], p->data[5]);
-
- if(p->flags & VM_POLYGON_FL3V)
- {
- qglTexCoord1f (p->data[16]);
- qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
- qglVertex3f (p->data[6] , p->data[7], p->data[8]);
-
- if(p->flags & VM_POLYGON_FL4V)
- {
- qglTexCoord1f (p->data[18]);
- qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
- qglVertex3f (p->data[9] , p->data[10], p->data[11]);
- }
- }
- qglEnd();
- }
- else
- {
- qglBegin(GL_POLYGON);
- qglTexCoord2f (p->data[12], p->data[13]);
- qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
- qglVertex3f (p->data[0] , p->data[1], p->data[2]);
-
- qglTexCoord2f (p->data[14], p->data[15]);
- qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
- qglVertex3f (p->data[3] , p->data[4], p->data[5]);
-
- qglTexCoord2f (p->data[16], p->data[17]);
- qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
- qglVertex3f (p->data[6] , p->data[7], p->data[8]);
-
- if(p->flags & VM_POLYGON_FL4V)
- {
- qglTexCoord2f (p->data[18], p->data[19]);
- qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
- qglVertex3f (p->data[9] , p->data[10], p->data[11]);
- }
- qglEnd();
- }
-}
-
-void VM_AddPolygonTo2DScene (vm_polygon_t *p)
-{
- drawqueuemesh_t mesh;
- static int picelements[6] = {0, 1, 2, 0, 2, 3};
-
- mesh.texture = p->tex;
- mesh.data_element3i = picelements;
- mesh.data_vertex3f = p->data;
- mesh.data_texcoord2f = p->data + 12;
- mesh.data_color4f = p->data + 20;
- if(p->flags & VM_POLYGON_FL4V)
- {
- mesh.num_vertices = 4;
- mesh.num_triangles = 2;
- }
- else
- {
- mesh.num_vertices = 3;
- mesh.num_triangles = 1;
- }
- if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
- DrawQ_LineLoop (&mesh, (p->flags&0x0f));
- else
- DrawQ_Mesh (&mesh, (p->flags&0x0f));
-}
-
-//void(string texturename, float flag, float 2d, float lines) R_BeginPolygon
-void VM_R_PolygonBegin (void)
-{
- vm_polygon_t *p;
- const char *picname;
- if(prog->argc < 2)
- VM_SAFEPARMCOUNT(2, VM_R_PolygonBegin);
-
- if(!vm_polygons_initialized)
- VM_InitPolygons();
- if(vm_polygonbegin)
- {
- Con_Printf("VM_R_PolygonBegin: called twice without VM_R_PolygonEnd after first\n");
- return;
- }
- if(vm_drawpolygons_num >= vm_polygons_num)
- {
- p = Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
- Mem_Free(vm_polygons);
- vm_polygons = p;
- vm_polygons_num *= 2;
- }
- p = &vm_polygons[vm_drawpolygons_num];
- picname = PRVM_G_STRING(OFS_PARM0);
- if(picname[0])
- p->tex = Draw_CachePic(picname, true)->tex;
- else
- p->tex = r_texture_notexture;
- p->flags = (unsigned char)PRVM_G_FLOAT(OFS_PARM1);
- vm_current_vertices = 0;
- vm_polygonbegin = true;
- if(prog->argc >= 3)
- {
- if(PRVM_G_FLOAT(OFS_PARM2))
- p->flags |= VM_POLYGON_FL2D;
- if(prog->argc >= 4 && PRVM_G_FLOAT(OFS_PARM3))
- {
- p->data[13] = PRVM_G_FLOAT(OFS_PARM3); //[515]: linewidth
- p->flags |= VM_POLYGON_FLLINES;
- }
- }
-}
-
-//void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
-void VM_R_PolygonVertex (void)
-{
- float *coords, *tx, *rgb, alpha;
- vm_polygon_t *p;
- VM_SAFEPARMCOUNT(4, VM_R_PolygonVertex);
-
- if(!vm_polygonbegin)
- {
- Con_Printf("VM_R_PolygonVertex: VM_R_PolygonBegin wasn't called\n");
- return;
- }
- coords = PRVM_G_VECTOR(OFS_PARM0);
- tx = PRVM_G_VECTOR(OFS_PARM1);
- rgb = PRVM_G_VECTOR(OFS_PARM2);
- alpha = PRVM_G_FLOAT(OFS_PARM3);
-
- p = &vm_polygons[vm_drawpolygons_num];
- if(vm_current_vertices > 4)
- {
- Con_Printf("VM_R_PolygonVertex: may have 4 vertices max\n");
- return;
- }
-
- p->data[vm_current_vertices*3] = coords[0];
- p->data[1+vm_current_vertices*3] = coords[1];
- if(!(p->flags & VM_POLYGON_FL2D))
- p->data[2+vm_current_vertices*3] = coords[2];
-
- p->data[12+vm_current_vertices*2] = tx[0];
- if(!(p->flags & VM_POLYGON_FLLINES))
- p->data[13+vm_current_vertices*2] = tx[1];
-
- p->data[20+vm_current_vertices*4] = rgb[0];
- p->data[21+vm_current_vertices*4] = rgb[1];
- p->data[22+vm_current_vertices*4] = rgb[2];
- p->data[23+vm_current_vertices*4] = alpha;
-
- vm_current_vertices++;
- if(vm_current_vertices == 4)
- p->flags |= VM_POLYGON_FL4V;
- else
- if(vm_current_vertices == 3)
- p->flags |= VM_POLYGON_FL3V;
-}
-
-//void() R_EndPolygon
-void VM_R_PolygonEnd (void)
-{
- if(!vm_polygonbegin)
- {
- Con_Printf("VM_R_PolygonEnd: VM_R_PolygonBegin wasn't called\n");
- return;
- }
- if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
- {
- if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
- VM_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
- else
- vm_drawpolygons_num++;
- }
- else
- Con_Printf("VM_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
- vm_polygonbegin = false;
-}
-
-void VM_AddPolygonsToMeshQueue (void)
-{
- unsigned int i;
- if(!vm_drawpolygons_num)
- return;
- for(i = 0;i < vm_drawpolygons_num;i++)
- R_MeshQueue_Add(VM_DrawPolygonCallback, NULL, i, NULL);
- vm_drawpolygons_num = 0;
-}