在sdl_gl_setattribute上的sdl app segfaults

时间:2010-10-10 00:19:35

标签: c opengl sdl segmentation-fault freeglut

我正在尝试编译这个example并稍微玩一下。我已经纠正了人们在这个例子中遇到的主要错误,他们在调用SDL_Init之前调用了sdl_gl_setattribute,但是在第一次SDL_GL_SetAttribute调用之后我仍然得到一个段错误。我之前在我的电脑上运行了带有opengl应用程序的sdl,我确信它一直在使用我的视频卡。

从这段代码中有人知道为什么会出现段错误吗?或者,此代码是否适用于任何其他人的计算机?如果它有任何区别我在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;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:-1)

试试这个版本:

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