/* ************************************************************************* ArmageTron -- Just another Tron Lightcycle Game in 3D. Copyright (C) 2000 Manuel Moos (manuel@moosnet.de) ************************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *************************************************************************** */ #include "defs.h" #ifndef DEDICATED #include "rSDL.h" #endif #include "rSysdep.h" #include "tInitExit.h" #include "rConsole.h" #include "config.h" #include #include "rScreen.h" #include "rGL.h" #ifndef DEDICATED #ifndef SDL_OPENGL #ifndef DIRTY #define DIRTY #endif #endif //#ifndef SDL_OPENGL //#error "need SDL 1.1" //#endif #ifndef DIRTY // nothing to be done. /* //#elif defined(HAVE_FXMESA) #include #include static fxMesaContext ctx=NULL; */ #elif defined(WIN32) #include #include #include "rGL.h" static HDC hDC=NULL; static HGLRC hRC=NULL; #elif defined(unix) || defined(__unix__) #include static GLXContext cx; Display *dpy=NULL; Window win; #endif #ifdef DIRTY #include // graphics initialisation and cleanup: bool sr_InitGL(){ SDL_SysWMinfo system; SDL_VERSION(&system.version); if (!SDL_GetWMInfo(&system)){ std::cerr << "Video information not available!\n"; return(false); } /* con << "SDL version: " << (int)system.version.major << "." << (int)system.version.minor << "." << (int)system.version.patch << '\n'; */ /* //#ifdef HAVE_FXMESA if(!ctx){ int x=fxQueryHardware(); if(x){ std::cerr << "No 3Dfx hardware available.\n" << x << '\n'; return(false); } GLint attribs[]={FXMESA_DOUBLEBUFFER,FXMESA_DEPTH_SIZE,16,FXMESA_NONE}; ctx=fxMesaCreateBestContext(0,sr_screenWidth,sr_screenHeight,attribs); if (!ctx){ std::cerr << "Could not create FX rendering context!\n"; return(false); } fxMesaMakeCurrent(ctx); } */ #ifdef WIN32 // windows GL initialisation stolen from // http://www.geocities.com/SiliconValley/Code/1219/opengl32.html if (!hRC){ HWND hWnd=system.window; PIXELFORMATDESCRIPTOR pfd; int iFormat; // get the device context (DC) hDC = GetDC( hWnd ); if (!hDC) return false; // set the pixel format for the DC ZeroMemory( &pfd, sizeof( pfd ) ); pfd.nSize = sizeof( pfd ); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = currentScreensetting.colorDepth ? 24 : 16; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE; iFormat = ChoosePixelFormat( hDC, &pfd ); SetPixelFormat( hDC, iFormat, &pfd ); // create and enable the render context (RC) hRC = wglCreateContext( hDC ); if (!hRC || !wglMakeCurrent( hDC, hRC )) return false; } #elif defined(unix) || defined(__unix__) if (system.subsystem!=SDL_SYSWM_X11){ std::cerr << "System is not X11!\n"; std::cerr << (int)system.subsystem << "!=" << (int)SDL_SYSWM_X11 <<'\n'; return false; } if(!dpy){ dpy=system.info.x11.display; win=system.info.x11.window; int errorbase,tEventbase; if (glXQueryExtension(dpy,&errorbase,&tEventbase) == False){ std::cerr << "OpenGL through GLX not supported.\n"; return false; } int configuration[]={GLX_DOUBLEBUFFER,GLX_RGBA,GLX_DEPTH_SIZE ,12, GLX_RED_SIZE,1, GLX_BLUE_SIZE,1,GLX_GREEN_SIZE,1,None}; XVisualInfo *vi=glXChooseVisual(dpy,DefaultScreen(dpy),configuration); if(vi== NULL){ std::cerr << "Could not initialize Visual.\n"; return false; } cx=glXCreateContext(dpy,vi, NULL,True); if(cx== NULL){ std::cerr << "Could not initialize GL context.\n"; return false; } if (!glXMakeCurrent(dpy,win,cx)){ dpy=0; return false; } } #endif return true; } void sr_ExitGL(){ SDL_SysWMinfo system; SDL_GetWMInfo(&system); /* #ifdef HAVE_FXMESA if(ctx){ fxMesaDestroyContext(ctx); ctx=NULL; fxCloseHardware(); } */ #if defined(WIN32) HWND hWnd=system.window; // windows GL cleanup stolen from // http://www.geocities.com/SiliconValley/Code/1219/opengl32.html if(hRC){ wglMakeCurrent( NULL, NULL ); wglDeleteContext( hRC ); ReleaseDC( hWnd, hDC ); hRC=NULL; hDC=NULL; } #elif defined(unix) || defined(__unix__) if(dpy){ // glXReleaseBuffersMESA( dpy, win ); glXMakeCurrent(dpy,None,NULL); glXDestroyContext(dpy, cx ); dpy=NULL; } #endif } #endif // DIRTY bool sr_screenshotIsPlanned=false; static void make_screenshot(){ #ifndef DEDICATED static int number=0; number++; SDL_Surface *image; SDL_Surface *temp; int idx; image = SDL_CreateRGBSurface(SDL_SWSURFACE, sr_screenWidth, sr_screenHeight, 24, 0x0000FF, 0x00FF00, 0xFF0000 ,0x00000000); temp = SDL_CreateRGBSurface(SDL_SWSURFACE, sr_screenWidth, sr_screenHeight, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0); glReadPixels(0,0,sr_screenWidth, sr_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, image->pixels); for (idx = 0; idx < sr_screenHeight; idx++) { memcpy(reinterpret_cast(temp->pixels) + 3 * sr_screenWidth * idx, reinterpret_cast(image->pixels)+ 3 * sr_screenWidth*(sr_screenHeight - idx-1), 3*sr_screenWidth); } //memcpy(image->pixels,temp->pixels,sr_screenWidth * sr_screenHeight * 3); tString fileName="screenshot_"; fileName << number; fileName << ".bmp"; SDL_SaveBMP(temp, fileName); SDL_FreeSurface(image); SDL_FreeSurface(temp); #endif } // buffer swap: void sr_SwapGL(){ if (!sr_glOut) return; sr_LockSDL(); rPerFrameTask::DoPerFrameTasks(); glFinish(); #if defined(SDL_OPENGL) if (lastSuccess.useSDL) SDL_GL_SwapBuffers(); //#elif defined(HAVE_FXMESA) //fxMesaSwapBuffers(); #endif #ifdef DIRTY if (!lastSuccess.useSDL){ #if defined(WIN32) SwapBuffers( hDC ); #elif defined(unix) || defined(__unix__) glXSwapBuffers(dpy,win); #endif } #endif if (sr_screenshotIsPlanned){ make_screenshot(); sr_screenshotIsPlanned=false; } sr_UnlockSDL(); #ifdef WIN32 Sleep(10); // let other tasks breathe! #endif } #endif // dedicated #ifndef DEDICATED static SDL_mutex *mut; static void stuff_init(){ mut=SDL_CreateMutex(); } static tInitExit stuff_ie(&stuff_init); #endif void sr_LockSDL(){ //std::cerr << "locking..."; #ifndef DEDICATED #ifndef WIN32 //SDL_mutexP(mut); #endif #endif //std::cerr << " locked!\n"; } void sr_UnlockSDL(){ //std::cerr << "unlocking..."; #ifndef DEDICATED #ifndef WIN32 //SDL_mutexV(mut); #endif #endif //std::cerr << " unlocked!\n"; } void sr_ClearGL(){ #ifndef DEDICATED if (sr_glOut){ /* if (sr_screenshotIsPlanned){ make_screenshot(); sr_screenshotIsPlanned=false; } */ glClearColor(0.0,0.0,0.0,1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } #endif }