OpenGL:纹理加载

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

我正在创建一个3D金字塔,并加载一个砖墙纹理。
我本来有金字塔的工作,但当我试图添加纹理,它无法加载,我留下了一个黑色的窗口:

  1. #include <iostream>
  2. #include <GL/glew.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. #define STB_IMAGE_IMPLEMENTATION
  8. #include "stb_image.h"
  9. // Vertex shader source code
  10. const char* vertexShaderSource = R"(
  11. #version 330 core
  12. layout(location = 0) in vec3 aPos;
  13. layout(location = 1) in vec3 aColor;
  14. layout(location = 2) in vec2 aTexCoord;
  15. uniform mat4 model;
  16. uniform mat4 view;
  17. uniform mat4 projection;
  18. out vec3 fragColor;
  19. out vec2 TexCoord;
  20. void main()
  21. {
  22. gl_Position = projection * view * model * vec4(aPos, 1.0);
  23. fragColor = aColor;
  24. TexCoord = aTexCoord;
  25. }
  26. )";
  27. // Fragment shader source code
  28. const char* fragmentShaderSource = R"(
  29. #version 330 core
  30. in vec3 fragColor;
  31. in vec2 TexCoord;
  32. out vec4 FragColor;
  33. uniform sampler2D ourTexture;
  34. void main()
  35. {
  36. FragColor = texture(ourTexture, TexCoord);
  37. }
  38. )";
  39. bool firstMouse = true;
  40. float lastX = 400, lastY = 300;
  41. float yaw = -90.0f, pitch = 0.0f;
  42. float fov = 45.0f;
  43. glm::vec3 cameraPos = glm::vec3(0.4f, 0.4f, 0.4f);
  44. glm::vec3 cameraFront = glm::vec3(-0.1f, -0.1f, -1.0f);
  45. glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
  46. glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
  47. glm::mat4 projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 10.0f);
  48. //Key navigation function
  49. void processInput(GLFWwindow* window) {
  50. const float cameraSpeed = 0.001f;
  51. if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
  52. cameraPos += cameraSpeed * cameraFront;
  53. if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
  54. cameraPos -= cameraSpeed * cameraFront;
  55. if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
  56. cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
  57. if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
  58. cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
  59. if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
  60. cameraPos += cameraSpeed * cameraUp;
  61. if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
  62. cameraPos -= cameraSpeed * cameraUp;
  63. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
  64. glfwSetWindowShouldClose(window, true);
  65. view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
  66. }
  67. //Mouse cursor navigation callback function
  68. void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
  69. if (firstMouse) {
  70. lastX = xpos;
  71. lastY = ypos;
  72. firstMouse = false;
  73. }
  74. float xoffset = xpos - lastX;
  75. float yoffset = lastY - ypos; // reversed since y-coordinates range from bottom to top
  76. lastX = xpos;
  77. lastY = ypos;
  78. const float sensitivity = 0.1f;
  79. xoffset *= sensitivity;
  80. yoffset *= sensitivity;
  81. yaw += xoffset;
  82. pitch += yoffset;
  83. // Constrain pitch to avoid flipping
  84. if (pitch > 89.0f)
  85. pitch = 89.0f;
  86. if (pitch < -89.0f)
  87. pitch = -89.0f;
  88. glm::vec3 front;
  89. front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
  90. front.y = sin(glm::radians(pitch));
  91. front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
  92. view = glm::lookAt(cameraPos, cameraPos + front, cameraUp);
  93. }
  94. //Mouse scroll wheel callback function
  95. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
  96. if (fov >= 1.0f && fov <= 45.0f)
  97. fov -= yoffset;
  98. if (fov <= 1.0f)
  99. fov = 1.0f;
  100. if (fov >= 45.0f)
  101. fov = 45.0f;
  102. projection = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 10.0f);
  103. }
  104. int main()
  105. {
  106. // Initialize GLFW
  107. if (!glfwInit())
  108. {
  109. std::cerr << "Failed to initialize GLFW" << std::endl;
  110. return -1;
  111. }
  112. // Configure GLFW
  113. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  114. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  115. // Create a GLFW window
  116. GLFWwindow* window = glfwCreateWindow(800, 600, "Nick's Pyramid", nullptr, nullptr);
  117. if (!window)
  118. {
  119. std::cerr << "Failed to create GLFW window" << std::endl;
  120. glfwTerminate();
  121. return -1;
  122. }
  123. // Make the OpenGL context current
  124. glfwMakeContextCurrent(window);
  125. // Initialize GLEW
  126. if (glewInit() != GLEW_OK)
  127. {
  128. std::cerr << "Failed to initialize GLEW" << std::endl;
  129. return -1;
  130. }
  131. // Define pyramid vertex data (positions and colors)
  132. float vertices[] = {
  133. // Base
  134. -0.5f, -0.5f, -0.5f, 0.3f, 0.7f, 0.9f, 1.0f, 1.0f,
  135. 0.5f, -0.5f, -0.5f, 0.7f, 1.0f, 0.3f, 1.0f, 0.0f,
  136. 0.5f, -0.5f, 0.5f, 0.5f, 0.2f, 0.4f, 0.0f, 0.0f,
  137. -0.5f, -0.5f, 0.5f, 0.5f, 0.2f, 0.4f, 0.0f, 1.0f,
  138. // Front
  139. 0.0f, 0.5f, 0.0f, 0.3f, 0.7f, 0.9f, 0.0f, 0.0f,
  140. -0.5f, -0.5f, 0.5f, 0.7f, 1.0f, 0.3f, 1.0f, 0.0f,
  141. 0.5f, -0.5f, 0.5f, 0.5f, 0.2f, 0.4f, 0.5f, 1.0f,
  142. // Right
  143. 0.0f, 0.5f, 0.0f, 0.3f, 0.7f, 0.9f, 0.0f, 0.0f,
  144. 0.5f, -0.5f, 0.5f, 0.7f, 1.0f, 0.3f, 1.0f, 0.0f,
  145. 0.5f, -0.5f, -0.5f, 0.5f, 0.2f, 0.4f, 0.5f, 1.0f,
  146. // Back
  147. 0.0f, 0.5f, 0.0f, 0.3f, 0.7f, 0.9f, 0.0f, 0.0f,
  148. 0.5f, -0.5f, -0.5f, 0.7f, 1.0f, 0.3f, 1.0f, 0.0f,
  149. -0.5f, -0.5f, -0.5f, 0.5f, 0.2f, 0.4f, 0.5f, 1.0f,
  150. // Left
  151. 0.0f, 0.5f, 0.0f, 0.3f, 0.7f, 0.9f, 0.0f, 0.0f,
  152. -0.5f, -0.5f, -0.5f, 0.7f, 1.0f, 0.3f, 1.0f, 0.0f,
  153. -0.5f, -0.5f, 0.5f, 0.5f, 0.2f, 0.4f, 0.5f, 1.0f
  154. };
  155. //Define texture coordinates
  156. float texCoords[] = {
  157. 0.0f, 0.0f, //Lower-left corner
  158. 1.0f, 0.0f, //Lower-right corner
  159. 0.5f, 1.0f //top-center corner
  160. };
  161. //Generate texture
  162. unsigned int texture;
  163. glGenTextures(1, &texture);
  164. glBindTexture(GL_TEXTURE_2D, texture);
  165. // set the texture wrapping/filtering options (on the currently bound texture object)
  166. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  167. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  168. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  169. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  170. // load and generate the texture
  171. int width, height, nrChannels;
  172. unsigned char* data = stbi_load("brick_texture.jpg", &width, &height, &nrChannels, 0);
  173. if (data)
  174. {
  175. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  176. glGenerateMipmap(GL_TEXTURE_2D);
  177. }
  178. else
  179. {
  180. std::cout << "Failed to load texture" << std::endl;
  181. }
  182. stbi_image_free(data);
  183. // Define pyramid indices
  184. unsigned int indices[] = {
  185. 0, 1, 2, // Base
  186. 0, 2, 3,
  187. 4, 5, 6, // Front
  188. 7, 8, 9, // Right
  189. 10, 11, 12, // Back
  190. 13, 14, 15 // Left
  191. };
  192. // Compile and link shaders
  193. unsigned int vertexShader, fragmentShader, shaderProgram;
  194. vertexShader = glCreateShader(GL_VERTEX_SHADER);
  195. glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
  196. glCompileShader(vertexShader);
  197. fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  198. glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
  199. glCompileShader(fragmentShader);
  200. shaderProgram = glCreateProgram();
  201. glAttachShader(shaderProgram, vertexShader);
  202. glAttachShader(shaderProgram, fragmentShader);
  203. glLinkProgram(shaderProgram);
  204. glDeleteShader(vertexShader);
  205. glDeleteShader(fragmentShader);
  206. // Create Vertex Array Object (VAO), Vertex Buffer Object (VBO), and Element Buffer Object (EBO)
  207. unsigned int VAO, VBO, EBO;
  208. glGenVertexArrays(1, &VAO);
  209. glGenBuffers(1, &VBO);
  210. glGenBuffers(1, &EBO);
  211. // Bind the VAO
  212. glBindVertexArray(VAO);
  213. // Bind and fill vertex buffer
  214. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  215. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  216. // Bind and fill element buffer
  217. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  218. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
  219. // Set vertex attribute pointers
  220. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
  221. glEnableVertexAttribArray(0);
  222. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
  223. glEnableVertexAttribArray(1);
  224. // Enable depth testing
  225. glEnable(GL_DEPTH_TEST);
  226. // Use the shader program
  227. glUseProgram(shaderProgram);
  228. // Set uniform matrices
  229. unsigned int modelLoc = glGetUniformLocation(shaderProgram, "model");
  230. unsigned int viewLoc = glGetUniformLocation(shaderProgram, "view");
  231. unsigned int projectionLoc = glGetUniformLocation(shaderProgram, "projection");
  232. glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
  233. glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
  234. // Set mouse navigation callbacks
  235. glfwSetCursorPosCallback(window, mouse_callback);
  236. glfwSetScrollCallback(window, scroll_callback);
  237. // Main rendering loop
  238. while (!glfwWindowShouldClose(window))
  239. {
  240. // Clear the screen and depth buffer
  241. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  242. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  243. // Define model matrix (rotation)
  244. glm::mat4 model = glm::mat4(1.0f);
  245. float angle = (float)glfwGetTime();
  246. //model = glm::rotate(model, angle, glm::vec3(0.0f, 1.0f, 0.0f));
  247. glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
  248. // Draw the pyramid
  249. glActiveTexture(GL_TEXTURE0); // Activate texture unit 0
  250. glBindTexture(GL_TEXTURE_2D, texture);
  251. glUniform1i(glGetUniformLocation(shaderProgram, "ourTexture"), 0); // Set the texture unit
  252. glBindVertexArray(VAO);
  253. glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, 0);
  254. processInput(window);
  255. glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
  256. glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
  257. // Swap buffers and poll events
  258. glfwSwapBuffers(window);
  259. glfwPollEvents();
  260. }
  261. // Clean up
  262. glDeleteVertexArrays(1, &VAO);
  263. glDeleteBuffers(1, &VBO);
  264. glDeleteBuffers(1, &EBO);
  265. glDeleteProgram(shaderProgram);
  266. glfwTerminate();
  267. return 0;
  268. }

字符串
纹理存在于/resources/textures/下的项目文件夹中,我已经尝试包括整个路径,但仍然没有。控制台似乎也没有产生任何有用的消息.
我做错了什么?

ego6inou

ego6inou1#

您忘记为aTexCoord设置顶点属性指针。

相关问题