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.
123 lines
3.6 KiB
123 lines
3.6 KiB
#include "model.h"
|
|
#include "utils.h"
|
|
|
|
Model::Model() {
|
|
}
|
|
|
|
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::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;
|
|
FloatData floatData;
|
|
ssOneLine >> floatData.v[0];
|
|
ssOneLine >> floatData.v[1];
|
|
texcoords.push_back(floatData);
|
|
}
|
|
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);
|
|
}
|
|
else {
|
|
ssOneLine >> temp;
|
|
FloatData floatData;
|
|
ssOneLine >> floatData.v[0];
|
|
ssOneLine >> floatData.v[1];
|
|
ssOneLine >> floatData.v[2];
|
|
positions.push_back(floatData);
|
|
}
|
|
}
|
|
else if (szOneLine[0] == 'f') {
|
|
std::stringstream ssOneLine(szOneLine);
|
|
ssOneLine >> temp;
|
|
std::string vertexStr;
|
|
for (int i = 0; i < 3; i++) {
|
|
ssOneLine >> vertexStr;
|
|
|
|
size_t pos = vertexStr.find_first_of('/');
|
|
std::string posIndexStr = vertexStr.substr(0, pos);
|
|
|
|
size_t pos2 = vertexStr.find_first_of('/', pos + 1);
|
|
std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - 1 - pos);
|
|
|
|
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());
|
|
vertexes.push_back(vd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
delete fileContent;
|
|
|
|
int vertexCount = (int)vertexes.size();
|
|
mVertexBuffer = new VertexBuffer;
|
|
mVertexBuffer->SetSize(vertexCount);
|
|
for (int i = 0; i < vertexCount; ++i) {
|
|
float *temp = positions[vertexes[i].posIndex - 1].v;
|
|
mVertexBuffer->SetPosition(i, temp[0], temp[1], temp[2]);
|
|
|
|
temp = texcoords[vertexes[i].texcoordIndex - 1].v;
|
|
mVertexBuffer->SetTexcoord(i, temp[0], temp[1]);
|
|
|
|
|
|
temp = normals[vertexes[i].normalIndex - 1].v;
|
|
mVertexBuffer->SetNormal(i, temp[0], temp[1], temp[2]);
|
|
}
|
|
|
|
mShader = new Shader;
|
|
mShader->Init("Res/model.vs", "Res/model.fs");
|
|
mShader->SetVec4("U_LightPos", 0.0f, 1.0f, 1.0f, 0.0f);//设置光源位置
|
|
mShader->SetVec4("U_LightAmbient", 1.0f, 1.0f, 1.0f, 1.0f);//设置环境光分量
|
|
mShader->SetVec4("U_LightDiffuse", 1.0f, 1.0f, 1.0f, 1.0f);//设置慢反射光分量
|
|
mShader->SetVec4("U_AmbientMaterial", 0.1f, 0.1f, 0.1f, 1.0f);//设置环境光材质分量
|
|
mShader->SetVec4("U_DiffuseMaterial", 0.6f, 0.6f, 0.6f, 1.0f);//设置漫反射材质分量
|
|
}
|
|
|
|
void Model::Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix) {
|
|
glEnable(GL_DEPTH_TEST);
|
|
mVertexBuffer->Bind();
|
|
glm::mat4 it = glm::inverseTranspose(mModelMatrix);
|
|
mShader->Bind(glm::value_ptr(mModelMatrix), glm::value_ptr(viewMatrix), glm::value_ptr(projectionMatrix));
|
|
glUniformMatrix4fv(glGetUniformLocation(mShader->mProgram, "IT_ModelMatrix"), 1, GL_FALSE, glm::value_ptr(it));
|
|
glDrawArrays(GL_TRIANGLES, 0, mVertexBuffer->mVertexCount);
|
|
mVertexBuffer->Unbind();
|
|
}
|
|
void Model::SetPosition(float x, float y, float z) {
|
|
mModelMatrix = glm::translate(x, y, z);
|
|
}
|