GTK: Rewrote the OpenGL code. The old code used a software path with

Mesa drivers. The new one (taken from the SDL port) is much faster with 
these drivers.


git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@857 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
bgk 2009-03-19 10:20:42 +00:00
parent 60202f1e1c
commit a7029d7b4d
7 changed files with 106 additions and 14 deletions

View File

@ -27,7 +27,9 @@ template<typename T> T min( T x, T y ) { return x < y ? x : y; }
template<typename T> T max( T x, T y ) { return x > y ? x : y; }
ScreenAreaGl::ScreenAreaGl(int _iWidth, int _iHeight, int _iScale) :
ScreenArea(_iWidth, _iHeight, _iScale)
ScreenArea(_iWidth, _iHeight, _iScale),
m_uiScreenTexture(0),
m_iTextureSize(256)
{
Glib::RefPtr<Gdk::GL::Config> glconfig;
@ -52,7 +54,13 @@ void ScreenAreaGl::on_realize()
if (!glwindow->gl_begin(get_gl_context()))
return;
glViewport(0, 0, get_width(), get_height());
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
if (glIsTexture(m_uiScreenTexture))
glDeleteTextures(1, &m_uiScreenTexture);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -62,7 +70,28 @@ void ScreenAreaGl::on_realize()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGenTextures(1, &m_uiScreenTexture);
glBindTexture(GL_TEXTURE_2D, m_uiScreenTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Calculate texture size as a the smallest working power of two
float n1 = log10((float)m_iScaledWidth ) / log10( 2.0f);
float n2 = log10((float)m_iScaledHeight ) / log10( 2.0f);
float n = (n1 > n2)? n1 : n2;
// round up
if (((float)((int)n)) != n)
n = ((float)((int)n)) + 1.0f;
m_iTextureSize = (int)pow(2.0f, n);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_iTextureSize, m_iTextureSize, 0,
GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glwindow->gl_end();
}
@ -87,32 +116,53 @@ void ScreenAreaGl::vOnWidgetResize()
{
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
int iWidth = get_width();
int iHeight = get_height();
float fScreenAspect = (float) m_iScaledWidth / m_iScaledHeight,
fWindowAspect = (float) iWidth / iHeight;
if (!glwindow->gl_begin(get_gl_context()))
return;
glViewport(0, 0, get_width(), get_height());
if (fWindowAspect == fScreenAspect)
glViewport(0, 0, iWidth, iHeight);
else if (fWindowAspect < fScreenAspect) {
int iAspectHeight = (int)(iWidth / fScreenAspect);
glViewport(0, (iHeight - iAspectHeight) / 2, iWidth, iAspectHeight);
} else {
int iAspectWidth = (int)(iHeight * fScreenAspect);
glViewport((iWidth - iAspectWidth) / 2, 0, iAspectWidth, iHeight);
}
glwindow->gl_end();
m_dScaleFactor = min<double>(get_height() / (double)m_iScaledHeight, get_width() / (double)m_iScaledWidth);
m_dAreaTop = (1 - m_dScaleFactor * m_iScaledHeight / (double)get_height()) / 2;
m_dAreaLeft = (1 - m_dScaleFactor * m_iScaledWidth / (double)get_width()) / 2;
}
bool ScreenAreaGl::on_expose_event(GdkEventExpose * _pstEvent)
{
glPixelZoom(m_dScaleFactor, -m_dScaleFactor);
glRasterPos2f(m_dAreaLeft, m_dAreaTop);
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_iScaledWidth + 1);
if (!m_bEnableRender)
return true;
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
if (!glwindow->gl_begin(get_gl_context()))
return false;
glClear( GL_COLOR_BUFFER_BIT );
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_iScaledWidth + 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_iScaledWidth + 1, m_iScaledHeight,
GL_RGBA, GL_UNSIGNED_BYTE, m_puiPixels);
glDrawPixels(m_iScaledWidth, m_iScaledHeight, GL_RGBA, GL_UNSIGNED_BYTE, m_puiPixels);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f, 0.0f);
glVertex3i(0, 0, 0);
glTexCoord2f(m_iScaledWidth / (GLfloat) m_iTextureSize, 0.0f);
glVertex3i(1, 0, 0);
glTexCoord2f(0.0f, m_iScaledHeight / (GLfloat) m_iTextureSize);
glVertex3i(0, 1, 0);
glTexCoord2f(m_iScaledWidth / (GLfloat) m_iTextureSize,
m_iScaledHeight / (GLfloat) m_iTextureSize);
glVertex3i(1, 1, 0);
glEnd();
glwindow->swap_buffers();

