2010-10-10 65 views
1

我試圖編譯這個example並且有點玩弄它。我已經糾正了人們在這個例子中遇到的主要錯誤,他們在SDL_Init被調用之前會調用sdl_gl_setattribute,但在第一個SDL_GL_SetAttribute調用之後,我仍然收到一個段錯誤。我已經在我的計算機上運行過帶有opengl應用程序的sdl,並且我確定它一直在使用我的視頻卡。sdl app sdl_gl_setattribute上的segfaults

從這段代碼是否有人知道它爲什麼會segfault?或者,此代碼是否可以在其他人的電腦上工作?如果它有什麼區別,我在Ubuntu 10.04上使用freeglut3作爲opengl的東西。

//compile with cc triangle.c -o triangle `sdl-config --libs --cflags` -lglut 

#include <stdio.h> 
#include "SDL.h" 
#include <GL/gl.h> 

int event_thread(void* nothing); 

int main(int argc, char** argv) { 
    float theta = 0.0f; 

    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD); 

    //first set buffer stuff, then doublebuf (if wanted), then SDL_SetVideoMode() 
    if(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) < 0) { printf("couldn't set double buffering: %s\n", SDL_GetError()); } 

    //go through and get the values to see if everything was set 
    int red, green, blue, doublebuf; 
    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red); 
    SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green); 
    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &blue); 
    SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuf); 
    printf("red size, green size, blue size: <%d, %d, %d>\ndouble buffered? %s\n", red, green, blue, (doublebuf == 1 ? "yes" : "no")); 

    //pass sdl_resizable if it's an opengl application that is windowed and not fullscreened 
    SDL_Surface* screen = SDL_SetVideoMode(600, 300, 32, SDL_OPENGL | SDL_HWSURFACE | SDL_NOFRAME | SDL_RESIZABLE); 
    if(screen == NULL) { 
     printf("video error: %s\n", SDL_GetError()); 
    } 

    //print video card memory 
    const SDL_VideoInfo* info = SDL_GetVideoInfo(); 
    printf("video card memory (in megabytes): %d\n", info->video_mem); 

    //set opengl params for drawing in 3d space 
    glViewport(0, 0, 600, 300); 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClearDepth(1.0); 
    glDepthFunc(GL_LESS); 
    glEnable(GL_DEPTH_TEST); 
    glShadeModel(GL_SMOOTH); 
    glMatrixMode(GL_PROJECTION); 
    glMatrixMode(GL_MODELVIEW); 

    //start up the event thread 
    int done = 0; 
    SDL_Thread* evt_thrd; 
    evt_thrd = SDL_CreateThread(event_thread, (void*)&done); 

    for(;!done;) { 
     //clear and move to 0, 0, 0 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glTranslatef(0.0f, 0.0f, 0.0f); 
     glRotatef(theta, 0.0f, 0.0f, 1.0f); 

     //draw the triangle 
     glBegin(GL_TRIANGLES); 
     glColor3f(1.0f, 0.0f, 0.0f); 
     glVertex2f(0.0f, 1.0f); 
     glColor3f(0.0f, 1.0f, 0.0f); 
     glVertex2f(0.87f, -0.5f); 
     glColor3f(0.0f, 0.0f, 1.0f); 
     glVertex2f(-0.87f, -0.5f); 
     glEnd(); 

     theta += 0.5f; 
     SDL_GL_SwapBuffers(); 
    } 

    SDL_Quit(); 
    return 0; 
} 

int event_thread(void* nothing) { 
    int* done = (int*)nothing; 
    SDL_Event event; 

    while(1) { 
     while(SDL_PollEvent(&event)) { 
      if(event.type == SDL_QUIT || 
      (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) { 
       *done = 1; 
       return 0; 
      } 
     } 
    } 
} 
+0

問題缺乏有關崩潰的發生位置的足夠信息。在你尋求幫助之前至少做一點事實調查。 – 2010-10-10 01:09:39

+0

段錯誤發生在第一個SDL_GL_SetAttribute調用後 – WhyCodeNoWork 2010-10-10 01:52:27

回答

0

試試這個版本:

//compile with cc triangle.c -o triangle `sdl-config --libs --cflags` -lglut 

#include <stdio.h> 
#include "SDL.h" 
#include "SDL_opengl.h" 

int event_thread(void* nothing); 

int main(int argc, char** argv) { 
    float theta = 0.0f; 

    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD); 

    //first set buffer stuff, then doublebuf (if wanted), then SDL_SetVideoMode() 
    if(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32) < 0) { printf("opengl error: %s\n", SDL_GetError()); } 
    if(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) < 0) { printf("couldn't set double buffering: %s\n", SDL_GetError()); } 

    //pass sdl_resizable if it's an opengl application that is windowed and not fullscreened 
    SDL_Surface* screen = SDL_SetVideoMode(600, 300, 32, SDL_OPENGL | SDL_HWSURFACE | SDL_NOFRAME | SDL_RESIZABLE); 
    if(screen == NULL) { 
     printf("video error: %s\n", SDL_GetError()); 
    } 

    //go through and get the values to see if everything was set 
    int red, green, blue, doublebuf; 
    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red); 
    SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green); 
    SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &blue); 
    SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuf); 
    printf("red size, green size, blue size: <%d, %d, %d>\ndouble buffered? %s\n", red, green, blue, (doublebuf == 1 ? "yes" : "no")); 

    //print video card memory 
    const SDL_VideoInfo* info = SDL_GetVideoInfo(); 
    printf("video card memory (in megabytes): %d\n", info->video_mem); 

    //set opengl params for drawing in 3d space 
    glViewport(0, 0, 600, 300); 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClearDepth(1.0); 
    glDepthFunc(GL_LESS); 
    glEnable(GL_DEPTH_TEST); 
    glShadeModel(GL_SMOOTH); 
    glMatrixMode(GL_PROJECTION); 
    glMatrixMode(GL_MODELVIEW); 

    //start up the event thread 
    int done = 0; 
    SDL_Thread* evt_thrd; 
    evt_thrd = SDL_CreateThread(event_thread, (void*)&done); 

    for(;!done;) { 
     //clear and move to 0, 0, 0 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glTranslatef(0.0f, 0.0f, 0.0f); 
     glRotatef(theta, 0.0f, 0.0f, 1.0f); 

     //draw the triangle 
     glBegin(GL_TRIANGLES); 
     glColor3f(1.0f, 0.0f, 0.0f); 
     glVertex2f(0.0f, 1.0f); 
     glColor3f(0.0f, 1.0f, 0.0f); 
     glVertex2f(0.87f, -0.5f); 
     glColor3f(0.0f, 0.0f, 1.0f); 
     glVertex2f(-0.87f, -0.5f); 
     glEnd(); 

     theta += 0.5f; 
     SDL_GL_SwapBuffers(); 
    } 

    SDL_Quit(); 
    return 0; 
} 

int event_thread(void* nothing) { 
    int* done = (int*)nothing; 
    SDL_Event event; 

    while(1) { 
     while(SDL_PollEvent(&event)) { 
      if(event.type == SDL_QUIT || 
      (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) { 
       *done = 1; 
       return 0; 
      } 
     } 
    } 
} 
+0

非常感謝。現在完美運作。 – WhyCodeNoWork 2010-10-11 05:53:57

+3

對於那些有興趣的人來說,由於它的提及被忽略了,我們並不都想要發揮差異。 他將OpenGL頭文件包含到SDL_opengl.h中(跨平臺支持);並將SDL_SetVideoMode語句移至getAttribute行之前。 – dcousens 2011-02-05 06:06:21