⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdx.cpp

📁 mpq文件查看器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************
    Warcraft 3 Viewer - Utility to view models and textures from Warcraft 3
    Copyright (C) 2002  David GRIMBICHLER (theprophet@wanadoo.Fr)
	http://www.xeberon.net

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
********************************************************************************/

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include <io.h>

#include <gl/gl.h>
#include <gl/glu.h>

#include <d3dx9.h>

#include "math.h"

#include "mdx.h"

#include "blp.h"


#ifndef PI
 #define PI 3.1415926535897932385f
#endif



extern DWORD FromMPQ(char*filename, char*& buffer);
extern BOOL g_showmeshes[MAX_CHUNKS];
extern MaChaine gLoadedTextures[128];
extern Vec3 MColor;
extern long bCam;
extern BOOL bShowCameras;
extern WarCraft_BLP gTex;


WarCraft_ModelX* singleton = NULL;

extern void *malloc_func(const size_t size);
extern void free_func(void* ptr);


WarCraft_ModelX::WarCraft_ModelX(void) :
	mpData(NULL),
	mSize(0),
	mLoaded(false)
{
	singleton = this;
}

void WarCraft_ModelX::Free(void)
{
	if(mTextures.mNumTextures)
		glDeleteTextures(mTextures.mNumTextures,(GLuint*)mTextures.mGLBind);

	if(mpData.c!=NULL)
		free_func(mpData.c);

	ZeroMemory(this,sizeof(WarCraft_ModelX));
}

WarCraft_ModelX::~WarCraft_ModelX(void)
{
	Free();
	singleton = NULL;
}

void WarCraft_ModelX::Render(void)
{	
	if(false == mLoaded)
		return;

	mGeometry.Render();
	if((bCam < 0)&&(bShowCameras == TRUE)) mCameras.Render();	
}

void WarCraft_ModelX::Load(char* inName)
{
	if(gTex.glbind)
		glDeleteTextures(1,&gTex.glbind);
	gTex.glbind = 0;

	ZeroMemory(&gLoadedTextures, sizeof(gLoadedTextures));
	toregistre("Attempting to read file %s...",inName);
	
	mSize = FromMPQ(inName,mpData.c);
	
	if(!mSize)
		return;

	//////////////////////////////////////////////////////////
	// File processing part

	TypePointer1 p(mpData.p);

	//
	// First check the tag
	//
	if('MDLX' != TAG(*p.dw))
	{
		toregistre("Missing model tag : '%c%c%c%c' instead of 'MDLX'",p.c[0],p.c[1],p.c[2],p.c[3]);
		return;
	}
	p.dw++;

	//
	// Main processing loop
	// parse all sections
	//
	while(p.c < mpData.c+mSize)
	{
		switch(TAG(*p.dw))
		{
		case 'BONE':
			{
				p.dw++;
				int size = *p.dw++;


				p.c += size;
			}
			break;

		case 'VERS': // VERSion
			{
				p.dw++;
				int size = *p.dw++;

				mVersion.Read(p,size);

				if( !mVersion.IsValid() )
					return;

	//			mVersion.Print();

				p.c += size;
			}
			break;

		case 'MODL': // MODeL
			{
				p.dw++;
				int size = *p.dw++;

				mModel.Read(p,size);
		
//				mModel.Print();

				p.c += size;
			}
			break;

		case 'GEOS': // GEOmetry Section or whatever....
			{
				p.dw++;
				int size = *p.dw++;

				mGeometry.Read(p,size);

	//			mGeometry.Print();
					
				p.c += size;
			}
			break;

		case 'SEQS': // SEQuences
			{
				p.dw++;
				int size = *p.dw++;

				mSequences.Read(p,size);

//				mSequences.Print();
				
				p.c += size; 
			}
			break;

		case 'TEXS': // TEXtureS
			{
				p.dw++;
				int size = *p.dw++;

				mTextures.Read(p,size);

				mTextures.Print();
				
				p.c += size; 				
			}
			break;

		case 'MTLS': // MaTeriaLS
			{
				p.dw++;
				int size = *p.dw++;

				mMaterials.Read(p,size);

				mMaterials.Print();
				
				p.c += size; 				
			}
			break;

		case 'CAMS': // Cameras
			{
				p.dw++;
				int size = *p.dw++;
				mCameras.Read(p, size);
				p.c += size;
			}
			break;

		default:
			{
				toregistre("Unknown tag found : '%c%c%c%c'",p.c[0],p.c[1],p.c[2],p.c[3]);
				p.dw++;
				int size = *p.dw++;
				p.c += size; 
			}
			break;
		}
	}

	//////////////////////////////////////////////////////////
	mLoaded = true;
}


