opengl GLFW 3中的透视图不正确

balp4ylt  于 2024-01-07  发布在  其他
关注(0)|答案(1)|浏览(237)

我试图在Linux中用C++和GLFW制作一个3D游戏。但是正确的3D视角不正确,我不知道为什么。
这应该会画出一个橙子三角形,当你离得越远,它就越小,当你离得越近,它就越大,但它永远不会改变大小,最终只会到达剪切平面并消失。
另外,如果这有帮助,如果我有一个三角形,在z为0,我不能看到它,即使我来回移动。
代码如下:

  1. #include <iostream>
  2. #include "glad/glad.h"
  3. #include "GLFW/glfw3.h"
  4. #include "glm/glm.hpp"
  5. #include "glm/gtc/matrix_transform.hpp"
  6. #include "glm/gtc/type_ptr.hpp"
  7. // Vertex Shader source code
  8. const char* vertexShaderSource = "#version 330 core\n"
  9. "layout (location = 0) in vec3 aPos;\n"
  10. "\n"
  11. "uniform mat4 model;\n"
  12. "uniform mat4 view;\n"
  13. "uniform mat4 proj;\n"
  14. "void main()\n"
  15. "{\n"
  16. " gl_Position = model * view * proj * vec4(aPos, 1.0);\n"
  17. "}\0";
  18. //Fragment Shader source code
  19. const char* fragmentShaderSource = "#version 330 core\n"
  20. "out vec4 FragColor;\n"
  21. "void main()\n"
  22. "{\n"
  23. " FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);\n"
  24. "}\n\0";
  25. int SCREEN_WIDTH=800;
  26. int SCREEN_HEIGHT=600;
  27. void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
  28. glViewport(0, 0, width, height);
  29. SCREEN_WIDTH=width;
  30. SCREEN_HEIGHT=height;
  31. }
  32. int main()
  33. {
  34. // Initialize GLFW
  35. glfwInit();
  36. // Tell GLFW what version of OpenGL we are using
  37. // In this case we are using OpenGL 3.3
  38. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  39. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  40. // Tell GLFW we are using the CORE profile
  41. // So that means we only have the modern functions
  42. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  43. // Create a GLFWwindow object of width by height pixels, naming it "3D C++"
  44. GLFWwindow* window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "3D C++", NULL, NULL);
  45. // Error check if the window fails to create
  46. if (window == NULL)
  47. {
  48. std::cout << "Failed to create GLFW window" << std::endl;
  49. glfwTerminate();
  50. return -1;
  51. }
  52. // Introduce the window into the current context
  53. glfwMakeContextCurrent(window);
  54. //Load GLAD so it configures OpenGL
  55. gladLoadGL();
  56. // Specify the viewport of OpenGL in the Window
  57. // In this case the viewport goes from x = 0, y = 0, to x = width, y = height
  58. glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
  59. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  60. // Create Vertex Shader Object and get its reference
  61. GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  62. // Attach Vertex Shader source to the Vertex Shader Object
  63. glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
  64. // Compile the Vertex Shader into machine code
  65. glCompileShader(vertexShader);
  66. // Create Fragment Shader Object and get its reference
  67. GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  68. // Attach Fragment Shader source to the Fragment Shader Object
  69. glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
  70. // Compile the Vertex Shader into machine code
  71. glCompileShader(fragmentShader);
  72. // Create Shader Program Object and get its reference
  73. GLuint shaderProgram = glCreateProgram();
  74. // Attach the Vertex and Fragment Shaders to the Shader Program
  75. glAttachShader(shaderProgram, vertexShader);
  76. glAttachShader(shaderProgram, fragmentShader);
  77. // Wrap-up/Link all the shaders together into the Shader Program
  78. glLinkProgram(shaderProgram);
  79. // Delete the now useless Vertex and Fragment Shader objects
  80. glDeleteShader(vertexShader);
  81. glDeleteShader(fragmentShader);
  82. // Vertices coordinates
  83. GLfloat vertices[] =
  84. {
  85. 1.0f, 0.0f, 0.0f, // Lower left corner
  86. -1.0f, 0.0f, 0.0f, // Lower right corner
  87. 0.0f, 1.73205080757f, 0.0f // Upper corner
  88. };
  89. // Create reference containers for the Vartex Array Object and the Vertex Buffer Object
  90. GLuint VAO, VBO;
  91. // Generate the VAO and VBO with only 1 object each
  92. glGenVertexArrays(1, &VAO);
  93. glGenBuffers(1, &VBO);
  94. // Make the VAO the current Vertex Array Object by binding it
  95. glBindVertexArray(VAO);
  96. // Bind the VBO specifying it's a GL_ARRAY_BUFFER
  97. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  98. // Introduce the vertices into the VBO
  99. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  100. // Configure the Vertex Attribute so that OpenGL knows how to read the VBO
  101. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
  102. // Enable the Vertex Attribute so that OpenGL knows to use it
  103. glEnableVertexAttribArray(0);
  104. // Bind both the VBO and VAO to 0 so that we don't accidentally modify the VAO and VBO we created
  105. glBindBuffer(GL_ARRAY_BUFFER, 0);
  106. glBindVertexArray(0);
  107. glm::vec3 cam = glm::vec3(0.0f,0.0f,0.0f);
  108. glm::mat4 model = glm::mat4(1.0f);
  109. glm::mat4 view = glm::lookAt(cam,glm::vec3(cam.x,cam.y,cam.z-3.0f),glm::vec3(0.0f,1.0f,0.0f));
  110. //view = glm::translate(view, cam);
  111. glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)SCREEN_WIDTH/(float)SCREEN_HEIGHT, 0.1f, 100.0f);
  112. // Main while loop
  113. while (!glfwWindowShouldClose(window))
  114. {
  115. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
  116. glfwSetWindowShouldClose(window, true);
  117. }
  118. if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) cam.z-=0.01f;
  119. if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) cam.z+=0.01f;
  120. if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) cam.x-=0.01f;
  121. if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) cam.x+=0.01f;
  122. if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) cam.y-=0.01f;
  123. if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) cam.y+=0.01f;
  124. std::cout << cam.x << " , " << cam.y << " , " << cam.z << std::endl;
  125. model = glm::mat4(1.0f);
  126. view = glm::lookAt(cam,glm::vec3(cam.x,cam.y,cam.z-3.0f),glm::vec3(0.0f,1.0f,0.0f));
  127. //view = glm::translate(view, cam);
  128. proj = glm::perspective(glm::radians(45.0f), (float)SCREEN_WIDTH/(float)SCREEN_HEIGHT, 0.1f, 100.0f);
  129. int modelLoc = glGetUniformLocation(shaderProgram, "model");
  130. glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
  131. int viewLoc = glGetUniformLocation(shaderProgram, "view");
  132. glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
  133. int projLoc = glGetUniformLocation(shaderProgram, "proj");
  134. glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj));
  135. glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
  136. // Clean the back buffer and assign the new color to it
  137. glClear(GL_COLOR_BUFFER_BIT);
  138. // Tell OpenGL which Shader Program we want to use
  139. glUseProgram(shaderProgram);
  140. // Bind the VAO so OpenGL knows to use it
  141. glBindVertexArray(VAO);
  142. // Draw the triangle using the GL_TRIANGLES primitive
  143. glDrawArrays(GL_TRIANGLES, 0, 3);
  144. // Swap the back buffer with the front buffer
  145. glfwSwapBuffers(window);
  146. // Take care of all GLFW events
  147. glfwPollEvents();
  148. }
  149. // Delete all the objects we've created
  150. glDeleteVertexArrays(1, &VAO);
  151. glDeleteBuffers(1, &VBO);
  152. glDeleteProgram(shaderProgram);
  153. // Delete window before ending the program
  154. glfwDestroyWindow(window);
  155. // Terminate GLFW before ending the program
  156. glfwTerminate();
  157. return 0;
  158. }

字符串

aurhwmvo

aurhwmvo1#

更改:gl_Position = model * view * proj * vec4(aPos, 1.0)));
至:gl_Position = proj * view * model * vec4(aPos, 1.0);
工作.有点奇怪,但感谢user 253751!

相关问题