OpenGL texture loading with SDL

10,469

I use the SOIL library, http://www.lonesock.net/soil.html,

It's a very easy to use OpenGL texture loader library, you don't have to worry about the image format or make any loading code yourself, it will do it all for you.

Loading a texture is as easy as this:

int textureID = SOIL_load_OGL_texture("img.png", SOIL_LOAD_AUTO, 
    SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);
if(textureID == 0) { cout << "Failed to load texture!" << endl };
Share:
10,469
arman_aegit
Author by

arman_aegit

Truly amateur in coding, my professional field is something totally different: Medicine. But I code for fun :) I do love programing ...

Updated on June 04, 2022

Comments

  • arman_aegit
    arman_aegit almost 2 years

    I have started learning OpenGL using NeHe tutorials for a little while.This is the code for lesson 6.It should load a bmp image and use it as texture for the cube I'm drawing.But It doesn't work properly and the cube remains white at all.The function for loading the image is "loadGLTextures".Can anyone help? My image bit depth is 24.I'm working with Visual Studio 2010.

    #include <Windows.h>
    #include <stdio.h>
    #include <gl\GL.h>
    #include <gl\GLU.h>
    #include <SDL\SDL.h>
    
    
    #pragma comment(lib , "SDL.lib")
    #pragma comment(lib , "SDLmain.lib")
    #pragma comment(lib , "OPENGL32.lib")
    #pragma comment(lib , "glu32.lib")
    
    
    //height , width and bit depth
    #define SCREEN_WIDTH 800
    #define SCREEN_HEIGHT 600
    #define SCREEN_BPP 16
    
    //SDL surface
    SDL_Surface* surface;
    
    //Texture storage.
    GLuint texture[1];
    
    //Quit func.
    void Quit(int returnCode)
    {
        SDL_Quit();
        exit(returnCode);
    }
    
    //This function will load a bitmap image.
    bool loadGLTextures(void)
    {
        SDL_Surface* textureImage;
        textureImage = SDL_LoadBMP("123.bmp");
        if(!textureImage)
        {
            fprintf(stderr , "Couldn't load %s.\n" , "123.bmp");
            return false;
        }
    
        else
        {
            //Create the texture.
            glGenTextures(1 , &texture[0]);
    
            //Typical texture generation using data from the bitmap.
            glBindTexture(GL_TEXTURE_2D , texture[0]);
    
            //Generate the texture.
            glTexImage2D(GL_TEXTURE_2D , 0 , 3 , textureImage->w , 
                textureImage->h , 0 , GL_RGB , GL_UNSIGNED_BYTE , 
                textureImage->pixels);
    
            //Linear filtering.
            glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR);
    
            //Free up the memory.
            if(textureImage)
                SDL_FreeSurface(textureImage);
    
            return true;
        }
    
    }
    
    //All of the drawing goes throw this.
    int drawGLScene(void)
    {
        static float xrot = 0 , yrot = 0 , zrot = 0;
        //Clear screen and depth buffer.
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
    
        glTranslatef(0.0f , 0.0f , -5.0f);
        glRotatef(xrot , 1.0f , 0.0f , 0.0f);
        glRotatef(yrot , 0.0f , 1.0f , 0.0f);
        glRotatef(zrot , 0.0f , 0.0f  ,1.0f);
    
        //Select the texture.
        glBindTexture(GL_TEXTURE_2D , texture[0]);
    
        glBegin(GL_QUADS);
        //Front:
        //Bottom left of the texture and quad.
        glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
        //Bottom right fo the texture and quad.
        glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , 1.0f);
        //Top right of the texture and quad.
        glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
        //Top left of the texture and quad.
        glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
    
        //Back:
        //Bottom left of the texture and quad.
        glTexCoord2f(0.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
        //Bottom right of the texture and quad.
        glTexCoord2f(1.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
        //Top right of the texture and the quad.
        glTexCoord2f(1.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
        //Top left of the texture and the quad.
        glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
    
        //Top:
        //Top right of the texture and quad.
        glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
        //Top left of the texture and quad.
        glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
        //Bottom left of the texture and quad.
        glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
        //Bottom right of the texture and quad.
        glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
    
        //Bottom:
        //Top left of the texture and quad.
        glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
        //Bottom left of the texture and quad.
        glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
        //Bottom right of the texture and quad.
        glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
        //Top right of the texture and quad.
        glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , -1.0f , 1.0f);
    
        //Right:
        //Bottom right of the texture and quad.
        glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
        //Top right of the texture and quad.
        glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
        //Top left of the texture and quad.
        glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
        //Bottom left of the texture and quad.
        glTexCoord2f(0.0f , 0.0f); glVertex3f(1.0f , -1.0f , 1.0f);
    
        //Left:
        //Bottom left of the texture and quad.
        glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
        //Bottom right of the texture and quad.
        glTexCoord2f(1.0f , 0.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
        //Top right of the texture and quad.
        glTexCoord2f(1.0f , 1.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
        //Top left of the texture and quad.
        glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
        glEnd();
    
        SDL_GL_SwapBuffers();
    
        xrot += 0.1;
        yrot += 0.1;
        zrot += 0.1;
    
        return true;
    
    }
    
    //This function will reset our viewport after a windows resize.
    int resizeWindow(int width , int height)
    {
        //Height / width ration.
        float ratio;
    
        //Protect against a division by zero.
        if(height == 0)
            height = 1;
    
        ratio = width / height;
    
        //Setup viewport
        glViewport(0 , 0 , width , height);
    
        //Change to the projection matrix and reset it.
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
    
        //set perspective.
        gluPerspective(45.0f , ratio , 0.1f , 100.0f);
    
        //Change to model view matrix and reset it.
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        return true;
    }
    
    //Toggle fullScreen.
    void toggleFullscreen(SDL_Surface* screen)
    {
        int videoFlags = screen->flags;
        (videoFlags & SDL_FULLSCREEN) == SDL_FULLSCREEN ? videoFlags ^= SDL_FULLSCREEN : videoFlags |= SDL_FULLSCREEN;//NICE!!
        screen = SDL_SetVideoMode(SCREEN_WIDTH , SCREEN_HEIGHT , SCREEN_BPP , videoFlags);
        resizeWindow(surface->w , surface->h);
        drawGLScene();
    }
    
    //OpenGL initialization.
    int initGL(void)
    {
        if(!loadGLTextures())
            return false;
    
        glShadeModel(GL_SMOOTH);
        glEnable(GL_TEXTURE_2D); //Enable texture mapping.
        glClearColor(0.0f , 0.0f , 0.0f , 0.5f);
        glClearDepth(1.0f);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        //Nice perspective.
        glHint(GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST);
        return true;
    }
    
    //This func will handle any key inputs.
    void handleKeyPress(SDL_keysym* keysym)
    {
        switch(keysym->sym)
        {
        case SDLK_ESCAPE:
                Quit(0);
                break;
        case SDLK_F1:
            toggleFullscreen(surface);
            break;
        case SDLK_r:
            drawGLScene();
            break;
        default:
            break;
        }
        return;
    }
    
    
    int main(int argc , char* argv[])
    {
        //Flags to pass to SDL_SetVideoMode : awsome!! ints can be compiled.
        int videoFlags;
        //Event
        SDL_Event event;
        //Holds information about display.
        const SDL_VideoInfo* videoInfo;
        //Is window active?
        bool isActive = true;
    
        //SDL initialization.
        if(SDL_Init(SDL_INIT_VIDEO) < 0)
        {
            fprintf(stderr , "SDL video initialization failed : %s\n" , SDL_GetError());
            Quit(1);
        }
    
        //Fetch the video info.
        videoInfo = SDL_GetVideoInfo();
    
        if(!videoInfo)
        {
            fprintf(stderr , "Video query failed : %s\n" , SDL_GetError());
            Quit(1);
        }
    
        //Add flags to pass to SDL_SetVideoMode.
        videoFlags = SDL_OPENGL;              //Enable OpenGL in SDL.
        videoFlags |= SDL_GL_DOUBLEBUFFER;    //Enable double buffering.
        videoFlags |= SDL_HWPALETTE;          //Store the palette in hardware.
        videoFlags |= SDL_RESIZABLE;          //Enable window resizing.
    
        //This checks to see if surfaces can be stored in hardware.
        videoInfo->hw_available ? videoFlags |= SDL_HWSURFACE : SDL_SWSURFACE;
    
        //This checks if harware blits can be done.
        if(videoInfo->blit_hw)
            videoFlags |= SDL_HWACCEL;
    
        //Set OpenGL double buffering.
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER , 1);
    
        surface = SDL_SetVideoMode(SCREEN_WIDTH , SCREEN_HEIGHT , 16 , videoFlags);
    
        //verify the surface.
        if(!surface)
        {
            fprintf(stderr , "Video mode set failed : %s\n" , SDL_GetError());
            Quit(1);
        }
    
        SDL_WM_SetCaption("OpenGL-Sample" , 0);
    
        //initialize OpenGL
        if(initGL() == false)
        {
            fprintf(stderr , "Could not initialize OpenGL.\n");
            Quit(1);
        }
    
        //Main loop
        while(1)
        {
            //Handle the events in the queue.
            if(SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                case SDL_ACTIVEEVENT:
                    if(event.active.gain == 0)
                        isActive = false;
                    else
                        isActive = true;
                    break;
                case SDL_VIDEORESIZE:
                    //Handle resize event.
                    surface = SDL_SetVideoMode(event.resize.w , event.resize.h , SCREEN_BPP , videoFlags);
                    if(!surface)
                    {
                        fprintf(stderr , "Could not get a surface after resize : %s\n" , SDL_GetError());
                        Quit(1);
                    }
                    resizeWindow(event.resize.w , event.resize.h);
                    break;
                case SDL_KEYDOWN:
                    handleKeyPress(&event.key.keysym);
                    break;
                case SDL_QUIT:
                    Quit(0);
                default:
                    break;
                }
            }
            if(isActive)
                drawGLScene();
        }
    
    }
    

    This is the image I'm trying to load.

  • arman_aegit
    arman_aegit about 12 years
    SDL_image's not working too.I have added the image at the end of my question if you want to check it.