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

时间:2014-02-01 13:39:37

标签: c++ visual-studio opengl glfw sdl-2

我目前正在学习使用C ++的OpenGL,而且我已经创建了一个可以走动的3D空间。我不是全新的GL,但我已经习惯了LWJGL和因此不太熟悉C ++库。我使用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似乎能够找到我尝试加载的图像但仍然 - 每当我尝试运行代码时,我得到一个&# 34; 0x001BFDBE&#34;处理未处理的异常其中有一个&#34;访问冲突读取位置0x7EF51000&#34;。

有谁知道为什么会这样?我没有正确加载图像吗?

在主类中,我只需通过&#34; Texture * crate = new Texture(&#34; crate.png&#34;);&#34;创建一个新纹理。在主循环中,我尝试 - > gt; apply()它。

我不知道这个错误可能来自哪里。非常感谢帮助。

1 个答案:

答案 0 :(得分:1)

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

BTW:对于OpenGL,你的纹理类是一种反模式。由于纹理对象绑定到OpenGL上下文,但OpenGL上下文可以在运行时反弹,切换等,因此可以在与析构函数不同的OpenGL上下文中调用Texture类构造函数。因此,您可能想要引用该类中使用的OpenGL上下文。这引起了下一个问题:纹理可以在OpenGL上下文之间共享,所以你必须实际跟踪,哪个OpenGL上下文共享纹理命名空间(很难,因为取决于操作系统,这个连接可以随时创建)而不是跟踪单个OpenGL上下文,您必须跟踪纹理所在的整个OpenGL上下文集。