diff --git a/src/gtk/screenarea-opengl.cpp b/src/gtk/screenarea-opengl.cpp index e6557aa9..28c98ee2 100644 --- a/src/gtk/screenarea-opengl.cpp +++ b/src/gtk/screenarea-opengl.cpp @@ -29,7 +29,7 @@ template T max( T x, T y ) { return x > y ? x : y; } ScreenAreaGl::ScreenAreaGl(int _iWidth, int _iHeight, int _iScale) : ScreenArea(_iWidth, _iHeight, _iScale), m_uiScreenTexture(0), - m_iTextureSize(256) + m_iTextureSize(0) { Glib::RefPtr glconfig; @@ -46,6 +46,23 @@ ScreenAreaGl::ScreenAreaGl(int _iWidth, int _iHeight, int _iScale) : vUpdateSize(); } +void ScreenAreaGl::vUpdateTexture() +{ + // Calculate the new texture size as a the smallest working power of two + // TODO: Support the ARB_texture_rectangle extension + int iExpX = 0, iExpY = 0; + for (int i = m_iScaledWidth; i; i >>= 1, ++iExpX); + for (int i = m_iScaledHeight; i; i >>= 1, ++iExpY); + int iNewTextureSize = 1 << max(iExpX, iExpY); + + // Notify the system if the texture size changed + if (iNewTextureSize != m_iTextureSize) { + m_iTextureSize = iNewTextureSize; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iNewTextureSize, iNewTextureSize, + 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } +} + void ScreenAreaGl::on_realize() { Gtk::DrawingArea::on_realize(); @@ -60,8 +77,6 @@ void ScreenAreaGl::on_realize() if (glIsTexture(m_uiScreenTexture)) glDeleteTextures(1, &m_uiScreenTexture); - - glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -76,19 +91,7 @@ void ScreenAreaGl::on_realize() 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); + vUpdateTexture(); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); @@ -171,4 +174,18 @@ bool ScreenAreaGl::on_expose_event(GdkEventExpose * _pstEvent) return true; } +void ScreenAreaGl::vOnSizeUpdated() +{ + if (!is_realized()) + return; + + Glib::RefPtr glwindow = get_gl_window(); + if (!glwindow->gl_begin(get_gl_context())) + return; + + vUpdateTexture(); + + glwindow->gl_end(); +} + } // namespace VBA diff --git a/src/gtk/screenarea-opengl.h b/src/gtk/screenarea-opengl.h index c7d70539..8873e6c7 100644 --- a/src/gtk/screenarea-opengl.h +++ b/src/gtk/screenarea-opengl.h @@ -42,9 +42,9 @@ protected: private: GLuint m_uiScreenTexture; int m_iTextureSize; -/* double m_dAreaTop; - double m_dAreaLeft; - double m_dScaleFactor;*/ + + void vUpdateTexture(); + void vOnSizeUpdated(); }; } // namespace VBA diff --git a/src/gtk/screenarea.cpp b/src/gtk/screenarea.cpp index 4efbe133..e4bd8024 100644 --- a/src/gtk/screenarea.cpp +++ b/src/gtk/screenarea.cpp @@ -224,6 +224,8 @@ void ScreenArea::vUpdateSize() memset(m_puiPixels, 0, (m_iScaledWidth + 1) * m_iScaledHeight * sizeof(u32)); memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * sizeof(u32)); + vOnSizeUpdated(); + set_size_request(m_iScale * m_iWidth, m_iScale * m_iHeight); } diff --git a/src/gtk/screenarea.h b/src/gtk/screenarea.h index a83f5ff2..dc1ecada 100644 --- a/src/gtk/screenarea.h +++ b/src/gtk/screenarea.h @@ -48,6 +48,7 @@ protected: virtual bool on_leave_notify_event(GdkEventCrossing * _pstEvent); virtual bool on_configure_event(GdkEventConfigure * event); virtual bool bOnCursorTimeout(); + virtual void vOnSizeUpdated() {} int m_iWidth; int m_iHeight; diff --git a/src/gtk/ui/vbam.ui b/src/gtk/ui/vbam.ui index 0e27bb88..44d5abd4 100644 --- a/src/gtk/ui/vbam.ui +++ b/src/gtk/ui/vbam.ui @@ -109,7 +109,7 @@ True False False - gtk-media-pause + Pause True