SDL_LoadBMP and IMG_Load

Started by
6 comments, last by whalegass 14 years, 10 months ago

#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include "SDL/SDL_image.h" 

#include <stdio.h>

int main(int argc, char *argv[])
{
    SDL_Surface *screen;

    // Slightly different SDL initialization
    if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
        printf("Unable to initialize SDL: %s\n", SDL_GetError());
        return 1;
    }

    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*

    screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL | SDL_FULLSCREEN ); // *changed*
    if ( !screen ) {
		printf("Unable to set video mode: %s\n", SDL_GetError());
		return 1;
	}
	
    // Set the OpenGL state after creating the context with SDL_SetVideoMode

	glClearColor( 0, 0, 0, 0 );
	
	glEnable( GL_TEXTURE_2D ); // Need this to display a texture

    glViewport( 0, 0, 640, 480 );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    glOrtho( 0, 640, 480, 0, -1, 1 );
    
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    
    // Load the OpenGL texture

    GLuint texture; // Texture object handle
    SDL_Surface *surface; // Gives us the information to make the texture
    
    if ( (surface = SDL_LoadBMP("look.bmp")) ) { 
    
        // Check that the image's width is a power of 2
        if ( (surface->w & (surface->w - 1)) != 0 ) {
            printf("warning: image.bmp's width is not a power of 2\n");
        }
    
        // Also check if the height is a power of 2
        if ( (surface->h & (surface->h - 1)) != 0 ) {
            printf("warning: image.bmp's height is not a power of 2\n");
        }
	SDL_Surface* ashhole;
	ashhole = SDL_DisplayFormat( surface ); 
        // Have OpenGL generate a texture object handle for us
        glGenTextures( 1, &texture );
    
        // Bind the texture object
        glBindTexture( GL_TEXTURE_2D, texture );
        
        // Set the texture's stretching properties
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        
        // Edit the texture object's image data using the information SDL_Surface gives us
        glTexImage2D( GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0, 
                      GL_BGR, GL_UNSIGNED_BYTE, surface->pixels );
    } 
    else {
        printf("SDL could not load image.bmp: %s\n", SDL_GetError());
        SDL_Quit();
        return 1;
    }    
    
    // Free the SDL_Surface only if it was successfully created
    if ( surface ) { 
        SDL_FreeSurface( surface );
    }
    
    // Clear the screen before drawing
	glClear( GL_COLOR_BUFFER_BIT );
    
    // Bind the texture to which subsequent calls refer to
    glBindTexture( GL_TEXTURE_2D, texture );

    glBegin( GL_QUADS );
        // Top-left vertex (corner)
        glTexCoord2i( 0, 0 );
        glVertex3f( 100, 100, 0 );
    
        // Bottom-left vertex (corner)
        glTexCoord2i( 1, 0 );
        glVertex3f( 228, 100, 0 );
    
        // Bottom-right vertex (corner)
        glTexCoord2i( 1, 1 );
        glVertex3f( 228, 228, 0 );
    
        // Top-right vertex (corner)
        glTexCoord2i( 0, 1 );
        glVertex3f( 100, 228, 0 );
    glEnd();
	
    SDL_GL_SwapBuffers();
    
    // Wait for 3 seconds to give us a chance to see the image
    SDL_Delay(3000);
    
    // Now we can delete the OpenGL texture and close down SDL
    glDeleteTextures( 1, &texture );
    
    SDL_Quit();
    
	return 0;
}



I am testing a bit of code from wikipedia and there is something I don't understand. The program loads some bitmaps right and some just draw rubbish. And all png's I tried were rubbish. There are no errors or something. Any ideas, men?
Advertisement
That code appears to be setup to only load BMP images. If want to load other format like PNG, you need to swap SDL_LoadBMP() for IMG_Load() which can use PNGs and Jpegs among others.

