Loading Texture (SDL surface to OpenGL)

Started by
3 comments, last by Aroidzap 11 years, 2 months ago

Hi, I can't figure out why this code throws me an exception. Can you help me?


TEXTURE LoadTexture(const char* file)
{
    TEXTURE texture;       // GLuint texture, int width, int height

    if ( IMG_Load(file) )
    {
        SDL_Surface* surface = IMG_Load(file);
        GLuint tex;
        
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);

THROWS EXCEPTION at this point -> glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, surface->w, surface->h);

        glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, 
                         surface->pixels);
        
        glGenerateMipmap(GL_TEXTURE_2D);


        GLfloat maxAniso;
        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);


        texture.texture=tex;
        texture.width=surface->w;
        texture.height=surface->h;


        SDL_FreeSurface(surface);
    }
    else
    {
        texture.texture=0;
        texture.width=0;
        texture.height=0;
    }
    return texture;
}
 
Advertisement

Why don't you use a single glTexImage2D() instead of your calls to glTexStorage2D() and glTexSubImage2D()?

As far as i know, glTexSubImage2D is useful if you want to change part of a texture after you've created it. You don't need to use it when creating the texture if you already have the data.

And i'm not sure, but you may want to set the texture parameters (glTexParameteri() calls) before calling glTexture2D() (or your calls to glTexStorage2D() and glTexSubImage2D()).

But i've never used SDL, so it might be different to you.

Will glTexImage2D work right for mipmapping? And one more thing... I just don't get, why this code works in one my app and in another not :/

Yes it generates them.Here's a sample code i use


//Up to this point you should have an array with the texture data. I don't know if the SDL_surface works the same
//Also the var image is a GLuint variable that holds a texture ID

    //Generate a GL texture
    glGenTextures(1, &image);

    //Bind GL texture
    glBindTexture(GL_TEXTURE_2D, image);

    //Sets wrapping style
    //I use GL_REPEAT here, but you can use GL_CLAMP_TO_EDGE, GL_CLAMP is deprecated
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

      //Sets mag / min filters
      //The TF_NO_FILTER, etc are just enums i made for selecting the filter
      switch(this->filter)
      {

      case TF_NO_FILTER:
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
          break;

      case TF_BILINEAR:
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
          break;

      //The this->mipmapMaxLevel is just the maximum level of mipmap to create
      //If it is 4, 4 levels of mipmaps will be created
      case TF_BILINEAR_MIPMAP:
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, this->mipmapMaxLevel);
          break;

      case TF_TRILINEAR:
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, this->mipmapMaxLevel);
          break;

      }

    //VAR: The image format
    //You should ignore this, since your texture may have a different data format
    uint32 format = 0;

      if(imageFormat == 0)
      format = GL_RGB;
      else if(imageFormat == 1)
      format = GL_RGBA;

    //Build the texture
    glTexImage2D(GL_TEXTURE_2D,
                 0,
                 GL_RGBA,     //This is the internal format in which OpenGL will store the texture
                 pData.width,  //Your image's width
                 pData.height, //Your image's height
                 0,
                 format,           //Your texture's data format (GL_RGB, GL_RGBA, etc)
                 GL_UNSIGNED_BYTE,  //The size of each color component
                 &imageData[0]);  //A pointer to your texture data (my was imageData)

      //Create mipmaps
      //Again only call this if you're creating mipmaps
      switch (this->filter)
      {

      case TF_BILINEAR_MIPMAP:
      case TF_TRILINEAR:
          glGenerateMipmap(GL_TEXTURE_2D);
          break;

      }

    //Cleanup here...

I don't know why your code sometimes don't work though...

Also, you are using anisotropic filtering, but i've never used that, so this code might not be exactly what you need.

Hope it helps.

Well...I've found that problem... I'm using GLEW... and I've forgotten to call glewInit(); rolleyes.gif

This topic is closed to new replies.

Advertisement