Reading on understanding Pixels/channels and what not? Help loading images.

Started by
0 comments, last by 21st Century Moose 11 years, 2 months ago

I have code trying load/display an image and keep getting this Unhandled Exception Error. I think its because the image is not a multiple of 4 or something like that (no idea) here is my code:


#include "SDL.h"
#include "SDL_image.h"
#include "SDL_opengl.h"
#include <math.h>
#include <stdio.h>
 
int loadImage();
void drawImage();
 
extern SDL_Event event;
 
GLuint texture = NULL;
GLenum texture_format=NULL;
GLint nofcolors;
 
int loadImage()
{
 
    SDL_Surface* surface;
        
        if((surface = IMG_Load("AvatarBasicCharacterModel.jpg"))){
 
        //get number of channels in the SDL surface
        nofcolors = surface -> format -> BytesPerPixel;
        
   //contains an alpha channel
        if(nofcolors == 4)
        {
                if ( surface -> format -> Rmask == 0x000000ff)
                        texture_format = GL_RGBA;
                else
                        texture_format = GL_BGRA;
        }
        else if ( nofcolors == 3) //no alpha channel
        {
                if(surface ->format->Rmask==0x000000ff)
                        texture_format=GL_RGB;
                else
                        texture_format=GL_BGR;
        }
 
        //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);
 
 
        glTexImage2D( GL_TEXTURE_2D, 0, nofcolors, surface -> w, surface ->h, 0, texture_format, GL_UNSIGNED_BYTE, surface -> pixels );
 
        }
        else //could not load image
                SDL_Quit();
return 1;
 
if (surface){
        SDL_FreeSurface(surface);
}
 
}
 
 
void drawImage()
{
 
        //Clear the screen before drawing 
        glClear( GL_COLOR_BUFFER_BIT);
 
        //Bind the texture to which subsequent calls refer to
        glBindTexture( GL_TEXTURE_2D, texture);
 
        glPushMatrix();
        glTranslatef(60,700,0.0f);
        glBegin(GL_QUADS);
        //Set color
        glColor4f(0.0,0.0,1.0,0.0);
 
        
        glTexCoord2i(1,1);
        glVertex2f(150.0,0);//bottom right
        glTexCoord2i(0,1);
        glVertex2f(150.0,-50);//top right
        glTexCoord2i(0,0);
        glVertex2f(0.0,-50);//top left
        glTexCoord2i(1,0);
        glVertex2f(0.0,0);//bottom left
    
 
        glEnd();
        
        glPopMatrix();
 
        
}

I want to A) Understand why the image needs to be a certain width/hieght and B) How to make it work.

The alpha channels and stuff. Not following.

Advertisement

Your code looks mostly correct (it's using some depreacted functionality but that shouldn't cause a crash); the one thing that you're missing is that for GL_RGB/GL_BGR images you may need to call glPixelStorei (GL_UNPACK_ALIGNMENT, 1) before your glTexImage2D call. This is because OpenGL by default expects each row to be padded to 4-byte boundaries, so if your image width * 3 is not a multiple of 4 your driver will attempt to read past the end of the "surface->pixels" buffer.

See http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml

Why 4-byte boundaries? Simple - because hardware likes to work in groups of 32 bits.

You should of course also be checking for non-power-of-two texture support and resizing your texture to a power of two if you don't have it - look for "GL_ARB_texture_non_power_of_two" in your GL_EXTENSIONS string, and beware that some drivers will drop you back to software emulation if the driver supports it but the hardware doesn't. You'll know that right away when you suddenly hit 1fps, and it shouldn't happen on any reasonably civilized modern hardware.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement