From 86c6e31f13771105dd3bbca810d087c81e7278a6 Mon Sep 17 00:00:00 2001 From: blobt Date: Wed, 16 Sep 2020 09:58:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90Model=E7=B1=BB=E5=A4=A7?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=96=B9=E6=B3=95=EF=BC=8C=E5=89=A9=E4=B8=8B?= =?UTF-8?q?Draw?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model.cpp | 171 ++++++++++++++++++++++++++++++++ model.h | 47 +++++++++ renderFramework.vcxproj | 2 + renderFramework.vcxproj.filters | 6 ++ 4 files changed, 226 insertions(+) create mode 100644 model.cpp create mode 100644 model.h diff --git a/model.cpp b/model.cpp new file mode 100644 index 0000000..0f33d84 --- /dev/null +++ b/model.cpp @@ -0,0 +1,171 @@ +#include "model.h" +#include "utils.h" + +Model::Model() +{ + mShader = new Shader; +} + +void Model::Init(const char*modelPath) { + int nFileSize = 0; + fileContent = LoadFileContent(modelPath, nFileSize); + + if (fileContent == nullptr) { + printf("load obj model fail\n"); + exit; + } + + //解析模型数据 + parseModel(); + delete fileContent; + + //填充VertexBuffer + createVertexBuffer(); +} + +void Model::parseModel() +{ + std::stringstream ssObjFile((char*)fileContent); + char szOneLine[256]; + + while (!ssObjFile.eof()) { + memset(szOneLine, 0, 256); + ssObjFile.getline(szOneLine, 256); + if (strlen(szOneLine) > 0) { + parseLine(szOneLine); + } + } +} + +void Model::parseLine(const char * line) +{ + if (line[0] == 'v') { + if (line[1] == 't') { + parseTexcoord(line); + } + else if (line[1] == 'n') { + parseNormal(line); + } + else { + parsePosition(line); + } + } + + if (line[0] == 'f') { + parseFace(line); + } +} + +void Model::parseTexcoord(const char * line) +{ + glm::float3 f3 = parseFloat(line); + texcoord.push_back(f3); +} + +void Model::parseNormal(const char * line) +{ + glm::float3 f3 = parseFloat(line); + normal.push_back(f3); +} + +void Model::parsePosition(const char * line) +{ + glm::float3 f3 = parseFloat(line); + position.push_back(f3); +} + +glm::float3 Model::parseFloat(const char * line) +{ + std::string t; + std::stringstream ssOneLine(line); + ssOneLine >> t; + glm::float3 f3; + ssOneLine >> f3.x; + ssOneLine >> f3.y; + if (line[1] == 't') { + f3.z = 0; + } + else { + ssOneLine >> f3.z; + } + return f3; +} + +void Model::parseFace(const char * line) +{ + std::string temp; + std::stringstream ssOneLine(line); + ssOneLine >> temp; //去除 f + + std::string pointerIndexStr; + for (int i = 0; i < 3; i++) { + //解析每一个点 + ssOneLine >> pointerIndexStr; + VertexIndex vi = parseVertexIndex(pointerIndexStr); + + //把点加到vertices + int index = addVertices(vi); + } +} + +VertexIndex Model::parseVertexIndex(std::string pointStr) +{ + size_t pos = pointStr.find_first_of('/'); + std::string positionIndexStr = pointStr.substr(0, pos); + size_t pos2 = pointStr.find_first_of('/', pos + 1); + std::string texcoordIndexStr = pointStr.substr(pos + 1, pos2 - pos - 1); + std::string normalIndexStr = pointStr.substr(pos2 + 1, pointStr.length() - pos2 - 1); + + VertexIndex ret; + ret.position = atoi(positionIndexStr.c_str()) - 1; + ret.texcoord = atoi(texcoordIndexStr.c_str()) - 1; + ret.normal = atoi(normalIndexStr.c_str()) - 1; + + return ret; +} + +int Model::addVertices(VertexIndex indexes) +{ + int currentIndex = -1; + size_t currentVerticeCount = vertices.size(); + currentIndex = vertices.size(); + vertices.push_back(indexes); + return currentIndex; +} + + +void Model::createVertexBuffer() +{ + int vertexCount = (int)vertices.size(); + mVertexBuffer = new VertexBuffer; + glm::float3 t; + mVertexBuffer->SetSize(vertexCount); + for (int i = 0; i < vertexCount; ++i) { + t = position[vertices[i].position - 1]; + mVertexBuffer->SetPosition(i, t[0], t[1], t[2]); + t = texcoord[vertices[i].texcoord - 1]; + mVertexBuffer->SetTexcoord(i, t[0], t[1]); + t = normal[vertices[i].normal - 1]; + mVertexBuffer->SetNormal(i, t[0], t[1], t[2]); + } +} + +void Model::Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix, float x, float y, float z) { + //TODO +} + +void Model::SetPosition(float x, float y, float z) { + mModelMatrix = glm::translate(x, y, z); +} +void Model::SetAmbientMaterial(float r, float g, float b, float a) { + mShader->SetVec4("U_AmbientMaterial", r, g, b, a); +} +void Model::SetDiffuseMaterial(float r, float g, float b, float a) { + mShader->SetVec4("U_DiffuseMaterial", r, g, b, a); +} +void Model::SetSpecularMaterial(float r, float g, float b, float a) { + mShader->SetVec4("U_SpecularMaterial", r, g, b, a); +} +void Model::SetTexture(const char*imagePath) { + mShader->SetTexture("U_Texture", imagePath); +} \ No newline at end of file diff --git a/model.h b/model.h new file mode 100644 index 0000000..a06a3b9 --- /dev/null +++ b/model.h @@ -0,0 +1,47 @@ +#pragma once +#include "ggl.h" +#include "vertexbuffer.h" +#include "shader.h" +#include +#include "Glm/glm.hpp" +#include "Glm/ext.hpp" + +struct VertexIndex +{ + int position; + int texcoord; + int normal; +}; + +class Model { +public: + VertexBuffer* mVertexBuffer; + Shader* mShader; +public: + glm::mat4 mModelMatrix; + float *mLightViewMatrix, *mLightProjectionMatrix; + Model(); + void Init(const char *modelPath); + void Draw(glm::mat4 &viewMatrix, glm::mat4 projectionMatrix, float x, float y, float z); + void SetPosition(float x, float y, float z); + void SetAmbientMaterial(float r, float g, float b, float a); + void SetDiffuseMaterial(float r, float g, float b, float a); + void SetSpecularMaterial(float r, float g, float b, float a); + void SetTexture(const char*imagePath); +private: + unsigned char* fileContent = nullptr; + std::vector position; + std::vector texcoord; + std::vector normal; + std::vector vertices; + void parseModel(); + void parseLine(const char* line); + glm::float3 parseFloat(const char* line); + VertexIndex parseVertexIndex(std::string pointStr); + int addVertices(VertexIndex indexes); + void parseTexcoord(const char* line); + void parseNormal(const char* line); + void parsePosition(const char* line); + void parseFace(const char* line); + void createVertexBuffer(); +}; \ No newline at end of file diff --git a/renderFramework.vcxproj b/renderFramework.vcxproj index c3cc46e..fd9d02f 100644 --- a/renderFramework.vcxproj +++ b/renderFramework.vcxproj @@ -127,6 +127,7 @@ + @@ -134,6 +135,7 @@ + diff --git a/renderFramework.vcxproj.filters b/renderFramework.vcxproj.filters index 0b87639..9a0550a 100644 --- a/renderFramework.vcxproj.filters +++ b/renderFramework.vcxproj.filters @@ -30,6 +30,9 @@ 婧愭枃浠 + + 婧愭枃浠 + @@ -47,5 +50,8 @@ 婧愭枃浠 + + 婧愭枃浠 + \ No newline at end of file