开发者

Sdl_image cannot find my jpg image; Won't load

I am currently using the Code::Blocks IDE, c++, opengl and SDL to make a game- and I have hit a severe block in road, if you will. I am using SDL_image to load these jpg images for the textures, but they just will not load. Currently, I have tried placing them in every folder in the project, even places where it would supposedly make no difference. I have tried running both the debug and release versions from the IDE, by double-clicking the executable, and by running the executable from the command line. They all produce the same error: Could not load image: "the path to my image". I have tried using full paths, I have tried using relative paths, I have tried just about everything. I have tried various image formats, to no success. Other useful information may be: I am using ubuntu 11.04, I am using GIMP to create the images, and this is my code in complete (I'm sure most of it is irrelevant, but I am just putting it all down just-in-case):

#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <Cg/cg.h>// NEW: Cg Header
#include <Cg/cgGL.h>// NEW: Cg OpenGL Specific Header
#include <iostream>
#include <math.h>
#include <string>
#include "../include/Camera.h"

#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480

// Keydown booleans
bool key[321];
Uint8 *keystate;
float fogDensity = 0.02f;
static float fog_color[] = { 0.8f, 0.8f, 0.8f, 1.0f };

// Process pending events
bool events()
{
    SDL_Event event;

    if( !SDL_PollEvent(&event) ){
        return true;
    }

    switch( event.type )
    {
        case SDL_KEYDOWN : key[ event.key.keysym.sym ]=true;   break;
        case SDL_KEYUP   : key[ event.key.keysym.sym ]=false;   break;
        case SDL_QUIT    : return false; break; //one-per-keypress
    }

    keystate = SDL_GetKeyState(NULL); //continuous
    return true;
}

// Initialze OpenGL perspective matrix
void setup(int width, int height)
{
   glViewport( 0, 0, width, height );
   glMatrixMode( GL_PROJECTION );
   glEnable( GL_DEPTH_TEST );
   gluPerspective( 45, (float)width/height, 0.1, 100 );
   glMatrixMode( GL_MODELVIEW );

}

Camera* cam = new Camera();
GLuint rocktexture;         // This is a handle to our texture object
GLuint earthtexture;


//add some default materials here
const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 0.0f, 1.0f, 0.0f, 0.0f };

const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };

void MouseUpdate() {
    int x, y;
    SDL_GetMouseState(&x,&y);
    SDL_WarpMouse(WINDOW_WIDTH/2,WINDOW_HEIGHT/2);

    cam->yaw+=(x-WINDOW_WIDTH/2)*0.2;
    cam->pitch+=(y-WINDOW_HEIGHT/2)*0.2;

    if(cam->pitch<-90) {
    cam->pitch=-90;
    }

    if(cam->pitch>90) {
    cam->pitch=90;
    }
}


static void display(void)
{
    while(events())
    {
        MouseUpdate();
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();
        glRotatef(cam->pitch,1.0,0.0,0.0);  //rotate our camera on the x-axis (left and right)
        glRotatef(cam->yaw,0.0,1.0,0.0);  //rotate our camera on the y-axis (up and down)
        glTranslated(cam->camx,cam->camy,cam->camz); //translate the screen to the position of our camera

        glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
        glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0);

        //glColor4f(1,1,1,0.5);
        glPushMatrix();
        glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
        //glDisable(GL_CULL_FACE);
        glBindTexture(GL_TEXTURE_2D, rocktexture);
        glBegin(GL_TRIANGLE_FAN);
        glTexCoord2i(0,0);glVertex3f(-32,0,32);
        glTexCoord2i(1,0);glVertex3f(32,0,32);
        glTexCoord2i(1,1);glVertex3f(32,0,-32);
        glTexCoord2i开发者_如何学运维(0,1);glVertex3f(-32,0,-32);
        glEnd();
        //glEnable(GL_CULL_FACE);
        glPopMatrix();
        /*glPushMatrix();
        GLUquadric* earth = gluNewQuadric();
    gluQuadricTexture(earth, true);
    gluQuadricDrawStyle(earth, GLU_FILL);
    gluQuadricNormals(earth, GLU_SMOOTH);
    gluQuadricOrientation(earth, GLU_OUTSIDE);
    gluSphere(earth, 1, 16, 16);
    gluDeleteQuadric(earth);
        glPopMatrix();*/
        glFlush();

        SDL_GL_SwapBuffers();

        if (key[SDLK_ESCAPE] || key[SDLK_q])
        {
            std::cout<<"Game Ended."<<std::endl;
            exit(0);
        }

        if (keystate[SDLK_w])
        {
            cam->camx-=sin(cam->yaw*M_PI/180)/4;
            cam->camz+=cos(cam->yaw*M_PI/180)/4;
        }

        if (keystate[SDLK_s])
        {
            cam->camx+=sin(cam->yaw*M_PI/180)/4;
            cam->camz-=cos(cam->yaw*M_PI/180)/4;
        }

        if (keystate[SDLK_a])
        {
            cam->camx+=cos(cam->yaw*M_PI/180)/4;
            cam->camz+=sin(cam->yaw*M_PI/180)/4;
        }

        if (keystate[SDLK_d])
        {
            cam->camx-=cos(cam->yaw*M_PI/180)/4;
            cam->camz-=sin(cam->yaw*M_PI/180)/4;
        }
    }
}

// Load the OpenGL texture
GLuint loadImage(std::string path, GLuint tx,SDL_Surface* sur)
{
    GLenum texture_format;
    GLint  nOfColors;
    if ((sur = SDL_LoadBMP(path.c_str())))
    {
        // Check that the image's width is a power of 2
        if ((sur->w & (sur->w - 1)) != 0)
    {
        printf("warning: image's width is not a power of 2\n");
    }
        // Also check if the height is a power of 2
    if ((sur->h & (sur->h - 1)) != 0)
    {
        printf("warning: image's height is not a power of 2\n");
    }
        // get the number of channels in the SDL surface
        nOfColors = sur->format->BytesPerPixel;
        if (nOfColors == 4)     // contains an alpha channel
        {
            if (sur->format->Rmask == 0x000000ff)
            {
                texture_format = GL_RGBA;
            }
            else
            {
                texture_format = GL_BGRA;
            }

        }
        else if (nOfColors == 3)     // no alpha channel
        {
            if (sur->format->Rmask == 0x000000ff)
            {
                texture_format = GL_RGB;
            }
            else
            {
                texture_format = GL_BGR;
            }
        }
        else
        {
            printf("warning: the image is not truecolor..  this will probably break\n");
            // this error should not go unhandled
        }


        // Have OpenGL generate a texture object handle for us
        glGenTextures( 1, &tx );
        // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, tx );
        // Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, 3, sur->w, sur->h, 0, GL_BGR, GL_UNSIGNED_BYTE, sur->pixels);
    //build mip-maps
    gluBuild2DMipmaps(tx, 3, sur->w, sur->h, texture_format, GL_UNSIGNED_BYTE, sur->pixels);
    }
    else
    {
        printf("SDL could not load image: %s\n", SDL_GetError());
            SDL_Quit();
    return 1;
    }
    // Free the SDL_Surface only if it was successfully created
    if (sur)
    {
    SDL_FreeSurface(sur);
    }
    delete &texture_format;
    delete &nOfColors;
    return tx;
}

/* Program entry point */

int main(int argc, char *argv[])
{
    cam->camz=-5;
    cam->camy=-1;
    if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
    {
        std::cout<<"Unable to initialize SDL: %s\n"<<SDL_GetError()<<std::endl;
        return 1;
    }
    const SDL_VideoInfo* info = SDL_GetVideoInfo();
    int vidFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER;
    if (info->hw_available) {vidFlags |= SDL_HWSURFACE;}
    else {vidFlags |= SDL_SWSURFACE;}
    //int bpp = info->vfmt->BitsPerPixel;
    SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, vidFlags);
    SDL_WM_SetCaption( "Treason", NULL);

    SDL_WarpMouse(WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
    gluLookAt(cam->camx,cam->camy,cam->camz,0,0,0,0,1,0);

    glClearColor(0, 0, 0, 0);//background color white

    float lmodel_ambient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
    float local_view[] = { 0.0f };

    glEnable(GL_TEXTURE_2D);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
    glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
    glLightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
    //glEnable(GL_BLEND);
    //glBlendFunc(GL_SRC_ALPHA, GL_ONE);

    glEnable(GL_DITHER);

    //glHint(GL_PHONG_HINT_WIN, GL_NICEST);
    glShadeModel(GL_SMOOTH);//GL_PHONG_WIN


    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

/*    glEnable(GL_FOG);
    glHint(GL_FOG_HINT, GL_NICEST);
    glEnable(GL_FOG);
    glFogi(GL_FOG_MODE, GL_EXP);
    glFogf(GL_FOG_DENSITY, fogDensity);
    glFogfv(GL_FOG_COLOR, fog_color);*/


    // glEnable(GL_STENCIL_TEST);
    //glStencilFunc(GL_KEEP, GL_KEEP, GL_INCR);

    SDL_Surface *rocktexsur;
    rocktexture = loadImage("rock.jpg", rocktexture, rocktexsur);
    SDL_Surface *earthtexsur;
    earthtexture = loadImage("earth.jpg", earthtexture, earthtexsur);


    setup(WINDOW_WIDTH, WINDOW_HEIGHT);
    display();

    glDeleteTextures(1, &rocktexture);
    glDeleteTextures(1, &earthtexture);

    return 0;
}

So if you find anything or know any reason why it would return an "SDL could not load image" Error, please respond! I can't continue on my project until this is resolved because it produces a segfault.


SDL by itself can only load BMP images, and it will return an error if you load anything but a BMP in using the function SDL_LoadBMP(). In order to load JPEGs, you need to use the supplemental library SDL_image, which is available at http://www.libsdl.org/projects/SDL_image/ . As JJG answered, the prototype for the function you have to use is:

SDL_Surface *IMG_Load( const char* );

rather than SDL_LoadBMP().


Not an expert on SDL or C++. But I just spent a minute looking over my tiny program I made a while back. I used:

 some_image = IMG_Load( "someimage.jpg" );
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