OpenGL中的纹理显示为单一颜色吗?

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

Textures in OpenGL show up as single colors?

问题

这段代码是关于使用OpenGL加载纹理的教程。作者遇到了一个问题,纹理应该显示为一个图片,但实际上显示为一个空白的米色矩形。作者已经尝试了多种方法,包括复制教程提供的源代码,但问题仍然存在。作者想知道为什么会出现这种情况。

这里是作者期望的效果:
OpenGL中的纹理显示为单一颜色吗?

这里是实际效果:
OpenGL中的纹理显示为单一颜色吗?

需要进一步检查代码和资源文件以解决问题。

英文:

I'm following this tutorial for using OpenGL https://learnopengl.com/Getting-started/Textures and everything was going great until I got to textures when for some reason instead of giving me the texture I expected, it seems to just give me a blank beige rectangle and I'm not sure why.

I tried several variations and eventually resorted to just copying the source code provided on the site https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.1.textures/textures.cpp and the problem still persisted. Why am I getting just a beige rectangle instead of the correct picture?

Here's what I expect:

OpenGL中的纹理显示为单一颜色吗?

Here's what I get:

OpenGL中的纹理显示为单一颜色吗?

Here's the code: (you can find stb_image.h here

main.cpp:

  1. #include <glad/glad.h>
  2. #include <GLFW/glfw3.h>
  3. #define STB_IMAGE_IMPLEMENTATION
  4. #include "stb_image.h"
  5. #include "shader_s.h"
  6. #include <iostream>
  7. void framebuffer_size_callback(GLFWwindow* window, int width, int height);
  8. void processInput(GLFWwindow *window);
  9. // settings
  10. const unsigned int SCR_WIDTH = 800;
  11. const unsigned int SCR_HEIGHT = 600;
  12. int main()
  13. {
  14. // glfw: initialize and configure
  15. // ------------------------------
  16. glfwInit();
  17. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  18. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  19. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  20. #ifdef __APPLE__
  21. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  22. #endif
  23. // glfw window creation
  24. // --------------------
  25. GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
  26. if (window == NULL)
  27. {
  28. std::cout << "Failed to create GLFW window" << std::endl;
  29. glfwTerminate();
  30. return -1;
  31. }
  32. glfwMakeContextCurrent(window);
  33. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  34. // glad: load all OpenGL function pointers
  35. // ---------------------------------------
  36. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
  37. {
  38. std::cout << "Failed to initialize GLAD" << std::endl;
  39. return -1;
  40. }
  41. // build and compile our shader zprogram
  42. // ------------------------------------
  43. Shader ourShader("./shaders/shader.vs", "./shaders/shader.fs");
  44. // set up vertex data (and buffer(s)) and configure vertex attributes
  45. // ------------------------------------------------------------------
  46. float vertices[] = {
  47. // positions // colors // texture coords
  48. 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
  49. 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
  50. -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
  51. -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
  52. };
  53. unsigned int indices[] = {
  54. 0, 1, 3, // first triangle
  55. 1, 2, 3 // second triangle
  56. };
  57. unsigned int VBO, VAO, EBO;
  58. glGenVertexArrays(1, &VAO);
  59. glGenBuffers(1, &VBO);
  60. glGenBuffers(1, &EBO);
  61. glBindVertexArray(VAO);
  62. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  63. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  64. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  65. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
  66. // position attribute
  67. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
  68. glEnableVertexAttribArray(0);
  69. // color attribute
  70. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
  71. glEnableVertexAttribArray(1);
  72. // texture coord attribute
  73. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
  74. glEnableVertexAttribArray(2);
  75. // load and create a texture
  76. // -------------------------
  77. unsigned int texture;
  78. glGenTextures(1, &texture);
  79. glBindTexture(GL_TEXTURE_2D, texture); // all upcoming GL_TEXTURE_2D operations now have effect on this texture object
  80. // set the texture wrapping parameters
  81. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
  82. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  83. // set texture filtering parameters
  84. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  85. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  86. // load image, create texture and generate mipmaps
  87. int width, height, nrChannels;
  88. // The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
  89. unsigned char *data = stbi_load("./resources/textures/container.jpg", &width, &height, &nrChannels, 0);
  90. if (data)
  91. {
  92. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  93. glGenerateMipmap(GL_TEXTURE_2D);
  94. }
  95. else
  96. {
  97. std::cout << "Failed to load texture" << std::endl;
  98. }
  99. stbi_image_free(data);
  100. // render loop
  101. // -----------
  102. while (!glfwWindowShouldClose(window))
  103. {
  104. // input
  105. // -----
  106. processInput(window);
  107. // render
  108. // ------
  109. glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
  110. glClear(GL_COLOR_BUFFER_BIT);
  111. // bind Texture
  112. glBindTexture(GL_TEXTURE_2D, texture);
  113. // render container
  114. ourShader.use();
  115. glBindVertexArray(VAO);
  116. glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  117. // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
  118. // -------------------------------------------------------------------------------
  119. glfwSwapBuffers(window);
  120. glfwPollEvents();
  121. }
  122. // optional: de-allocate all resources once they've outlived their purpose:
  123. // ------------------------------------------------------------------------
  124. glDeleteVertexArrays(1, &VAO);
  125. glDeleteBuffers(1, &VBO);
  126. glDeleteBuffers(1, &EBO);
  127. // glfw: terminate, clearing all previously allocated GLFW resources.
  128. // ------------------------------------------------------------------
  129. glfwTerminate();
  130. return 0;
  131. }
  132. // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
  133. // ---------------------------------------------------------------------------------------------------------
  134. void processInput(GLFWwindow *window)
  135. {
  136. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
  137. glfwSetWindowShouldClose(window, true);
  138. }
  139. // glfw: whenever the window size changed (by OS or user resize) this callback function executes
  140. // ---------------------------------------------------------------------------------------------
  141. void framebuffer_size_callback(GLFWwindow* window, int width, int height)
  142. {
  143. // make sure the viewport matches the new window dimensions; note that width and
  144. // height will be significantly larger than specified on retina displays.
  145. glViewport(0, 0, width, height);
  146. }

