OpenGL – 使用模型矩阵移动对象

huangapple go评论94阅读模式
英文:

OpenGL - Moving Object using Modelmatrix

问题

I am working on an OpenGL project. In this project, I would like to simulate a 3D chess game in c++. Of course, the pieces should be movable at will. The chessboard and pieces are already displayed with textures included.

我正在进行一个OpenGL项目。在这个项目中,我想用C++模拟一个3D国际象棋游戏。当然,棋子应该可以随意移动。棋盘和棋子已经显示了纹理。

I have been working on transforming the pieces. In my model class, all important parameters such as vertices, indices, numvertices, numindices and more are read from the respective model. This happens in the constructor of this class.

我一直在处理棋子的变换。在我的模型类中,从各个模型中读取所有重要的参数,如顶点、索引、顶点数、索引数等。这发生在该类的构造函数中。

I also create an identity matrix (glm::mat4(1.0f)) for each model in the constructor of the model class.

我还在模型类的构造函数中为每个模型创建一个单位矩阵(glm::mat4(1.0f))。

After all the parameters have been read, I push them into a vector<Mesh*>.

在读取所有参数后,我将它们推入一个vector<Mesh*>中。

In the mesh class, the vertices and indices are first loaded into the vertex buffer/index buffer in the constructor.

在mesh类中,在构造函数中首先将顶点和索引加载到顶点缓冲区/索引缓冲区中。

The location of the uniform variable in the vertex shader for my model matrix is also calculated in the constructor.

在构造函数中还计算了顶点着色器中用于模型矩阵的uniform变量的位置。

In the render function of the mesh class, the vertex buffer/index buffer is bound and all uniforms are set. At the end of the function, I call glDrawElements.

在mesh类的渲染函数中,绑定了顶点缓冲区/索引缓冲区,并设置了所有uniform变量。在函数的结尾,我调用了glDrawElements。

In the vertex shader, I multiply the model matrix, the viewProjectionMatrix, and vec4(a_position, 1.0f) into gl_Position. If the identity matrix in the constructor of the model class is glm::mat4(1.0f), the model is displayed normally. But if I transform, scale or rotate the matrix in the constructor for testing purposes, nothing is displayed anymore. Did I make a mistake in the way I'm doing it or am I on the right track?

在顶点着色器中,我将模型矩阵、viewProjectionMatrix 和 vec4(a_position, 1.0f) 相乘,并将结果赋给gl_Position。如果在模型类的构造函数中使用单位矩阵glm::mat4(1.0f),模型会正常显示。但如果出于测试目的在构造函数中对矩阵进行变换、缩放或旋转,就不会显示任何内容了。我在做法上犯了错误,还是我在正确的轨道上?

英文:

I am working on an OpenGL project. In this project, I would like to simulate a 3D chess game in c++. Of course, the pieces should be movable at will. The chessboard and pieces are already displayed with textures included.

I have been working on transforming the pieces. In my model class, all important parameters such as vertices, indices, numvertices, numindices and more are read from the respective model. This happens in the constructor of this class.

I also create an identity matrix (glm::mat4(1.0f)) for each model in the constructor of the model class.

After all the parameters have been read, I push them into a vector<Mesh*>.

In the mesh class, the vertices and indices are first loaded into the vertex buffer/index buffer in the constructor.

The location of the uniform variable in the vertex shader for my model matrix is also calculated in the constructor.

In the render function of the mesh class, the vertex buffer/index buffer is bound and all uniforms are set. At the end of the function, I call glDrawElements.

In the vertex shader, I multiply the model matrix, the viewProjectionMatrix, and vec4(a_position, 1.0f) into gl_Position.
If the identity matrix in the constructor of the model class is glm::mat4(1.0f), the model is displayed normally.

