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);
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));
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;
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);
// 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++)
{
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
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
// 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;
}
/*
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;
}
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);
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);
{
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
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;
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;
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)
{
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];
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)
break;
}
}
- R_SetupShader_Generic(Draw_GetPicTexture(map->pic), NULL, GL_MODULATE, 1, (flags & DRAWFLAGS_BLEND) ? false : true, true, false);
}
mapch = ch - map->start;
}
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;
}
}
}
- 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;
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)
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);
+}
R_TimeReport("explosions");
}
- if (cl.csqc_loaded)
- VM_CL_AddPolygonsToMeshQueue(CLVM_prog);
-
if (r_refdef.view.showdebug)
{
if (cl_locs_show.integer)
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];
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;
}
}
+ 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];
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;
}
}
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);
}
}
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++;
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
{
// 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;
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)
{
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));
#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
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;
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)
{
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)
}
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)
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;
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:
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.
r_refdef_scene_t *scene;
VM_Cmd_Init(prog);
- VM_Polygons_Reset(prog);
+ prog->polygonbegin_model = NULL;
scene = R_GetScenePointer( RST_MENU );
//VM_Cmd_Init();
VM_Cmd_Reset(prog);
- VM_Polygons_Reset(prog);
+ prog->polygonbegin_model = NULL;
}
} 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))
// 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;
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);
}
}
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);
}
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);
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);