简体   繁体   中英

SDL2 and GLFW3: Loading Textures; Access Violation

I'm currently learning OpenGL with C++ and I've already created a 3D room to walk around in. I'm not completely new to GL, but I'm used to LWJGL and therefore not really familiar with C++ libs. I use GLFW3 for input, the window etc. and only need SDL2 (or rather SDL_Image 2) for loading PNG Images and converting them to OpenGL textures. Right now my implementation in the Texture.cpp looks like this:

#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);
}

I use Visual Studio 2013 as an IDE, the libraries and header files are all linked correctly, SDL2 seems to be able to find the images I try to load but still - whenever I try to run the code I get an "Unhandled exception at 0x001BFDBE" which say that there was an "Access violation reading location 0x7EF51000".

Does anyone have an idea why this happens? Am I not loading the image correctly?

In the main class I just create a new texture by "Texture *crate = new Texture("crate.png");" and in the main loop I try to ->apply() it.

I have no idea where this error could come from. Help is very appreciated.

You must make sure that SDL_Image and a OpenGL context are initialized and available at the time the constructor is called. Which means, that you must move the new Texture after SDL and OpenGL initialization.

BTW: Your texture class is an anti-pattern when it comes to OpenGL. Since texture objects are bound to OpenGL contexts, but OpenGL contexts can be rebound, switched, etc at runtime your Texture class constructor may be called on a different OpenGL context than the destructor. So you might be tempted to put a reference to the OpenGL context used into the class. Which gives raise to the next problem: Textures can be shared among OpenGL contexts, so you'd have to actually track, which OpenGL context share the texture namespace (hard, because depending on the OS this connection can be created anytime) and instead of tracking a single OpenGL context you have to track the whole set of OpenGL contexts the texture lives in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM