Sdl_image无法找到我的jpg图像;不会加载

时间:2011-02-23 01:38:38

标签: c++ opengl ubuntu sdl codeblocks

我目前正在使用Code :: Blocks IDE,c ++,opengl和SDL制作游戏 - 如果你愿意的话,我已经遇到了严重阻碍。我正在使用SDL_image为纹理加载这些jpg图像,但它们不会加载。目前,我已经尝试将它们放在项目的每个文件夹中,即使它们应该没有任何区别。我尝试从IDE运行调试版和发行版,双击可执行文件,并从命令行运行可执行文件。它们都产生相同的错误:无法加载图像:“我的图像的路径”。我尝试过使用完整路径,我尝试过使用相对路径,我已经尝试了几乎所有东西。我尝试过各种图像格式,但没有成功。其他有用的信息可能是:我正在使用ubuntu 11.04,我正在使用GIMP来创建图像,这是我完整的代码(我敢肯定它的大部分内容都是无关紧要的,但我只是把它全部放在了 - - 案例):

#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;
}

因此,如果您发现任何或知道任何原因导致“SDL无法加载图片”错误,请回复!在解决此问题之前,我无法继续我的项目,因为它会产生段错误。

2 个答案:

答案 0 :(得分:3)

SDL本身只能加载BMP图像,如果在使用函数SDL_LoadBMP()时加载除BMP之外的任何内容,它将返回错误。要加载JPEG,您需要使用http://www.libsdl.org/projects/SDL_image/提供的补充库SDL_image。正如JJG回答的那样,你必须使用的函数的原型是:

SDL_Surface *IMG_Load( const char* );

而不是SDL_LoadBMP()。

答案 1 :(得分:1)

不是SDL或C ++方面的专家。但是我花了一分钟时间查看我做了一段时间的小程序。我用过:

 some_image = IMG_Load( "someimage.jpg" );