/* ================ GL_MakeAliasModelDisplayLists ================ */ void GL_MakeAliasModelDisplayLists (qmodel_t *m, aliashdr_t *hdr) { int i, j; int *cmds; trivertx_t *verts; float hscale, vscale; //johnfitz -- padded skins int count; //johnfitz -- precompute texcoords for padded skins int *loadcmds; //johnfitz //johnfitz -- padded skins hscale = (float)hdr->skinwidth/(float)TexMgr_PadConditional(hdr->skinwidth); vscale = (float)hdr->skinheight/(float)TexMgr_PadConditional(hdr->skinheight); //johnfitz aliasmodel = m; paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); //johnfitz -- generate meshes Con_DPrintf2 ("meshing %s...\n",m->name); BuildTris (); // save the data out paliashdr->poseverts = numorder; cmds = (int *) Hunk_Alloc (numcommands * 4); paliashdr->commands = (byte *)cmds - (byte *)paliashdr; //johnfitz -- precompute texcoords for padded skins loadcmds = commands; while(1) { *cmds++ = count = *loadcmds++; if (!count) break; if (count < 0) count = -count; do { *(float *)cmds++ = hscale * (*(float *)loadcmds++); *(float *)cmds++ = vscale * (*(float *)loadcmds++); } while (--count); } //johnfitz verts = (trivertx_t *) Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t)); paliashdr->posedata = (byte *)verts - (byte *)paliashdr; for (i=0 ; i<paliashdr->numposes ; i++) for (j=0 ; j<numorder ; j++) *verts++ = poseverts[i][vertexorder[j]]; // ericw GL_MakeAliasModelDisplayLists_VBO (); }
void GuiImage::Draw() { if (!IsVisible()) { return; } if (GetCombinedPos() != m_oldPos || GetSize() != m_oldSize) { BuildTris(); m_oldPos = GetCombinedPos(); m_oldSize = GetSize(); } Assert(m_texture); m_texture->UseThisTexture(); // AmjuGL::DrawTriList(m_tris); AmjuGL::Draw(m_triList); }
void GL_MakeAliasModelDisplayLists(model_t *m, aliashdr_t *hdr) { aliasmodel = m; paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); // build it from scratch BuildTris(); // trifans or lists // save the data out paliashdr->poseverts = numorder; int *cmds = (int *) Hunk_Alloc(numcommands * 4); paliashdr->commands = (byte *) cmds - (byte *) paliashdr; memcpy(cmds, commands, numcommands * 4); trivertx_t *verts = (trivertx_t *) Hunk_Alloc(paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx_t)); paliashdr->posedata = (byte *) verts - (byte *) paliashdr; for (int i = 0; i < paliashdr->numposes; i++) for (int j = 0; j < numorder; j++) *verts++ = poseverts[i][vertexorder[j]]; }
void gl_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s, int extra) { dstring_t *cache, *fullpath; unsigned char model_digest[MDFOUR_DIGEST_BYTES]; unsigned char mesh_digest[MDFOUR_DIGEST_BYTES]; int i, j; int *cmds; QFile *f; qboolean remesh = true; qboolean do_cache = false; aliasmodel = m; paliashdr = hdr; cache = dstring_new (); fullpath = dstring_new (); if (!gl_alias_render_tri->int_val) { if (gl_mesh_cache->int_val && gl_mesh_cache->int_val <= paliashdr->mdl.numtris) { do_cache = true; mdfour (model_digest, (unsigned char *) _m, _s); // look for a cached version dstring_copystr (cache, "glquake/"); dstring_appendstr (cache, m->name); QFS_StripExtension (m->name + strlen ("progs/"), cache->str + strlen ("glquake/")); dstring_appendstr (cache, ".qfms"); QFS_FOpenFile (cache->str, &f); if (f) { unsigned char d1[MDFOUR_DIGEST_BYTES]; unsigned char d2[MDFOUR_DIGEST_BYTES]; struct mdfour md; int len, vers; int nc = 0, no = 0; int *c = 0, *vo = 0; memset (d1, 0, sizeof (d1)); memset (d2, 0, sizeof (d2)); Qread (f, &vers, sizeof (int)); Qread (f, &len, sizeof (int)); Qread (f, &nc, sizeof (int)); Qread (f, &no, sizeof (int)); if (vers == 1 && (nc + no) == len) { c = malloc (((nc + 1023) & ~1023) * sizeof (c[0])); vo = malloc (((no + 1023) & ~1023) * sizeof (vo[0])); if (!c || !vo) Sys_Error ("gl_mesh.c: out of memory"); Qread (f, c, nc * sizeof (c[0])); Qread (f, vo, no * sizeof (vo[0])); Qread (f, d1, MDFOUR_DIGEST_BYTES); Qread (f, d2, MDFOUR_DIGEST_BYTES); Qclose (f); mdfour_begin (&md); mdfour_update (&md, (unsigned char *) &vers, sizeof(int)); mdfour_update (&md, (unsigned char *) &len, sizeof(int)); mdfour_update (&md, (unsigned char *) &nc, sizeof(int)); mdfour_update (&md, (unsigned char *) &no, sizeof(int)); mdfour_update (&md, (unsigned char *) c, nc * sizeof (c[0])); mdfour_update (&md, (unsigned char *) vo, no * sizeof (vo[0])); mdfour_update (&md, d1, MDFOUR_DIGEST_BYTES); mdfour_result (&md, mesh_digest); if (memcmp (d2, mesh_digest, MDFOUR_DIGEST_BYTES) == 0 && memcmp (d1, model_digest, MDFOUR_DIGEST_BYTES) == 0) { remesh = false; numcommands = nc; numorder = no; if (numcommands > commands_size) { if (commands) free (commands); commands_size = (numcommands + 1023) & ~1023; commands = c; } else { memcpy (commands, c, numcommands * sizeof (c[0])); free(c); } if (numorder > vertexorder_size) { if (vertexorder) free (vertexorder); vertexorder_size = (numorder + 1023) & ~1023; vertexorder = vo; } else { memcpy (vertexorder, vo, numorder * sizeof (vo[0])); free (vo); } } } } } if (remesh) { // build it from scratch Sys_MaskPrintf (SYS_DEV, "meshing %s...\n", m->name); BuildTris (); // trifans or lists if (do_cache) { // save out the cached version dsprintf (fullpath, "%s/%s", qfs_gamedir->dir.def, cache->str); f = QFS_WOpen (fullpath->str, 9); if (f) { struct mdfour md; int vers = 1; int len = numcommands + numorder; mdfour_begin (&md); mdfour_update (&md, (unsigned char *) &vers, sizeof (int)); mdfour_update (&md, (unsigned char *) &len, sizeof (int)); mdfour_update (&md, (unsigned char *) &numcommands, sizeof (int)); mdfour_update (&md, (unsigned char *) &numorder, sizeof (int)); mdfour_update (&md, (unsigned char *) commands, numcommands * sizeof (commands[0])); mdfour_update (&md, (unsigned char *) vertexorder, numorder * sizeof (vertexorder[0])); mdfour_update (&md, model_digest, MDFOUR_DIGEST_BYTES); mdfour_result (&md, mesh_digest); Qwrite (f, &vers, sizeof (int)); Qwrite (f, &len, sizeof (int)); Qwrite (f, &numcommands, sizeof (int)); Qwrite (f, &numorder, sizeof (int)); Qwrite (f, commands, numcommands * sizeof (commands[0])); Qwrite (f, vertexorder, numorder * sizeof (vertexorder[0])); Qwrite (f, model_digest, MDFOUR_DIGEST_BYTES); Qwrite (f, mesh_digest, MDFOUR_DIGEST_BYTES); Qclose (f); } } } // save the data out paliashdr->poseverts = numorder; cmds = Hunk_Alloc (numcommands * sizeof (int)); paliashdr->commands = (byte *) cmds - (byte *) paliashdr; memcpy (cmds, commands, numcommands * sizeof (int)); } else { tex_coord_t *tex_coord; numorder = 0; for (i=0; i < pheader->mdl.numtris; i++) { add_vertex(triangles[i].vertindex[0]); add_vertex(triangles[i].vertindex[1]); add_vertex(triangles[i].vertindex[2]); } paliashdr->poseverts = numorder; tex_coord = Hunk_Alloc (numorder * sizeof(tex_coord_t)); paliashdr->tex_coord = (byte *) tex_coord - (byte *) paliashdr; for (i=0; i < numorder; i++) { float s, t; int k; k = vertexorder[i]; s = stverts[k].s; t = stverts[k].t; if (!triangles[i/3].facesfront && stverts[k].onseam) s += pheader->mdl.skinwidth / 2; // on back side s = (s + 0.5) / pheader->mdl.skinwidth; t = (t + 0.5) / pheader->mdl.skinheight; tex_coord[i].st[0] = s; tex_coord[i].st[1] = t; } } if (extra) { trivertx16_t *verts; verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx16_t)); paliashdr->posedata = (byte *) verts - (byte *) paliashdr; for (i = 0; i < paliashdr->numposes; i++) { trivertx_t *pv = poseverts[i]; for (j = 0; j < numorder; j++) { trivertx16_t v; // convert MD16's split coordinates into something a little // saner. The first chunk of vertices is fully compatible with // IDPO alias models (even the scale). The second chunk is the // fractional bits of the vertex, giving 8.8. However, it's // easier for us to multiply everything by 256 and adjust the // model scale appropriately VectorMultAdd (pv[vertexorder[j] + hdr->mdl.numverts].v, 256, pv[vertexorder[j]].v, v.v); v.lightnormalindex = poseverts[i][vertexorder[j]].lightnormalindex; *verts++ = v; } } } else { trivertx_t *verts; verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx_t)); paliashdr->posedata = (byte *) verts - (byte *) paliashdr; for (i = 0; i < paliashdr->numposes; i++) { for (j = 0; j < numorder; j++) *verts++ = poseverts[i][vertexorder[j]]; } } dstring_delete (cache); dstring_delete (fullpath); }
/* ================ GL_MakeAliasModelDisplayLists ================ */ void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) { int i, j; maliasgroup_t *paliasgroup; int *cmds; trivertx_t *verts; char cache[MAX_QPATH], fullpath[MAX_OSPATH], *c; FILE *f; int len; byte *data; aliasmodel = m; paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); // // look for a cached version // strcpy (cache, "glquake/"); COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/")); strcat (cache, ".ms2"); COM_FOpenFile (cache, &f, NULL); // 2001-09-12 Returning from which searchpath a file was loaded by Maddes if (f) { fread (&numcommands, 4, 1, f); fread (&numorder, 4, 1, f); fread (&commands, numcommands * sizeof(commands[0]), 1, f); fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); fclose (f); } else { // // build it from scratch // Con_Printf ("meshing %s...\n",m->name); BuildTris (); // trifans or lists // // save out the cached version // sprintf (fullpath, "%s/%s", com_gamedir, cache); f = fopen (fullpath, "wb"); if (f) { fwrite (&numcommands, 4, 1, f); fwrite (&numorder, 4, 1, f); fwrite (&commands, numcommands * sizeof(commands[0]), 1, f); fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); fclose (f); } } // save the data out paliashdr->poseverts = numorder; cmds = Hunk_Alloc (numcommands * 4); paliashdr->commands = (byte *)cmds - (byte *)paliashdr; memcpy (cmds, commands, numcommands * 4); verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) ); paliashdr->posedata = (byte *)verts - (byte *)paliashdr; for (i=0 ; i<paliashdr->numposes ; i++) for (j=0 ; j<numorder ; j++) *verts++ = poseverts[i][vertexorder[j]]; }
void WriteModel( ) { int i, j, k; mstudiobodyparts_t *pbodypart; mstudiomodel_t *pmodel; // vec3_t *bbox; byte *pbone; vec3_t *pvert; vec3_t *pnorm; mstudiomesh_t *pmesh; s_trianglevert_t *psrctri; int cur; int total_tris = 0; int total_strips = 0; pbodypart = (mstudiobodyparts_t *)pData; phdr->numbodyparts = numbodyparts; phdr->bodypartindex = (pData - pStart); pData += numbodyparts * sizeof( mstudiobodyparts_t ); pmodel = (mstudiomodel_t *)pData; pData += nummodels * sizeof( mstudiomodel_t ); for (i = 0, j = 0; i < numbodyparts; i++) { strcpy( pbodypart[i].name, bodypart[i].name ); pbodypart[i].nummodels = bodypart[i].nummodels; pbodypart[i].base = bodypart[i].base; pbodypart[i].modelindex = ((byte *)&pmodel[j]) - pStart; j += bodypart[i].nummodels; } ALIGN( pData ); cur = (int)pData; for (i = 0; i < nummodels; i++) { int normmap[MAXSTUDIOVERTS]; int normimap[MAXSTUDIOVERTS]; int n = 0; strcpy( pmodel[i].name, model[i]->name ); // save bbox info // remap normals to be sorted by skin reference for (j = 0; j < model[i]->nummesh; j++) { for (k = 0; k < model[i]->numnorms; k++) { if (model[i]->normal[k].skinref == model[i]->pmesh[j]->skinref) { normmap[k] = n; normimap[n] = k; n++; model[i]->pmesh[j]->numnorms++; } } } // save vertice bones pbone = pData; pmodel[i].numverts = model[i]->numverts; pmodel[i].vertinfoindex = (pData - pStart); for (j = 0; j < pmodel[i].numverts; j++) { *pbone++ = model[i]->vert[j].bone; } ALIGN( pbone ); // save normal bones pmodel[i].numnorms = model[i]->numnorms; pmodel[i].norminfoindex = ((byte *)pbone - pStart); for (j = 0; j < pmodel[i].numnorms; j++) { *pbone++ = model[i]->normal[normimap[j]].bone; } ALIGN( pbone ); pData = pbone; // save group info pvert = (vec3_t *)pData; pData += model[i]->numverts * sizeof( vec3_t ); pmodel[i].vertindex = ((byte *)pvert - pStart); ALIGN( pData ); pnorm = (vec3_t *)pData; pData += model[i]->numnorms * sizeof( vec3_t ); pmodel[i].normindex = ((byte *)pnorm - pStart); ALIGN( pData ); for (j = 0; j < model[i]->numverts; j++) { VectorCopy( model[i]->vert[j].org, pvert[j] ); } for (j = 0; j < model[i]->numnorms; j++) { VectorCopy( model[i]->normal[normimap[j]].org, pnorm[j] ); } printf("vertices %6d bytes (%d vertices, %d normals)\n", pData - cur, model[i]->numverts, model[i]->numnorms); cur = (int)pData; // save mesh info pmesh = (mstudiomesh_t *)pData; pmodel[i].nummesh = model[i]->nummesh; pmodel[i].meshindex = (pData - pStart); pData += pmodel[i].nummesh * sizeof( mstudiomesh_t ); ALIGN( pData ); total_tris = 0; total_strips = 0; for (j = 0; j < model[i]->nummesh; j++) { int numCmdBytes; byte *pCmdSrc; pmesh[j].numtris = model[i]->pmesh[j]->numtris; pmesh[j].skinref = model[i]->pmesh[j]->skinref; pmesh[j].numnorms = model[i]->pmesh[j]->numnorms; psrctri = (s_trianglevert_t *)(model[i]->pmesh[j]->triangle); for (k = 0; k < pmesh[j].numtris * 3; k++) { psrctri->normindex = normmap[psrctri->normindex]; psrctri++; } numCmdBytes = BuildTris( model[i]->pmesh[j]->triangle, model[i]->pmesh[j], &pCmdSrc ); pmesh[j].triindex = (pData - pStart); memcpy( pData, pCmdSrc, numCmdBytes ); pData += numCmdBytes; ALIGN( pData ); total_tris += pmesh[j].numtris; total_strips += numcommandnodes; } printf("mesh %6d bytes (%d tris, %d strips)\n", pData - cur, total_tris, total_strips); cur = (int)pData; } }
/* ================ GL_MakeAliasModelDisplayLists ================ */ void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) { int i, j; int *cmds; trivertx_t *verts; #if 0 char cache[MAX_QPATH], fullpath[MAX_OSPATH]; FILE *f; #endif aliasmodel = m; paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); #if 0 // // look for a cached version // strcpy (cache, "glquake/"); COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/")); strcat (cache, ".ms2"); FS_FOpenFile (cache, &f); if (f) { fread (&numcommands, 4, 1, f); fread (&numorder, 4, 1, f); fread (&commands, numcommands * sizeof(commands[0]), 1, f); fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); fclose (f); } else { // // build it from scratch // Com_Printf ("meshing %s...\n",m->name); BuildTris (); // trifans or lists // // save out the cached version // sprintf (fullpath, "%s/%s", com_gamedir, cache); f = fopen (fullpath, "wb"); if (!f) { char gldir[MAX_OSPATH]; sprintf (gldir, "%s/glquake", com_gamedir); Sys_mkdir (gldir); f = fopen (fullpath, "wb"); } if (f) { fwrite (&numcommands, 4, 1, f); fwrite (&numorder, 4, 1, f); fwrite (&commands, numcommands * sizeof(commands[0]), 1, f); fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); fclose (f); } } #else // Tonik: don't cache anything, because it seems just as fast // (if not faster) to rebuild the tris instead of loading them from disk BuildTris (); // trifans or lists #endif // save the data out paliashdr->poseverts = numorder; cmds = Hunk_Alloc (numcommands * 4); paliashdr->commands = (byte *)cmds - (byte *)paliashdr; memcpy (cmds, commands, numcommands * 4); verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) ); paliashdr->posedata = (byte *)verts - (byte *)paliashdr; for (i=0 ; i<paliashdr->numposes ; i++) for (j=0 ; j<numorder ; j++) *verts++ = poseverts[i][vertexorder[j]]; }
/* ================ GL_MakeAliasModelDisplayLists ================ */ void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) { int i, j; maliasgroup_t *paliasgroup; int *cmds; trivertx_t *verts; char cache[MAX_QPATH], fullpath[MAX_OSPATH], *c; FILE *f; int len; byte *data; aliasmodel = m; paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); #ifdef NO_CACHE_MESH BuildTris (); // trifans or lists #else // // look for a cached version // strcpy (cache, "glquake/"); COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/")); strcat (cache, ".ms2"); COM_FOpenFile (cache, &f); if (f) { fread (&numcommands, 4, 1, f); fread (&numorder, 4, 1, f); fread (&commands, numcommands * sizeof(commands[0]), 1, f); fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); fclose (f); } else { // // build it from scratch // Con_SafePrintf ("meshing %s...\n",m->name); BuildTris (); // trifans or lists // // save out the cached version // sprintf (fullpath, "%s/%s", com_gamedir, cache); f = fopen (fullpath, "wb"); if (f) { fwrite (&numcommands, 4, 1, f); fwrite (&numorder, 4, 1, f); fwrite (&commands, numcommands * sizeof(commands[0]), 1, f); fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); fclose (f); } } #endif // save the data out paliashdr->poseverts = numorder; cmds = Hunk_Alloc (numcommands * 4); paliashdr->commands = (byte *)cmds - (byte *)paliashdr; memcpy (cmds, commands, numcommands * 4); verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) ); paliashdr->posedata = (byte *)verts - (byte *)paliashdr; for (i=0 ; i<paliashdr->numposes ; i++) { for (j=0 ; j<numorder ; j++) { if (vertexorder[j] < 0 || vertexorder[j] >= MAXALIASVERTS) Sys_Error ("GL_MakeAliasModelDisplayLists: invalid vertexorder[%d] (%d, max = %d) in %s", j, vertexorder[j], MAXALIASVERTS, m->name); *verts++ = poseverts[i][vertexorder[j]]; } } }
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) { int i, j; // maliasgroup_t *paliasgroup; int *cmds; trivertx_t *verts; char cache[MAX_QPATH], fullpath[MAX_OSPATH];//, *c; FILE *f; size_t success = 0; // int len; // byte *data; aliasmodel = m; paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); // // look for a cached version // strcpy (cache, "glquake/"); COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/")); strcat (cache, ".ms2"); COM_FOpenFile (cache, &f); if (f) { // <AWE> we always read now little endian and do more checks on fread: success = fread (&numcommands, 4, 1, f); if (success == 1) { success = fread (&numorder, 4, 1, f); } numcommands = LittleLong(numcommands); numorder = LittleLong(numorder); if (numcommands >= 8192 || numorder >= 8192) { success = 0; } if (success == 1) { success = fread (&commands, numcommands * sizeof(commands[0]), 1, f); } if (success == 1) { success = fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); } if (success == 1) { SwapBufferEndianess(); } fclose (f); } if (success == 0) { // // build it from scratch // Con_Printf ("meshing %s...\n",m->name); BuildTris (); // trifans or lists // // save out the cached version // #if defined (__APPLE__) || defined (MACOSX) snprintf (fullpath, MAX_OSPATH, "%s/%s", com_gamedir, cache); #else sprintf (fullpath, "%s/%s", com_gamedir, cache); #endif /* __APPLE__ || MACOSX */ f = fopen (fullpath, "wb"); /* if (!f) { char gldir[MAX_OSPATH]; #if defined (__APPLE__) || defined (MACOSX) snprintf (gldir, MAX_OSPATH, "%s/glquake", com_gamedir); #else sprintf (gldir, "%s/glquake", com_gamedir); #endif Sys_mkdir (gldir); f = fopen (fullpath, "wb"); } */ if (f) { // <AWE> we always write now in little endian: int littleNumCommands = LittleLong(numcommands); int littleNumOrder = LittleLong(numorder); fwrite (&littleNumCommands, 4, 1, f); fwrite (&littleNumOrder, 4, 1, f); SwapBufferEndianess(); fwrite (&commands, numcommands * sizeof(commands[0]), 1, f); fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); fclose (f); SwapBufferEndianess(); } } // save the data out paliashdr->poseverts = numorder; cmds = Hunk_Alloc (numcommands * 4); paliashdr->commands = (int) ((byte *)cmds - (byte *)paliashdr); memcpy (cmds, commands, numcommands * 4); verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) ); paliashdr->posedata = (int) ((byte *)verts - (byte *)paliashdr); for (i=0 ; i<paliashdr->numposes ; i++) for (j=0 ; j<numorder ; j++) *verts++ = poseverts[i][vertexorder[j]]; }