views:

36

answers:

1

Hi, 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* 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;
            }
        }
    }
}
A: 

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;
            }
        }
    }
}
genpfault
Thanks very much. Works perfectly now.
WhyCodeNoWork