You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

193 lines
5.1 KiB

#include "model.h"
#include "utils.h"
Model::Model()
{
//初始化材质
memset(mAmbientMaterial, 0, sizeof(mAmbientMaterial));
memset(mDiffuseMaterial, 0, sizeof(mDiffuseMaterial));
memset(mSpecularMaterial, 0, sizeof(mSpecularMaterial));
}
void Model::Init(const char * modelPath)
{
struct FloatData {
float v[3];
};
struct VertexDefine {
int posIndex;
int texcoordIndex;
int normalIndex;
};
int nFileSize = 0;
unsigned char* fileContent = LoadFileContent(modelPath, nFileSize);
if (fileContent == nullptr) {
return;
}
std::vector<FloatData> positions, texcoords, normals;
std::vector<VertexDefine> vertexes;
std::vector<int> indexes;
std::string temp;
//存储文件内容,内存块
std::stringstream ssFileContent((char*)fileContent);
//存储行数据
char szOneLine[256];
//使用流来读取文件
while (!ssFileContent.eof()) {
//读取一行
memset(szOneLine, 0, 256);
ssFileContent.getline(szOneLine, 256);
//空行不处理
if (strlen(szOneLine) > 0) {
if (szOneLine[0] == 'v') {
std::stringstream ssOneLine(szOneLine);
if (szOneLine[1] == 't') {
ssOneLine >> temp;//通过流输出vt到 temp
FloatData floatData;
ssOneLine >> floatData.v[0];
ssOneLine >> floatData.v[1];
texcoords.push_back(floatData);
printf("texcoord : %f,%f\n", floatData.v[0], floatData.v[1]);
}
else if (szOneLine[1] == 'n') {
ssOneLine >> temp;
FloatData floatData;
ssOneLine >> floatData.v[0];
ssOneLine >> floatData.v[1];
ssOneLine >> floatData.v[2];
normals.push_back(floatData);
printf("normal : %f,%f,%f\n", floatData.v[0], floatData.v[1], floatData.v[2]);
}
else {
ssOneLine >> temp;
FloatData floatData;
ssOneLine >> floatData.v[0];
ssOneLine >> floatData.v[1];
ssOneLine >> floatData.v[2];
positions.push_back(floatData);
printf("position : %f,%f,%f\n", floatData.v[0], floatData.v[1], floatData.v[2]);
}
}
else if (szOneLine[0] == 'f') {
std::stringstream ssOneLine(szOneLine);
ssOneLine >> temp;
std::string vertexStr;
for (int i = 0; i < 3; i++) {
ssOneLine >> vertexStr;
//获取position索引
size_t pos = vertexStr.find_first_of('/');
std::string posIndexStr = vertexStr.substr(0, pos);
//获取texcoord索引
size_t pos2 = vertexStr.find_first_of('/', pos + 1);
std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - 1 - pos);
//获取normal索引
std::string normalIndexStr = vertexStr.substr(pos2 + 1, vertexStr.length() - 1 - pos2);
VertexDefine vd;
vd.posIndex = atoi(posIndexStr.c_str());
vd.texcoordIndex = atoi(texcoordIndexStr.c_str());
vd.normalIndex = atoi(normalIndexStr.c_str());
//去除重复
int nCurrentVertexIndex = -1;
int nCurrentVertexCount = (int)vertexes.size();
for (int j = 0; j < nCurrentVertexCount; j++) {
if (vertexes[j].posIndex == vd.posIndex && vertexes[j].texcoordIndex == vd.texcoordIndex && vertexes[j].normalIndex == vd.normalIndex) {
nCurrentVertexIndex = j;
break;
}
}
if (nCurrentVertexIndex == -1) {
nCurrentVertexIndex = (int)vertexes.size();
vertexes.push_back(vd);
}
indexes.push_back(nCurrentVertexIndex);
}
printf("draw command : %s\n", szOneLine);
}
}
}
//TODO为啥要复制???
mIndexCount = (int)indexes.size();
mIndexes = new unsigned short[mIndexCount];
for (int i = 0; i < mIndexCount; ++i) {
mIndexes[i] = indexes[i];
}
int vertexCount = (int)vertexes.size();
mVertexes = new VertexData[vertexCount];
for (int i = 0; i < vertexCount; i++) {
memcpy(mVertexes[i].position, positions[vertexes[i].posIndex - 1].v, sizeof(float) * 3);
memcpy(mVertexes[i].texcoord, texcoords[vertexes[i].texcoordIndex - 1].v, sizeof(float) * 2);
memcpy(mVertexes[i].normal, normals[vertexes[i].normalIndex - 1].v, sizeof(float) * 3);
}
delete fileContent;
}
void Model::Draw()
{
//开启光照
glEnable(GL_LIGHTING);
glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbientMaterial);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseMaterial);
glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecularMaterial);
//开启纹理
glEnable(GL_TEXTURE_2D);
//glMaterialf(GL_FRONT, GL_SHININESS, 64.0f);
//glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mTexture);
glEnable(GL_DEPTH_TEST);
glPushMatrix();
glTranslatef(0.0f, 0.0f, -5.0f);
static float t = 0.0;
glRotated(t, 1.0f, 1.0f, 1.0f);
t += 0.05;
glBegin(GL_TRIANGLES);
for (int i = 0; i < mIndexCount; i++) {
glTexCoord2fv(mVertexes[mIndexes[i]].texcoord);
glNormal3fv(mVertexes[mIndexes[i]].normal);
glVertex3fv(mVertexes[mIndexes[i]].position);
}
glEnd();
glPopMatrix();
}
void Model::SetAmbientMaterial(float r, float g, float b, float a) {
mAmbientMaterial[0] = r;
mAmbientMaterial[1] = g;
mAmbientMaterial[2] = b;
mAmbientMaterial[3] = a;
}
void Model::SetDiffuseMaterial(float r, float g, float b, float a) {
mDiffuseMaterial[0] = r;
mDiffuseMaterial[1] = g;
mDiffuseMaterial[2] = b;
mDiffuseMaterial[3] = a;
}
void Model::SetSpecularMaterial(float r, float g, float b, float a) {
mSpecularMaterial[0] = r;
mSpecularMaterial[1] = g;
mSpecularMaterial[2] = b;
mSpecularMaterial[3] = a;
}