mirror of https://github.com/stella-emu/stella.git
Now that OpenGL support seems to be working in Windows, I'm removing these dead D3D files. I *really* don't want to add yet another renderer to Stella.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1392 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
09ff92d46c
commit
5da06ccdca
|
@ -1,576 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: FrameBufferD3D.cxx,v 1.2 2007-09-03 18:37:24 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifdef DISPLAY_D3D
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FrameBufferD3D.hxx"
|
||||
#include "MediaSrc.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Font.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferD3D::FrameBufferD3D(OSystem* osystem)
|
||||
: FrameBuffer(osystem),
|
||||
myTexture(NULL),
|
||||
myHaveTexRectEXT(false),
|
||||
myFilterParamName("GL_NEAREST"),
|
||||
myScaleFactor(1.0),
|
||||
myDirtyFlag(true)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferD3D::~FrameBufferD3D()
|
||||
{
|
||||
if(myTexture)
|
||||
SDL_FreeSurface(myTexture);
|
||||
|
||||
p_glDeleteTextures(1, &myBuffer.texture);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferD3D::loadFuncs(const string& library)
|
||||
{
|
||||
return myFuncsLoaded = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferD3D::initSubsystem(VideoMode mode)
|
||||
{
|
||||
mySDLFlags |= SDL_OPENGL;
|
||||
|
||||
// Set up the OpenGL attributes
|
||||
myDepth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
||||
switch(myDepth)
|
||||
{
|
||||
case 15:
|
||||
case 16:
|
||||
myRGB[0] = 5; myRGB[1] = 5; myRGB[2] = 5; myRGB[3] = 0;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
myRGB[0] = 8; myRGB[1] = 8; myRGB[2] = 8; myRGB[3] = 0;
|
||||
break;
|
||||
default: // This should never happen
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the screen
|
||||
if(!setVidMode(mode))
|
||||
return false;
|
||||
|
||||
// Now check to see what color components were actually created
|
||||
SDL_GL_GetAttribute( SDL_GL_RED_SIZE, (int*)&myRGB[0] );
|
||||
SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, (int*)&myRGB[1] );
|
||||
SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, (int*)&myRGB[2] );
|
||||
SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, (int*)&myRGB[3] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FrameBufferD3D::about()
|
||||
{
|
||||
string extensions;
|
||||
if(myHaveTexRectEXT) extensions += "GL_TEXTURE_RECTANGLE_ARB ";
|
||||
if(extensions == "") extensions = "None";
|
||||
|
||||
ostringstream out;
|
||||
out << "Video rendering: OpenGL mode" << endl
|
||||
<< " Vendor: " << p_glGetString(GL_VENDOR) << endl
|
||||
<< " Renderer: " << p_glGetString(GL_RENDERER) << endl
|
||||
<< " Version: " << p_glGetString(GL_VERSION) << endl
|
||||
<< " Color: " << myDepth << " bit, " << myRGB[0] << "-"
|
||||
<< myRGB[1] << "-" << myRGB[2] << "-" << myRGB[3] << endl
|
||||
<< " Filter: " << myFilterParamName << endl
|
||||
<< " Extensions: " << extensions << endl;
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferD3D::setVidMode(VideoMode mode)
|
||||
{
|
||||
myScreenDim.x = myScreenDim.y = 0;
|
||||
myScreenDim.w = mode.screen_w;
|
||||
myScreenDim.h = mode.screen_h;
|
||||
|
||||
myImageDim.x = mode.image_x;
|
||||
myImageDim.y = mode.image_y;
|
||||
myImageDim.w = mode.image_w;
|
||||
myImageDim.h = mode.image_h;
|
||||
|
||||
// Activate stretching if its been requested and it makes sense to do so
|
||||
myScaleFactor = 1.0;
|
||||
if(fullScreen() && (mode.image_w < mode.screen_w) &&
|
||||
(mode.image_h < mode.screen_h))
|
||||
{
|
||||
const string& gl_fsmax = myOSystem->settings().getString("gl_fsmax");
|
||||
bool inUIMode =
|
||||
myOSystem->eventHandler().state() == EventHandler::S_LAUNCHER ||
|
||||
myOSystem->eventHandler().state() == EventHandler::S_DEBUGGER;
|
||||
|
||||
// Only stretch in certain modes
|
||||
if((gl_fsmax == "always") ||
|
||||
(inUIMode && gl_fsmax == "ui") ||
|
||||
(!inUIMode && gl_fsmax == "tia"))
|
||||
{
|
||||
float scaleX = float(myImageDim.w) / myScreenDim.w;
|
||||
float scaleY = float(myImageDim.h) / myScreenDim.h;
|
||||
|
||||
if(scaleX > scaleY)
|
||||
myScaleFactor = float(myScreenDim.w) / myImageDim.w;
|
||||
else
|
||||
myScaleFactor = float(myScreenDim.h) / myImageDim.h;
|
||||
|
||||
myImageDim.w = (Uint16) (myScaleFactor * myImageDim.w);
|
||||
myImageDim.h = (Uint16) (myScaleFactor * myImageDim.h);
|
||||
myImageDim.x = (myScreenDim.w - myImageDim.w) / 2;
|
||||
myImageDim.y = (myScreenDim.h - myImageDim.h) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the zoom level and scaler into one quantity
|
||||
myScaleFactor *= (float) mode.zoom;
|
||||
|
||||
GLdouble orthoWidth = (GLdouble)
|
||||
(myImageDim.w / myScaleFactor);
|
||||
GLdouble orthoHeight = (GLdouble)
|
||||
(myImageDim.h / myScaleFactor);
|
||||
|
||||
// Create screen containing GL context
|
||||
if(myScreen)
|
||||
{
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_GL_SwapBuffers();
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
|
||||
if(myScreen == NULL)
|
||||
{
|
||||
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
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 );
|
||||
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
|
||||
|
||||
// There's no guarantee this is supported on all hardware
|
||||
// We leave it to the user to test and decide
|
||||
int vsync = myOSystem->settings().getBool("gl_vsync") ? 1 : 0;
|
||||
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, vsync );
|
||||
|
||||
loadFuncs("");
|
||||
|
||||
// Check for some extensions that can potentially speed up operation
|
||||
cerr << "address = " << (int) p_glGetString << endl;
|
||||
const char* extensions = (const char *) p_glGetString(GL_EXTENSIONS);
|
||||
myHaveTexRectEXT = strstr(extensions, "ARB_texture_rectangle") != NULL;
|
||||
|
||||
// Initialize GL display
|
||||
p_glViewport(myImageDim.x, myImageDim.y, myImageDim.w, myImageDim.h);
|
||||
p_glShadeModel(GL_FLAT);
|
||||
p_glDisable(GL_CULL_FACE);
|
||||
p_glDisable(GL_DEPTH_TEST);
|
||||
p_glDisable(GL_ALPHA_TEST);
|
||||
p_glDisable(GL_LIGHTING);
|
||||
p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
|
||||
p_glMatrixMode(GL_PROJECTION);
|
||||
p_glLoadIdentity();
|
||||
p_glOrtho(0.0, orthoWidth, orthoHeight, 0, -1.0, 1.0);
|
||||
p_glMatrixMode(GL_MODELVIEW);
|
||||
p_glLoadIdentity();
|
||||
|
||||
// Allocate GL textures
|
||||
createTextures();
|
||||
|
||||
p_glEnable(myBuffer.target);
|
||||
|
||||
// Make sure any old parts of the screen are erased
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_GL_SwapBuffers();
|
||||
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::drawMediaSource()
|
||||
{
|
||||
MediaSource& mediasrc = myOSystem->console().mediaSource();
|
||||
|
||||
// Copy the mediasource framebuffer to the RGB texture
|
||||
uInt8* currentFrame = mediasrc.currentFrameBuffer();
|
||||
uInt8* previousFrame = mediasrc.previousFrameBuffer();
|
||||
uInt32 width = mediasrc.width();
|
||||
uInt32 height = mediasrc.height();
|
||||
uInt16* buffer = (uInt16*) myTexture->pixels;
|
||||
|
||||
// TODO - is this fast enough?
|
||||
if(!myUsePhosphor)
|
||||
{
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y )
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x )
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
if(v != w || theRedrawTIAIndicator)
|
||||
{
|
||||
// If we ever get to this point, we know the current and previous
|
||||
// buffers differ. In that case, make sure the changes are
|
||||
// are drawn in postFrameUpdate()
|
||||
myDirtyFlag = true;
|
||||
|
||||
buffer[pos] = buffer[pos+1] = (uInt16) myDefPalette[v];
|
||||
}
|
||||
pos += 2;
|
||||
}
|
||||
bufofsY += width;
|
||||
screenofsY += myBuffer.pitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Phosphor mode always implies a dirty update,
|
||||
// so we don't care about theRedrawTIAIndicator
|
||||
myDirtyFlag = true;
|
||||
|
||||
uInt32 bufofsY = 0;
|
||||
uInt32 screenofsY = 0;
|
||||
for(uInt32 y = 0; y < height; ++y )
|
||||
{
|
||||
uInt32 pos = screenofsY;
|
||||
for(uInt32 x = 0; x < width; ++x )
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
uInt8 w = previousFrame[bufofs];
|
||||
|
||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||
buffer[pos++] = (uInt16) myAvgPalette[v][w];
|
||||
}
|
||||
bufofsY += width;
|
||||
screenofsY += myBuffer.pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::preFrameUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::postFrameUpdate()
|
||||
{
|
||||
if(myDirtyFlag)
|
||||
{
|
||||
// Texturemap complete texture to surface so we have free scaling
|
||||
// and antialiasing
|
||||
uInt32 w = myBuffer.width, h = myBuffer.height;
|
||||
|
||||
p_glTexSubImage2D(myBuffer.target, 0, 0, 0,
|
||||
myBuffer.texture_width, myBuffer.texture_height,
|
||||
myBuffer.format, myBuffer.type, myBuffer.pixels);
|
||||
p_glBegin(GL_QUADS);
|
||||
p_glTexCoord2f(myBuffer.tex_coord[0], myBuffer.tex_coord[1]); p_glVertex2i(0, 0);
|
||||
p_glTexCoord2f(myBuffer.tex_coord[2], myBuffer.tex_coord[1]); p_glVertex2i(w, 0);
|
||||
p_glTexCoord2f(myBuffer.tex_coord[2], myBuffer.tex_coord[3]); p_glVertex2i(w, h);
|
||||
p_glTexCoord2f(myBuffer.tex_coord[0], myBuffer.tex_coord[3]); p_glVertex2i(0, h);
|
||||
p_glEnd();
|
||||
|
||||
// Now show all changes made to the texture
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
myDirtyFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::scanline(uInt32 row, uInt8* data)
|
||||
{
|
||||
// Invert the row, since OpenGL rows start at the bottom
|
||||
// of the framebuffer
|
||||
row = myImageDim.h + myImageDim.y - row - 1;
|
||||
|
||||
p_glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
p_glReadPixels(myImageDim.x, row, myImageDim.w, 1, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::toggleFilter()
|
||||
{
|
||||
if(myBuffer.filter == GL_NEAREST)
|
||||
{
|
||||
myBuffer.filter = GL_LINEAR;
|
||||
myOSystem->settings().setString("gl_filter", "linear");
|
||||
showMessage("Filtering: GL_LINEAR");
|
||||
}
|
||||
else
|
||||
{
|
||||
myBuffer.filter = GL_NEAREST;
|
||||
myOSystem->settings().setString("gl_filter", "nearest");
|
||||
showMessage("Filtering: GL_NEAREST");
|
||||
}
|
||||
|
||||
p_glBindTexture(myBuffer.target, myBuffer.texture);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_MAG_FILTER, myBuffer.filter);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_MIN_FILTER, myBuffer.filter);
|
||||
|
||||
// The filtering has changed, so redraw the entire screen
|
||||
theRedrawTIAIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
|
||||
{
|
||||
// Horizontal line
|
||||
SDL_Rect tmp;
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.w = x2 - x + 1;
|
||||
tmp.h = 1;
|
||||
SDL_FillRect(myTexture, &tmp, myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
|
||||
{
|
||||
// Vertical line
|
||||
SDL_Rect tmp;
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.w = 1;
|
||||
tmp.h = y2 - y + 1;
|
||||
SDL_FillRect(myTexture, &tmp, myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
int color)
|
||||
{
|
||||
// Fill the rectangle
|
||||
SDL_Rect tmp;
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.w = w;
|
||||
tmp.h = h;
|
||||
SDL_FillRect(myTexture, &tmp, myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::drawChar(const GUI::Font* font, uInt8 chr,
|
||||
uInt32 tx, uInt32 ty, int color)
|
||||
{
|
||||
// If this character is not included in the font, use the default char.
|
||||
if(chr < font->desc().firstchar ||
|
||||
chr >= font->desc().firstchar + font->desc().size)
|
||||
{
|
||||
if (chr == ' ')
|
||||
return;
|
||||
chr = font->desc().defaultchar;
|
||||
}
|
||||
|
||||
const Int32 w = font->getCharWidth(chr);
|
||||
const Int32 h = font->getFontHeight();
|
||||
chr -= font->desc().firstchar;
|
||||
const uInt16* tmp = font->desc().bits + (font->desc().offset ?
|
||||
font->desc().offset[chr] : (chr * h));
|
||||
|
||||
uInt16* buffer = (uInt16*) myTexture->pixels + ty * myBuffer.pitch + tx;
|
||||
for(int y = 0; y < h; ++y)
|
||||
{
|
||||
const uInt16 ptr = *tmp++;
|
||||
uInt16 mask = 0x8000;
|
||||
|
||||
for(int x = 0; x < w; ++x, mask >>= 1)
|
||||
if(ptr & mask)
|
||||
buffer[x] = (uInt16) myDefPalette[color];
|
||||
|
||||
buffer += myBuffer.pitch;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::drawBitmap(uInt32* bitmap, Int32 tx, Int32 ty,
|
||||
int color, Int32 h)
|
||||
{
|
||||
uInt16* buffer = (uInt16*) myTexture->pixels + ty * myBuffer.pitch + tx;
|
||||
|
||||
for(int y = 0; y < h; ++y)
|
||||
{
|
||||
uInt32 mask = 0xF0000000;
|
||||
for(int x = 0; x < 8; ++x, mask >>= 4)
|
||||
if(bitmap[y] & mask)
|
||||
buffer[x] = (uInt16) myDefPalette[color];
|
||||
|
||||
buffer += myBuffer.pitch;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::translateCoords(Int32& x, Int32& y)
|
||||
{
|
||||
// Wow, what a mess :)
|
||||
x = (Int32) ((x - myImageDim.x) / myScaleFactor);
|
||||
y = (Int32) ((y - myImageDim.y) / myScaleFactor);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||
{
|
||||
myDirtyFlag = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferD3D::enablePhosphor(bool enable, int blend)
|
||||
{
|
||||
myUsePhosphor = enable;
|
||||
myPhosphorBlend = blend;
|
||||
|
||||
theRedrawTIAIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferD3D::createTextures()
|
||||
{
|
||||
if(myTexture) SDL_FreeSurface(myTexture);
|
||||
if(myBuffer.texture) p_glDeleteTextures(1, &myBuffer.texture);
|
||||
memset(&myBuffer, 0, sizeof(glBufferType));
|
||||
myBuffer.filter = GL_NEAREST;
|
||||
|
||||
// Fill buffer struct with valid data
|
||||
// This changes depending on the texturing used
|
||||
myBuffer.width = myBaseDim.w;
|
||||
myBuffer.height = myBaseDim.h;
|
||||
myBuffer.tex_coord[0] = 0.0f;
|
||||
myBuffer.tex_coord[1] = 0.0f;
|
||||
if(myHaveTexRectEXT)
|
||||
{
|
||||
myBuffer.texture_width = myBuffer.width;
|
||||
myBuffer.texture_height = myBuffer.height;
|
||||
myBuffer.target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
myBuffer.tex_coord[2] = (GLfloat) myBuffer.texture_width;
|
||||
myBuffer.tex_coord[3] = (GLfloat) myBuffer.texture_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
myBuffer.texture_width = power_of_two(myBuffer.width);
|
||||
myBuffer.texture_height = power_of_two(myBuffer.height);
|
||||
myBuffer.target = GL_TEXTURE_2D;
|
||||
myBuffer.tex_coord[2] = (GLfloat) myBuffer.width / myBuffer.texture_width;
|
||||
myBuffer.tex_coord[3] = (GLfloat) myBuffer.height / myBuffer.texture_height;
|
||||
}
|
||||
|
||||
// Create a texture that best suits the current display depth and system
|
||||
// This code needs to be Apple-specific, otherwise performance is
|
||||
// terrible on a Mac Mini
|
||||
#if defined(MAC_OSX)
|
||||
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||
myBuffer.texture_width, myBuffer.texture_height, 16,
|
||||
0x00007c00, 0x000003e0, 0x0000001f, 0x00000000);
|
||||
#else
|
||||
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||
myBuffer.texture_width, myBuffer.texture_height, 16,
|
||||
0x0000f800, 0x000007e0, 0x0000001f, 0x00000000);
|
||||
#endif
|
||||
if(myTexture == NULL)
|
||||
return false;
|
||||
|
||||
myBuffer.pixels = myTexture->pixels;
|
||||
switch(myTexture->format->BytesPerPixel)
|
||||
{
|
||||
case 2: // 16-bit
|
||||
myBuffer.pitch = myTexture->pitch/2;
|
||||
break;
|
||||
case 3: // 24-bit
|
||||
myBuffer.pitch = myTexture->pitch;
|
||||
break;
|
||||
case 4: // 32-bit
|
||||
myBuffer.pitch = myTexture->pitch/4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Create an OpenGL texture from the SDL texture
|
||||
const string& filter = myOSystem->settings().getString("gl_filter");
|
||||
if(filter == "linear")
|
||||
{
|
||||
myBuffer.filter = GL_LINEAR;
|
||||
myFilterParamName = "GL_LINEAR";
|
||||
}
|
||||
else if(filter == "nearest")
|
||||
{
|
||||
myBuffer.filter = GL_NEAREST;
|
||||
myFilterParamName = "GL_NEAREST";
|
||||
}
|
||||
|
||||
p_glGenTextures(1, &myBuffer.texture);
|
||||
p_glBindTexture(myBuffer.target, myBuffer.texture);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_MIN_FILTER, myBuffer.filter);
|
||||
p_glTexParameteri(myBuffer.target, GL_TEXTURE_MAG_FILTER, myBuffer.filter);
|
||||
|
||||
// Finally, create the texture in the most optimal format
|
||||
GLenum tex_intformat;
|
||||
#if defined (MAC_OSX)
|
||||
tex_intformat = GL_RGB5;
|
||||
myBuffer.format = GL_BGRA;
|
||||
myBuffer.type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||
#else
|
||||
tex_intformat = GL_RGB;
|
||||
myBuffer.format = GL_RGB;
|
||||
myBuffer.type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
#endif
|
||||
p_glTexImage2D(myBuffer.target, 0, tex_intformat,
|
||||
myBuffer.texture_width, myBuffer.texture_height, 0,
|
||||
myBuffer.format, myBuffer.type, myBuffer.pixels);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferD3D::myFuncsLoaded = false;
|
||||
|
||||
#endif // DISPLAY_D3D
|
|
@ -1,270 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: FrameBufferD3D.hxx,v 1.2 2007-09-03 18:37:24 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_D3D_HXX
|
||||
#define FRAMEBUFFER_D3D_HXX
|
||||
|
||||
#ifdef DISPLAY_D3D
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
#include <SDL_syswm.h>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
|
||||
class OSystem;
|
||||
class GUI::Font;
|
||||
|
||||
/**
|
||||
This class implements an SDL Direct3D framebuffer.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBufferD3D.hxx,v 1.2 2007-09-03 18:37:24 stephena Exp $
|
||||
*/
|
||||
class FrameBufferD3D : public FrameBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Creates a new Direct3D framebuffer
|
||||
*/
|
||||
FrameBufferD3D(OSystem* osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~FrameBufferD3D();
|
||||
|
||||
/**
|
||||
Check if OpenGL is available on this system and dynamically load
|
||||
all required GL functions. If any errors occur, we shouldn't attempt
|
||||
to instantiate a FrameBufferGL object.
|
||||
|
||||
@param library The filename of the OpenGL library
|
||||
*/
|
||||
static bool loadFuncs(const string& library);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following methods are derived from FrameBuffer.hxx
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
This method is called to initialize OpenGL video mode.
|
||||
Return false if any operation fails, otherwise return true.
|
||||
*/
|
||||
virtual bool initSubsystem(VideoMode mode);
|
||||
|
||||
/**
|
||||
This method is called to query the type of the FrameBuffer.
|
||||
*/
|
||||
virtual BufferType type() { return kGLBuffer; }
|
||||
|
||||
/**
|
||||
This method is called to provide information about the FrameBuffer.
|
||||
*/
|
||||
virtual string about();
|
||||
|
||||
/**
|
||||
This method is called to change to the given video mode.
|
||||
|
||||
@param mode The mode to use for rendering the mediasource
|
||||
*/
|
||||
virtual bool setVidMode(VideoMode mode);
|
||||
|
||||
/**
|
||||
Switches between the two filtering options in OpenGL.
|
||||
Currently, these are GL_NEAREST and GL_LINEAR.
|
||||
*/
|
||||
virtual void toggleFilter();
|
||||
|
||||
/**
|
||||
This method should be called anytime the MediaSource needs to be redrawn
|
||||
to the screen.
|
||||
*/
|
||||
virtual void drawMediaSource();
|
||||
|
||||
/**
|
||||
This method is called before any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void preFrameUpdate();
|
||||
|
||||
/**
|
||||
This method is called after any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void postFrameUpdate();
|
||||
|
||||
/**
|
||||
This method is called to get the specified scanline data.
|
||||
|
||||
@param row The row we are looking for
|
||||
@param data The actual pixel data (in bytes)
|
||||
*/
|
||||
virtual void scanline(uInt32 row, uInt8* data);
|
||||
|
||||
/**
|
||||
This method is called to map a given r,g,b triple to the screen palette.
|
||||
|
||||
@param r The red component of the color.
|
||||
@param g The green component of the color.
|
||||
@param b The blue component of the color.
|
||||
*/
|
||||
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
|
||||
{ return SDL_MapRGB(myTexture->format, r, g, b); }
|
||||
|
||||
/**
|
||||
This method is called to draw a horizontal line.
|
||||
|
||||
@param x The first x coordinate
|
||||
@param y The y coordinate
|
||||
@param x2 The second x coordinate
|
||||
@param color The color of the line
|
||||
*/
|
||||
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, int color);
|
||||
|
||||
/**
|
||||
This method is called to draw a vertical line.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The first y coordinate
|
||||
@param y2 The second y coordinate
|
||||
@param color The color of the line
|
||||
*/
|
||||
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, int color);
|
||||
|
||||
/**
|
||||
This method is called to draw a filled rectangle.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the area
|
||||
@param h The height of the area
|
||||
@param color The color of the area
|
||||
*/
|
||||
virtual void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
int color);
|
||||
|
||||
/**
|
||||
This method is called to draw the specified character.
|
||||
|
||||
@param font The font to use to draw the character
|
||||
@param c The character to draw
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param color The color of the character
|
||||
*/
|
||||
virtual void drawChar(const GUI::Font* font, uInt8 c, uInt32 x, uInt32 y,
|
||||
int color);
|
||||
|
||||
/**
|
||||
This method is called to draw the bitmap image.
|
||||
|
||||
@param bitmap The data to draw
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param color The color of the character
|
||||
@param h The height of the data image
|
||||
*/
|
||||
virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color,
|
||||
Int32 h = 8);
|
||||
|
||||
/**
|
||||
This method translates the given coordinates to their
|
||||
unzoomed/unscaled equivalents.
|
||||
|
||||
@param x X coordinate to translate
|
||||
@param y Y coordinate to translate
|
||||
*/
|
||||
inline virtual void translateCoords(Int32& x, Int32& y);
|
||||
|
||||
/**
|
||||
This method adds a dirty rectangle
|
||||
(ie, an area of the screen that has changed)
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the area
|
||||
@param h The height of the area
|
||||
*/
|
||||
virtual void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
||||
|
||||
/**
|
||||
Enable/disable phosphor effect.
|
||||
*/
|
||||
virtual void enablePhosphor(bool enable, int blend);
|
||||
|
||||
private:
|
||||
bool createTextures();
|
||||
|
||||
inline uInt32 power_of_two(uInt32 input)
|
||||
{
|
||||
uInt32 value = 1;
|
||||
while( value < input )
|
||||
value <<= 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
private:
|
||||
// Points to the current texture data
|
||||
SDL_Surface* myTexture;
|
||||
|
||||
// Holds all items specifically needed by GL commands
|
||||
struct glBufferType
|
||||
{
|
||||
GLuint texture;
|
||||
GLsizei texture_width;
|
||||
GLsizei texture_height;
|
||||
GLfloat tex_coord[4];
|
||||
|
||||
GLenum target;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
GLint filter;
|
||||
|
||||
void* pixels;
|
||||
int width, height;
|
||||
int pitch;
|
||||
};
|
||||
glBufferType myBuffer;
|
||||
|
||||
// Optional GL extensions that may increase performance
|
||||
bool myHaveTexRectEXT;
|
||||
|
||||
// The depth of the texture buffer
|
||||
uInt32 myDepth;
|
||||
|
||||
// The size of color components for OpenGL
|
||||
uInt32 myRGB[4];
|
||||
|
||||
// The name of the texture filtering to use
|
||||
string myFilterParamName;
|
||||
|
||||
// The amount by which to scale the imagein fullscreen mode
|
||||
float myScaleFactor;
|
||||
|
||||
// TODO - will be removed when textured dirty rect support is added
|
||||
bool myDirtyFlag;
|
||||
|
||||
// Indicates if the OpenGL functions have been properly loaded
|
||||
static bool myFuncsLoaded;
|
||||
};
|
||||
|
||||
#endif // DISPLAY_D3D
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue