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.

188 lines
4.6 KiB

4 years ago
  1. #include "model.h"
  2. #include "utils.h"
  3. Model::Model()
  4. {
  5. mShader = new Shader;
  6. }
  7. void Model::Init(const char*modelPath) {
  8. int nFileSize = 0;
  9. fileContent = LoadFileContent(modelPath, nFileSize);
  10. if (fileContent == nullptr) {
  11. printf("load obj model fail\n");
  12. exit;
  13. }
  14. //����ģ������
  15. parseModel();
  16. delete fileContent;
  17. //����VertexBuffer
  18. createVertexBuffer();
  19. }
  20. void Model::parseModel()
  21. {
  22. std::stringstream ssObjFile((char*)fileContent);
  23. char szOneLine[256];
  24. while (!ssObjFile.eof()) {
  25. memset(szOneLine, 0, 256);
  26. ssObjFile.getline(szOneLine, 256);
  27. if (strlen(szOneLine) > 0) {
  28. parseLine(szOneLine);
  29. }
  30. }
  31. }
  32. void Model::parseLine(const char * line)
  33. {
  34. if (line[0] == 'v') {
  35. if (line[1] == 't') {
  36. parseTexcoord(line);
  37. }
  38. else if (line[1] == 'n') {
  39. parseNormal(line);
  40. }
  41. else {
  42. parsePosition(line);
  43. }
  44. }
  45. if (line[0] == 'f') {
  46. parseFace(line);
  47. }
  48. }
  49. void Model::parseTexcoord(const char * line)
  50. {
  51. glm::float3 f3 = parseFloat(line);
  52. texcoord.push_back(f3);
  53. }
  54. void Model::parseNormal(const char * line)
  55. {
  56. glm::float3 f3 = parseFloat(line);
  57. normal.push_back(f3);
  58. }
  59. void Model::parsePosition(const char * line)
  60. {
  61. glm::float3 f3 = parseFloat(line);
  62. position.push_back(f3);
  63. }
  64. glm::float3 Model::parseFloat(const char * line)
  65. {
  66. std::string t;
  67. std::stringstream ssOneLine(line);
  68. ssOneLine >> t;
  69. glm::float3 f3;
  70. ssOneLine >> f3.x;
  71. ssOneLine >> f3.y;
  72. if (line[1] == 't') {
  73. f3.z = 0;
  74. }
  75. else {
  76. ssOneLine >> f3.z;
  77. }
  78. return f3;
  79. }
  80. void Model::parseFace(const char * line)
  81. {
  82. std::string temp;
  83. std::stringstream ssOneLine(line);
  84. ssOneLine >> temp; //ȥ�� f
  85. std::string pointerIndexStr;
  86. for (int i = 0; i < 3; i++) {
  87. //����ÿһ����
  88. ssOneLine >> pointerIndexStr;
  89. VertexIndex vi = parseVertexIndex(pointerIndexStr);
  90. //�ѵ��ӵ�vertices
  91. int index = addVertices(vi);
  92. }
  93. }
  94. VertexIndex Model::parseVertexIndex(std::string pointStr)
  95. {
  96. size_t pos = pointStr.find_first_of('/');
  97. std::string positionIndexStr = pointStr.substr(0, pos);
  98. size_t pos2 = pointStr.find_first_of('/', pos + 1);
  99. std::string texcoordIndexStr = pointStr.substr(pos + 1, pos2 - pos - 1);
  100. std::string normalIndexStr = pointStr.substr(pos2 + 1, pointStr.length() - pos2 - 1);
  101. VertexIndex ret;
  102. ret.position = atoi(positionIndexStr.c_str()) - 1;
  103. ret.texcoord = atoi(texcoordIndexStr.c_str()) - 1;
  104. ret.normal = atoi(normalIndexStr.c_str()) - 1;
  105. return ret;
  106. }
  107. int Model::addVertices(VertexIndex indexes)
  108. {
  109. int currentIndex = -1;
  110. size_t currentVerticeCount = vertices.size();
  111. currentIndex = vertices.size();
  112. vertices.push_back(indexes);
  113. return currentIndex;
  114. }
  115. void Model::createVertexBuffer()
  116. {
  117. int vertexCount = (int)vertices.size();
  118. mVertexBuffer = new VertexBuffer;
  119. glm::float3 t;
  120. mVertexBuffer->SetSize(vertexCount);
  121. for (int i = 0; i < vertexCount; ++i) {
  122. t = position[vertices[i].position];
  123. mVertexBuffer->SetPosition(i, t[0], t[1], t[2]);
  124. t = texcoord[vertices[i].texcoord];
  125. mVertexBuffer->SetTexcoord(i, t[0], t[1]);
  126. t = normal[vertices[i].normal];
  127. mVertexBuffer->SetNormal(i, t[0], t[1], t[2]);
  128. }
  129. }
  130. void Model::Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix, float x, float y, float z) {
  131. mShader->SetVec4("U_CameraPos", x, y, z, 1.0);
  132. glEnable(GL_DEPTH_TEST);
  133. mVertexBuffer->Bind();
  134. if (mShader->mProgram > 0) {
  135. mShader->Bind(glm::value_ptr(mModelMatrix), glm::value_ptr(viewMatrix), glm::value_ptr(projectionMatrix));
  136. glm::mat4 it = glm::inverseTranspose(mModelMatrix);
  137. GLint itLocation = glGetUniformLocation(mShader->mProgram, "IT_ModelMatrix");
  138. glUniformMatrix4fv(itLocation, 1, GL_FALSE, glm::value_ptr(it));
  139. itLocation = glGetUniformLocation(mShader->mProgram, "LightViewMatrix");
  140. if (itLocation >= 0 && mLightViewMatrix != nullptr) {
  141. glUniformMatrix4fv(itLocation, 1, GL_FALSE, mLightViewMatrix);
  142. }
  143. itLocation = glGetUniformLocation(mShader->mProgram, "LightProjectionMatrix");
  144. if (itLocation >= 0 && mLightProjectionMatrix != nullptr) {
  145. glUniformMatrix4fv(itLocation, 1, GL_FALSE, mLightProjectionMatrix);
  146. }
  147. }
  148. glDrawArrays(GL_TRIANGLES, 0, mVertexBuffer->mVertexCount);
  149. mVertexBuffer->Unbind();
  150. }
  151. void Model::SetPosition(float x, float y, float z) {
  152. mModelMatrix = glm::translate(x, y, z);
  153. }
  154. void Model::SetAmbientMaterial(float r, float g, float b, float a) {
  155. mShader->SetVec4("U_AmbientMaterial", r, g, b, a);
  156. }
  157. void Model::SetDiffuseMaterial(float r, float g, float b, float a) {
  158. mShader->SetVec4("U_DiffuseMaterial", r, g, b, a);
  159. }
  160. void Model::SetSpecularMaterial(float r, float g, float b, float a) {
  161. mShader->SetVec4("U_SpecularMaterial", r, g, b, a);
  162. }
  163. void Model::SetTexture(const char*imagePath) {
  164. mShader->SetTexture("U_Texture", imagePath);
  165. }