shader_s.h:

  1. #ifndef SHADER_H
  2. #define SHADER_H
  3. #include <glad/glad.h>
  4. #include <string>
  5. #include <fstream>
  6. #include <sstream>
  7. #include <iostream>
  8. class Shader
  9. {
  10. public:
  11. unsigned int ID;
  12. // constructor generates the shader on the fly
  13. // ------------------------------------------------------------------------
  14. Shader(const char* vertexPath, const char* fragmentPath)
  15. {
  16. // 1. retrieve the vertex/fragment source code from filePath
  17. std::string vertexCode;
  18. std::string fragmentCode;
  19. std::ifstream vShaderFile;
  20. std::ifstream fShaderFile;
  21. // ensure ifstream objects can throw exceptions:
  22. vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
  23. fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
  24. try
  25. {
  26. // open files
  27. vShaderFile.open(vertexPath);
  28. fShaderFile.open(fragmentPath);
  29. std::stringstream vShaderStream, fShaderStream;
  30. // read file's buffer contents into streams
  31. vShaderStream << vShaderFile.rdbuf();
  32. fShaderStream << fShaderFile.rdbuf();
  33. // close file handlers
  34. vShaderFile.close();
  35. fShaderFile.close();
  36. // convert stream into string
  37. vertexCode = vShaderStream.str();
  38. fragmentCode = fShaderStream.str();
  39. }
  40. catch (std::ifstream::failure& e)
  41. {
  42. std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;
  43. }
  44. const char* vShaderCode = vertexCode.c_str();
  45. const char * fShaderCode = fragmentCode.c_str();
  46. // 2. compile shaders
  47. unsigned int vertex, fragment;
  48. // vertex shader
  49. vertex = glCreateShader(GL_VERTEX_SHADER);
  50. glShaderSource(vertex, 1, &vShaderCode, NULL);
  51. glCompileShader(vertex);
  52. checkCompileErrors(vertex, "VERTEX");
  53. // fragment Shader
  54. fragment = glCreateShader(GL_FRAGMENT_SHADER);
  55. glShaderSource(fragment, 1, &fShaderCode, NULL);
  56. glCompileShader(fragment);
  57. checkCompileErrors(fragment, "FRAGMENT");
  58. // shader Program
  59. ID = glCreateProgram();
  60. glAttachShader(ID, vertex);
  61. glAttachShader(ID, fragment);
  62. glLinkProgram(ID);
  63. checkCompileErrors(ID, "PROGRAM");
  64. // delete the shaders as they're linked into our program now and no longer necessary
  65. glDeleteShader(vertex);
  66. glDeleteShader(fragment);
  67. }
  68. // activate the shader
  69. // ------------------------------------------------------------------------
  70. void use()
  71. {
  72. glUseProgram(ID);
  73. }
  74. // utility uniform functions
  75. // ------------------------------------------------------------------------
  76. void setBool(const std::string &name, bool value) const
  77. {
  78. glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
  79. }
  80. // ------------------------------------------------------------------------
  81. void setInt(const std::string &name, int value) const
  82. {
  83. glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
  84. }
  85. // ------------------------------------------------------------------------
  86. void setFloat(const std::string &name, float value) const
  87. {
  88. glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
  89. }
  90. private:
  91. // utility function for checking shader compilation/linking errors.
  92. // ------------------------------------------------------------------------
  93. void checkCompileErrors(unsigned int shader, std::string type)
  94. {
  95. int success;
  96. char infoLog[1024];
  97. if (type != "PROGRAM")
  98. {
  99. glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
  100. if (!success)
  101. {
  102. glGetShaderInfoLog(shader, 1024, NULL, infoLog);
  103. std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
  104. }
  105. }
  106. else
  107. {
  108. glGetProgramiv(shader, GL_LINK_STATUS, &success);
  109. if (!success)
  110. {
  111. glGetProgramInfoLog(shader, 1024, NULL, infoLog);
  112. std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
  113. }
  114. }
  115. }
  116. };
  117. #endif

