test/testdyngl.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1659 14717b52abc0
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.

/*
 * Small SDL example to demonstrate dynamically loading 
 * OpenGL lib and functions
 *
 * (FYI it was supposed to look like snow in the wind or something...)
 *
 * Compile with :
 * gcc testdyngl.c `sdl-config --libs --cflags` -o testdyngl -DHAVE_OPENGL
 *
 * You can specify a different OpenGL lib on the command line, i.e. :
 * ./testdyngl  /usr/X11R6/lib/libGL.so.1.2
 * or
 * ./testdyngl  /usr/lib/libGL.so.1.0.4496
 *
 */

#include <stdio.h>
#include <stdlib.h>

#include "SDL.h"

#ifdef __MACOS__
#define HAVE_OPENGL
#endif

#ifdef HAVE_OPENGL

#include "SDL_opengl.h"

/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit (int rc)
{
    SDL_Quit ();
    exit (rc);
}

void *
get_funcaddr (const char *p)
{
    void *f = SDL_GL_GetProcAddress (p);
    if (f) {
        return f;
    } else {
        printf ("Unable to get function pointer for %s\n", p);
        quit (1);
    }
    return NULL;
}

typedef struct
{
    void (APIENTRY * glBegin) (GLenum);
    void (APIENTRY * glEnd) ();
    void (APIENTRY * glVertex3f) (GLfloat, GLfloat, GLfloat);
    void (APIENTRY * glClearColor) (GLfloat, GLfloat, GLfloat, GLfloat);
    void (APIENTRY * glClear) (GLbitfield);
    void (APIENTRY * glDisable) (GLenum);
    void (APIENTRY * glEnable) (GLenum);
    void (APIENTRY * glColor4ub) (GLubyte, GLubyte, GLubyte, GLubyte);
    void (APIENTRY * glPointSize) (GLfloat);
    void (APIENTRY * glHint) (GLenum, GLenum);
    void (APIENTRY * glBlendFunc) (GLenum, GLenum);
    void (APIENTRY * glMatrixMode) (GLenum);
    void (APIENTRY * glLoadIdentity) ();
    void (APIENTRY * glOrtho) (GLdouble, GLdouble, GLdouble, GLdouble,
                               GLdouble, GLdouble);
    void (APIENTRY * glRotatef) (GLfloat, GLfloat, GLfloat, GLfloat);
    void (APIENTRY * glViewport) (GLint, GLint, GLsizei, GLsizei);
    void (APIENTRY * glFogf) (GLenum, GLfloat);
}
glfuncs;

void
init_glfuncs (glfuncs * f)
{
    f->glBegin = get_funcaddr ("glBegin");
    f->glEnd = get_funcaddr ("glEnd");
    f->glVertex3f = get_funcaddr ("glVertex3f");
    f->glClearColor = get_funcaddr ("glClearColor");
    f->glClear = get_funcaddr ("glClear");
    f->glDisable = get_funcaddr ("glDisable");
    f->glEnable = get_funcaddr ("glEnable");
    f->glColor4ub = get_funcaddr ("glColor4ub");
    f->glPointSize = get_funcaddr ("glPointSize");
    f->glHint = get_funcaddr ("glHint");
    f->glBlendFunc = get_funcaddr ("glBlendFunc");
    f->glMatrixMode = get_funcaddr ("glMatrixMode");
    f->glLoadIdentity = get_funcaddr ("glLoadIdentity");
    f->glOrtho = get_funcaddr ("glOrtho");
    f->glRotatef = get_funcaddr ("glRotatef");
    f->glViewport = get_funcaddr ("glViewport");
    f->glFogf = get_funcaddr ("glFogf");
}

#define NB_PIXELS 1000

int
main (int argc, char *argv[])
{
    glfuncs f;
    int i;
    SDL_Event event;
    int done = 0;
    GLfloat pixels[NB_PIXELS * 3];
    const char *gl_library = NULL;      /* Use the default GL library */

    if (argv[1]) {
        gl_library = argv[1];
    }

    if (SDL_Init (SDL_INIT_VIDEO) < 0) {
        printf ("Unable to init SDL : %s\n", SDL_GetError ());
        return (1);
    }

    if (SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1) < 0) {
        printf ("Unable to set GL attribute : %s\n", SDL_GetError ());
        quit (1);
    }

    if (SDL_GL_LoadLibrary (gl_library) < 0) {
        printf ("Unable to dynamically open GL lib : %s\n", SDL_GetError ());
        quit (1);
    }

    if (SDL_SetVideoMode (640, 480, 0, SDL_OPENGL) == NULL) {
        printf ("Unable to open video mode : %s\n", SDL_GetError ());
        quit (1);
    }

    /* Set the window manager title bar */
    SDL_WM_SetCaption ("SDL Dynamic OpenGL Loading Test", "testdyngl");

    init_glfuncs (&f);

    for (i = 0; i < NB_PIXELS; i++) {
        pixels[3 * i] = rand () % 250 - 125;
        pixels[3 * i + 1] = rand () % 250 - 125;
        pixels[3 * i + 2] = rand () % 250 - 125;
    }

    f.glViewport (0, 0, 640, 480);

    f.glMatrixMode (GL_PROJECTION);
    f.glLoadIdentity ();
    f.glOrtho (-100, 100, -100, 100, -500, 500);

    f.glMatrixMode (GL_MODELVIEW);
    f.glLoadIdentity ();

    f.glEnable (GL_DEPTH_TEST);
    f.glDisable (GL_TEXTURE_2D);
    f.glEnable (GL_BLEND);
    f.glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    f.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    f.glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    f.glEnable (GL_POINT_SMOOTH);
    f.glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
    f.glPointSize (5.0f);
    f.glEnable (GL_FOG);
    f.glFogf (GL_FOG_START, -500);
    f.glFogf (GL_FOG_END, 500);
    f.glFogf (GL_FOG_DENSITY, 0.005);

    do {
        f.glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        f.glRotatef (2.0, 1.0, 1.0, 1.0);
        f.glRotatef (1.0, 0.0, 1.0, 1.0);

        f.glColor4ub (255, 255, 255, 255);
        f.glBegin (GL_POINTS);
        for (i = 0; i < NB_PIXELS; i++) {
            f.glVertex3f (pixels[3 * i], pixels[3 * i + 1],
                          pixels[3 * i + 2]);
        }
        f.glEnd ();
        SDL_GL_SwapBuffers ();

        while (SDL_PollEvent (&event)) {
            if (event.type & SDL_KEYDOWN)
                done = 1;
        }

        SDL_Delay (20);
    }
    while (!done);

    SDL_Quit ();
    return 0;
}

#else /* HAVE_OPENGL */

int
main (int argc, char *argv[])
{
    printf ("No OpenGL support on this system\n");
    return 1;
}

#endif /* HAVE_OPENGL */