void mdxGeoChunk::Read(TypePointer1 inP,int inSize)
{
	TypePointer1 p(inP);

	int n = 0;

	while((p.c < inP.c+inSize) && (n<8))
	{
		switch(TAG(*p.dw))
		{
		case 'VRTX': // vertex
			{
				p.dw++;
				mNumVertices = *p.dw++;

				mVertices = p.v3;

				p.c += mNumVertices*12; 
				++n;
			}
			break;

		case 'NRMS': // normal
			{
				p.dw++;
				int NumNormals = *p.dw++;

				if(mNumVertices != NumNormals)
				{
					toregistre("NumVertices and NumNormals does not match !!!!!!!!!");
				}

				mNormals = p.v3;

				p.c += NumNormals*12; 
				++n;
			}
			break;

		case 'PTYP': // primitives type
			{
				p.dw++;
				int size = *p.dw++;
			
				if(*p.dw != 4) // == Triangles
				{
					toregistre("Unknown polytype !!!!!!!!!!!");
					return;
				}

				p.c += size*4; 
				++n;
			}
			break;

		case 'PCNT': // primitives count
			{
				p.dw++;
				int size = *p.dw++;
				mPolyCount = (*p.dw)/3;
			
				p.c += size*4; 
				++n;
			}
			break;

		case 'PVTX': // primitives vertices
			{
				p.dw++;
				int size = *p.dw++;
				mTriangles = p.tri;

				if(size/3 != mPolyCount)
				{
					toregistre("Polycount and size of triangle block do not match!!!!!!!!!!!");
					return;
				}
			
				p.c += size*2;
				++n;
			}
			break;

		case 'GNDX': // vertex group indices
						// links every vertex to a matrix
			{
				p.dw++;
				int size = *p.dw++;

				if(mNumVertices != size)
				{
					toregistre("NumVertices and vertex group index count do not match !!!!!!!!!");
				}

				mVertexGroupIndices = p.c;

				p.c += size; 
				++n;
			}
			break;
			
		case 'MTGC': // group matrix counts
						// this is the number of vertices defined by GNDX for each matrix
			{
				p.dw++;
				int size = *p.dw++;
			
				p.c += size*4; 
				++n;
			}
			break;

		case 'MATS': // matrices
			{
				p.dw++;
				int size = *p.dw++;
			
				p.c += size*4;  
				++n;
			}
			break;

		default:
			{
				//__asm int 3;
				toregistre("Unknown geotag found : '%c%c%c%c'",p.c[0],p.c[1],p.c[2],p.c[3]);
				p.dw++;
				int size = *p.dw++;
				p.c += size; 
			}
			break;
		}
	}

	//
	// Now process the remaining data :
	//
	if(p.c < inP.c+inSize)
	{
		mMaterial = *p.dw++;
		mUnk2 = *p.dw++;
		mUnk3 = *p.dw++;

		mUnk4 = *p.f++;
		mMins = p.v3++;
		mMaxs = p.v3++;

		mSomeCount = *p.dw++;

		for(int i=0;i<mSomeCount;++i)
		{
			p.f++; // some float 
			p.v3++; // vec3
			p.v3++; // vec3 
			// combinations....
		}

		if(TAG(*p.dw) == 'UVAS' )
		{
			p.dw++;

			int size = *p.dw++; // no skip

			if(TAG(*p.dw) == 'UVBS' )
			{
				p.dw++;
				int size = *p.dw++;

				mUVs = p.v2;
				
				p.c += size*8;
			}
			else
				toregistre("UVBS geotag missing, instead: '%c%c%c%c'",p.c[0],p.c[1],p.c[2],p.c[3]);
		}
		else
			toregistre("Unknown geotag found : '%c%c%c%c'",p.c[0],p.c[1],p.c[2],p.c[3]);
	}
	else
		toregistre("No data remainder in geoset...");
}


void mdxModel::RenderBBox(void)
{
	if(!mMins || !mMaxs)
		return;

	glDisable(GL_LIGHTING);

	Vec3 mins = *mMins;
	Vec3 maxs = *mMaxs;

	glColor3f(0.3f,0.9f,0.3f);
	glBegin(GL_LINE_LOOP);
	glVertex3fv(mins);
	glVertex3f(mins[0],maxs[1],mins[2]);
	glVertex3f(maxs[0],maxs[1],mins[2]);
	glVertex3f(maxs[0],mins[1],mins[2]);

	glVertex3f(maxs[0],mins[1],maxs[2]);
	glVertex3fv(maxs);
	glVertex3f(mins[0],maxs[1],maxs[2]);
	glVertex3f(mins[0],mins[1],maxs[2]);

	glVertex3fv(mins);
	glEnd();

	glBegin(GL_LINES);
	glVertex3fv(mins);
	glVertex3f(maxs[0],mins[1],mins[2]);

	glVertex3f(mins[0],mins[1],maxs[2]);
	glVertex3f(maxs[0],mins[1],maxs[2]);

	glVertex3fv(maxs);
	glVertex3f(maxs[0],maxs[1],mins[2]);

	glVertex3f(mins[0],maxs[1],maxs[2]);
	glVertex3f(mins[0],maxs[1],mins[2]);
	glEnd();


	glEnable(GL_LIGHTING);
}



void mdxGeometry::Read(TypePointer1 inP,int inSize)
{
	if(mLoaded)
	{
		toregistre("Duplicate GEOS tag... ignoring");
		return;
	}
	mLoaded = true;

	TypePointer1 p(inP);

	//
	// read the chunks
	//
	
	while(p.c<inP.c+inSize)
	{
		int size = (*p.dw++)-4;

		mChunks[mNumChunks].Read(p,size);

		p.c += size;

		++mNumChunks;
	}
}

void mdxGeometry::Render(void)
{
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);	
	glDepthFunc(GL_LEQUAL);
	glColor3f(1,1,1);
	
	for(int i=0;i<mNumChunks;++i)
	{
		if(g_showmeshes[i] == TRUE)	mChunks[i].Render();
	}
}

void mdxGeometry::Print(void)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -