Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm going to create a game in C++ with SDL & openGL but adding textures won't work. the code is in some different classes. here's the main file

//==============================================================================
#include "ZOMBOX.h"

//==============================================================================
ZOMBOX::ZOMBOX() {

    isRunning = true;
}

//------------------------------------------------------------------------------
int ZOMBOX::Execute() {
    Init();

    bool mainloop = false;

    SDL_Event event;

    //Create an texture
    unsigned int Ball_texture = 0;
    //Load the image into the texture using the function
    Ball_texture = loadTexture("Smile.png");
    std::cout << "OpenGL is running\n";

    while(isRunning) {
        while(SDL_PollEvent(&event)) {
            Event(&event);
        }
        if(mainloop == false){
            std::cout << "Main loop has started\n";
            mainloop = true;
        }
        Logic();
        Render();
        }

    //Clear();

    SDL_Quit();

    return 0;
}

//==============================================================================
int main(int argc, char* argv[]) {
    ZOMBOX theApp;

    return theApp.Execute();
}

//==============================================================================

Ok, now the rendering;

//============================================================================== #include "ZOMBOX.h"

//==============================================================================
void ZOMBOX::Render() {

    extern float ballX;
    extern float ballY;
    extern float ballWH;
    extern int vellX;
    extern int vellY;
    extern unsigned int Ball_texture;
    Ball_texture = loadTexture("Smile.png");

    //RENDERING to the screen
    //Enable textures when we are going to blend an texture
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix(); //Start rendering phase
    glOrtho(0,800,600,0,-1,1); //Set the matrix
    glColor4ub(0,0,0,255); //White color
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, Ball_texture);

    glBegin(GL_QUADS); //Start drawing the pad
    //We set the corners of the texture using glTexCoord2d
    glTexCoord2d(0,0); glVertex2f(ballX,ballY); //Upper-left corner
    glTexCoord2d(1,0); glVertex2f(ballX+ballWH,ballY); //Upper-right corner
    glTexCoord2d(1,1); glVertex2f(ballX+ballWH,ballY+ballWH); //Down-right corner
    glTexCoord2d(0,1); glVertex2f(ballX,ballY+ballWH); //Down-left corner
    glEnd(); //End drawing
    //Disable textures when we are done using them
    glDisable(GL_TEXTURE_2D);

    glPopMatrix(); //End rendering phase
    SDL_GL_SwapBuffers();

    SDL_Delay(1);
}

//==============================================================================

i know the comments are not right but i understand it...

now the texture; here's the fault i think

//==============================================================================
#include "ZOMBOX.h"
//==============================================================================
//Function for loading an image into an texture
GLuint ZOMBOX::loadTexture( const std::string &fileName )
{
    SDL_Surface* image = IMG_Load( fileName.c_str() );

    SDL_DisplayFormatAlpha(image);

    unsigned object(0);

    glGenTextures(1, &object);

    glBindTexture(GL_TEXTURE_2D, object);

    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);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);

    //Free surface
    SDL_FreeSurface(image);

return object;
}
//==============================================================================

I use variables you cant see but that's no problem thus they are not nessecary(i think).

Sorry for my bad English im just a dutch highschool student.

share|improve this question

3 Answers 3

up vote 5 down vote accepted

In addition to the comments above, your conversion of an SDL_Surface to an OpenGL texture is incorrect. You're missing two important issues:

  1. Ensure that the image dimensions are a power of two. (64, 128, 256, 512, etc)
  2. Ensure that your SDL_Surface is in the pixel format that you're telling OpenGL that it's using (GL_RGBA, GL_UNSIGNED_BYTE, in your case). This one could easily be the cause of crashes, if your image isn't actually stored as a 32-bit image.
  3. I also tell OpenGL to automatically generate mipmaps. No need to do that part, but I've included it here for completeness.

Here's the code I use for doing this texture setup. Basic idea: create a new SDL_Surface of the correct size and pixel format, copy the original surface into it, create the OpenGL texture from the correctly-formatted copy, and then clean up.

Source code:

static int power_of_two(int input)
{
    int value = 1;

    while ( value < input ) {
        value <<= 1;
    }
    return value;
}

int ConvertSDLSurfaceToTexture( SDL_Surface *source )
{
    SDL_Rect    area;
    uint32_t saved_flags;
    uint8_t  saved_alpha;

    SDL_SetAlpha(source, 0, SDL_ALPHA_OPAQUE);

    m_width = (float)source->w;
    m_height = (float)source->h;

    int w = power_of_two(source->w);
    int h = power_of_two(source->h);

    SDL_Surface *image = SDL_CreateRGBSurface(
                                          SDL_SWSURFACE,
                                          w, h,
                                          32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
                                          0x000000FF,
                                          0x0000FF00,
                                          0x00FF0000,
                                          0xFF000000
#else
                                          0xFF000000,
                                          0x00FF0000,
                                          0x0000FF00,
                                          0x000000FF
#endif
                                          );
    assert(image != NULL);

    saved_flags = source->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
    saved_alpha = source->format->alpha;
    if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
        SDL_SetAlpha(source, 0, 0);
    }

    /* Copy the surface into the GL texture image */
    area.x = 0;
    area.y = 0;
    area.w = source->w;
    area.h = source->h;
    SDL_BlitSurface(source, &area, image, &area);

    /* Restore the alpha blending attributes */
    if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
        SDL_SetAlpha(source, saved_flags, saved_alpha);
    }

    /* Create an OpenGL texture for the image */
    GLuint t;
    glGenTextures(1, &t);

    glBindTexture(GL_TEXTURE_2D, m_texture);
    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_GENERATE_MIPMAP, GL_TRUE);
    glTexImage2D(GL_TEXTURE_2D,
                 0,
                 GL_RGBA,
                 w, h,
                 0,
                 GL_RGBA,
                 GL_UNSIGNED_INT_8_8_8_8_REV,
                 image->pixels);

    SDL_FreeSurface(image); /* done with this copy of the input surface */

    return t;
}
share|improve this answer
    
@ Trevor Powell i made my image with Paint.net,added an alpha layer and saved it as a 32-bit .png file. i use this as an function which i got from my friend he explained me what it does and i understood it, but he made a big main.cpp file, and i use different files for different functions, like render.cpp loadTexture.cpp ZOMBOX.cpp(which is the main file) maybe that makes a difference, one question, how should i use your code? –  Ninjakiller275 Mar 1 '12 at 13:08
    
can i use it like so: GLuint ZOMBOX::loadTexture(){yourfunction} or should it look like this: GLuint ZOMBOX::loadTexture(){myfunction yourfunction} ? i don't know how to implement your source code. please explain. Still THNX! –  Ninjakiller275 Mar 1 '12 at 13:27
    
You'd do IMG_Load(), then my function using the SDL_Surface that was created to create the OpenGL texture, then SDL_FreeSurface() to destroy the SDL_Surface you loaded. –  Trevor Powell Mar 2 '12 at 9:48
    
I will try that i'v been trying to use your function but my compiler(Mingw) keeps telling me that it cant recognize Uint32 & uint8 what's the problem then. I'm not really familiar with C++ most of time i use C –  Ninjakiller275 Mar 2 '12 at 11:20
1  
uint32 & uint8 must be uint32_t & uint8_t. –  Ninjakiller275 Mar 3 '12 at 19:37

Are there any errors when loading the image? Try to verify that the image loads properly.

After this:

SDL_Surface* image = IMG_Load( fileName.c_str() );

Add this:

if(!image) {
    printf("IMG_Load: %s\n", IMG_GetError());
    // handle error
}
share|improve this answer
    
i tried that but it gives no error until i delete my image file. some weird sort of smiley. i see what i can do with your answer. thnx –  Ninjakiller275 Mar 1 '12 at 12:57

You load the texture every time you Render().
It should be this way:

  1. You start the program
  2. Load the texture (before the while-loop)
  3. Render the texture (in the while-loop)
  4. Unload the texture (after the while-loop)
  5. Close the program
share|improve this answer
    
Hmm mayby that's a problem. I load the texture twice. one time before the while loop, and in the rendering part... I will thange that and see what it does. –  Ninjakiller275 Mar 1 '12 at 13:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.