Mercurial > sdl-ios-xcode
view test/testgl.c @ 4426:1bceff8f008f
Fixed bug #943
Ozkan Sezer 2010-02-06 12:31:06 PST
Hi:
Here are some small fixes for compiling SDL against mingw-w64.
(see http://mingw-w64.sourceforge.net/ . Despite the name, it
supports both win32 and win64.)
src/audio/windx5/directx.h and src/video/windx5/directx.h (both
SDL-1.2 and SDL-1.3.) I get compilation errors about some union
not having a member named u1 and alike, because of other system
headers being included before this one and them already defining
DUMMYUNIONNAME and stuff. This header probably assumes that those
stuff are defined in windef.h, but mingw-w64 headers define them
in _mingw.h. Easily fixed by moving NONAMELESSUNION definition to
the top of the file.
src/thread/win32/SDL_systhread.c (both SDL-1.2 and SDL-1.3.) :
The __GNUC__ case for pfnSDL_CurrentBeginThread is 32-bit centric
because _beginthreadex returns uintptr_t, not unsigned long which
is 32 bits in win64. Changing the return type to uintptr_t fixes
it.
video/SDL_blit.h (and configure.in) (SDL-1.3-only) : MinGW-w64
uses msvcrt version of _aligned_malloc and _aligned_free and
they are defined in intrin.h (similar to VC). Adding proper
ifdefs fixes it. (Notes about macros to check: __MINGW32__ is
defined for both mingw.org and for mingw-w64 for both win32 and
win64, __MINGW64__ is only defined for _WIN64, so __MINGW64__
can't be used to detect mingw-w64: including _mingw.h and then
checking for __MINGW64_VERSION_MAJOR does the trick.)
SDL_win32video.h (SDL-1.3-only) : Tweaked the VINWER definition
and location in order to avoid multiple redefinition warnings.
Hope these are useful. Thanks.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 10 Mar 2010 15:02:58 +0000 |
parents | f8816ffa210b |
children | 27ab20a36eba |
line wrap: on
line source
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include "SDL.h" #ifdef __MACOS__ #define HAVE_OPENGL #endif #ifdef HAVE_OPENGL #include "SDL_opengl.h" /* Undefine this if you want a flat cube instead of a rainbow cube */ #define SHADED_CUBE /* Define this to be the name of the logo image to use with -logo */ #define LOGO_FILE "icon.bmp" static SDL_Surface *global_image = NULL; static GLuint global_texture = 0; static GLuint cursor_texture = 0; /**********************************************************************/ void HotKey_ToggleFullScreen(void) { SDL_Surface *screen; screen = SDL_GetVideoSurface(); if (SDL_WM_ToggleFullScreen(screen)) { printf("Toggled fullscreen mode - now %s\n", (screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed"); } else { printf("Unable to toggle fullscreen mode\n"); } } void HotKey_ToggleGrab(void) { SDL_GrabMode mode; printf("Ctrl-G: toggling input grab!\n"); mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); if (mode == SDL_GRAB_ON) { printf("Grab was on\n"); } else { printf("Grab was off\n"); } mode = SDL_WM_GrabInput(!mode); if (mode == SDL_GRAB_ON) { printf("Grab is now on\n"); } else { printf("Grab is now off\n"); } } void HotKey_Iconify(void) { printf("Ctrl-Z: iconifying window!\n"); SDL_WM_IconifyWindow(); } int HandleEvent(SDL_Event * event) { int done; done = 0; switch (event->type) { case SDL_ACTIVEEVENT: /* See what happened */ printf("app %s ", event->active.gain ? "gained" : "lost"); if (event->active.state & SDL_APPACTIVE) { printf("active "); } else if (event->active.state & SDL_APPMOUSEFOCUS) { printf("mouse "); } else if (event->active.state & SDL_APPINPUTFOCUS) { printf("input "); } printf("focus\n"); break; case SDL_KEYDOWN: if (event->key.keysym.sym == SDLK_ESCAPE) { done = 1; } if ((event->key.keysym.sym == SDLK_g) && (event->key.keysym.mod & KMOD_CTRL)) { HotKey_ToggleGrab(); } if ((event->key.keysym.sym == SDLK_z) && (event->key.keysym.mod & KMOD_CTRL)) { HotKey_Iconify(); } if ((event->key.keysym.sym == SDLK_RETURN) && (event->key.keysym.mod & KMOD_ALT)) { HotKey_ToggleFullScreen(); } printf("key '%s' pressed\n", SDL_GetKeyName(event->key.keysym.sym)); break; case SDL_QUIT: done = 1; break; } return (done); } void SDL_GL_Enter2DMode() { SDL_Surface *screen = SDL_GetVideoSurface(); /* Note, there may be other things you need to change, depending on how you have your OpenGL state set up. */ glPushAttrib(GL_ENABLE_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); /* This allows alpha blending of 2D textures with the scene */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, screen->w, screen->h); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0.0, (GLdouble) screen->w, (GLdouble) screen->h, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); } void SDL_GL_Leave2DMode() { glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); } /* Quick utility function for texture creation */ static int power_of_two(int input) { int value = 1; while (value < input) { value <<= 1; } return value; } GLuint SDL_GL_LoadTexture(SDL_Surface * surface, GLfloat * texcoord) { GLuint texture; int w, h; SDL_Surface *image; SDL_Rect area; Uint32 saved_flags; Uint8 saved_alpha; /* Use the surface width and height expanded to powers of 2 */ w = power_of_two(surface->w); h = power_of_two(surface->h); texcoord[0] = 0.0f; /* Min X */ texcoord[1] = 0.0f; /* Min Y */ texcoord[2] = (GLfloat) surface->w / w; /* Max X */ texcoord[3] = (GLfloat) surface->h / h; /* Max Y */ image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); if (image == NULL) { return 0; } /* Save the alpha blending attributes */ saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); SDL_GetSurfaceAlphaMod(surface, &saved_alpha); if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { SDL_SetAlpha(surface, 0, 0); } /* Copy the surface into the GL texture image */ area.x = 0; area.y = 0; area.w = surface->w; area.h = surface->h; SDL_BlitSurface(surface, &area, image, &area); /* Restore the alpha blending attributes */ if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { SDL_SetAlpha(surface, saved_flags, saved_alpha); } /* Create an OpenGL texture for the image */ glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); SDL_FreeSurface(image); /* No longer needed */ return texture; } void DrawLogoCursor(void) { static GLfloat texMinX, texMinY; static GLfloat texMaxX, texMaxY; static int w, h; int x, y; if (!cursor_texture) { SDL_Surface *image; GLfloat texcoord[4]; /* Load the image (could use SDL_image library here) */ image = SDL_LoadBMP(LOGO_FILE); if (image == NULL) { return; } w = image->w; h = image->h; /* Convert the image into an OpenGL texture */ cursor_texture = SDL_GL_LoadTexture(image, texcoord); /* Make texture coordinates easy to understand */ texMinX = texcoord[0]; texMinY = texcoord[1]; texMaxX = texcoord[2]; texMaxY = texcoord[3]; /* We don't need the original image anymore */ SDL_FreeSurface(image); /* Make sure that the texture conversion is okay */ if (!cursor_texture) { return; } } /* Move the image around */ SDL_GetMouseState(&x, &y); x -= w / 2; y -= h / 2; /* Show the image on the screen */ SDL_GL_Enter2DMode(); glBindTexture(GL_TEXTURE_2D, cursor_texture); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(texMinX, texMinY); glVertex2i(x, y); glTexCoord2f(texMaxX, texMinY); glVertex2i(x + w, y); glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y + h); glTexCoord2f(texMaxX, texMaxY); glVertex2i(x + w, y + h); glEnd(); SDL_GL_Leave2DMode(); } void DrawLogoTexture(void) { static GLfloat texMinX, texMinY; static GLfloat texMaxX, texMaxY; static int x = 0; static int y = 0; static int w, h; static int delta_x = 1; static int delta_y = 1; SDL_Surface *screen = SDL_GetVideoSurface(); if (!global_texture) { SDL_Surface *image; GLfloat texcoord[4]; /* Load the image (could use SDL_image library here) */ image = SDL_LoadBMP(LOGO_FILE); if (image == NULL) { return; } w = image->w; h = image->h; /* Convert the image into an OpenGL texture */ global_texture = SDL_GL_LoadTexture(image, texcoord); /* Make texture coordinates easy to understand */ texMinX = texcoord[0]; texMinY = texcoord[1]; texMaxX = texcoord[2]; texMaxY = texcoord[3]; /* We don't need the original image anymore */ SDL_FreeSurface(image); /* Make sure that the texture conversion is okay */ if (!global_texture) { return; } } /* Move the image around */ x += delta_x; if (x < 0) { x = 0; delta_x = -delta_x; } else if ((x + w) > screen->w) { x = screen->w - w; delta_x = -delta_x; } y += delta_y; if (y < 0) { y = 0; delta_y = -delta_y; } else if ((y + h) > screen->h) { y = screen->h - h; delta_y = -delta_y; } /* Show the image on the screen */ SDL_GL_Enter2DMode(); glBindTexture(GL_TEXTURE_2D, global_texture); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(texMinX, texMinY); glVertex2i(x, y); glTexCoord2f(texMaxX, texMinY); glVertex2i(x + w, y); glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y + h); glTexCoord2f(texMaxX, texMaxY); glVertex2i(x + w, y + h); glEnd(); SDL_GL_Leave2DMode(); } int RunGLTest(int argc, char *argv[], int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa, int sync, int accel) { int i; int rgb_size[3]; int w = 640; int h = 480; int done = 0; int frames; Uint32 start_time, this_time; float color[8][3] = { {1.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 0.0, 1.0}, {0.0, 0.0, 1.0} }; float cube[8][3] = { {0.5, 0.5, -0.5}, {0.5, -0.5, -0.5}, {-0.5, -0.5, -0.5}, {-0.5, 0.5, -0.5}, {-0.5, 0.5, 0.5}, {0.5, 0.5, 0.5}, {0.5, -0.5, 0.5}, {-0.5, -0.5, 0.5} }; Uint32 video_flags; int value; if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } /* See if we should detect the display depth */ if (bpp == 0) { if (SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8) { bpp = 8; } else { bpp = 16; /* More doesn't seem to work */ } } /* Set the flags we want to use for setting the video mode */ video_flags = SDL_OPENGL; for (i = 1; argv[i]; ++i) { if (strcmp(argv[i], "-fullscreen") == 0) { video_flags |= SDL_FULLSCREEN; } } if (noframe) { video_flags |= SDL_NOFRAME; } /* Initialize the display */ switch (bpp) { case 8: rgb_size[0] = 3; rgb_size[1] = 3; rgb_size[2] = 2; break; case 15: case 16: rgb_size[0] = 5; rgb_size[1] = 5; rgb_size[2] = 5; break; default: rgb_size[0] = 8; rgb_size[1] = 8; rgb_size[2] = 8; break; } SDL_GL_SetAttribute(SDL_GL_RED_SIZE, rgb_size[0]); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, rgb_size[1]); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, rgb_size[2]); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if (fsaa) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa); } if (accel >= 0) { SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, accel); } if (SDL_SetVideoMode(w, h, bpp, video_flags) == NULL) { fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError()); SDL_Quit(); exit(1); } if (sync) { SDL_GL_SetSwapInterval(1); } else { SDL_GL_SetSwapInterval(0); } printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel); printf("\n"); printf("Vendor : %s\n", glGetString(GL_VENDOR)); printf("Renderer : %s\n", glGetString(GL_RENDERER)); printf("Version : %s\n", glGetString(GL_VERSION)); printf("Extensions : %s\n", glGetString(GL_EXTENSIONS)); printf("\n"); SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); printf("SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0], value); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); printf("SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1], value); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); printf("SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2], value); SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); printf("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &value); printf("SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value); if (fsaa) { SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); printf("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, value); } if (accel >= 0) { SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); printf("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d\n", accel, value); } if (sync) { printf("Buffer swap interval: requested 1, got %d\n", SDL_GL_GetSwapInterval()); } /* Set the window manager title bar */ SDL_WM_SetCaption("SDL GL test", "testgl"); /* Set the gamma for the window */ if (gamma != 0.0) { SDL_SetGamma(gamma, gamma, gamma); } glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glShadeModel(GL_SMOOTH); /* Loop until done. */ start_time = SDL_GetTicks(); frames = 0; while (!done) { GLenum gl_error; char *sdl_error; SDL_Event event; /* Do our drawing, too. */ glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_QUADS); #ifdef SHADED_CUBE glColor3fv(color[0]); glVertex3fv(cube[0]); glColor3fv(color[1]); glVertex3fv(cube[1]); glColor3fv(color[2]); glVertex3fv(cube[2]); glColor3fv(color[3]); glVertex3fv(cube[3]); glColor3fv(color[3]); glVertex3fv(cube[3]); glColor3fv(color[4]); glVertex3fv(cube[4]); glColor3fv(color[7]); glVertex3fv(cube[7]); glColor3fv(color[2]); glVertex3fv(cube[2]); glColor3fv(color[0]); glVertex3fv(cube[0]); glColor3fv(color[5]); glVertex3fv(cube[5]); glColor3fv(color[6]); glVertex3fv(cube[6]); glColor3fv(color[1]); glVertex3fv(cube[1]); glColor3fv(color[5]); glVertex3fv(cube[5]); glColor3fv(color[4]); glVertex3fv(cube[4]); glColor3fv(color[7]); glVertex3fv(cube[7]); glColor3fv(color[6]); glVertex3fv(cube[6]); glColor3fv(color[5]); glVertex3fv(cube[5]); glColor3fv(color[0]); glVertex3fv(cube[0]); glColor3fv(color[3]); glVertex3fv(cube[3]); glColor3fv(color[4]); glVertex3fv(cube[4]); glColor3fv(color[6]); glVertex3fv(cube[6]); glColor3fv(color[1]); glVertex3fv(cube[1]); glColor3fv(color[2]); glVertex3fv(cube[2]); glColor3fv(color[7]); glVertex3fv(cube[7]); #else /* flat cube */ glColor3f(1.0, 0.0, 0.0); glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); glColor3f(0.0, 1.0, 0.0); glVertex3fv(cube[3]); glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[2]); glColor3f(0.0, 0.0, 1.0); glVertex3fv(cube[0]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[1]); glColor3f(0.0, 1.0, 1.0); glVertex3fv(cube[5]); glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glColor3f(1.0, 1.0, 0.0); glVertex3fv(cube[5]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); glVertex3fv(cube[4]); glColor3f(1.0, 0.0, 1.0); glVertex3fv(cube[6]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[7]); #endif /* SHADED_CUBE */ glEnd(); glMatrixMode(GL_MODELVIEW); glRotatef(5.0, 1.0, 1.0, 1.0); /* Draw 2D logo onto the 3D display */ if (logo) { DrawLogoTexture(); } if (logocursor) { DrawLogoCursor(); } SDL_GL_SwapBuffers(); /* Check for error conditions. */ gl_error = glGetError(); if (gl_error != GL_NO_ERROR) { fprintf(stderr, "testgl: OpenGL error: %d\n", gl_error); } sdl_error = SDL_GetError(); if (sdl_error[0] != '\0') { fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error); SDL_ClearError(); } /* Allow the user to see what's happening */ if (slowly) { SDL_Delay(20); } /* Check if there's a pending event. */ while (SDL_PollEvent(&event)) { done |= HandleEvent(&event); } ++frames; } /* Print out the frames per second */ this_time = SDL_GetTicks(); if (this_time != start_time) { printf("%2.2f FPS\n", ((float) frames / (this_time - start_time)) * 1000.0); } if (global_image) { SDL_FreeSurface(global_image); global_image = NULL; } if (global_texture) { glDeleteTextures(1, &global_texture); global_texture = 0; } if (cursor_texture) { glDeleteTextures(1, &cursor_texture); cursor_texture = 0; } /* Destroy our GL context, etc. */ SDL_Quit(); return (0); } int main(int argc, char *argv[]) { int i, logo, logocursor = 0; int numtests; int bpp = 0; int slowly; float gamma = 0.0; int noframe = 0; int fsaa = 0; int accel = -1; int sync = 0; logo = 0; slowly = 0; numtests = 1; for (i = 1; argv[i]; ++i) { if (strcmp(argv[i], "-twice") == 0) { ++numtests; } if (strcmp(argv[i], "-logo") == 0) { logo = 1; } if (strcmp(argv[i], "-logocursor") == 0) { logocursor = 1; } if (strcmp(argv[i], "-slow") == 0) { slowly = 1; } if (strcmp(argv[i], "-bpp") == 0) { bpp = atoi(argv[++i]); } if (strcmp(argv[i], "-gamma") == 0) { gamma = (float) atof(argv[++i]); } if (strcmp(argv[i], "-noframe") == 0) { noframe = 1; } if (strcmp(argv[i], "-fsaa") == 0) { ++fsaa; } if (strcmp(argv[i], "-accel") == 0) { accel = atoi(argv[++i]); } if (strcmp(argv[i], "-sync") == 0) { ++sync; } if (strncmp(argv[i], "-h", 2) == 0) { printf ("Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-accel n] [-sync] [-fullscreen]\n", argv[0]); exit(0); } } for (i = 0; i < numtests; ++i) { RunGLTest(argc, argv, logo, logocursor, slowly, bpp, gamma, noframe, fsaa, sync, accel); } return 0; } #else /* HAVE_OPENGL */ int main(int argc, char *argv[]) { printf("No OpenGL support on this system\n"); return 1; } #endif /* HAVE_OPENGL */