#include "SDL/SDL.h"#include "SDL/SDL_opengl.h"#include "SDL/SDL_image.h" #include <stdio.h>int main(int argc, char *argv[]){    SDL_Surface *screen;    // Slightly different SDL initialization    if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {        printf("Unable to initialize SDL: %s\n", SDL_GetError());        return 1;    }    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*    screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL | SDL_FULLSCREEN ); // *changed*    if ( !screen ) {		printf("Unable to set video mode: %s\n", SDL_GetError());		return 1;	}	    // Set the OpenGL state after creating the context with SDL_SetVideoMode	glClearColor( 0, 0, 0, 0 );		glEnable( GL_TEXTURE_2D ); // Need this to display a texture    glViewport( 0, 0, 640, 480 );    glMatrixMode( GL_PROJECTION );    glLoadIdentity();    glOrtho( 0, 640, 480, 0, -1, 1 );        glMatrixMode( GL_MODELVIEW );    glLoadIdentity();        // Load the OpenGL texture    GLuint texture; // Texture object handle    SDL_Surface *surface; // Gives us the information to make the texture        if ( (surface = IMG_Load("look.bmp")) ) {   //Changed SDL_LoadBMP() to IMG_Load()            // Check that the image's width is a power of 2        if ( (surface->w & (surface->w - 1)) != 0 ) {            printf("warning: image.bmp's width is not a power of 2\n");        }            // Also check if the height is a power of 2        if ( (surface->h & (surface->h - 1)) != 0 ) {            printf("warning: image.bmp's height is not a power of 2\n");        }	SDL_Surface* ashhole;	ashhole = SDL_DisplayFormat( surface );         // Have OpenGL generate a texture object handle for us        glGenTextures( 1, &texture );            // Bind the texture object        glBindTexture( GL_TEXTURE_2D, texture );                // Set the texture's stretching properties        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );                // Edit the texture object's image data using the information SDL_Surface gives us        glTexImage2D( GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0,                       GL_BGR, GL_UNSIGNED_BYTE, surface->pixels );    }     else {        printf("SDL could not load image.bmp: %s\n", SDL_GetError());        SDL_Quit();        return 1;    }            // Free the SDL_Surface only if it was successfully created    if ( surface ) {         SDL_FreeSurface( surface );    }        // Clear the screen before drawing	glClear( GL_COLOR_BUFFER_BIT );        // Bind the texture to which subsequent calls refer to    glBindTexture( GL_TEXTURE_2D, texture );    glBegin( GL_QUADS );        // Top-left vertex (corner)        glTexCoord2i( 0, 0 );        glVertex3f( 100, 100, 0 );            // Bottom-left vertex (corner)        glTexCoord2i( 1, 0 );        glVertex3f( 228, 100, 0 );            // Bottom-right vertex (corner)        glTexCoord2i( 1, 1 );        glVertex3f( 228, 228, 0 );            // Top-right vertex (corner)        glTexCoord2i( 0, 1 );        glVertex3f( 100, 228, 0 );    glEnd();	    SDL_GL_SwapBuffers();        // Wait for 3 seconds to give us a chance to see the image    SDL_Delay(3000);        // Now we can delete the OpenGL texture and close down SDL    glDeleteTextures( 1, &texture );        SDL_Quit();    	return 0;}
Patrick
Yeah I know. But both of them give me weird output. For example if I have a bmp which shows correctly and convert it to png, then tweak the code to load png's some colours becomes incorrect or the whole picture becomes a mess.
Bitmap images are generally 24 bit RGB triplets and are handled differently than PINGs which may also contain an alpha component making it RGBA or some variation depending on the image converter you used.
Quote:// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0,
GL_BGR, GL_UNSIGNED_BYTE, surface->pixels );

You will most likely have to play with this portion of your code in order to get the format you are passing to OpenGL to match the image format you loaded.

Unless you are actually using the alpha channel in the images there is no real reason to use PNG vs BMP as in most cases the image will be uncompressed in memory anyway. I am just mentioning this as the only real difference is image space on disk vs extra dlls and libraries to achieve smaller space on disk.
Evillive2
During the image loading drop the,

SDL_DisplayFormat( surface );


From my experience it screws it up, I got rid of it and all formats work, from what I can see it is only needed for SDLs fast blitting.
evillive2 pointed correctly. If anyone else has a similar problem try messing with format specific arguments while calling glTexImage2D. A useful reference http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/teximage2d.html
If you don't do any kind of image manipulation at load time you might want to look into using DevIL or SOIL which do a much better job of abstracting the whole process of image file to OpenGL texture by letting you load directly to a texture with one line of code instead of having to manually figure out the format of the image.
Evillive2
okay, I will check them out. You have been a great help !

This topic is closed to new replies.

Advertisement