OpenGL纹理加载异常:颜色错误、纹理偏移问题求助
OpenGL纹理加载异常:颜色错误与纹理偏移问题
使用OpenGL结合SDL2加载图像时,多张图片均出现颜色显示错误、纹理偏移的情况。参照LearnOpenGL教程实现,甚至直接复制示例代码仍未解决问题。怀疑问题与OpenGL状态机有关,或是自身实现存在疏漏。目前已将图像加载逻辑封装到TextureManager类中,不确定是否是该类的实现导致异常。
显示输出:存在明显的颜色失真与纹理位置偏移现象
主函数代码
#include <iostream> #include <Window/Window.hpp> #include <Shaders/Shader.hpp> #include <Managers/TextureManager.hpp> int main(int argc, char* argv[]) { Kaim::Window window("Game", 1080, 720); Kaim::Shader shader("Assets/shaders/basic/vertex.glsl", "Assets/shaders/basic/fragment.glsl"); Kaim::Manager::TextureManager textureManager; float vertices[] = { // positions // colors // texture coords 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left }; unsigned int indices[] = { 0, 1, 3, // first triangle 1, 2, 3 // second triangle }; unsigned int VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); // texture coord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glEnableVertexAttribArray(2); textureManager.LoadTexture("box", "Assets/images/Box.png"); while (window.IsOpen()) { GLenum error = glGetError(); SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { window.Close(); } } window.Update(0.2f, 0.3f, 0.3f, 1.0f); shader.use(); textureManager.Bind("box"); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); window.Render(); } std::cout << "Hello, World!" << std::endl; return 0; }
TextureManager.cpp代码
#include "TextureManager.hpp" namespace Kaim { namespace Manager { TextureManager::TextureManager() { INFO("Texture Manager Created"); } TextureManager::~TextureManager() { INFO("Texture Manager Destroyed"); } void TextureManager::LoadTexture(std::string name, std::string path) { for(auto const& [key, val] : textures) { if (val.path == path) { WARNING("Texture with path %s already exists", path.c_str()); return; } if(key == name) { WARNING("Texture with name %s already exists", name.c_str()); return; } } SDL_Surface* surface = IMG_Load(path.c_str()); if (surface == NULL) { ERROR("Failed to load image: %s", IMG_GetError()); return; } unsigned int texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); // get number of channels in the SDL surface GLint nOfColors = surface->format->BytesPerPixel; unsigned int format; if (nOfColors == 4) // contains an alpha channel { if (surface->format->Rmask == 0x000000ff) format = GL_RGBA; else format = GL_BGRA; } else if (nOfColors == 3) // no alpha channel { if (surface->format->Rmask == 0x000000ff) format = GL_RGB; else format = GL_BGR; } else { ERROR("Image is not truecolor"); return; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // set texture filtering parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, format, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels); glGenerateMipmap(GL_TEXTURE_2D); SDL_FreeSurface(surface); Texture textureStruct; textureStruct.id = texture; textureStruct.path = path; textures[name] = textureStruct; } void TextureManager::Bind(std::string path) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[path].id); } void TextureManager::Unbind() { glBindTexture(GL_TEXTURE_2D, 0); } }}
顶点着色器代码
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; layout (location = 2) in vec2 aTexCoord; out vec3 ourColor; out vec2 TexCoord; void main() { gl_Position = vec4(aPos, 1.0); ourColor = aColor; TexCoord = vec2(aTexCoord.x, aTexCoord.y); }
片段着色器代码
#version 330 core out vec4 FragColor; in vec3 ourColor; in vec2 TexCoord; // texture samplers uniform sampler2D texture1; void main() { FragColor = texture(texture1, TexCoord); }
Window初始化类代码
#include "Window.hpp" namespace Kaim { Window::Window(std::string title, int width, int height) { SDL_Init(SDL_INIT_EVERYTHING); IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG); this->width = width; this->height = height; window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); if (window == NULL) { ERROR("Failed to create window: %s", SDL_GetError()); open = false; return; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); context = SDL_GL_CreateContext(window); if (glewInit() != GLEW_OK) { ERROR("OpenGL Could not Initalize"); open = false; } glewExperimental = GL_TRUE; glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, width, height); open = true; } void Window::Update(float r, float g, float b, float a) { glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void Window::Render() { SDL_GL_SwapWindow(window); } SDL_Window* Window::GetWindow() { return this->window; } bool Window::IsOpen() { return this->open; } void Window::Close() { this->open = false; } Window::~Window() { SDL_GL_DeleteContext(context); SDL_DestroyWindow(this->window); IMG_Quit(); SDL_Quit(); } }
内容的提问来源于stack exchange,提问作者Kaimetsu
相关产品推荐
相关产品推荐

