开发者

sdl app segfaults on sdl_gl_setattribute

I'm trying to compile this example and play around with it a bit. I've already corrected the main error the people were having with this example where they would call sdl_gl_setattribute before SDL_Init was called but I'm still getting a segfault right after the first SDL_GL_SetAttribute call. I've ran sdl with opengl apps before on my computer and I'm certain it's been working with my video card.

From this code does anybody know why it would segfault? Or, does this code work on anybody else's computer? If it makes any difference I'm on ubuntu 10.04 using freeglut3 for opengl stuff.

//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*开发者_C百科 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;
            }
        }
    }
}


Try this version:

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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