📄 coremodel.cpp
字号:
// CoreModel.cpp: implementation of the CoreModel class.
//
//////////////////////////////////////////////////////////////////////
#include "CoreModel.h"
#include "tga.h"
//----------------------------------------------------------------------------//
// Read a int from file stream (to avoid Little/Big endian issue)
//----------------------------------------------------------------------------//
int readInt( std::ifstream *file )
{
int x = 0;
for ( int i = 0; i < 32; i+=8 )
{
char c;
file->read ( &c, 1 );
x += c << i;
}
return x;
}
//----------------------------------------------------------------------------//
// Constructors //
//----------------------------------------------------------------------------//
CoreModel::CoreModel()
{
m_calCoreModel = new CalCoreModel("monkey");
m_animationCount = 0;
m_meshCount = 0;
m_renderScale = 1.0f;
}
//----------------------------------------------------------------------------//
// Destructor //
//----------------------------------------------------------------------------//
CoreModel::~CoreModel()
{
delete m_calCoreModel;
}
//----------------------------------------------------------------------------//
// Set a path to override any config file path //
//----------------------------------------------------------------------------//
void CoreModel::setPath( const std::string& strPath )
{
m_path = strPath;
}
//----------------------------------------------------------------------------//
// Get the render scale of the model //
//----------------------------------------------------------------------------//
float CoreModel::getRenderScale()
{
return m_renderScale;
}
//----------------------------------------------------------------------------//
// Load and create a texture from a given file //
//----------------------------------------------------------------------------//
GLuint CoreModel::loadTexture(const std::string& strFilename)
{
GLuint pId=0;
if(stricmp(strrchr(strFilename.c_str(),'.'),".raw")==0)
{
// open the texture file
std::ifstream file;
file.open(strFilename.c_str(), std::ios::in | std::ios::binary);
if(!file)
{
std::cerr << "Texture file '" << strFilename << "' not found." << std::endl;
return 0;
}
// load the dimension of the texture
int width = readInt(&file);
int height = readInt(&file);
int depth = readInt(&file);
// allocate a temporary buffer to load the texture to
unsigned char *pBuffer;
pBuffer = new unsigned char[width * height * depth];
if(pBuffer == 0)
{
std::cerr << "Memory allocation for texture '" << strFilename << "' failed." << std::endl;
return 0;
}
// load the texture
file.read((char *)pBuffer, width * height * depth);
// explicitely close the file
file.close();
// generate texture
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &pId);
glBindTexture(GL_TEXTURE_2D, pId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, (depth == 3) ? GL_RGB : GL_RGBA, width, height, 0, (depth == 3) ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, &pBuffer[0]);
// free the allocated memory
delete [] pBuffer;
}
else if (stricmp(strrchr(strFilename.c_str(),'.'),".tga")==0)
{
CTga *Tga;
Tga = new CTga();
//Note: This will always make a 32-bit texture
if(Tga->ReadFile(strFilename.c_str())==0)
{
Tga->Release();
return false;
}
//Bind texture
int width = Tga->GetSizeX();
int height = Tga->GetSizeY();
int depth = Tga->Bpp() / 8;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &pId);
glBindTexture(GL_TEXTURE_2D, pId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, ((depth == 3) ? GL_RGB : GL_RGBA), width, height, 0, ((depth == 3) ? GL_RGB : GL_RGBA) , GL_UNSIGNED_BYTE, (char*)Tga->GetPointer() );
Tga->Release();
}
return pId;
}
//----------------------------------------------------------------------------//
// Initialize the model //
//----------------------------------------------------------------------------//
bool CoreModel::onInit(const std::string& strFilename)
{
// open the model configuration file
std::ifstream file;
file.open(strFilename.c_str(), std::ios::in | std::ios::binary);
if(!file)
{
std::cerr << "Failed to open model configuration file '" << strFilename << "'." << std::endl;
return false;
}
// initialize the data path
std::string strPath = m_path;
// initialize the animation count
int animationCount;
animationCount = 0;
// parse all lines from the model configuration file
int line;
for(line = 1; ; line++)
{
// read the next model configuration line
std::string strBuffer;
std::getline(file, strBuffer);
// stop if we reached the end of file
if(file.eof()) break;
// check if an error happend while reading from the file
if(!file)
{
std::cerr << "Error while reading from the model configuration file '" << strFilename << "'." << std::endl;
return false;
}
// find the first non-whitespace character
std::string::size_type pos;
pos = strBuffer.find_first_not_of(" \t");
// check for empty lines
if((pos == std::string::npos) || (strBuffer[pos] == '\n') || (strBuffer[pos] == '\r') || (strBuffer[pos] == 0)) continue;
// check for comment lines
if(strBuffer[pos] == '#') continue;
// get the key
std::string strKey;
strKey = strBuffer.substr(pos, strBuffer.find_first_of(" =\t\n\r", pos) - pos);
pos += strKey.size();
// get the '=' character
pos = strBuffer.find_first_not_of(" \t", pos);
if((pos == std::string::npos) || (strBuffer[pos] != '='))
{
std::cerr << strFilename << "(" << line << "): Invalid syntax." << std::endl;
return false;
}
// find the first non-whitespace character after the '=' character
pos = strBuffer.find_first_not_of(" \t", pos + 1);
// get the data
std::string strData;
strData = strBuffer.substr(pos, strBuffer.find_first_of("\n\r", pos) - pos);
// handle the model creation
if(strKey == "scale")
{
// set rendering scale factor
m_renderScale = atof(strData.c_str());
}
else if(strKey == "path")
{
// set the new path for the data files if one hasn't been set already
if (m_path == "") strPath = strData;
}
else if(strKey == "skeleton")
{
// load core skeleton
std::cout << "Loading skeleton '" << strData << "'..." << std::endl;
if(!m_calCoreModel->loadCoreSkeleton(strPath + strData))
{
CalError::printLastError();
return false;
}
}
else if(strKey == "animation")
{
// load core animation
std::cout << "Loading animation '" << strData << "'..." << std::endl;
m_animationId[animationCount] = m_calCoreModel->loadCoreAnimation(strPath + strData);
if(m_animationId[animationCount] == -1)
{
CalError::printLastError();
return false;
}
animationCount++;
}
else if(strKey == "mesh")
{
// load core mesh
std::cout << "Loading mesh '" << strData << "'..." << std::endl;
if(m_calCoreModel->loadCoreMesh(strPath + strData) == -1)
{
CalError::printLastError();
return false;
}
}
else if(strKey == "material")
{
// load core material
std::cout << "Loading material '" << strData << "'..." << std::endl;
if(m_calCoreModel->loadCoreMaterial(strPath + strData) == -1)
{
CalError::printLastError();
return false;
}
}
else
{
std::cerr << strFilename << "(" << line << "): Invalid syntax." << std::endl;
return false;
}
}
// explicitely close the file
file.close();
// load all textures and store the opengl texture id in the corresponding map in the material
int materialId;
for(materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
{
// get the core material
CalCoreMaterial *pCoreMaterial;
pCoreMaterial = m_calCoreModel->getCoreMaterial(materialId);
// loop through all maps of the core material
int mapId;
for(mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++)
{
// get the filename of the texture
std::string strFilename;
strFilename = pCoreMaterial->getMapFilename(mapId);
// load the texture from the file
GLuint textureId;
textureId = loadTexture(strPath + strFilename);
// store the opengl texture id in the user data of the map
pCoreMaterial->setMapUserData(mapId, (Cal::UserData)textureId);
}
}
// make one material thread for each material
// NOTE: this is not the right way to do it, but this viewer can't do the right
// mapping without further information on the model etc.
for(materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
{
// create the a material thread
m_calCoreModel->createCoreMaterialThread(materialId);
// initialize the material thread
m_calCoreModel->setCoreMaterialId(materialId, 0, materialId);
}
// Calculate Bounding Boxes
m_calCoreModel->getCoreSkeleton()->calculateBoundingBoxes(m_calCoreModel);
//创建虚拟人实体
/*
for(int jj=0;jj<5;jj++)
{
for(int ii=-10;ii<10;ii++)
{
//虚拟人1
Model *pModel=new Model(m_calCoreModel);
pModel->setState(1,0.1);
pModel->x=-30*ii;
pModel->z=-30*jj;
m_ModelVector.push_back(pModel);
}
}
*/
//虚拟人1
Model *pModel=new Model(m_calCoreModel);
pModel->m_bSkeleton=0;
pModel->setState(0,0.5);
pModel->x=0;
m_ModelVector.push_back(pModel);
//虚拟人2
pModel=new Model(m_calCoreModel);
pModel->m_bSkeleton=1;
pModel->setState(1,0.5);
pModel->x=-100;
m_ModelVector.push_back(pModel);
//虚拟人3
pModel=new Model(m_calCoreModel);
pModel->m_bSkeleton=2;
pModel->x=100;
pModel->setState(2,0.5);
m_ModelVector.push_back(pModel);
return true;
}
//----------------------------------------------------------------------------//
// Shut the model down //
//----------------------------------------------------------------------------//
void CoreModel::onShutdown()
{
for(int ii=0;ii<m_ModelVector.size();ii++)
delete m_ModelVector[ii];
}
//----------------------------------------------------------------------------//
// Render the model //
//----------------------------------------------------------------------------//
void CoreModel::onRender()
{
for(int ii=0;ii<m_ModelVector.size();ii++)
m_ModelVector[ii]->onRender();
}
//----------------------------------------------------------------------------//
// Update the model //
//----------------------------------------------------------------------------//
void CoreModel::onUpdate(float elapsedSeconds)
{
for(int ii=0;ii<m_ModelVector.size();ii++)
m_ModelVector[ii]->onUpdate(elapsedSeconds);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -