Drawing textures from an SDL_Surface: BMP image > Surface > Texture > Quad

Hello,

I am trying to draw a 2D bitmap image to the screen (or defined space on the window) in Opengl context. I am using the SDL and SDL_Image libraries. I’m getting an unhandled win32 exception when I run the code posted below. I think I also need to draw the quad where the texture will go on the screen (buffer), but have not done that. The program didn’t return this error when I had GL_BITMAP in glTexImage2D instead of BL_UNSIGNED_BYTE, but in that situation the window was blank. What am I doing wrong in this code?


       /*                        Draw                      */




        SDL_Surface *surface;
        char *image_path = "helloworld.bmp";
        int x_pos = 720;
        int y_pos = 450;

        GLuint mTextureWidth = 720;
        GLuint mTextureHeight = 450;

        SDL_Surface *image = IMG_Load ( image_path );
            if ( !image )
            {
                std::cout << "Error Cannot load image";
            }
        // Draws the image on the surface:
        SDL_Rect rcDest = { x_pos, y_pos, 0, 0 };
        SDL_BlitSurface ( image, NULL, surface, &rcDest );
        // something like SDL_UpdateRect(surface, x_pos, y_pos, image->w, image->h); is missing here

        SDL_FreeSurface ( image );

        glEnable(GL_TEXTURE_2D);

        GLuint textures;
        glGenTextures(1, &textures); //Number of textures stored in array name specified

        glBindTexture(GL_TEXTURE_2D, textures);


        /* Map the surface to the texture in video memory */
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 720, 450, 0, GL_RGB, GL_UNSIGNED_BYTE, surface); //GL_BITMAP,

        glBindTexture(GL_TEXTURE_2D, textures);

        //Render texture quad
        glBegin( GL_QUADS );
            glTexCoord2f( 0.f, 0.f ); glVertex2f(           0.f,            0.f );
            glTexCoord2f( 1.f, 0.f ); glVertex2f( mTextureWidth,            0.f );
            glTexCoord2f( 1.f, 1.f ); glVertex2f( mTextureWidth, mTextureHeight );
            glTexCoord2f( 0.f, 1.f ); glVertex2f(           0.f, mTextureHeight );
        glEnd();


        glDisable(GL_TEXTURE_2D);

	//Do I need to create another GL_QUADS here to put the texture on the screen?




        glPopMatrix(); //End rendering phase



        //Draw to screen
        SDL_GL_SwapBuffers();

        SDL_Delay(10); //Hold rendered frame on screen for indicated amount of time

You don’t appear to initialise this variable.

The last argument to glTexImage2D() must be a pointer to the actual pixel data, e.g. surface->pixels for an SDL surface (in some cases, you may need to call SDL_LockSurface() first).

The data must be in the expected format; in this case, 450 rows of 720 pixels at 3 bytes per pixel. Unless you have changed the unpacking parameters with glPixelStorei(), there should be no padding between rows (i.e. surface->pitch must be 2160). Note that if the width wasn’t a multiple of 4, you would need to call glPixelStorei(GL_UNPACK_ALIGNMENT, …), as the default requires each row of pixel data to be aligned to a 4-byte boundary.

Textures whose width or height aren’t a power of two require OpenGL 2.0 or the GL_ARB_texture_non_power_of_two extension.

I got it to work, I never thought OpenGL would be so difficult to write from scratch. I ended up looking up how each individual function works. I may create a function to simplify things or tweak the code if not set up properly. Thanks for the guidance!



   glClear(GL_COLOR_BUFFER_BIT);



        glPushMatrix(); //Start phase

        glOrtho(0,720,480,0,-1,1); //Set the matrix





        /*                        Draw                      */

        char *image_path = "helloworld.bmp";
        int x_pos = 124;
        int y_pos = 124;

        GLuint mTextureWidth = 124;
        GLuint mTextureHeight = 124;

        SDL_Surface *image = IMG_Load ( image_path );
            if ( !image )
            {
                std::cout << "Error Cannot load image";
            }

        float x = 450.0f;
        float y = 150.0f;
        float width = 100.0f;
        float height = 100.0f;

        float iheight = 124.0f;
        float iwidth = 124.0f;


        glEnable(GL_TEXTURE_2D);

        //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        GLuint textures;
        glGenTextures(1, &textures); //Number of textures stored in array name specified

        glBindTexture(GL_TEXTURE_2D, textures);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // Map the surface to the texture in video memory
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 124, 124, 0, GL_RGB, GL_UNSIGNED_BYTE, image->pixels); //GL_BITMAP
        SDL_FreeSurface ( image );
        
        
        glBindTexture(GL_TEXTURE_2D, textures);

        //Render texture quad
        glBegin( GL_QUADS );
        glTexCoord2f( 0.f, 0.f ); glVertex2f(x, y); //Bottom left
        glTexCoord2f( 1.f, 0.f ); glVertex2f(x + iwidth, y); //Bottom right
        glTexCoord2f( 1.f, 1.f ); glVertex2f(x + iwidth, y + iheight); //Top right
        glTexCoord2f( 0.f, 1.f ); glVertex2f(x, y + iheight); //Top left
        glEnd();

        glDisable(GL_TEXTURE_2D);


        glPopMatrix(); //End rendering phase