X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=clvm_cmds.c;h=d2836b3740c87a3643f3f91450a0c9fd0743dfa4;hp=25f3b195a32441e89ae583875990eadcbb5c44cf;hb=3291222c2c2c8cc53d63d859cf0f89940be25604;hpb=1890125248366989ff299dfca7f36e55d95bb0d2 diff --git a/clvm_cmds.c b/clvm_cmds.c index 25f3b195..d2836b37 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -743,6 +743,8 @@ static void VM_CL_R_ClearScene (prvm_prog_t *prog) cl.csqc_vidvars.drawenginesbar = false; cl.csqc_vidvars.drawcrosshair = false; CSQC_R_RecalcView(); + // clear the CL_Mesh_Scene() used for CSQC polygons and engine effects, they will be added by CSQC_RelinkAllEntities and manually created by CSQC + CL_MeshEntities_Scene_Clear(); } //#301 void(float mask) addentities (EXT_CSQC) @@ -1623,20 +1625,9 @@ static void VM_CL_setlistener (prvm_prog_t *prog) //#352 void(string cmdname) registercommand (EXT_CSQC) static void VM_CL_registercmd (prvm_prog_t *prog) { - char *t; VM_SAFEPARMCOUNT(1, VM_CL_registercmd); if(!Cmd_Exists(&cmd_client, PRVM_G_STRING(OFS_PARM0))) - { - size_t alloclen; - - alloclen = strlen(PRVM_G_STRING(OFS_PARM0)) + 1; - t = (char *)Z_Malloc(alloclen); - memcpy(t, PRVM_G_STRING(OFS_PARM0), alloclen); - Cmd_AddCommand(&cmd_client, t, NULL, "console command created by QuakeC"); - } - else Cmd_AddCommand(&cmd_client, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC"); - } //#360 float() readbyte (EXT_CSQC) @@ -3262,17 +3253,17 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog) csqc_main_r_refdef_view = r_refdef.view; } + // now after all of the predraw we know the geometry in the scene mesh and can finalize it for rendering + CL_MeshEntities_Scene_FinalizeRenderEntity(); + // 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(0, NULL, NULL, r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); - 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; @@ -3314,9 +3305,13 @@ static void VM_CL_R_PolygonBegin (prvm_prog_t *prog) } // we need to remember whether this is a 2D or 3D mesh we're adding to - mod = draw2d ? CL_Mesh_UI() : CL_Mesh_CSQC(); + mod = draw2d ? CL_Mesh_UI() : CL_Mesh_Scene(); prog->polygonbegin_model = mod; - Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, texname, drawflags, TEXF_ALPHA, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX), false); + if (texname == NULL || texname[0] == 0) + texname = "$whiteimage"; + strlcpy(prog->polygonbegin_texname, texname, sizeof(prog->polygonbegin_texname)); + prog->polygonbegin_drawflags = drawflags; + prog->polygonbegin_numvertices = 0; } //void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex @@ -3326,47 +3321,97 @@ static void VM_CL_R_PolygonVertex (prvm_prog_t *prog) 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); + float *o; dp_model_t *mod = prog->polygonbegin_model; - int e0, e1, e2; - msurface_t *surf; VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex); - if (!mod || mod->num_surfaces == 0) + if (!mod) { VM_Warning(prog, "VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n"); return; } - 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) + if (prog->polygonbegin_maxvertices <= prog->polygonbegin_numvertices) { - // 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); + prog->polygonbegin_maxvertices = max(16, prog->polygonbegin_maxvertices * 2); + prog->polygonbegin_vertexdata = (float *)Mem_Realloc(prog->progs_mempool, prog->polygonbegin_vertexdata, prog->polygonbegin_maxvertices * sizeof(float[10])); } + o = prog->polygonbegin_vertexdata + prog->polygonbegin_numvertices++ * 10; + + o[0] = v[0]; + o[1] = v[1]; + o[2] = v[2]; + o[3] = tc[0]; + o[4] = tc[1]; + o[5] = tc[2]; + o[6] = c[0]; + o[7] = c[1]; + o[8] = c[2]; + o[9] = a; } //void() R_EndPolygon static void VM_CL_R_PolygonEnd (prvm_prog_t *prog) { + int i; + qboolean hascolor; + qboolean hasalpha; + int e0 = 0, e1 = 0, e2 = 0; + float *o; dp_model_t *mod = prog->polygonbegin_model; msurface_t *surf; + texture_t *tex; + int materialflags; VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd); - if (!mod || mod->num_surfaces == 0) + if (!mod) { VM_Warning(prog, "VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n"); return; } - surf = &mod->data_surfaces[mod->num_surfaces - 1]; + + // determine if vertex alpha is being used so we can provide that hint to GetTexture... + hascolor = false; + hasalpha = false; + for (i = 0; i < prog->polygonbegin_numvertices; i++) + { + o = prog->polygonbegin_vertexdata + 10 * i; + if (o[6] != 1.0f || o[7] != 1.0f || o[8] != 1.0f) + hascolor = true; + if (o[9] != 1.0f) + hasalpha = true; + } + + // create the surface, looking up the best matching texture/shader + materialflags = MATERIALFLAG_WALL; + if (csqc_polygons_defaultmaterial_nocullface.integer) + materialflags |= MATERIALFLAG_NOCULLFACE; + if (hascolor) + materialflags |= MATERIALFLAG_VERTEXCOLOR; + if (hasalpha) + materialflags |= MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; + tex = Mod_Mesh_GetTexture(mod, prog->polygonbegin_texname, prog->polygonbegin_drawflags, TEXF_ALPHA, materialflags); + surf = Mod_Mesh_AddSurface(mod, tex, false); + // create triangle fan + for (i = 0; i < prog->polygonbegin_numvertices; i++) + { + o = prog->polygonbegin_vertexdata + 10 * i; + e2 = Mod_Mesh_IndexForVertex(mod, surf, o[0], o[1], o[2], 0, 0, 0, o[3], o[4], 0, 0, o[6], o[7], o[8], o[9]); + if (i >= 2) + Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2); + else if (i == 0) + e0 = e2; + e1 = e2; + } + // build normals (since they are not provided) 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); + + // reset state prog->polygonbegin_model = NULL; + prog->polygonbegin_texname[0] = 0; + prog->polygonbegin_drawflags = 0; + prog->polygonbegin_numvertices = 0; } /*