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
This commit is contained in:
stephena 2004-06-23 00:15:32 +00:00
parent 464972cc31
commit db6d064ebf
7 changed files with 77 additions and 62 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 <SDL.h> #include <SDL.h>
@ -47,36 +47,34 @@ FrameBufferGL::~FrameBufferGL()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::createScreen() bool FrameBufferGL::createScreen()
{ {
uInt32 screenWidth = 0, screenHeight = 0;
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, myRGB[0] ); SDL_GL_SetAttribute( SDL_GL_RED_SIZE, myRGB[0] );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, myRGB[1] ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, myRGB[1] );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, myRGB[2] ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, myRGB[2] );
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, myRGB[3] ); SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, myRGB[3] );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
GLint viewportX = 0, viewportY = 0; myDimensions.w = (Uint16) (myWidth * theZoomLevel * theAspectRatio);
uInt32 screenWidth = 0; myDimensions.h = (Uint16) myHeight * theZoomLevel;
uInt32 screenHeight = 0;
uInt32 imageWidth = (uInt32) (myWidth * theZoomLevel * theAspectRatio);
uInt32 imageHeight = myHeight * theZoomLevel;
// Determine if we're in fullscreen or windowed mode // Determine if we're in fullscreen or windowed mode
// In fullscreen mode, we clip the SDL screen to known resolutions // In fullscreen mode, we clip the SDL screen to known resolutions
// In windowed mode, we use the actual image resolution for the SDL screen // In windowed mode, we use the actual image resolution for the SDL screen
if(mySDLFlags & SDL_FULLSCREEN) if(mySDLFlags & SDL_FULLSCREEN)
{ {
SDL_Rect rect = viewport(imageWidth, imageHeight); SDL_Rect rect = viewport(myDimensions.w, myDimensions.h);
viewportX = rect.x; myDimensions.x = rect.x;
viewportY = rect.y; myDimensions.y = rect.y;
screenWidth = rect.w - 1; screenWidth = rect.w;
screenHeight = rect.h - 1; screenHeight = rect.h;
} }
else else
{ {
screenWidth = imageWidth; myDimensions.x = myDimensions.y = 0;
screenHeight = imageHeight; screenWidth = myDimensions.w;
viewportX = viewportY = 0; screenHeight = myDimensions.h;
} }
myScreen = SDL_SetVideoMode(screenWidth, screenHeight, 0, mySDLFlags); myScreen = SDL_SetVideoMode(screenWidth, screenHeight, 0, mySDLFlags);
@ -89,14 +87,13 @@ bool FrameBufferGL::createScreen()
glPushAttrib(GL_ENABLE_BIT); glPushAttrib(GL_ENABLE_BIT);
// Center the screen horizontally and vertically // Center the screen horizontally and vertically
glViewport(viewportX, viewportY, imageWidth, imageHeight); glViewport(0, 0, screenWidth, screenHeight);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glOrtho(0.0, (GLdouble) imageWidth/(theZoomLevel * theAspectRatio), glOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0);
(GLdouble) imageHeight/theZoomLevel, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
@ -106,9 +103,6 @@ bool FrameBufferGL::createScreen()
createTextures(); createTextures();
#endif #endif
// Make sure any old parts of the screen are erased
glClear(GL_COLOR_BUFFER_BIT);
theRedrawEntireFrameIndicator = true; theRedrawEntireFrameIndicator = true;
return true; return true;
} }
@ -199,6 +193,9 @@ bool FrameBufferGL::init()
break; break;
} }
// Set the color used to erase the screen
glClearColor(0, 0, 0, 1);
// Create the screen // Create the screen
if(!createScreen()) if(!createScreen())
return false; return false;
@ -286,14 +283,31 @@ void FrameBufferGL::drawMediaSource()
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h, glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels); GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 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); glBegin(GL_QUADS);
glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0); glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0);
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(myWidth, 0); glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(myWidth, 0);
glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(myWidth, myHeight); glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(myWidth, myHeight);
glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, myHeight); glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, myHeight);
glEnd(); glEnd();
*/
// The frame doesn't need to be completely redrawn anymore // The frame doesn't need to be completely redrawn anymore
theRedrawEntireFrameIndicator = false; theRedrawEntireFrameIndicator = false;
@ -357,10 +371,10 @@ void FrameBufferGL::scanline(uInt32 row, uInt8* data)
{ {
// Invert the row, since OpenGL rows start at the bottom // Invert the row, since OpenGL rows start at the bottom
// of the framebuffer // of the framebuffer
row = winHeight() - row - 1; row = myDimensions.h - row - 1;
glPixelStorei(GL_PACK_ALIGNMENT, 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); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D); 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; return true;
} }
@ -520,16 +540,17 @@ SDL_Rect FrameBufferGL::viewport(uInt32 width, uInt32 height)
}; };
// List of valid fullscreen OpenGL modes // List of valid fullscreen OpenGL modes
Screenmode myScreenmode[6] = { Screenmode myScreenmode[7] = {
{320, 240 }, {320, 240 },
{640, 480 }, {640, 480 },
{800, 600 }, {800, 600 },
{1024, 768 }, {1024, 768 },
{1280, 1024}, {1280, 1024},
{1400, 1050},
{1600, 1200} {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) if(width <= myScreenmode[i].w && height <= myScreenmode[i].h)
{ {

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 #ifndef FRAMEBUFFER_GL_HXX
@ -34,7 +34,7 @@ class MediaSource;
This class implements an SDL OpenGL framebuffer. This class implements an SDL OpenGL framebuffer.
@author Stephen Anthony @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 class FrameBufferGL : public FrameBufferSDL
{ {
@ -74,16 +74,6 @@ class FrameBufferGL : public FrameBufferSDL
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
{ return SDL_MapRGB(myTexture->format, r, g, 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. This routine is called to get the specified scanline data.

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 #ifndef FRAMEBUFFER_SDL_HXX
@ -35,7 +35,7 @@
the core FrameBuffer. the core FrameBuffer.
@author Stephen Anthony @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 class FrameBufferSDL : public FrameBuffer
{ {
@ -92,6 +92,16 @@ class FrameBufferSDL : public FrameBuffer
*/ */
uInt32 maxWindowSizeForScreen(); 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. Set the title and icon for the main SDL window.
*/ */
@ -143,6 +153,10 @@ class FrameBufferSDL : public FrameBuffer
// Used to get window-manager specifics // Used to get window-manager specifics
SDL_SysWMinfo myWMInfo; 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 // Indicates if we are running under X11
bool x11Available; bool x11Available;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 #ifndef FRAMEBUFFER_SOFT_HXX
@ -35,7 +35,7 @@ class RectList;
This class implements an SDL software framebuffer. This class implements an SDL software framebuffer.
@author Stephen Anthony @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 class FrameBufferSoft : public FrameBufferSDL
{ {
@ -69,16 +69,6 @@ class FrameBufferSoft : public FrameBufferSDL
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
{ return SDL_MapRGB(myScreen->format, r, g, 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. This routine is called to get the specified scanline data.

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 <png.h> #include <png.h>
@ -68,10 +68,10 @@ string Snapshot::savePNG(string filename)
png_structp png_ptr = 0; png_structp png_ptr = 0;
png_infop info_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 // as the framebuffer dimensions
uInt32 width = myFrameBuffer.winWidth(); uInt32 width = myFrameBuffer.imageWidth();
uInt32 height = myFrameBuffer.winHeight(); uInt32 height = myFrameBuffer.imageHeight();
ofstream* out = new ofstream(filename.c_str(), ios_base::binary); ofstream* out = new ofstream(filename.c_str(), ios_base::binary);
if(!out) if(!out)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 <fstream> #include <fstream>
@ -381,7 +381,7 @@ void handleEvents()
theDisplay->resize(-1); theDisplay->resize(-1);
else if(key == SDLK_RETURN) else if(key == SDLK_RETURN)
{ {
#ifdef WIN32 #ifdef FIXMEWIN32
// Disable fullscreen OpenGL mode - FIXME // Disable fullscreen OpenGL mode - FIXME
if(theSettings->getString("video") == "gl") if(theSettings->getString("video") == "gl")
theDisplay->showMessage("Fullscreen OpenGL disabled"); theDisplay->showMessage("Fullscreen OpenGL disabled");

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 #ifndef FRAMEBUFFER_HXX
@ -35,7 +35,7 @@ class Console;
can be changed. can be changed.
@author Stephen Anthony @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 class FrameBuffer
{ {
@ -196,12 +196,12 @@ class FrameBuffer
/** /**
This routine is called to get the width of the onscreen image. 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. 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. This routine is called to get the specified scanline data.