#include "stdafx.h" #include "cModel.h" #include "BSPTypes.h" cModel::cModel() { m_pTranslation = cPoint3D(0,0,0); for (int i=0;i<4;i++) m_fRotation[i] = 0; } cModel::~cModel() { for (std::vector::iterator i = m_vTriSets.begin(); i != m_vTriSets.end(); i++) { glDeleteTextures(1, (GLuint *) &((*i)->dwGLTex)); delete *i; } } int cModel::Draw() { int tricount = 0; glPushMatrix(); glTranslatef(m_pTranslation.x, m_pTranslation.y, m_pTranslation.z); float s = m_fRotation[1]*m_fRotation[1] + m_fRotation[2]*m_fRotation[2] + m_fRotation[3]*m_fRotation[3]; if (s > 0) glRotatef(2*acos(m_fRotation[0])*180.0f/(float)M_PI, m_fRotation[1]/s, m_fRotation[2]/s, m_fRotation[3]/s); glPushName(m_dwID); int i = 0; for (std::vector::iterator rgi = m_vTriSets.begin(); rgi != m_vTriSets.end(); rgi++) { tricount += (*rgi)->iTriCount; glBindTexture(GL_TEXTURE_2D, (*rgi)->dwGLTex); glColor4f(0,0,0,0.5f); glVertexPointer(3, GL_FLOAT, 0, (*rgi)->pVertarray); glColorPointer(4, GL_UNSIGNED_BYTE, 0, (*rgi)->pColorarray); glTexCoordPointer(2, GL_FLOAT, 0, (*rgi)->pTexarray); glDrawElements(GL_TRIANGLES, (*rgi)->iTriCount*3, GL_UNSIGNED_INT, (*rgi)->pTriarray); } glPopName(); glPopMatrix(); return tricount; } bool cModel::ReadDungeonPart(DWORD dwDungeon, WORD wDungeonPart, std::vector * v_Textures) { cPortalFile *pf = m_Portal->OpenEntry(dwDungeon); if (!pf) { return false; } // char lele[500]; // sprintf(lele, "c:\\portalfiles\\%08X.pf", dwDungeon); // pf->Dump(lele); cByteStream pBS(pf->data, pf->length); pBS.ReadBegin(); m_dwID = pBS.ReadDWORD(); DWORD dwNumParts = pBS.ReadDWORD(); for (int i=0; i<(int) dwNumParts; i++) { //Read Part Header DWORD dwPartID = pBS.ReadDWORD(); cACPreModel NewModel; NewModel.iNumTriFans = (int) pBS.ReadDWORD(); DWORD dwNumClipping = pBS.ReadDWORD(); DWORD dwNumConnectable = pBS.ReadDWORD(); pBS.ReadDWORD(); //unk2 NewModel.iNumVerts = (int) pBS.ReadDWORD(); for (std::vector::iterator i = v_Textures->begin(); i != v_Textures->end(); i++) NewModel.m_Textures.push_back(0x08000000 | *i); NewModel.m_Vertices = new cACVertex[NewModel.iNumVerts]; for (int h=0; h *vPaletteSwaps, std::vector *vTextureSwaps) { // return true; //out with the old for (std::vector::iterator i = m_vTriSets.begin(); i != m_vTriSets.end(); i++) delete *i; m_vTriSets.clear(); //in with the new cPortalFile *pf = m_Portal->OpenEntry(dwModel); if (!pf) { return false; } //stage one - loading from turbine's ass format //note: need to clean this out a bit at some point... //switch this to auto_ptr cByteStream pBS(pf->data, pf->length); pBS.ReadBegin(); //data m_dwID = pBS.ReadDWORD(); DWORD dwType = pBS.ReadDWORD(); cACPreModel NewModel; NewModel.vTextureSwaps = vTextureSwaps; NewModel.vPaletteSwaps = vPaletteSwaps; NewModel.iSwapModelNum = iModelNum; NewModel.m_bSwaps = (vTextureSwaps) || (vPaletteSwaps); BYTE bTextureCount = pBS.ReadByte(); for (int i=0; i mTex; std::vector vTex; for (int i=0; iiNumTriFans; i++) { if (pModel->m_TriFans[i].wTexNum >= pModel->m_Textures.size()) { return false; } DWORD dwTexture = pModel->m_Textures[pModel->m_TriFans[i].wTexNum]; cPortalFile *pfTexInfo = m_Portal->OpenEntry(dwTexture); if (!pfTexInfo) { return false; } cByteStream pBSTex(pfTexInfo->data, pfTexInfo->length); pBSTex.ReadBegin(); stTexInfo tiTex; DWORD flags = pBSTex.ReadDWORD(); if (flags & 1) { //rgb tiTex.dwColor = pBSTex.ReadDWORD(); tiTex.dwTexID = 0; //Enable transparency... this seems wrong somehow... float fTransTex = pBSTex.ReadFloat(); float fTransUnknown = pBSTex.ReadFloat(); float fTransPix = pBSTex.ReadFloat(); //1-Transtex doesn't seem to work, 1-transpix seems to work DWORD tpf = ((DWORD) (0xFF * (1.0f-fTransPix))) << 24; tiTex.dwColor &= 0x00FFFFFF; tiTex.dwColor |= tpf; } if ((flags & 2) || (flags & 4)) { DWORD dwTexture = pBSTex.ReadDWORD(); //This used to be palette, but no longer makes any sense since palettes are embedded in the file... DWORD dwPalette = pBSTex.ReadDWORD(); if (dwPalette > 0) int a = 4; float fTransTex = pBSTex.ReadFloat(); float fTransUnknown = pBSTex.ReadFloat(); float fTransPix = pBSTex.ReadFloat(); tiTex.dwColor = 0x7F7F7F7F; //textureswap if (pModel->m_bSwaps) { for (std::vector::iterator i = pModel->vTextureSwaps->begin(); i != pModel->vTextureSwaps->end(); i++) { if (i->modelIndex == pModel->iSwapModelNum) { if (i->oldTexture == (dwTexture & 0xFFFF)) { dwTexture = (*i).newTexture | 0x05000000; break; } } } } //retrieve texture/palette combo from portal tiTex.dwTexID = m_Portal->FindTexturePalette(dwTexture, pModel->vPaletteSwaps, fTransTex, fTransPix); } vTex.push_back(tiTex); mTex.insert(tiTex.dwTexID); } //Now, loop through each unique texture index and figure out which triangles use this texture int icnt = 0; for (std::unordered_set::iterator texid = mTex.begin(); texid != mTex.end(); texid++, icnt++) { stTriSet *rgT = new stTriSet(); rgT->dwGLTex = *texid; //Should probably turn these into pointers - vectors suck at making new large structs std::vector vTris; std::vector vVerts; std::vector vTexels; std::vector vColors; //Loop through the trifans and see if any of them use this texture int vertcount = 0; for (int i=0; iiNumTriFans; i++) { if (vTex[i].dwTexID == rgT->dwGLTex) { for (int j=0; jm_TriFans[i].bNumVerts;j++) { int iVertNum = pModel->m_TriFans[i].wVerts[j]; vVerts.push_back(pModel->m_Vertices[iVertNum].GetP3D()); if (pModel->m_TriFans[i].bUVs) vTexels.push_back(pModel->m_Vertices[iVertNum].UVs[pModel->m_TriFans[i].bUVs[j]]); else vTexels.push_back(stACUV(0,0)); vColors.push_back(vTex[i].dwColor); } for (int j=0;jm_TriFans[i].bNumVerts-2;j++) { renderTriangle rtTemp; rtTemp.pt[0] = vertcount; rtTemp.pt[1] = vertcount+j+1; rtTemp.pt[2] = vertcount+j+2; vTris.push_back(rtTemp); } vertcount = (int) vVerts.size(); } } rgT->iTriCount = (int) vTris.size(); rgT->pColorarray = new GLuint[vertcount]; rgT->pTriarray = new GLuint[3*rgT->iTriCount]; rgT->pTexarray = new GLfloat[2*vertcount]; rgT->pVertarray = new GLfloat[3*vertcount]; int jcnt = 0; for (std::vector::iterator j = vTris.begin(); j != vTris.end(); j++, jcnt++) { rgT->pTriarray[3*jcnt] = (*j).pt[0]; rgT->pTriarray[3*jcnt+1] = (*j).pt[1]; rgT->pTriarray[3*jcnt+2] = (*j).pt[2]; } for (int j=0;jpColorarray[j] = vColors[j]; rgT->pTexarray[2*j] = vTexels[j].u; rgT->pTexarray[2*j+1] = vTexels[j].v; rgT->pVertarray[3*j] = vVerts[j].x; rgT->pVertarray[3*j+1] = vVerts[j].y; rgT->pVertarray[3*j+2] = vVerts[j].z; } m_vTriSets.push_back(rgT); } return true; } void cModel::SetTranslation(cPoint3D Translation) { m_pTranslation = Translation; } void cModel::SetRotation(float Rot1, float Rot2, float Rot3, float Rot4) { m_fRotation[0] = Rot1; m_fRotation[1] = Rot2; m_fRotation[2] = Rot3; m_fRotation[3] = Rot4; }