X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FOpenGL_Windows.cpp;h=15073ce19546940855d9e54b1a598907c24bcdaf;hb=9a6e6bc703ee7942f4c39b4ae13f339654206456;hp=8ce1a4ce34e88a150d2c357054a4601a096d30e6;hpb=d72054c5ab036810ee8a09ce57950aa977fcab06;p=lugaru.git diff --git a/Source/OpenGL_Windows.cpp b/Source/OpenGL_Windows.cpp index 8ce1a4c..15073ce 100644 --- a/Source/OpenGL_Windows.cpp +++ b/Source/OpenGL_Windows.cpp @@ -25,6 +25,8 @@ static bool load_image(const char * fname, TGAImageRec & tex); static bool load_png(const char * fname, TGAImageRec & tex); static bool load_jpg(const char * fname, TGAImageRec & tex); + static bool save_image(const char * fname); + static bool save_png(const char * fname); #endif // ADDED GWC @@ -132,6 +134,43 @@ typedef struct tagPOINT { #endif #if USE_SDL +#define GL_FUNC(ret,fn,params,call,rt) \ + extern "C" { \ + static ret GLAPIENTRY (*p##fn) params = NULL; \ + ret GLAPIENTRY fn params { rt p##fn call; } \ + } +#include "glstubs.h" +#undef GL_FUNC + +static bool lookup_glsym(const char *funcname, void **func, const char *libname) +{ + *func = SDL_GL_GetProcAddress(funcname); + if (*func == NULL) + { + fprintf(stderr, "Failed to find OpenGL symbol \"%s\" in \"%s\"\n", + funcname, libname); + return false; + } + return true; +} + +static bool lookup_all_glsyms(const char *libname) +{ + bool retval = true; + #define GL_FUNC(ret,fn,params,call,rt) \ + if (!lookup_glsym(#fn, (void **) &p##fn, libname)) retval = false; + #include "glstubs.h" + #undef GL_FUNC + return retval; +} + +static void GLAPIENTRY glDeleteTextures_doNothing(GLsizei n, const GLuint *textures) +{ + // no-op. +} + + + void sdlGetCursorPos(POINT *pt) { int x, y; @@ -796,9 +835,20 @@ Boolean SetUp (Game & game) fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError()); return false; } + + const char *libname = "libGL.so.1"; // !!! FIXME: Linux specific! + if (SDL_GL_LoadLibrary(libname) == -1) + { + fprintf(stderr, "SDL_GL_LoadLibrary(\"%s\") failed: %s\n", + libname, SDL_GetError()); + return false; + } + + if (!lookup_all_glsyms(libname)) + return false; } - Uint32 sdlflags = SDL_OPENGL; + Uint32 sdlflags = SDL_OPENGL; // !!! FIXME: SDL_FULLSCREEN? SDL_WM_SetCaption("Lugaru", "lugaru"); SDL_ShowCursor(0); if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL) @@ -807,6 +857,8 @@ Boolean SetUp (Game & game) return false; } + + #elif (defined WIN32) //------------------------------------------------------------------ // create window @@ -1181,6 +1233,12 @@ void CleanUp (void) #if USE_SDL SDL_Quit(); + #define GL_FUNC(ret,fn,params,call,rt) p##fn = NULL; + #include "glstubs.h" + #undef GL_FUNC + // cheat here...static destructors are calling glDeleteTexture() after + // the context is destroyed and libGL unloaded by SDL_Quit(). + pglDeleteTextures = glDeleteTextures_doNothing; #elif (defined WIN32) if (hRC) @@ -1252,7 +1310,8 @@ int main (void) //ofstream os("log.txt"); //os.close(); - SetUp (game); + if (!SetUp (game)) + return 42; while (!gDone&&!game.quit&&(!game.tryquit||!game.registered)) { @@ -2204,7 +2263,7 @@ int main (void) free(f); #else - STUBBED("Non-DevIL screenshot"); + save_image(fname); #endif } @@ -2246,7 +2305,7 @@ static bool load_jpg(const char *file_name, TGAImageRec &tex) struct my_error_mgr jerr; JSAMPROW buffer[1]; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ - FILE *infile = fopen(file_name, "rb") + FILE *infile = fopen(file_name, "rb"); if (infile == NULL) return false; @@ -2286,6 +2345,7 @@ static bool load_jpg(const char *file_name, TGAImageRec &tex) return true; } + /* stolen from public domain example.c code in libpng distribution. */ static bool load_png(const char *file_name, TGAImageRec &tex) { @@ -2370,53 +2430,95 @@ static bool load_png(const char *file_name, TGAImageRec &tex) retval = true; png_done: - png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); - fclose(fp); - return (retval); + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + if (fp) + fclose(fp); + return (retval); +} + + +static bool save_image(const char *file_name) +{ + char *ptr = strrchr(file_name, '.'); + if (ptr) + { + if (stricmp(ptr+1, "png") == 0) + return save_png(file_name); + } + + STUBBED("Unsupported image type"); + return false; } -#if 0 -void save_png(char *file_name /* , ... other image information ... */) + +static bool save_png(const char *file_name) { - FILE *fp; - png_structp png_ptr; - png_infop info_ptr; - - /* open the file */ - fp = fopen(file_name, "wb"); - if (fp == NULL) - return (ERROR); - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) - { - fclose(fp); - return (ERROR); - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) - { - fclose(fp); - png_destroy_write_struct(&png_ptr, png_infopp_NULL); - return (ERROR); - } - - if (setjmp(png_jmpbuf(png_ptr))) - { - /* If we get here, we had a problem reading the file */ - fclose(fp); - png_destroy_write_struct(&png_ptr, &info_ptr); - return (ERROR); - } - - png_init_io(png_ptr, fp); - png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); - return (OK); + FILE *fp = NULL; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + bool retval = false; + + fp = fopen(file_name, "wb"); + if (fp == NULL) + return false; + + png_bytep *row_pointers = new png_bytep[kContextHeight]; + png_bytep screenshot = new png_byte[kContextWidth * kContextHeight * 3]; + if ((!screenshot) || (!row_pointers)) + goto save_png_done; + + glGetError(); + glReadPixels(0, 0, kContextWidth, kContextHeight, + GL_RGB, GL_UNSIGNED_BYTE, screenshot); + if (glGetError() != GL_NO_ERROR) + goto save_png_done; + + for (int i = 0; i < kContextHeight; i++) + row_pointers[i] = screenshot + ((kContextWidth * ((kContextHeight-1) - i)) * 3); + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) + goto save_png_done; + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + goto save_png_done; + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_init_io(png_ptr, fp); + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_set_IHDR(png_ptr, info_ptr, kContextWidth, kContextHeight, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_write_image(png_ptr, row_pointers); + + if (setjmp(png_jmpbuf(png_ptr))) + goto save_png_done; + + png_write_end(png_ptr, NULL); + retval = true; + +save_png_done: + png_destroy_write_struct(&png_ptr, &info_ptr); + delete[] screenshot; + delete[] row_pointers; + if (fp) + fclose(fp); + if (!retval) + unlink(ConvertFileName(file_name)); + return retval; } -#endif #endif