But if I transform, scale or rotate the matrix in the constructor for testing purposes, nothing is displayed anymore.
Did I make a mistake in the way I'm doing it or am I on the right track?

  1. #pragma once
  2. #include &lt;vector&gt;
  3. #include &lt;fstream&gt;
  4. #include &quot;libs/glm/glm.hpp&quot;
  5. #include &quot;shader.h&quot;
  6. #include &quot;vertexbuffer.h&quot;
  7. #include &quot;indexbuffer.h&quot;
  8. #include &quot;mesh.h&quot;
  9. #include &lt;cassert&gt;
  10. class Model {
  11. public:
  12. Model(const char* filename, Shader* shader) {
  13. this-&gt;shader = shader;
  14. modelmatrix = glm::mat4(1.0f);
  15. //modelmatrix = glm::scale(modelmatrix, glm::vec3(10));
  16. std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary);
  17. uint64 numMeshes;
  18. uint64 numMaterials;
  19. input.read((char*)&amp;numMaterials, sizeof(uint64));
  20. for (uint64 i = 0; i &lt; numMaterials; i++) {
  21. Material material = {};
  22. input.read((char*)&amp;material, sizeof(BMFMaterial));
  23. uint64 diffuseMapNameLenght = 0;
  24. input.read((char*)&amp;diffuseMapNameLenght, sizeof(uint64));
  25. std::string diffuseMapName(diffuseMapNameLenght, &#39;
    #pragma once
  26. #include &lt;vector&gt;
  27. #include &lt;fstream&gt;
  28. #include &quot;libs/glm/glm.hpp&quot;
  29. #include &quot;shader.h&quot;
  30. #include &quot;vertexbuffer.h&quot;
  31. #include &quot;indexbuffer.h&quot;
  32. #include &quot;mesh.h&quot;
  33. #include &lt;cassert&gt;
  34. class Model {
  35. public:
  36. Model(const char* filename, Shader* shader) {
  37. this-&gt;shader = shader;
  38. modelmatrix = glm::mat4(1.0f); 
  39. //modelmatrix = glm::scale(modelmatrix, glm::vec3(10));
  40. std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary); 
  41. uint64 numMeshes;
  42. uint64 numMaterials;
  43. input.read((char*)&amp;numMaterials, sizeof(uint64));
  44. for (uint64 i = 0; i &lt; numMaterials; i++) {
  45. Material material = {};
  46. input.read((char*)&amp;material, sizeof(BMFMaterial)); 
  47. uint64 diffuseMapNameLenght = 0;
  48. input.read((char*)&amp;diffuseMapNameLenght, sizeof(uint64)); 
  49. std::string diffuseMapName(diffuseMapNameLenght, &#39;\0&#39;); 
  50. input.read((char*)&amp;diffuseMapName[0], diffuseMapNameLenght); 
  51. uint64 normalMapNameLenght = 0;
  52. input.read((char*)&amp;normalMapNameLenght, sizeof(uint64)); 
  53. std::string normalMapName(normalMapNameLenght, &#39;\0&#39;); 
  54. input.read((char*)&amp;normalMapName[0], normalMapNameLenght); 
  55. if (diffuseMapNameLenght &gt; 0) {
  56. std::cout &lt;&lt; filename &lt;&lt; &quot; successfully loaded&quot; &lt;&lt; std::endl;
  57. }
  58. else {
  59. std::cout &lt;&lt; filename &lt;&lt; &quot; failed loading&quot; &lt;&lt; std::endl;
  60. }
  61. int32 textureWidth = 0;
  62. int32 textureHeight = 0;
  63. int32 bitsPerPixel = 0;
  64. glGenTextures(2, &amp;material.diffuseMap); 
  65. stbi_set_flip_vertically_on_load(true);
  66. auto textureBuffer = stbi_load(diffuseMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
  67. glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
  68. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  69. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  70. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  71. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  72. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer); //Texture in Grafikkarte geladen
  73. if (textureBuffer) {
  74. stbi_image_free(textureBuffer);
  75. }
  76. auto textureBuffer2 = stbi_load(normalMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
  77. glBindTexture(GL_TEXTURE_2D, material.normalMap);
  78. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  79. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  80. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  81. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  82. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer2); //Texture in Grafikkarte geladen
  83. if (textureBuffer2) {
  84. stbi_image_free(textureBuffer2);
  85. }
  86. glBindTexture(GL_TEXTURE_2D, 0); 
  87. materials.push_back(material); 
  88. }
  89. input.read((char*)&amp;numMeshes, sizeof(uint64)); 
  90. for (uint64 i = 0; i &lt; numMeshes; i++) {
  91. input.read((char*)&amp;materialIndex, sizeof(uint64)); 
  92. input.read((char*)&amp;numVertices, sizeof(uint64)); 
  93. input.read((char*)&amp;numIndices, sizeof(uint64)); 
  94. for (uint64 i = 0; i &lt; numVertices; i++) {
  95. Vertex vertex;
  96. input.read((char*)&amp;vertex.position.x, sizeof(float));
  97. input.read((char*)&amp;vertex.position.y, sizeof(float));
  98. input.read((char*)&amp;vertex.position.z, sizeof(float));
  99. input.read((char*)&amp;vertex.normal.x, sizeof(float));
  100. input.read((char*)&amp;vertex.normal.y, sizeof(float));
  101. input.read((char*)&amp;vertex.normal.z, sizeof(float));
  102. input.read((char*)&amp;vertex.textureCoord.x, sizeof(float));
  103. input.read((char*)&amp;vertex.textureCoord.y, sizeof(float));
  104. vertices.push_back(vertex);
  105. }
  106. for (uint64 i = 0; i &lt; numIndices; i++) {
  107. uint32 index;
  108. input.read((char*)&amp;index, sizeof(uint32));
  109. indices.push_back(index);
  110. }
  111. Mesh* mesh = new Mesh(vertices, numVertices, indices, numIndices, materials[materialIndex], shader, modelmatrix); //Mesh laden 
  112. meshes.push_back(mesh);
  113. }
  114. }
  115. void render() {
  116. for (Mesh* mesh : meshes) {
  117. mesh-&gt;render();
  118. }
  119. }
  120. ~Model() {
  121. for (Mesh* mesh : meshes) {
  122. delete mesh;
  123. }
  124. }
  125. private:
  126. std::vector&lt;Mesh*&gt; meshes; 
  127. std::vector&lt;Material&gt; materials; 
  128. glm::mat4 modelmatrix;
  129. std::vector&lt;Vertex&gt; vertices;
  130. uint64 numVertices = 0;
  131. std::vector&lt;uint32&gt; indices;
  132. uint64 numIndices = 0;
  133. uint64 materialIndex = 0;
  134. Shader* shader;
  135. };
  136. &#39;);
  137. input.read((char*)&amp;diffuseMapName[0], diffuseMapNameLenght);
  138. uint64 normalMapNameLenght = 0;
  139. input.read((char*)&amp;normalMapNameLenght, sizeof(uint64));
  140. std::string normalMapName(normalMapNameLenght, &#39;
    #pragma once
  141. #include &lt;vector&gt;
  142. #include &lt;fstream&gt;
  143. #include &quot;libs/glm/glm.hpp&quot;
  144. #include &quot;shader.h&quot;
  145. #include &quot;vertexbuffer.h&quot;
  146. #include &quot;indexbuffer.h&quot;
  147. #include &quot;mesh.h&quot;
  148. #include &lt;cassert&gt;
  149. class Model {
  150. public:
  151. Model(const char* filename, Shader* shader) {
  152. this-&gt;shader = shader;
  153. modelmatrix = glm::mat4(1.0f); 
  154. //modelmatrix = glm::scale(modelmatrix, glm::vec3(10));
  155. std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary); 
  156. uint64 numMeshes;
  157. uint64 numMaterials;
  158. input.read((char*)&amp;numMaterials, sizeof(uint64));
  159. for (uint64 i = 0; i &lt; numMaterials; i++) {
  160. Material material = {};
  161. input.read((char*)&amp;material, sizeof(BMFMaterial)); 
  162. uint64 diffuseMapNameLenght = 0;
  163. input.read((char*)&amp;diffuseMapNameLenght, sizeof(uint64)); 
  164. std::string diffuseMapName(diffuseMapNameLenght, &#39;\0&#39;); 
  165. input.read((char*)&amp;diffuseMapName[0], diffuseMapNameLenght); 
  166. uint64 normalMapNameLenght = 0;
  167. input.read((char*)&amp;normalMapNameLenght, sizeof(uint64)); 
  168. std::string normalMapName(normalMapNameLenght, &#39;\0&#39;); 
  169. input.read((char*)&amp;normalMapName[0], normalMapNameLenght); 
  170. if (diffuseMapNameLenght &gt; 0) {
  171. std::cout &lt;&lt; filename &lt;&lt; &quot; successfully loaded&quot; &lt;&lt; std::endl;
  172. }
  173. else {
  174. std::cout &lt;&lt; filename &lt;&lt; &quot; failed loading&quot; &lt;&lt; std::endl;
  175. }
  176. int32 textureWidth = 0;
  177. int32 textureHeight = 0;
  178. int32 bitsPerPixel = 0;
  179. glGenTextures(2, &amp;material.diffuseMap); 
  180. stbi_set_flip_vertically_on_load(true);
  181. auto textureBuffer = stbi_load(diffuseMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
  182. glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
  183. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  184. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  185. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  186. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  187. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer); //Texture in Grafikkarte geladen
  188. if (textureBuffer) {
  189. stbi_image_free(textureBuffer);
  190. }
  191. auto textureBuffer2 = stbi_load(normalMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
  192. glBindTexture(GL_TEXTURE_2D, material.normalMap);
  193. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  194. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  195. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  196. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  197. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer2); //Texture in Grafikkarte geladen
  198. if (textureBuffer2) {
  199. stbi_image_free(textureBuffer2);
  200. }
  201. glBindTexture(GL_TEXTURE_2D, 0); 
  202. materials.push_back(material); 
  203. }
  204. input.read((char*)&amp;numMeshes, sizeof(uint64)); 
  205. for (uint64 i = 0; i &lt; numMeshes; i++) {
  206. input.read((char*)&amp;materialIndex, sizeof(uint64)); 
  207. input.read((char*)&amp;numVertices, sizeof(uint64)); 
  208. input.read((char*)&amp;numIndices, sizeof(uint64)); 
  209. for (uint64 i = 0; i &lt; numVertices; i++) {
  210. Vertex vertex;
  211. input.read((char*)&amp;vertex.position.x, sizeof(float));
  212. input.read((char*)&amp;vertex.position.y, sizeof(float));
  213. input.read((char*)&amp;vertex.position.z, sizeof(float));
  214. input.read((char*)&amp;vertex.normal.x, sizeof(float));
  215. input.read((char*)&amp;vertex.normal.y, sizeof(float));
  216. input.read((char*)&amp;vertex.normal.z, sizeof(float));
  217. input.read((char*)&amp;vertex.textureCoord.x, sizeof(float));
  218. input.read((char*)&amp;vertex.textureCoord.y, sizeof(float));
  219. vertices.push_back(vertex);
  220. }
  221. for (uint64 i = 0; i &lt; numIndices; i++) {
  222. uint32 index;
  223. input.read((char*)&amp;index, sizeof(uint32));
  224. indices.push_back(index);
  225. }
  226. Mesh* mesh = new Mesh(vertices, numVertices, indices, numIndices, materials[materialIndex], shader, modelmatrix); //Mesh laden 
  227. meshes.push_back(mesh);
  228. }
  229. }
  230. void render() {
  231. for (Mesh* mesh : meshes) {
  232. mesh-&gt;render();
  233. }
  234. }
  235. ~Model() {
  236. for (Mesh* mesh : meshes) {
  237. delete mesh;
  238. }
  239. }
  240. private:
  241. std::vector&lt;Mesh*&gt; meshes; 
  242. std::vector&lt;Material&gt; materials; 
  243. glm::mat4 modelmatrix;
  244. std::vector&lt;Vertex&gt; vertices;
  245. uint64 numVertices = 0;
  246. std::vector&lt;uint32&gt; indices;
  247. uint64 numIndices = 0;
  248. uint64 materialIndex = 0;
  249. Shader* shader;
  250. };
  251. &#39;);
  252. input.read((char*)&amp;normalMapName[0], normalMapNameLenght);
  253. if (diffuseMapNameLenght &gt; 0) {
  254. std::cout &lt;&lt; filename &lt;&lt; &quot; successfully loaded&quot; &lt;&lt; std::endl;
  255. }
  256. else {
  257. std::cout &lt;&lt; filename &lt;&lt; &quot; failed loading&quot; &lt;&lt; std::endl;
  258. }
  259. int32 textureWidth = 0;
  260. int32 textureHeight = 0;
  261. int32 bitsPerPixel = 0;
  262. glGenTextures(2, &amp;material.diffuseMap);
  263. stbi_set_flip_vertically_on_load(true);
  264. auto textureBuffer = stbi_load(diffuseMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen
  265. glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
  266. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  267. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  268. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  269. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  270. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer); //Texture in Grafikkarte geladen
  271. if (textureBuffer) {
  272. stbi_image_free(textureBuffer);
  273. }
  274. auto textureBuffer2 = stbi_load(normalMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen
  275. glBindTexture(GL_TEXTURE_2D, material.normalMap);
  276. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  277. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  278. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  279. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  280. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer2); //Texture in Grafikkarte geladen
  281. if (textureBuffer2) {
  282. stbi_image_free(textureBuffer2);
  283. }
  284. glBindTexture(GL_TEXTURE_2D, 0);
  285. materials.push_back(material);
  286. }
  287. input.read((char*)&amp;numMeshes, sizeof(uint64));
  288. for (uint64 i = 0; i &lt; numMeshes; i++) {
  289. input.read((char*)&amp;materialIndex, sizeof(uint64));
  290. input.read((char*)&amp;numVertices, sizeof(uint64));
  291. input.read((char*)&amp;numIndices, sizeof(uint64));
  292. for (uint64 i = 0; i &lt; numVertices; i++) {
  293. Vertex vertex;
  294. input.read((char*)&amp;vertex.position.x, sizeof(float));
  295. input.read((char*)&amp;vertex.position.y, sizeof(float));
  296. input.read((char*)&amp;vertex.position.z, sizeof(float));
  297. input.read((char*)&amp;vertex.normal.x, sizeof(float));
  298. input.read((char*)&amp;vertex.normal.y, sizeof(float));
  299. input.read((char*)&amp;vertex.normal.z, sizeof(float));
  300. input.read((char*)&amp;vertex.textureCoord.x, sizeof(float));
  301. input.read((char*)&amp;vertex.textureCoord.y, sizeof(float));
  302. vertices.push_back(vertex);
  303. }
  304. for (uint64 i = 0; i &lt; numIndices; i++) {
  305. uint32 index;
  306. input.read((char*)&amp;index, sizeof(uint32));
  307. indices.push_back(index);
  308. }
  309. Mesh* mesh = new Mesh(vertices, numVertices, indices, numIndices, materials[materialIndex], shader, modelmatrix); //Mesh laden
  310. meshes.push_back(mesh);
  311. }
  312. }
  313. void render() {
  314. for (Mesh* mesh : meshes) {
  315. mesh-&gt;render();
  316. }
  317. }
  318. ~Model() {
  319. for (Mesh* mesh : meshes) {
  320. delete mesh;
  321. }
  322. }
  323. private:
  324. std::vector&lt;Mesh*&gt; meshes;
  325. std::vector&lt;Material&gt; materials;
  326. glm::mat4 modelmatrix;
  327. std::vector&lt;Vertex&gt; vertices;
  328. uint64 numVertices = 0;
  329. std::vector&lt;uint32&gt; indices;
  330. uint64 numIndices = 0;
  331. uint64 materialIndex = 0;
  332. Shader* shader;
  333. };
  1. #pragma once
  2. #include &lt;iostream&gt;
  3. #include &lt;vector&gt;
  4. #include &lt;fstream&gt;
  5. #include &quot;libs/glm/mat4x4.hpp&quot;
  6. #include &quot;libs/glm/glm.hpp&quot;
  7. #include &quot;shader.h&quot;
  8. #include &quot;vertexbuffer.h&quot;
  9. #include &quot;indexbuffer.h&quot;
  10. #include &quot;libs/stb_image.h&quot;
  11. struct BMFMaterial {
  12. glm::vec3 diffuse;
  13. glm::vec3 specular;
  14. glm::vec3 emissive;
  15. float shininess;
  16. };
  17. struct Material {
  18. BMFMaterial material;
  19. GLuint diffuseMap;
  20. GLuint normalMap;
  21. };
  22. class Mesh {
  23. public:
  24. Mesh(std::vector&lt;Vertex&gt;&amp; vertices, uint64 numVertices, std::vector&lt;uint32&gt;&amp;indices, uint64 numIndices, Material material, Shader* shader, glm::mat4 modelmatrix) {
  25. this-&gt;material = material;
  26. this-&gt;shader = shader;
  27. this-&gt;numIndices = numIndices;
  28. this-&gt;modelmatrix = modelmatrix;
  29. vertexBuffer = new VertexBuffer(vertices.data(), numVertices);
  30. indexBuffer = new IndexBuffer(indices.data(), numIndices, sizeof(indices[0]));
  31. diffuseLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.diffuse&quot;);
  32. specularLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.specular&quot;);
  33. emissiveLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.emissive&quot;);
  34. shininessLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.shininess&quot;);
  35. diffuseMapLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_diffuse_map&quot;);
  36. modelmatrixlocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_modelmatrix&quot;);
  37. }
  38. ~Mesh() {
  39. delete vertexBuffer;
  40. delete indexBuffer;
  41. }
  42. inline void render() {
  43. std::cout &lt;&lt; glm::to_string(modelmatrix) &lt;&lt; std::endl;
  44. vertexBuffer-&gt;bind();
  45. indexBuffer-&gt;bind();
  46. glUniformMatrix4fv(modelmatrixlocation, 1, GL_FALSE, &amp;modelmatrix[0][0]);
  47. glUniform3fv(diffuseLocation, 1, (float*)&amp;material.material.diffuse[0]);
  48. glUniform3fv(specularLocation, 1, (float*)&amp;material.material.specular[0]);
  49. glUniform3fv(emissiveLocation, 1, (float*)&amp;material.material.emissive[0]);
  50. glUniform1f(shininessLocation, material.material.shininess);
  51. glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
  52. glUniform1i(diffuseMapLocation, 0);
  53. glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0);
  54. }
  55. private:
  56. VertexBuffer* vertexBuffer;
  57. IndexBuffer* indexBuffer;
  58. Shader* shader;
  59. Material material;
  60. uint64 numIndices = 0;
  61. glm::mat4 modelmatrix;
  62. int diffuseLocation;
  63. int specularLocation;
  64. int emissiveLocation;
  65. int shininessLocation;
  66. int diffuseMapLocation;
  67. int modelmatrixlocation;
  68. };
  1. while (!close) { //GAMELOOP
  2. camera.update();
  3. //model = glm::rotate(model, glm::radians(rotation = 1.0f), glm::vec3(1.0f, 0.0f, 0.0f));
  4. modelViewProj = camera.getViewProj();//*model //Pro Frame jedes mal neu berechnen
  5. glm::mat4 modelView = camera.getView(); //*model
  6. glm::mat4 invModelView = glm::transpose(glm::inverse(modelView));
  7. glm::vec4 sunDirectionCamera = glm::transpose(glm::inverse(camera.getView())) * glm::vec4(sunDirection, 1.0f); //sunDirection ist abh&#228;nging von Kamera, weil Licht wird im viewspace berechnet
  8. glUniform3fv(directionLocationDirection, 1, (float*)&amp;sunDirectionCamera[0]); //aktivieren
  9. glm::mat4 pointLightMatrix = glm::mat4(1.0f); //F&#252;r Matrixmultiplikation weil der Punkt nicht immer am gleichen Punkt bleiben soll
  10. pointLightPosition = pointLightPosition * pointLightMatrix; //Position &#228;ndert sich, rotiert nun um y-Achse
  11. glm::vec3 transformedPointLightPosition = (glm::vec3)(camera.getView() * pointLightPosition); //Transformierte Position im Viewspace
  12. glUniform3fv(positionLocationPoint, 1, (float*)&amp;transformedPointLightPosition[0]);
  13. glUniformMatrix4fv(modelViewProjMatrixLocation, 1, GL_FALSE, &amp;modelViewProj[0][0]); //Matrix setzen/aktivieren
  14. glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, &amp;modelView[0][0]);
  15. glUniformMatrix4fv(invModelViewLocation, 1, GL_FALSE, &amp;invModelView[0][0]);
  16. //Brett und Figuren rendern/zeichnen
  17. whitepawnA2.render();
  18. board.render();
  19. /*
  20. whitebishopright.render();
  21. whitebishopleft.render();
  22. whiteking.render();
  23. whiteknightleft.render();
  24. whiteknightright.render();
  25. whiterookleft.render();
  26. whiterookright.render();
  27. whitequeen.render();
  28. whitepawnH2.render();
  29. whitepawnG2.render();
  30. whitepawnF2.render();
  31. whitepawnE2.render();
  32. whitepawnD2.render();
  33. whitepawnC2.render();
  34. whitepawnB2.render();
  35. blackknightleft.render();
  36. blackknightright.render();
  37. blackking.render();
  38. blackbishopleft.render();
  39. blackbishopright.render();
  40. blackqueen.render();
  41. blackrookleft.render();
  42. blackrookright.render();
  43. blackpawnA.render();
  44. blackpawnB.render();
  45. blackpawnC.render();
  46. blackpawnD.render();
  47. blackpawnE.render();
  48. blackpawnF.render();
  49. blackpawnG.render();
  50. blackpawnH.render();
  51. */
  52. SDL_GL_SwapWindow(window); //double buffer aktivieren
  53. //FPS COUNTER
  54. uint64 endCounter = SDL_GetPerformanceCounter();
  55. uint64 counterElapsed = endCounter - lastCounter;
  56. delta = ((float32)counterElapsed) / (float32)perfCounterFrequency; //Zeit die seit letztem Frame vergangen ist
  57. uint32 FPS = (uint32)((float32)perfCounterFrequency / (float32)counterElapsed);
  58. //std::cout &lt;&lt; FPS &lt;&lt; std::endl;
  59. lastCounter = endCounter;
  60. }
  61. return 0;
  62. }
  1. #include &quot;shader.h&quot;
  2. #include &lt;fstream&gt;
  3. #include &lt;iostream&gt;
  4. Shader::Shader(const char* vertexShaderFilename, const char* fragmentShaderFilename) {
  5. shaderID = createShader(vertexShaderFilename, fragmentShaderFilename);
  6. }
  7. Shader::~Shader() {
  8. glDeleteProgram(shaderID);
  9. }
  10. void Shader::bind() {
  11. glUseProgram(shaderID);
  12. }
  13. void Shader::unbind() {
  14. glUseProgram(0);
  15. }
  16. GLuint Shader::getShaderID() {
  17. return shaderID;
  18. }
  19. GLuint Shader::compile(std::string shaderSource, GLenum type) { //Shadersourcecode so kompiliert werden
  20. GLuint id = glCreateShader(type);
  21. const char* src = shaderSource.c_str();
  22. glShaderSource(id, 1, &amp;src, 0);
  23. glCompileShader(id);
  24. int result;
  25. glGetShaderiv(id, GL_COMPILE_STATUS, &amp;result);
  26. if (result != GL_TRUE) {
  27. int length = 0;
  28. glGetShaderiv(id, GL_INFO_LOG_LENGTH, &amp;length);
  29. char* message = new char[length];
  30. glGetShaderInfoLog(id, length, &amp;length, message);
  31. std::cout &lt;&lt; &quot;Shader compilation error: &quot; &lt;&lt; message &lt;&lt; std::endl;
  32. delete[] message;
  33. return 0;
  34. }
  35. return id;
  36. }
  37. std::string Shader::parse(const char* filename) {
  38. FILE* file;
  39. #ifdef _WIN32
  40. if (fopen_s(&amp;file, filename, &quot;rb&quot;) != 0) {
  41. std::cout &lt;&lt; &quot;File &quot; &lt;&lt; filename &lt;&lt; &quot; not found&quot; &lt;&lt; std::endl;
  42. return &quot;&quot;;
  43. }
  44. #else
  45. file = fopen(filename, &quot;rb&quot;);
  46. if (file == nullptr) {
  47. std::cout &lt;&lt; &quot;File &quot; &lt;&lt; filename &lt;&lt; &quot; not found&quot; &lt;&lt; std::endl;
  48. return &quot;&quot;;
  49. }
  50. #endif
  51. std::string content; //Dateininhalt
  52. fseek(file, 0, SEEK_END); //ans ende der datei gehen
  53. size_t filesize = ftell(file); //wie weit ist man im file
  54. rewind(file); //wieder zur&#252;ckgehen
  55. content.resize(filesize); //file resizen damit man nicht zu wenig oder zu viel speicher reserviert
  56. fread(&amp;content[0], 1, filesize, file); //&amp;content[0] gibt adresse auf speicherbereich - 1 ganze filesize soll gelesen werden -
  57. fclose(file); //file wieder schlie&#223;en
  58. return content; //code returnen
  59. }
  60. GLuint Shader::createShader(const char* vertexShaderFilename, const char* fragmentShaderFilename) {
  61. std::string vertexShaderSource = parse(vertexShaderFilename); //Sourcecode speichern
  62. std::string fragmentShaderSource = parse(fragmentShaderFilename);
  63. GLuint program = glCreateProgram(); //program erstellen
  64. GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER); //shader erstellen
  65. GLuint fs = compile(fragmentShaderSource, GL_FRAGMENT_SHADER);
  66. glAttachShader(program, vs); //shader wird program hinzugef&#252;gt
  67. glAttachShader(program, fs);
  68. glLinkProgram(program); //executable erstellt und l&#228;uft auf vertex
  69. //Solange program gelinked ist, kann alles wieder deattached und gel&#246;scht werden - spart speicherplatz
  70. #ifdef _RELEASE
  71. glDetachShader(progam, vs);
  72. glDetachShader(program, fs);
  73. glDeleteShader(vs);
  74. glDeleteShader(fs);
  75. #endif
  76. return program;
  77. }
  1. //Vertexshader soll Position von Vertex berechnen
  2. #version 330 core
  3. //INPUTS IN DEN SHADER
  4. layout(location = 0) in vec3 a_position; //layout location 0 -&gt; 1 Attribut
  5. layout(location = 1) in vec3 a_normal;
  6. layout(location = 2) in vec2 a_tex_coord;
  7. //OUTPUTS
  8. out vec3 v_normal;
  9. out vec3 v_position;
  10. out vec2 v_tex_coord;
  11. uniform mat4 u_modelmatrix;
  12. uniform mat4 u_modelView;
  13. uniform mat4 u_modelViewProj;
  14. uniform mat4 u_invModelView;
  15. void main()
  16. {
  17. gl_Position = u_modelmatrix * u_modelViewProj * vec4(a_position, 1.0f); //vec4 f&#252;r Matrixmultiplikationen - Position in positionsvariable - 1.0f -&gt; 4 Koordinate
  18. v_normal = mat3(u_invModelView) * a_normal; //Normalevktor berechnen
  19. v_position = vec3(u_modelView * vec4(a_position, 1.0f)); //Position des Fragments berechnen
  20. v_tex_coord = a_tex_coord;
  21. }