shader.vs:

  1. #version 330 core
  2. layout (location = 0) in vec3 aPos;
  3. layout (location = 1) in vec3 aColor;
  4. layout (location = 2) in vec2 aTexCoord;
  5. out vec3 ourColor;
  6. out vec2 texCoord;
  7. void main()
  8. {
  9. gl_Position = vec4(aPos, 1.0);
  10. ourColor = aColor;
  11. texCoord = aTexCoord;
  12. }

shader.fs

  1. #version 330 core
  2. out vec4 FragColor;
  3. in vec3 ourColor;
  4. in vec2 TexCoord;
  5. uniform sampler2D texture1;
  6. void main()
  7. {
  8. FragColor = texture(texture1, TexCoord);
  9. }

And the texture image: https://learnopengl.com/img/textures/container.jpg

The directory structure:

  1. main.cpp
  2. stb_image.h
  3. shader_s.h
  4. resources/textures/
  5. container.jpg
  6. shaders/
  7. shader.fs
  8. shader.vs

I can't give you the glad headers/source, they're machine dependent, but there's a tutorial for installing them on the same site: https://learnopengl.com/Getting-started/Creating-a-window

I know the site is geared towards doing this stuff in windows with VS, but I've been doing it all in linux, and so far it was all working great, until now...

答案1

得分: 3

问题出在纹理坐标上,它们在片段着色器中未正确传递,每个片段的坐标都是 (0, 0)。GLSL 区分大小写,顶点着色器的输出与片段着色器的输入通过名称连接。而在你的顶点着色器中,纹理坐标的输出变量名称是 texCoord

  1. out vec2 texCoord;

而对应的片段着色器中的输入变量名称应该是 texCoord

  1. in vec2 texCoord;

请修改片段着色器并将 TexCoord 重命名为 texCoord

  1. #version 330 core
  2. out vec4 FragColor;
  3. in vec3 ourColor;
  4. in vec2 texCoord;
  5. uniform sampler2D texture1;
  6. void main()
  7. {
  8. FragColor = texture(texture1, texCoord);
  9. }
英文:

The problem is the texture coordinates, which do not arrive correctly in the fragment shader and are (0, 0) for each fragment. glsl is case-sensitive, and the output of the vertex shader is linked to the input of the fragment shader by its name. While the name of the output variable for the texture coordinates in your vertex shader is texCoord,

  1. out vec2 texCoord;

the name of the corresponding input variable for the texture coordinates in your fragment shader is TexCoord

  1. in vec2 TexCoord;

Change the fragment shader and rename TexCoord to texCoord:

  1. #version 330 core
  2. out vec4 FragColor;
  3. in vec3 ourColor;
  4. in vec2 texCoord;
  5. uniform sampler2D texture1;
  6. void main()
  7. {
  8. FragColor = texture(texture1, texCoord);
  9. }

huangapple
  • 本文由 发表于 2023年6月5日 07:41:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76402844.html
匿名

发表评论

匿名网友

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

确定