From db6d064ebfe3e0d22114291e08bc55d7a1f94b88 Mon Sep 17 00:00:00 2001 From: stephena Date: Wed, 23 Jun 2004 00:15:32 +0000 Subject: [PATCH] Reworked the fullscreen OpenGL mode. Finally, Windows fullscreen OpenGL works! Still to do is scale the OpenGL text to the current screen size. Right now, it still shows up very small (and not centered). Also, fullscreen OpenGL snapshots aren't quite working right yet. Both of these are easy to fix. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@276 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/common/FrameBufferGL.cxx | 73 +++++++++++++++++---------- stella/src/common/FrameBufferGL.hxx | 14 +---- stella/src/common/FrameBufferSDL.hxx | 18 ++++++- stella/src/common/FrameBufferSoft.hxx | 14 +---- stella/src/common/Snapshot.cxx | 8 +-- stella/src/common/mainSDL.cxx | 4 +- stella/src/emucore/FrameBuffer.hxx | 8 +-- 7 files changed, 77 insertions(+), 62 deletions(-) diff --git a/stella/src/common/FrameBufferGL.cxx b/stella/src/common/FrameBufferGL.cxx index 60a71da79..4d3e49ff5 100644 --- a/stella/src/common/FrameBufferGL.cxx +++ b/stella/src/common/FrameBufferGL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferGL.cxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ +// $Id: FrameBufferGL.cxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ //============================================================================ #include @@ -47,36 +47,34 @@ FrameBufferGL::~FrameBufferGL() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferGL::createScreen() { + uInt32 screenWidth = 0, screenHeight = 0; + SDL_GL_SetAttribute( SDL_GL_RED_SIZE, myRGB[0] ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, myRGB[1] ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, myRGB[2] ); SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, myRGB[3] ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - GLint viewportX = 0, viewportY = 0; - uInt32 screenWidth = 0; - uInt32 screenHeight = 0; - - uInt32 imageWidth = (uInt32) (myWidth * theZoomLevel * theAspectRatio); - uInt32 imageHeight = myHeight * theZoomLevel; + myDimensions.w = (Uint16) (myWidth * theZoomLevel * theAspectRatio); + myDimensions.h = (Uint16) myHeight * theZoomLevel; // Determine if we're in fullscreen or windowed mode // In fullscreen mode, we clip the SDL screen to known resolutions // In windowed mode, we use the actual image resolution for the SDL screen if(mySDLFlags & SDL_FULLSCREEN) { - SDL_Rect rect = viewport(imageWidth, imageHeight); + SDL_Rect rect = viewport(myDimensions.w, myDimensions.h); - viewportX = rect.x; - viewportY = rect.y; - screenWidth = rect.w - 1; - screenHeight = rect.h - 1; + myDimensions.x = rect.x; + myDimensions.y = rect.y; + screenWidth = rect.w; + screenHeight = rect.h; } else { - screenWidth = imageWidth; - screenHeight = imageHeight; - viewportX = viewportY = 0; + myDimensions.x = myDimensions.y = 0; + screenWidth = myDimensions.w; + screenHeight = myDimensions.h; } myScreen = SDL_SetVideoMode(screenWidth, screenHeight, 0, mySDLFlags); @@ -89,14 +87,13 @@ bool FrameBufferGL::createScreen() glPushAttrib(GL_ENABLE_BIT); // Center the screen horizontally and vertically - glViewport(viewportX, viewportY, imageWidth, imageHeight); + glViewport(0, 0, screenWidth, screenHeight); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0.0, (GLdouble) imageWidth/(theZoomLevel * theAspectRatio), - (GLdouble) imageHeight/theZoomLevel, 0.0, 0.0, 1.0); + glOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -106,9 +103,6 @@ bool FrameBufferGL::createScreen() createTextures(); #endif - // Make sure any old parts of the screen are erased - glClear(GL_COLOR_BUFFER_BIT); - theRedrawEntireFrameIndicator = true; return true; } @@ -199,6 +193,9 @@ bool FrameBufferGL::init() break; } + // Set the color used to erase the screen + glClearColor(0, 0, 0, 1); + // Create the screen if(!createScreen()) return false; @@ -286,14 +283,31 @@ void FrameBufferGL::drawMediaSource() glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - glColor3f(0.0, 0.0, 0.0); +// glColor3f(0.0, 0.0, 0.0); +// glRecti(0, 0, myDimensions.w, myDimensions.h); + glBegin(GL_QUADS); + glTexCoord2f(myTexCoord[0], myTexCoord[1]); + glVertex2i(myDimensions.x, myDimensions.y); + + glTexCoord2f(myTexCoord[2], myTexCoord[1]); + glVertex2i(myDimensions.x + myDimensions.w, myDimensions.y); + + glTexCoord2f(myTexCoord[2], myTexCoord[3]); + glVertex2i(myDimensions.x + myDimensions.w, myDimensions.y + myDimensions.h); + + glTexCoord2f(myTexCoord[0], myTexCoord[3]); + glVertex2i(myDimensions.x, myDimensions.y + myDimensions.h); + glEnd(); + +/* glBegin(GL_QUADS); glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0); glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(myWidth, 0); glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(myWidth, myHeight); glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, myHeight); glEnd(); +*/ // The frame doesn't need to be completely redrawn anymore theRedrawEntireFrameIndicator = false; @@ -357,10 +371,10 @@ void FrameBufferGL::scanline(uInt32 row, uInt8* data) { // Invert the row, since OpenGL rows start at the bottom // of the framebuffer - row = winHeight() - row - 1; + row = myDimensions.h - row - 1; glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, row, winWidth(), 1, GL_RGB, GL_UNSIGNED_BYTE, data); + glReadPixels(0, row, myDimensions.w, 1, GL_RGB, GL_UNSIGNED_BYTE, data); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -468,6 +482,12 @@ bool FrameBufferGL::createTextures() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); + // Make sure any old parts of the screen are erased + // Do it for both buffers! + glClear(GL_COLOR_BUFFER_BIT); + SDL_GL_SwapBuffers(); + glClear(GL_COLOR_BUFFER_BIT); + return true; } @@ -520,16 +540,17 @@ SDL_Rect FrameBufferGL::viewport(uInt32 width, uInt32 height) }; // List of valid fullscreen OpenGL modes - Screenmode myScreenmode[6] = { + Screenmode myScreenmode[7] = { {320, 240 }, {640, 480 }, {800, 600 }, {1024, 768 }, {1280, 1024}, + {1400, 1050}, {1600, 1200} }; - for(uInt32 i = 0; i < 6; i++) + for(uInt32 i = 0; i < 7; i++) { if(width <= myScreenmode[i].w && height <= myScreenmode[i].h) { diff --git a/stella/src/common/FrameBufferGL.hxx b/stella/src/common/FrameBufferGL.hxx index dbaff9136..52280b4a9 100644 --- a/stella/src/common/FrameBufferGL.hxx +++ b/stella/src/common/FrameBufferGL.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferGL.hxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ +// $Id: FrameBufferGL.hxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_GL_HXX @@ -34,7 +34,7 @@ class MediaSource; This class implements an SDL OpenGL framebuffer. @author Stephen Anthony - @version $Id: FrameBufferGL.hxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ + @version $Id: FrameBufferGL.hxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ */ class FrameBufferGL : public FrameBufferSDL { @@ -74,16 +74,6 @@ class FrameBufferGL : public FrameBufferSDL virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) { return SDL_MapRGB(myTexture->format, r, g, b); } - /** - This routine is called to get the width of the onscreen image. - */ - virtual uInt32 winWidth() { return (uInt32) (myWidth * theZoomLevel * theAspectRatio); } - - /** - This routine is called to get the height of the onscreen image. - */ - virtual uInt32 winHeight() { return myHeight * theZoomLevel; } - /** This routine is called to get the specified scanline data. diff --git a/stella/src/common/FrameBufferSDL.hxx b/stella/src/common/FrameBufferSDL.hxx index f56f81b4c..4c79dc1ee 100644 --- a/stella/src/common/FrameBufferSDL.hxx +++ b/stella/src/common/FrameBufferSDL.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferSDL.hxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ +// $Id: FrameBufferSDL.hxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_SDL_HXX @@ -35,7 +35,7 @@ the core FrameBuffer. @author Stephen Anthony - @version $Id: FrameBufferSDL.hxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ + @version $Id: FrameBufferSDL.hxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ */ class FrameBufferSDL : public FrameBuffer { @@ -92,6 +92,16 @@ class FrameBufferSDL : public FrameBuffer */ uInt32 maxWindowSizeForScreen(); + /** + This routine is called to get the width of the onscreen image. + */ + uInt32 imageWidth() { return myDimensions.w; } + + /** + This routine is called to get the height of the onscreen image. + */ + uInt32 imageHeight() { return myDimensions.h; } + /** Set the title and icon for the main SDL window. */ @@ -143,6 +153,10 @@ class FrameBufferSDL : public FrameBuffer // Used to get window-manager specifics SDL_SysWMinfo myWMInfo; + // Indicates the width/height and origin x/y of the onscreen image + // (these may be different than the screen/window dimensions) + SDL_Rect myDimensions; + // Indicates if we are running under X11 bool x11Available; diff --git a/stella/src/common/FrameBufferSoft.hxx b/stella/src/common/FrameBufferSoft.hxx index 8a6f71287..6a6af08bc 100644 --- a/stella/src/common/FrameBufferSoft.hxx +++ b/stella/src/common/FrameBufferSoft.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferSoft.hxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ +// $Id: FrameBufferSoft.hxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_SOFT_HXX @@ -35,7 +35,7 @@ class RectList; This class implements an SDL software framebuffer. @author Stephen Anthony - @version $Id: FrameBufferSoft.hxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ + @version $Id: FrameBufferSoft.hxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ */ class FrameBufferSoft : public FrameBufferSDL { @@ -69,16 +69,6 @@ class FrameBufferSoft : public FrameBufferSDL virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) { return SDL_MapRGB(myScreen->format, r, g, b); } - /** - This routine is called to get the width of the onscreen image. - */ - virtual uInt32 winWidth() { return myScreen->w; } - - /** - This routine is called to get the height of the onscreen image. - */ - virtual uInt32 winHeight() { return myScreen->h; } - /** This routine is called to get the specified scanline data. diff --git a/stella/src/common/Snapshot.cxx b/stella/src/common/Snapshot.cxx index 988c9d61f..be327dd67 100644 --- a/stella/src/common/Snapshot.cxx +++ b/stella/src/common/Snapshot.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Snapshot.cxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ +// $Id: Snapshot.cxx,v 1.3 2004-06-23 00:15:32 stephena Exp $ //============================================================================ #include @@ -68,10 +68,10 @@ string Snapshot::savePNG(string filename) png_structp png_ptr = 0; png_infop info_ptr = 0; - // Get actual screen dimensions. which are not always the same + // Get actual image dimensions. which are not always the same // as the framebuffer dimensions - uInt32 width = myFrameBuffer.winWidth(); - uInt32 height = myFrameBuffer.winHeight(); + uInt32 width = myFrameBuffer.imageWidth(); + uInt32 height = myFrameBuffer.imageHeight(); ofstream* out = new ofstream(filename.c_str(), ios_base::binary); if(!out) diff --git a/stella/src/common/mainSDL.cxx b/stella/src/common/mainSDL.cxx index 2a4799c20..e9ff2fff0 100644 --- a/stella/src/common/mainSDL.cxx +++ b/stella/src/common/mainSDL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: mainSDL.cxx,v 1.6 2004-06-16 00:31:32 stephena Exp $ +// $Id: mainSDL.cxx,v 1.7 2004-06-23 00:15:32 stephena Exp $ //============================================================================ #include @@ -381,7 +381,7 @@ void handleEvents() theDisplay->resize(-1); else if(key == SDLK_RETURN) { -#ifdef WIN32 +#ifdef FIXMEWIN32 // Disable fullscreen OpenGL mode - FIXME if(theSettings->getString("video") == "gl") theDisplay->showMessage("Fullscreen OpenGL disabled"); diff --git a/stella/src/emucore/FrameBuffer.hxx b/stella/src/emucore/FrameBuffer.hxx index ed2d66caa..289b84040 100644 --- a/stella/src/emucore/FrameBuffer.hxx +++ b/stella/src/emucore/FrameBuffer.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBuffer.hxx,v 1.8 2004-06-20 23:30:48 stephena Exp $ +// $Id: FrameBuffer.hxx,v 1.9 2004-06-23 00:15:32 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_HXX @@ -35,7 +35,7 @@ class Console; can be changed. @author Stephen Anthony - @version $Id: FrameBuffer.hxx,v 1.8 2004-06-20 23:30:48 stephena Exp $ + @version $Id: FrameBuffer.hxx,v 1.9 2004-06-23 00:15:32 stephena Exp $ */ class FrameBuffer { @@ -196,12 +196,12 @@ class FrameBuffer /** This routine is called to get the width of the onscreen image. */ - virtual uInt32 winWidth() = 0; + virtual uInt32 imageWidth() = 0; /** This routine is called to get the height of the onscreen image. */ - virtual uInt32 winHeight() = 0; + virtual uInt32 imageHeight() = 0; /** This routine is called to get the specified scanline data.