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:
parent
60202f1e1c
commit
a7029d7b4d
|
@ -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; }
|
template<typename T> T max( T x, T y ) { return x > y ? x : y; }
|
||||||
|
|
||||||
ScreenAreaGl::ScreenAreaGl(int _iWidth, int _iHeight, int _iScale) :
|
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;
|
Glib::RefPtr<Gdk::GL::Config> glconfig;
|
||||||
|
|
||||||
|
@ -52,7 +54,13 @@ void ScreenAreaGl::on_realize()
|
||||||
if (!glwindow->gl_begin(get_gl_context()))
|
if (!glwindow->gl_begin(get_gl_context()))
|
||||||
return;
|
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);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
@ -62,7 +70,28 @@ void ScreenAreaGl::on_realize()
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
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);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glwindow->gl_end();
|
glwindow->gl_end();
|
||||||
}
|
}
|
||||||
|
@ -87,32 +116,53 @@ void ScreenAreaGl::vOnWidgetResize()
|
||||||
{
|
{
|
||||||
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
|
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()))
|
if (!glwindow->gl_begin(get_gl_context()))
|
||||||
return;
|
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();
|
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)
|
bool ScreenAreaGl::on_expose_event(GdkEventExpose * _pstEvent)
|
||||||
{
|
{
|
||||||
glPixelZoom(m_dScaleFactor, -m_dScaleFactor);
|
if (!m_bEnableRender)
|
||||||
glRasterPos2f(m_dAreaLeft, m_dAreaTop);
|
return true;
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_iScaledWidth + 1);
|
|
||||||
|
|
||||||
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
|
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
|
||||||
if (!glwindow->gl_begin(get_gl_context()))
|
if (!glwindow->gl_begin(get_gl_context()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
glClear( GL_COLOR_BUFFER_BIT );
|
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();
|
glwindow->swap_buffers();
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,11 @@ protected:
|
||||||
void vOnWidgetResize();
|
void vOnWidgetResize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double m_dAreaTop;
|
GLuint m_uiScreenTexture;
|
||||||
|
int m_iTextureSize;
|
||||||
|
/* double m_dAreaTop;
|
||||||
double m_dAreaLeft;
|
double m_dAreaLeft;
|
||||||
double m_dScaleFactor;
|
double m_dScaleFactor;*/
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace VBA
|
} // namespace VBA
|
||||||
|
|
|
@ -31,6 +31,7 @@ ScreenArea::ScreenArea(int _iWidth, int _iHeight, int _iScale) :
|
||||||
m_puiDelta(NULL),
|
m_puiDelta(NULL),
|
||||||
m_iScaledWidth(_iWidth),
|
m_iScaledWidth(_iWidth),
|
||||||
m_iScaledHeight(_iHeight),
|
m_iScaledHeight(_iHeight),
|
||||||
|
m_bEnableRender(true),
|
||||||
m_bShowCursor(true)
|
m_bShowCursor(true)
|
||||||
{
|
{
|
||||||
g_assert(_iWidth >= 1 && _iHeight >= 1 && _iScale >= 1);
|
g_assert(_iWidth >= 1 && _iHeight >= 1 && _iScale >= 1);
|
||||||
|
@ -233,4 +234,9 @@ bool ScreenArea::on_configure_event(GdkEventConfigure * event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScreenArea::vSetEnableRender(bool _bEnable)
|
||||||
|
{
|
||||||
|
m_bEnableRender = _bEnable;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace VBA
|
} // namespace VBA
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
void vSetScale(int _iScale);
|
void vSetScale(int _iScale);
|
||||||
void vSetFilter(EFilter _eFilter);
|
void vSetFilter(EFilter _eFilter);
|
||||||
void vSetFilterIB(EFilterIB _eFilterIB);
|
void vSetFilterIB(EFilterIB _eFilterIB);
|
||||||
|
void vSetEnableRender(bool _bEnable);
|
||||||
virtual void vDrawPixels(u8 * _puiData);
|
virtual void vDrawPixels(u8 * _puiData);
|
||||||
virtual void vDrawBlackScreen() = 0;
|
virtual void vDrawBlackScreen() = 0;
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ protected:
|
||||||
u8 * m_puiDelta;
|
u8 * m_puiDelta;
|
||||||
int m_iScaledWidth;
|
int m_iScaledWidth;
|
||||||
int m_iScaledHeight;
|
int m_iScaledHeight;
|
||||||
|
bool m_bEnableRender;
|
||||||
|
|
||||||
bool m_bShowCursor;
|
bool m_bShowCursor;
|
||||||
Gdk::Cursor * m_poEmptyCursor;
|
Gdk::Cursor * m_poEmptyCursor;
|
||||||
|
|
|
@ -155,6 +155,16 @@ Window::Window(GtkWindow * _pstWindow, const Glib::RefPtr<Xml> & _poXml) :
|
||||||
|
|
||||||
// Menu bar
|
// Menu bar
|
||||||
m_poMenuBar = dynamic_cast<Gtk::MenuBar *>(_poXml->get_widget("MenuBar"));
|
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
|
// File menu
|
||||||
//
|
//
|
||||||
|
|
|
@ -135,6 +135,8 @@ protected:
|
||||||
ColorFormatBGR
|
ColorFormatBGR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtual void vOnMenuEnter();
|
||||||
|
virtual void vOnMenuExit();
|
||||||
virtual void vOnFileOpen();
|
virtual void vOnFileOpen();
|
||||||
virtual void vOnFileLoad();
|
virtual void vOnFileLoad();
|
||||||
virtual void vOnFileSave();
|
virtual void vOnFileSave();
|
||||||
|
|
|
@ -44,6 +44,26 @@
|
||||||
namespace VBA
|
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()
|
void Window::vOnFileOpen()
|
||||||
{
|
{
|
||||||
while (m_poFileOpenDialog->run() == Gtk::RESPONSE_OK)
|
while (m_poFileOpenDialog->run() == Gtk::RESPONSE_OK)
|
||||||
|
|
Loading…
Reference in New Issue