答案1

得分: 0

对于任何未来的读者:

一个更准确的问题应该是:

为什么应用变换后我的对象消失了?

在我最初的猜测之后 - 你可以在下面看到 - OP发布了更详细的代码,最后我在着色器程序中找到了一个错误。

矩阵乘法的顺序错了:

  1. // OP的原始代码
  2. gl_Position = u_modelmatrix * u_modelViewProj * vec4(a_position, 1.0f);
  3. // 正确的顺序
  4. gl_Position = projection * view * model * vec4(aPos, 1.0);

根据矩阵顺序,反向顺序也可能是正确的。

关于变换坐标系统的好教程。


原始回答

你没有提供你的代码的所有部分,所以我只能猜测。
我假设在你的着色器类中,你创建了一个着色器程序,然后正确地进行了链接。

但为了在着色器中更新uniform变量,你必须告诉OpenGL,要使用哪个着色器程序,通过调用:

  1. glUseProgram(shader->getShaderID());
  2. //然后
  3. glUniformMatrix4fv(...);
  4. ...

这通常在render()函数中完成(特别是如果你使用多个着色器时至关重要),但我在你的代码中看不到这一点。

如果问题不是这个(你在哪里调用render()函数以及那里发生了什么?你的着色器程序是什么样的?),可能需要附加的代码来找到问题。

英文:

For any future reader:

A more accurate question would be.

Why did my objects disappear after applying transformation?

After my initial guess - which you can see below - OP posted more detailed code and in the end I found an error in the shader program.

The matrix multiplicaton was in the wrong order:

  1. // OP&#39;s original code
  2. gl_Position = u_modelmatrix * u_modelViewProj * vec4(a_position, 1.0f);
  3. // Good order
  4. gl_Position = projection * view * model * vec4(aPos, 1.0);

Reverse order might also be good depending on matrix ordering

Good tutorial about transformations and coordinate systems


Original answer

You didn't provide every part of your code so I can only guess.
I assume in your shader class you create a shader program and then you do the linking correctly.

But in order to update uniforms in a shader, you have to tell that to OpenGL, which shader program to use, by calling:

  1. glUseProgram(shader-&gt;getShaderID());
  2. //and then
  3. glUniformMatrix4fv(...);
  4. ...

That is usually done in a the render() function (especially crucial if you use multiple shaders) and I can't see that in your code.

Additional code might be needed to find the issue if it's something else (where do you call the render() function and what is happening there? how does you shader program look like?).

huangapple
  • 本文由 发表于 2023年2月14日 06:10:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75441680.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定