SDL2和GLFW3:加载纹理;违反访问

SDL2 and GLFW3: Loading Textures; Access Violation

本文关键字:访问 纹理 加载 GLFW3 SDL2      更新时间:2023-10-16

我目前正在使用C 学习OpenGL,并且我已经创建了一个3D房间来四处走动。我并不是GL的新手,但我习惯了LWJGL和因此,不太熟悉C Libs。我使用glfw3进行输入,窗口等。只需要SDL2(或更确切地说是SDL_IMAGE 2)即可加载PNG图像并将其转换为OpenGL纹理。现在我在texture.cpp中的实现如下:

#include "Texture.h"
#include <glfw3.h>
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
/*The constructor gets the path as a char pointer, the SDL_Image library gets
  initialized, the GLuint tex from the Texture.h is initialized to store the
  pixel data, the image is loaded to a surface and then, after some error-handling,
  the pixeldata is filled in the tex-pointer. After this, the surface gets
  thrown in the trashcan.*/
Texture::Texture(const char *file) {
    IMG_Init(IMG_INIT_PNG); //Initializing the PNG 
    glGenTextures(1, &tex);
    SDL_Surface *img = IMG_Load(file);
    if (img == nullptr) {
        cout << "*ERROR* Image wasn't loaded successfully! *ERROR*" << endl << IMG_GetError() << endl;
        return;
    }
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->w, img->h, 0, GL_RGBA, GL_UNSIGNED_INT, img->pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    SDL_FreeSurface(img);
}
//This function simply makes it easier to apply the texture
void Texture::apply() {
    glBindTexture(GL_TEXTURE_2D, tex);
}
//When the program is done the texture gets deleted
Texture::~Texture() {
    glDeleteTextures(1, &tex);
}

我使用Visual Studio 2013作为IDE,库和标题文件都正确链接,SDL2似乎能够找到我尝试加载的图像,但仍然 - 每当我尝试运行代码时,我都会获得"未手动"0x001bfdbe的例外"说"访问违规位置0x7EF51000"。

有人知道为什么会发生这种情况吗?我不是正确加载图像吗?

在主类中,我只是通过"纹理 *crate = new Texture(" crate.png")创建一个新纹理。在主循环中,我尝试 -> apply()it。

我不知道此错误可能来自何处。帮助非常感谢。

您必须确保初始化sdl_image和OpenGL上下文,并在调用构造函数时可用。这意味着,您必须在SDL和OpenGL初始化后移动new Texture

btw:在OpenGL方面,您的纹理类是一种反图案。由于纹理对象必将与OpenGL上下文相关,但是在运行时可以反弹,切换等openGL上下文,您的Texture类构造函数可以在与destructor不同的OpenGL上下文上调用。因此,您可能会很想引用该类使用的OpenGL上下文。这会引起下一个问题:可以在OpenGL上下文之间共享纹理,因此您必须实际跟踪,哪些OpenGL上下文共享纹理名称空间(很难,因为可以随时创建此连接),而不是跟踪单个OpenGL上下文您必须跟踪整个OpenGL上下文。