View File

@ -40,9 +40,11 @@ protected:
void vOnWidgetResize();
private:
double m_dAreaTop;
GLuint m_uiScreenTexture;
int m_iTextureSize;
/* double m_dAreaTop;
double m_dAreaLeft;
double m_dScaleFactor;
double m_dScaleFactor;*/
};
} // namespace VBA

View File

@ -31,6 +31,7 @@ ScreenArea::ScreenArea(int _iWidth, int _iHeight, int _iScale) :
m_puiDelta(NULL),
m_iScaledWidth(_iWidth),
m_iScaledHeight(_iHeight),
m_bEnableRender(true),
m_bShowCursor(true)
{
g_assert(_iWidth >= 1 && _iHeight >= 1 && _iScale >= 1);
@ -233,4 +234,9 @@ bool ScreenArea::on_configure_event(GdkEventConfigure * event)
return true;
}
void ScreenArea::vSetEnableRender(bool _bEnable)
{
m_bEnableRender = _bEnable;
}
} // namespace VBA

View File

@ -38,6 +38,7 @@ public:
void vSetScale(int _iScale);
void vSetFilter(EFilter _eFilter);
void vSetFilterIB(EFilterIB _eFilterIB);
void vSetEnableRender(bool _bEnable);
virtual void vDrawPixels(u8 * _puiData);
virtual void vDrawBlackScreen() = 0;
@ -60,6 +61,7 @@ protected:
u8 * m_puiDelta;
int m_iScaledWidth;
int m_iScaledHeight;
bool m_bEnableRender;
bool m_bShowCursor;
Gdk::Cursor * m_poEmptyCursor;

View File

@ -155,6 +155,16 @@ Window::Window(GtkWindow * _pstWindow, const Glib::RefPtr<Xml> & _poXml) :
// Menu bar
m_poMenuBar = dynamic_cast<Gtk::MenuBar *>(_poXml->get_widget("MenuBar"));
m_poMenuBar->signal_deactivate().connect(sigc::mem_fun(*this, &Window::vOnMenuExit));
poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileMenu"));
poMI->signal_activate().connect(sigc::mem_fun(*this, &Window::vOnMenuEnter));
poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("EmulationMenu"));
poMI->signal_activate().connect(sigc::mem_fun(*this, &Window::vOnMenuEnter));
poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("OptionsMenu"));
poMI->signal_activate().connect(sigc::mem_fun(*this, &Window::vOnMenuEnter));
poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("HelpMenu"));
poMI->signal_activate().connect(sigc::mem_fun(*this, &Window::vOnMenuEnter));
// File menu
//

View File

@ -135,6 +135,8 @@ protected:
ColorFormatBGR
};
virtual void vOnMenuEnter();
virtual void vOnMenuExit();
virtual void vOnFileOpen();
virtual void vOnFileLoad();
virtual void vOnFileSave();

View File

@ -44,6 +44,26 @@
namespace VBA
{
void Window::vOnMenuEnter()
{
if (emulating && ! m_bPaused)
{
m_poScreenArea->vSetEnableRender(false);
vStopEmu();
soundPause();
}
}
void Window::vOnMenuExit()
{
if (emulating && ! m_bPaused)
{
m_poScreenArea->vSetEnableRender(true);
vStartEmu();
soundResume();
}
}
void Window::vOnFileOpen()
{
while (m_poFileOpenDialog->run() == Gtk::RESPONSE_OK)