From 4a7eb0f11da147f22ae7a2a17b4e5f4b0aad60ac Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 14 Oct 2009 09:20:11 +0000 Subject: [PATCH] fixed bug with gl_paranoid 1 when gl_vbo is 0 where element3s contained no valid triangles because they were not initialized by Mod_BuildVBOs moved unfinished OBJ loader from alias code to brush code git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9336 d7cf8633-e32d-0410-b094-e92efae38249 --- model_alias.c | 464 ++----------------------------------------------- model_brush.c | 461 ++++++++++++++++++++++++++++++++++++++++++++++++ model_shared.c | 18 +- 3 files changed, 488 insertions(+), 455 deletions(-) diff --git a/model_alias.c b/model_alias.c index 2cd55b36..7095e7ea 100644 --- a/model_alias.c +++ b/model_alias.c @@ -1071,11 +1071,10 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) // generate ushort elements array if possible if (loadmodel->surfmesh.num_vertices <= 65536) - { loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles); + if (loadmodel->surfmesh.data_element3s) for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - } // load the frames loadmodel->animscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes); @@ -1403,11 +1402,10 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend) // generate ushort elements array if possible if (loadmodel->surfmesh.num_vertices <= 65536) - { loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles); + if (loadmodel->surfmesh.data_element3s) for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - } // load the frames datapointer = (base + LittleLong(pinmodel->ofs_frames)); @@ -1568,11 +1566,7 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += meshvertices * sizeof(float[2]); loadmodel->surfmesh.data_morphmd3vertex = (md3vertex_t *)data;data += meshvertices * loadmodel->numframes * sizeof(md3vertex_t); if (meshvertices <= 65536) - { loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += meshtriangles * sizeof(unsigned short[3]); - for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) - loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - } meshvertices = 0; meshtriangles = 0; @@ -1615,6 +1609,9 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend) Mod_ValidateElements(loadmodel->surfmesh.data_element3i + surface->num_firsttriangle * 3, surface->num_triangles, surface->num_firstvertex, surface->num_vertices, __FILE__, __LINE__); } + if (loadmodel->surfmesh.data_element3s) + for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) + loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); Mod_Alias_MorphMesh_CompileFrames(); Mod_Alias_CalculateBoundingBox(); @@ -1820,11 +1817,7 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * loadmodel->num_bones * sizeof(float[12]); loadmodel->data_baseboneposeinverse = (float *)data;data += loadmodel->num_bones * sizeof(float[12]); if (loadmodel->surfmesh.num_vertices <= 65536) - { loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3]); - for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) - loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - } //zymlump_t lump_poses; // float pose[numposes][numbones][3][4]; // animation data poses = (float *) (pheader->lump_poses.start + pbase); @@ -1940,6 +1933,9 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) Mod_MakeSortedSurfaces(loadmodel); // compute all the mesh information that was not loaded from the file + if (loadmodel->surfmesh.data_element3s) + for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) + loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; Mod_ValidateElements(loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles, 0, loadmodel->surfmesh.num_vertices, __FILE__, __LINE__); Mod_BuildBaseBonePoses(); Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, true); @@ -2076,11 +2072,7 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->data_bones = (aliasbone_t *)data;data += loadmodel->num_bones * sizeof(aliasbone_t); loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t); if (meshvertices <= 65536) - { loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += meshtriangles * sizeof(unsigned short[3]); - for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) - loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - } for (i = 0;i < loadmodel->numskins;i++) { @@ -2247,6 +2239,9 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) Mod_MakeSortedSurfaces(loadmodel); // compute all the mesh information that was not loaded from the file + if (loadmodel->surfmesh.data_element3s) + for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) + loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; Mod_BuildBaseBonePoses(); Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true); Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); @@ -2668,11 +2663,7 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->data_bones = (aliasbone_t *)data;data += loadmodel->num_bones * sizeof(aliasbone_t); loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t); if (loadmodel->surfmesh.num_vertices <= 65536) - { loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3]); - for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) - loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - } for (i = 0;i < loadmodel->numskins;i++) { @@ -2798,6 +2789,9 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) // compute all the mesh information that was not loaded from the file // TODO: honor smoothing groups somehow? + if (loadmodel->surfmesh.data_element3s) + for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) + loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; Mod_ValidateElements(loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles, 0, loadmodel->surfmesh.num_vertices, __FILE__, __LINE__); Mod_BuildBaseBonePoses(); Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, true); @@ -2807,433 +2801,3 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1; } - -void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend) -{ -#if 0 - const char *textbase = (char *)buffer, *text = textbase; - char *s; - char *argv[512]; - char line[1024]; - char materialname[MAX_QPATH]; - int j, index1, index2, index3, first, prev, index; - int argc; - int linelen; - int numtriangles = 0; - int maxtriangles = 32768; - int *element3i = Mem_Alloc(tempmempool, maxtriangles * sizeof(int[3])); - int *oldelement3i; - int numsurfaces = 0; - int maxsurfaces = 0; - msurface_t *surfaces = NULL; - int linenumber = 0; - int hashindex; - float *v, *vt, *vn; - float *oldv, *oldvt, *oldvn; - int maxv = 65536, numv = 1; - int maxvt = 65536, numvt = 1; - int maxvn = 65536, numvn = 1; - int maxverthash = 65536, numverthash = 0; - int numhashindex = 65536; - struct objverthash_s - { - struct objverthash_s *next; - int s; - int v; - int vt; - int vn; - } - *hash, **verthash = Mem_Alloc(tempmempool, numhashindex * sizeof(*verthash)), *verthashdata = Mem_Alloc(tempmempool, maxverthash * sizeof(*verthashdata)), *oldverthashdata; - skinfile_t *skinfiles; - - dpsnprintf(materialname, sizeof(materialname), "%s", loadmodel->name); - - skinfiles = Mod_LoadSkinFiles(); - - loadmodel->modeldatatypestring = "OBJ"; - - loadmodel->type = mod_alias; - loadmodel->AnimateVertices = NULL; - loadmodel->DrawSky = NULL; - loadmodel->DrawAddWaterPlanes = NULL; - loadmodel->Draw = R_Q1BSP_Draw; - loadmodel->DrawDepth = R_Q1BSP_DrawDepth; - loadmodel->DrawDebug = R_Q1BSP_DrawDebug; - loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; - loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; - loadmodel->DrawLight = R_Q1BSP_DrawLight; - loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; - loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; - loadmodel->PointSuperContents = NULL; - - // parse the OBJ text now - for(;;) - { - if (!*text) - break; - linenumber++; - linelen = 0; - for (linelen = 0;text[linelen] && text[linelen] != '\r' && text[linelen] != '\n';linelen++) - line[linelen] = text[linelen]; - line[linelen] = 0; - for (argc = 0;argc < (int)(sizeof(argv)/sizeof(argv[0]));argc++) - argv[argc] = ""; - argc = 0; - s = line; - while (*s == ' ' || *s == '\t') - s++; - while (*s) - { - argv[argc++] = s; - while (*s > ' ') - s++; - if (!*s) - break; - *s++ = 0; - while (*s == ' ' || *s == '\t') - s++; - } - if (!argc) - continue; - if (argv[0][0] == '#') - continue; - if (!strcmp(argv[0], "v")) - { - if (maxv <= numv) - { - maxv *= 2; - oldv = v; - v = Mem_Alloc(tempmempool, maxv * sizeof(float[3])); - if (oldv) - { - memcpy(v, oldv, numv * sizeof(float[3])); - Mem_Free(oldv); - } - } - v[numv*3+0] = atof(argv[1]); - v[numv*3+1] = atof(argv[2]); - v[numv*3+2] = atof(argv[3]); - numv++; - } - else if (!strcmp(argv[0], "vt")) - { - if (maxvt <= numvt) - { - maxvt *= 2; - oldvt = vt; - vt = Mem_Alloc(tempmempool, maxvt * sizeof(float[2])); - if (oldvt) - { - memcpy(vt, oldvt, numvt * sizeof(float[2])); - Mem_Free(oldvt); - } - } - vt[numvt*2+0] = atof(argv[1]); - vt[numvt*2+1] = atof(argv[2]); - numvt++; - } - else if (!strcmp(argv[0], "vn")) - { - if (maxvn <= numvn) - { - maxvn *= 2; - oldvn = vn; - vn = Mem_Alloc(tempmempool, maxvn * sizeof(float[3])); - if (oldvn) - { - memcpy(vn, oldvn, numvn * sizeof(float[3])); - Mem_Free(oldvn); - } - } - vn[numvn*3+0] = atof(argv[1]); - vn[numvn*3+1] = atof(argv[2]); - vn[numvn*3+2] = atof(argv[3]); - numvn++; - } - else if (!strcmp(argv[0], "f")) - { - if (!surface) - { - if (maxsurfaces <= numsurfaces) - { - maxsurfaces++; - oldsurfaces = surfaces; - surfaces = Mem_Alloc(tempmempool, maxsurfaces * sizeof(*surfaces)); - if (oldsurfaces) - { - memcpy(surfaces, oldsurfaces, numsurfaces * sizeof(*surfaces)); - Mem_Free(oldsurfaces); - } - } - surface = surfaces + numsurfaces++; - surface-> - } - for (j = 1;j < argc;j++) - { - index1 = atoi(argv[j]); - while(argv[j][0] && argv[j][0] != '/') - argv[j]++; - if (argv[j][0]) - argv[j]++; - if (index1 < 0) - index1 = numv + 1 - index1; - index2 = atoi(argv[j]); - if (index2 < 0) - index2 = numvt + 1 - index2; - while(argv[j][0] && argv[j][0] != '/') - argv[j]++; - if (argv[j][0]) - argv[j]++; - index3 = atoi(argv[j]); - if (index3 < 0) - index3 = numvn + 1 - index3; - hashindex = (index1 + index2 * 3571 + index3 * 42589) & (numhashindex - 1); - for (hash = verthash[hashindex];hash;hash = hash->next) - if (hash->surface == numsurfaces-1 && hash->v == index1 && hash->vt == index2 && hash->vn == index3) - break; - if (!hash) - { - if (maxverthash <= numverthash) - { - maxverthash *= 2; - oldverthashdata = verthashdata; - verthashdata = Mem_Alloc(tempmempool, maxverthash * sizeof(*verthashdata)); - if (oldverthashdata) - { - memcpy(verthashdata, oldverthashdata, numverthash * sizeof(*verthashdata)); - Mem_Free(oldverthashdata); - } - } - hash = verthashdata + numverthash++; - hash->next = verthash[hashindex]; - hash->s = numsurfaces; - hash->v = index1; - hash->vt = index2; - hash->vn = index3; - verthash[hashindex] = hash; - } - index = (int)((size_t)(hash - verthashdata)); - if (j == 1) - first = index; - else if (j >= 3) - { - if (maxtriangles <= numtriangles) - { - maxtriangles *= 2; - oldelement3i = element3i; - element3i = Mem_Alloc(tempmempool, numtriangles * sizeof(int[3])); - if (oldelement3i) - { - memcpy(element3i, oldelement3i, numtriangles * sizeof(int[3])); - Mem_Free(oldelement3i); - } - } - element3i[numtriangles*3+0] = first; - element3i[numtriangles*3+1] = prev; - element3i[numtriangles*3+2] = index; - numtriangles++; - } - prev = index; - } - } - else if (!strcmp(argv[0], "o") || !strcmp(argv[0], "g")) - surface = NULL; - else if (!!strcmp(argv[0], "usemtl")) - { - surface = NULL; - strlcpy(materialname, argv[1], sizeof(materialname); - } - text += linelen; - if (*text == '\r') - text++; - if (*text == '\n') - text++; - } - - if (skinfiles) - Mod_FreeSkinFiles(skinfiles); - - // now that we have the OBJ data loaded as-is, we can convert it - loadmodel->numskins = LittleLong(pinmodel->num_skins); - numxyz = LittleLong(pinmodel->num_xyz); - numst = LittleLong(pinmodel->num_st); - loadmodel->surfmesh.num_triangles = LittleLong(pinmodel->num_tris); - loadmodel->numframes = LittleLong(pinmodel->num_frames); - loadmodel->surfmesh.num_morphframes = loadmodel->numframes; - loadmodel->num_poses = loadmodel->surfmesh.num_morphframes; - skinwidth = LittleLong(pinmodel->skinwidth); - skinheight = LittleLong(pinmodel->skinheight); - iskinwidth = 1.0f / skinwidth; - iskinheight = 1.0f / skinheight; - - loadmodel->num_surfaces = 1; - loadmodel->nummodelsurfaces = loadmodel->num_surfaces; - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->numframes * sizeof(animscene_t) + loadmodel->numframes * sizeof(float[6]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_triangles * sizeof(int[3])); - loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); - loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); - loadmodel->sortedmodelsurfaces[0] = 0; - loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t); - loadmodel->surfmesh.data_morphmd2framesize6f = (float *)data;data += loadmodel->numframes * sizeof(float[6]); - loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); - - loadmodel->synctype = ST_RAND; - - // load the skins - inskin = (char *)(base + LittleLong(pinmodel->ofs_skins)); - skinfiles = Mod_LoadSkinFiles(); - if (skinfiles) - { - loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; - loadmodel->num_texturesperskin = loadmodel->num_surfaces; - loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t)); - Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures, skinfiles, "default", ""); - Mod_FreeSkinFiles(skinfiles); - } - else if (loadmodel->numskins) - { - // skins found (most likely not a player model) - loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; - 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->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP | TEXF_COMPRESS); - } - else - { - // no skins (most likely a player model) - loadmodel->numskins = 1; - loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; - loadmodel->num_texturesperskin = loadmodel->num_surfaces; - loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t)); - Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures, NULL); - } - - loadmodel->skinscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins); - for (i = 0;i < loadmodel->numskins;i++) - { - loadmodel->skinscenes[i].firstframe = i; - loadmodel->skinscenes[i].framecount = 1; - loadmodel->skinscenes[i].loop = true; - loadmodel->skinscenes[i].framerate = 10; - } - - // load the triangles and stvert data - inst = (unsigned short *)(base + LittleLong(pinmodel->ofs_st)); - intri = (md2triangle_t *)(base + LittleLong(pinmodel->ofs_tris)); - md2verthash = (struct md2verthash_s **)Mem_Alloc(tempmempool, 65536 * sizeof(hash)); - md2verthashdata = (struct md2verthash_s *)Mem_Alloc(tempmempool, loadmodel->surfmesh.num_triangles * 3 * sizeof(*hash)); - // swap the triangle list - loadmodel->surfmesh.num_vertices = 0; - for (i = 0;i < loadmodel->surfmesh.num_triangles;i++) - { - for (j = 0;j < 3;j++) - { - xyz = (unsigned short) LittleShort (intri[i].index_xyz[j]); - st = (unsigned short) LittleShort (intri[i].index_st[j]); - if (xyz >= numxyz) - { - Con_Printf("%s has an invalid xyz index (%i) on triangle %i, resetting to 0\n", loadmodel->name, xyz, i); - xyz = 0; - } - if (st >= numst) - { - Con_Printf("%s has an invalid st index (%i) on triangle %i, resetting to 0\n", loadmodel->name, st, i); - st = 0; - } - hashindex = (xyz * 256 + st) & 65535; - for (hash = md2verthash[hashindex];hash;hash = hash->next) - if (hash->xyz == xyz && hash->st == st) - break; - if (hash == NULL) - { - hash = md2verthashdata + loadmodel->surfmesh.num_vertices++; - hash->xyz = xyz; - hash->st = st; - hash->next = md2verthash[hashindex]; - md2verthash[hashindex] = hash; - } - loadmodel->surfmesh.data_element3i[i*3+j] = (hash - md2verthashdata); - } - } - - vertremap = (int *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(int)); - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * loadmodel->surfmesh.num_morphframes * sizeof(trivertx_t)); - loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[2]); - loadmodel->surfmesh.data_morphmdlvertex = (trivertx_t *)data;data += loadmodel->surfmesh.num_vertices * loadmodel->surfmesh.num_morphframes * sizeof(trivertx_t); - for (i = 0;i < loadmodel->surfmesh.num_vertices;i++) - { - int sts, stt; - hash = md2verthashdata + i; - vertremap[i] = hash->xyz; - sts = LittleShort(inst[hash->st*2+0]); - stt = LittleShort(inst[hash->st*2+1]); - if (sts < 0 || sts >= skinwidth || stt < 0 || stt >= skinheight) - { - Con_Printf("%s has an invalid skin coordinate (%i %i) on vert %i, changing to 0 0\n", loadmodel->name, sts, stt, i); - sts = 0; - stt = 0; - } - loadmodel->surfmesh.data_texcoordtexture2f[i*2+0] = sts * iskinwidth; - loadmodel->surfmesh.data_texcoordtexture2f[i*2+1] = stt * iskinheight; - } - - Mem_Free(md2verthash); - Mem_Free(md2verthashdata); - - // generate ushort elements array if possible - if (loadmodel->surfmesh.num_vertices <= 65536) - { - loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles); - for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) - loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - } - - // load the frames - datapointer = (base + LittleLong(pinmodel->ofs_frames)); - for (i = 0;i < loadmodel->surfmesh.num_morphframes;i++) - { - int k; - trivertx_t *v; - trivertx_t *out; - pinframe = (md2frame_t *)datapointer; - datapointer += sizeof(md2frame_t); - // store the frame scale/translate into the appropriate array - for (j = 0;j < 3;j++) - { - loadmodel->surfmesh.data_morphmd2framesize6f[i*6+j] = LittleFloat(pinframe->scale[j]); - loadmodel->surfmesh.data_morphmd2framesize6f[i*6+3+j] = LittleFloat(pinframe->translate[j]); - } - // convert the vertices - v = (trivertx_t *)datapointer; - out = loadmodel->surfmesh.data_morphmdlvertex + i * loadmodel->surfmesh.num_vertices; - for (k = 0;k < loadmodel->surfmesh.num_vertices;k++) - out[k] = v[vertremap[k]]; - datapointer += numxyz * sizeof(trivertx_t); - - strlcpy(loadmodel->animscenes[i].name, pinframe->name, sizeof(loadmodel->animscenes[i].name)); - loadmodel->animscenes[i].firstframe = i; - loadmodel->animscenes[i].framecount = 1; - loadmodel->animscenes[i].framerate = 10; - loadmodel->animscenes[i].loop = true; - } - - Mem_Free(vertremap); - - Mod_MakeSortedSurfaces(loadmodel); - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); - Mod_Alias_CalculateBoundingBox(); - Mod_Alias_MorphMesh_CompileFrames(); - - surface = loadmodel->data_surfaces; - surface->texture = loadmodel->data_textures; - surface->num_firsttriangle = 0; - surface->num_triangles = loadmodel->surfmesh.num_triangles; - surface->num_firstvertex = 0; - surface->num_vertices = loadmodel->surfmesh.num_vertices; - - loadmodel->surfmesh.isanimated = false; -#endif -} diff --git a/model_brush.c b/model_brush.c index d30aca74..da1585ca 100644 --- a/model_brush.c +++ b/model_brush.c @@ -6302,6 +6302,467 @@ void Mod_MAP_Load(dp_model_t *mod, void *buffer, void *bufferend) Host_Error("Mod_MAP_Load: not yet implemented"); } +typedef struct objvertex_s +{ + float v[3]; + float vt[2]; + float vn[3]; +} +objvertex_t; + +typedef struct objtriangle_s +{ + objvertex_t vertex[3]; + int textureindex; +} +objtriangle_t; + +void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend) +{ +#if 0 + const char *textbase = (char *)buffer, *text = textbase; + char *s; + char *argv[512]; + char line[1024]; + char materialname[MAX_QPATH]; + int j, index1, index2, index3, first, prev, index; + int argc; + int linelen; + int numtriangles = 0; + int maxtriangles = 131072; + objtriangle_t *triangles = Mem_Alloc(tempmempool, maxtriangles * sizeof(*triangles)); + int linenumber = 0; + int maxtextures = 256, numtextures = 0, textureindex = 0; + int maxv = 1024, numv = 0; + int maxvt = 1024, numvt = 0; + int maxvn = 1024, numvn = 0; + char **texturenames; + float *v = Mem_Alloc(tempmempool, maxv * sizeof(float[3])); + float *vt = Mem_Alloc(tempmempool, maxvt * sizeof(float[2])); + float *vn = Mem_Alloc(tempmempool, maxvn * sizeof(float[3])); + objvertex_t vfirst, vprev, vcurrent; +#if 0 + int hashindex; + int maxverthash = 65536, numverthash = 0; + int numhashindex = 65536; + struct objverthash_s + { + struct objverthash_s *next; + int s; + int v; + int vt; + int vn; + } + *hash, **verthash = Mem_Alloc(tempmempool, numhashindex * sizeof(*verthash)), *verthashdata = Mem_Alloc(tempmempool, maxverthash * sizeof(*verthashdata)), *oldverthashdata; +#endif + + dpsnprintf(materialname, sizeof(materialname), "%s", loadmodel->name); + + loadmodel->modeldatatypestring = "OBJ"; + + loadmodel->type = mod_obj; + loadmodel->soundfromcenter = true; + loadmodel->TraceBox = Mod_OBJ_TraceBox; + loadmodel->TraceLine = Mod_OBJ_TraceLine; + loadmodel->TracePoint = Mod_OBJ_TracePoint; + loadmodel->PointSuperContents = Mod_OBJ_PointSuperContents; + loadmodel->brush.TraceLineOfSight = Mod_OBJ_TraceLineOfSight; + loadmodel->brush.SuperContentsFromNativeContents = Mod_OBJ_SuperContentsFromNativeContents; + loadmodel->brush.NativeContentsFromSuperContents = Mod_OBJ_NativeContentsFromSuperContents; + loadmodel->brush.GetPVS = Mod_OBJ_GetPVS; + loadmodel->brush.FatPVS = Mod_OBJ_FatPVS; + loadmodel->brush.BoxTouchingPVS = Mod_OBJ_BoxTouchingPVS; + loadmodel->brush.BoxTouchingLeafPVS = Mod_OBJ_BoxTouchingLeafPVS; + loadmodel->brush.BoxTouchingVisibleLeafs = Mod_OBJ_BoxTouchingVisibleLeafs; + loadmodel->brush.FindBoxClusters = Mod_OBJ_FindBoxClusters; + loadmodel->brush.LightPoint = Mod_OBJ_LightPoint; + loadmodel->brush.FindNonSolidLocation = Mod_OBJ_FindNonSolidLocation; + loadmodel->brush.AmbientSoundLevelsForPoint = NULL; + loadmodel->brush.RoundUpToHullSize = NULL; + loadmodel->brush.PointInLeaf = Mod_OBJ_PointInLeaf; + loadmodel->Draw = R_Q1BSP_Draw; + loadmodel->DrawDepth = R_Q1BSP_DrawDepth; + loadmodel->DrawDebug = R_Q1BSP_DrawDebug; + loadmodel->GetLightInfo = R_Q1BSP_GetLightInfo; + loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; + loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; + loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; + loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; + loadmodel->DrawLight = R_Q1BSP_DrawLight; + + // parse the OBJ text now + for(;;) + { + if (!*text) + break; + linenumber++; + linelen = 0; + for (linelen = 0;text[linelen] && text[linelen] != '\r' && text[linelen] != '\n';linelen++) + line[linelen] = text[linelen]; + line[linelen] = 0; + for (argc = 0;argc < (int)(sizeof(argv)/sizeof(argv[0]));argc++) + argv[argc] = ""; + argc = 0; + s = line; + while (*s == ' ' || *s == '\t') + s++; + while (*s) + { + argv[argc++] = s; + while (*s > ' ') + s++; + if (!*s) + break; + *s++ = 0; + while (*s == ' ' || *s == '\t') + s++; + } + if (!argc) + continue; + if (argv[0][0] == '#') + continue; + if (!strcmp(argv[0], "v")) + { + if (maxv <= numv) + { + float *oldv = v; + maxv *= 2; + v = Mem_Alloc(tempmempool, maxv * sizeof(float[3])); + if (oldv) + { + memcpy(v, oldv, numv * sizeof(float[3])); + Mem_Free(oldv); + } + } + v[numv*3+0] = atof(argv[1]); + v[numv*3+1] = atof(argv[2]); + v[numv*3+2] = atof(argv[3]); + numv++; + } + else if (!strcmp(argv[0], "vt")) + { + if (maxvt <= numvt) + { + float *oldvt = vt; + maxvt *= 2; + vt = Mem_Alloc(tempmempool, maxvt * sizeof(float[2])); + if (oldvt) + { + memcpy(vt, oldvt, numvt * sizeof(float[2])); + Mem_Free(oldvt); + } + } + vt[numvt*2+0] = atof(argv[1]); + vt[numvt*2+1] = atof(argv[2]); + numvt++; + } + else if (!strcmp(argv[0], "vn")) + { + if (maxvn <= numvn) + { + float *oldvn = vn; + maxvn *= 2; + vn = Mem_Alloc(tempmempool, maxvn * sizeof(float[3])); + if (oldvn) + { + memcpy(vn, oldvn, numvn * sizeof(float[3])); + Mem_Free(oldvn); + } + } + vn[numvn*3+0] = atof(argv[1]); + vn[numvn*3+1] = atof(argv[2]); + vn[numvn*3+2] = atof(argv[3]); + numvn++; + } + else if (!strcmp(argv[0], "f")) + { + for (j = 1;j < argc;j++) + { + index1 = atoi(argv[j]); + while(argv[j][0] && argv[j][0] != '/') + argv[j]++; + if (argv[j][0]) + argv[j]++; + index2 = atoi(argv[j]); + while(argv[j][0] && argv[j][0] != '/') + argv[j]++; + if (argv[j][0]) + argv[j]++; + index3 = atoi(argv[j]); + // negative refers to a recent vertex + // zero means not specified + // positive means an absolute vertex index + if (index1 < 0) + index1 = numv - index1; + if (index2 < 0) + index2 = numvt - index2; + if (index3 < 0) + index3 = numvn - index3; + VectorCopy(v + 3*index1, vcurrent.v); + Vector2Copy(vt + 2*index2, vcurrent.vt); + VectorCopy(vn + 3*index3, vcurrent.vn); + if (j == 1) + vfirst = vcurrent; + else if (j >= 3) + { + if (maxtriangles <= numtriangles) + { + objtriangle_t *oldtriangles = triangles; + maxtriangles *= 2; + triangles = Mem_Alloc(tempmempool, numtriangles * sizeof(*triangles)); + if (oldtriangles) + { + memcpy(triangles, oldtriangles, numtriangles * sizeof(*triangles)); + Mem_Free(oldtriangles); + } + } + triangles[numtriangles].textureindex = textureindex; + triangles[numtriangles].vertex[0] = vfirst; + triangles[numtriangles].vertex[1] = vprev; + triangles[numtriangles].vertex[2] = vcurrent; + numtriangles++; + } + vprev = vcurrent; + prev = index; + } + } + else if (!strcmp(argv[0], "o") || !strcmp(argv[0], "g")) + ; + else if (!!strcmp(argv[0], "usemtl")) + { + for (i = 0;i < numtextures;i++) + if (!strcmp(texturenames[numtextures], argv[1])) + break; + if (i < numtextures) + texture = textures + i; + else + { + if (maxtextures <= numtextures) + { + texture_t *oldtextures = textures; + maxtextures *= 2; + textures = Mem_Alloc(tempmempool, maxtextures * sizeof(*textures)); + if (oldtextures) + { + memcpy(textures, oldtextures, numtexutres * sizeof(*textures)); + Mem_Free(oldtextures); + } + } + textureindex = numtextures++; + texturenames[textureindex] = Mem_Alloc(tempmempool, strlen(argv[1]) + 1); + memcpy(texturenames[textureindex], argv[1], strlen(argv[1]) + 1); + } + } + text += linelen; + if (*text == '\r') + text++; + if (*text == '\n') + text++; + } + + // now that we have the OBJ data loaded as-is, we can convert it + + // load the textures + loadmodel->num_textures = numtextures; + loadmodel->data_textures = Mem_Alloc(loadmodel->mempool, loadmodel->num_textures * sizeof(texture_t)); + for (i = 0;i < numtextures;i++) + Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + i, texturenames[i], true, true, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | (r_picmipworld.integer ? TEXF_PICMIP : 0) | TEXF_COMPRESS); + + // free the texturenames array since we are now done with it + for (i = 0;i < numtextures;i++) + { + Mem_Free(texturenames[i]); + texturenames[i] = NULL; + } + Mem_Free(texturenames); + texturenames = NULL; + + // generate a rough BSP tree from triangle data, we don't have to be too careful here, it only has to define the basic areas of the map + + // generate surfaces by recursing triangles into BSP tree and ensuring they do not overlap in the lightmap projection axis + + loadmodel->numskins = LittleLong(pinmodel->num_skins); + numxyz = LittleLong(pinmodel->num_xyz); + numst = LittleLong(pinmodel->num_st); + loadmodel->surfmesh.num_triangles = LittleLong(pinmodel->num_tris); + loadmodel->numframes = LittleLong(pinmodel->num_frames); + loadmodel->surfmesh.num_morphframes = loadmodel->numframes; + loadmodel->num_poses = loadmodel->surfmesh.num_morphframes; + skinwidth = LittleLong(pinmodel->skinwidth); + skinheight = LittleLong(pinmodel->skinheight); + iskinwidth = 1.0f / skinwidth; + iskinheight = 1.0f / skinheight; + + loadmodel->num_surfaces = 1; + loadmodel->nummodelsurfaces = loadmodel->num_surfaces; + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->numframes * sizeof(animscene_t) + loadmodel->numframes * sizeof(float[6]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_triangles * sizeof(int[3])); + loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); + loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); + loadmodel->sortedmodelsurfaces[0] = 0; + loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t); + loadmodel->surfmesh.data_morphmd2framesize6f = (float *)data;data += loadmodel->numframes * sizeof(float[6]); + loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); + loadmodel->surfmesh.data_neighbor3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); + + loadmodel->synctype = ST_RAND; + + // load the skins + inskin = (char *)(base + LittleLong(pinmodel->ofs_skins)); + skinfiles = Mod_LoadSkinFiles(); + if (skinfiles) + { + loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; + loadmodel->num_texturesperskin = loadmodel->num_surfaces; + loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t)); + Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures, skinfiles, "default", ""); + Mod_FreeSkinFiles(skinfiles); + } + else if (loadmodel->numskins) + { + // skins found (most likely not a player model) + loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; + 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->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP | TEXF_COMPRESS); + } + else + { + // no skins (most likely a player model) + loadmodel->numskins = 1; + loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; + loadmodel->num_texturesperskin = loadmodel->num_surfaces; + loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t)); + Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures, NULL); + } + + loadmodel->skinscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins); + for (i = 0;i < loadmodel->numskins;i++) + { + loadmodel->skinscenes[i].firstframe = i; + loadmodel->skinscenes[i].framecount = 1; + loadmodel->skinscenes[i].loop = true; + loadmodel->skinscenes[i].framerate = 10; + } + + // load the triangles and stvert data + inst = (unsigned short *)(base + LittleLong(pinmodel->ofs_st)); + intri = (md2triangle_t *)(base + LittleLong(pinmodel->ofs_tris)); + md2verthash = (struct md2verthash_s **)Mem_Alloc(tempmempool, 65536 * sizeof(hash)); + md2verthashdata = (struct md2verthash_s *)Mem_Alloc(tempmempool, loadmodel->surfmesh.num_triangles * 3 * sizeof(*hash)); + // swap the triangle list + loadmodel->surfmesh.num_vertices = 0; + for (i = 0;i < loadmodel->surfmesh.num_triangles;i++) + { + for (j = 0;j < 3;j++) + { + xyz = (unsigned short) LittleShort (intri[i].index_xyz[j]); + st = (unsigned short) LittleShort (intri[i].index_st[j]); + if (xyz >= numxyz) + { + Con_Printf("%s has an invalid xyz index (%i) on triangle %i, resetting to 0\n", loadmodel->name, xyz, i); + xyz = 0; + } + if (st >= numst) + { + Con_Printf("%s has an invalid st index (%i) on triangle %i, resetting to 0\n", loadmodel->name, st, i); + st = 0; + } + hashindex = (xyz * 256 + st) & 65535; + for (hash = md2verthash[hashindex];hash;hash = hash->next) + if (hash->xyz == xyz && hash->st == st) + break; + if (hash == NULL) + { + hash = md2verthashdata + loadmodel->surfmesh.num_vertices++; + hash->xyz = xyz; + hash->st = st; + hash->next = md2verthash[hashindex]; + md2verthash[hashindex] = hash; + } + loadmodel->surfmesh.data_element3i[i*3+j] = (hash - md2verthashdata); + } + } + + vertremap = (int *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(int)); + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * loadmodel->surfmesh.num_morphframes * sizeof(trivertx_t)); + loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[2]); + loadmodel->surfmesh.data_morphmdlvertex = (trivertx_t *)data;data += loadmodel->surfmesh.num_vertices * loadmodel->surfmesh.num_morphframes * sizeof(trivertx_t); + for (i = 0;i < loadmodel->surfmesh.num_vertices;i++) + { + int sts, stt; + hash = md2verthashdata + i; + vertremap[i] = hash->xyz; + sts = LittleShort(inst[hash->st*2+0]); + stt = LittleShort(inst[hash->st*2+1]); + if (sts < 0 || sts >= skinwidth || stt < 0 || stt >= skinheight) + { + Con_Printf("%s has an invalid skin coordinate (%i %i) on vert %i, changing to 0 0\n", loadmodel->name, sts, stt, i); + sts = 0; + stt = 0; + } + loadmodel->surfmesh.data_texcoordtexture2f[i*2+0] = sts * iskinwidth; + loadmodel->surfmesh.data_texcoordtexture2f[i*2+1] = stt * iskinheight; + } + + Mem_Free(md2verthash); + Mem_Free(md2verthashdata); + + // generate ushort elements array if possible + if (loadmodel->surfmesh.num_vertices <= 65536) + loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles); + + // load the frames + datapointer = (base + LittleLong(pinmodel->ofs_frames)); + for (i = 0;i < loadmodel->surfmesh.num_morphframes;i++) + { + int k; + trivertx_t *v; + trivertx_t *out; + pinframe = (md2frame_t *)datapointer; + datapointer += sizeof(md2frame_t); + // store the frame scale/translate into the appropriate array + for (j = 0;j < 3;j++) + { + loadmodel->surfmesh.data_morphmd2framesize6f[i*6+j] = LittleFloat(pinframe->scale[j]); + loadmodel->surfmesh.data_morphmd2framesize6f[i*6+3+j] = LittleFloat(pinframe->translate[j]); + } + // convert the vertices + v = (trivertx_t *)datapointer; + out = loadmodel->surfmesh.data_morphmdlvertex + i * loadmodel->surfmesh.num_vertices; + for (k = 0;k < loadmodel->surfmesh.num_vertices;k++) + out[k] = v[vertremap[k]]; + datapointer += numxyz * sizeof(trivertx_t); + + strlcpy(loadmodel->animscenes[i].name, pinframe->name, sizeof(loadmodel->animscenes[i].name)); + loadmodel->animscenes[i].firstframe = i; + loadmodel->animscenes[i].framecount = 1; + loadmodel->animscenes[i].framerate = 10; + loadmodel->animscenes[i].loop = true; + } + + Mem_Free(vertremap); + + Mod_MakeSortedSurfaces(loadmodel); + Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); + Mod_Alias_CalculateBoundingBox(); + Mod_Alias_MorphMesh_CompileFrames(); + + surface = loadmodel->data_surfaces; + surface->texture = loadmodel->data_textures; + surface->num_firsttriangle = 0; + surface->num_triangles = loadmodel->surfmesh.num_triangles; + surface->num_firstvertex = 0; + surface->num_vertices = loadmodel->surfmesh.num_vertices; + + loadmodel->surfmesh.isanimated = false; + + if (loadmodel->surfmesh.data_element3s) + for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) + loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; +#endif +} + qboolean Mod_CanSeeBox_Trace(int numsamples, float t, dp_model_t *model, vec3_t eye, vec3_t minsX, vec3_t maxsX) { // we already have done PVS culling at this point... diff --git a/model_shared.c b/model_shared.c index 4893aea6..653c715c 100644 --- a/model_shared.c +++ b/model_shared.c @@ -2346,6 +2346,19 @@ void Mod_MakeSortedSurfaces(dp_model_t *mod) static void Mod_BuildVBOs(void) { + if (developer.integer && loadmodel->surfmesh.data_element3s && loadmodel->surfmesh.data_element3i) + { + int i; + for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) + { + if (loadmodel->surfmesh.data_element3s[i] != loadmodel->surfmesh.data_element3i[i]) + { + Con_Printf("Mod_BuildVBOs: element %u is incorrect (%u should be %u)\n", i, loadmodel->surfmesh.data_element3s[i], loadmodel->surfmesh.data_element3i[i]); + loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; + } + } + } + if (!gl_support_arb_vertex_buffer_object) return; @@ -2353,12 +2366,7 @@ static void Mod_BuildVBOs(void) if (loadmodel->surfmesh.num_triangles) { if (loadmodel->surfmesh.data_element3s) - { - int i; - for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) - loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; loadmodel->surfmesh.ebo3s = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, loadmodel->surfmesh.data_element3s, loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3]), loadmodel->name); - } else loadmodel->surfmesh.ebo3i = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles * sizeof(unsigned int[3]), loadmodel->name); } -- 2.39.2