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
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;
|
|
}
|