From ea0b6a14ccae1fa55d99b32112839988481fd65d Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 3 Jun 2015 23:30:56 -0700 Subject: [PATCH 1/3] OpenGL: Start modular renderer --- src/platform/opengl/gl.c | 117 ++++++++++++++++++++++++++++++++ src/platform/opengl/gl.h | 25 +++++++ src/platform/sdl/CMakeLists.txt | 1 + src/platform/sdl/gl-sdl.c | 116 ++++++++----------------------- src/platform/sdl/main.h | 8 +-- src/platform/video-backend.h | 34 ++++++++++ 6 files changed, 206 insertions(+), 95 deletions(-) create mode 100644 src/platform/opengl/gl.c create mode 100644 src/platform/opengl/gl.h create mode 100644 src/platform/video-backend.h diff --git a/src/platform/opengl/gl.c b/src/platform/opengl/gl.c new file mode 100644 index 000000000..e941f705a --- /dev/null +++ b/src/platform/opengl/gl.c @@ -0,0 +1,117 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "gl.h" + +#include "gba/video.h" + +static const GLint _glVertices[] = { + 0, 0, + 256, 0, + 256, 256, + 0, 256 +}; + +static const GLint _glTexCoords[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 +}; + +static void GBAGLContextInit(struct VideoBackend* v, WHandle handle) { + UNUSED(handle); + struct GBAGLContext* context = (struct GBAGLContext*) v; + glGenTextures(1, &context->tex); + glBindTexture(GL_TEXTURE_2D, context->tex); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +#ifndef _WIN32 + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#endif + +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); +#endif +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); +#endif +} + +static void GBAGLContextDeinit(struct VideoBackend* v) { + struct GBAGLContext* context = (struct GBAGLContext*) v; + glDeleteTextures(1, &context->tex); +} + +static void GBAGLContextResized(struct VideoBackend* v, int w, int h) { + int drawW = w; + int drawH = h; + if (v->lockAspectRatio) { + if (w * 2 > h * 3) { + drawW = h * 3 / 2; + } else if (w * 2 < h * 3) { + drawH = w * 2 / 3; + } + } + glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); +} + +static void GBAGLContextClear(struct VideoBackend* v) { + UNUSED(v); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); +} + +void GBAGLContextDrawFrame(struct VideoBackend* v) { + struct GBAGLContext* context = (struct GBAGLContext*) v; + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_INT, 0, _glVertices); + glTexCoordPointer(2, GL_INT, 0, _glTexCoords); + glMatrixMode (GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glBindTexture(GL_TEXTURE_2D, context->tex); + if (v->filter) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + +void GBAGLContextPostFrame(struct VideoBackend* v, const void* frame) { + struct GBAGLContext* context = (struct GBAGLContext*) v; + glBindTexture(GL_TEXTURE_2D, context->tex); +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, frame); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frame); +#endif +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame); +#endif +} + +void GBAGLContextCreate(struct GBAGLContext* context) { + context->d.init = GBAGLContextInit; + context->d.deinit = GBAGLContextDeinit; + context->d.resized = GBAGLContextResized; + context->d.swap = 0; + context->d.clear = GBAGLContextClear; + context->d.postFrame = GBAGLContextPostFrame; + context->d.drawFrame = GBAGLContextDrawFrame; + context->d.setMessage = 0; + context->d.clearMessage = 0; +} diff --git a/src/platform/opengl/gl.h b/src/platform/opengl/gl.h new file mode 100644 index 000000000..e2471950a --- /dev/null +++ b/src/platform/opengl/gl.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef GL_H +#define GL_H + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "platform/video-backend.h" + +struct GBAGLContext { + struct VideoBackend d; + + GLuint tex; +}; + +void GBAGLContextCreate(struct GBAGLContext*); + +#endif diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 9aaf13fa4..c96d97dc3 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -67,6 +67,7 @@ else() list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c) if(BUILD_GL) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c) add_definitions(-DBUILD_GL) find_package(OpenGL REQUIRED) include_directories(${OPENGL_INCLUDE_DIR}) diff --git a/src/platform/sdl/gl-sdl.c b/src/platform/sdl/gl-sdl.c index 6760b72cc..6b9c7f4c5 100644 --- a/src/platform/sdl/gl-sdl.c +++ b/src/platform/sdl/gl-sdl.c @@ -6,47 +6,22 @@ #include "main.h" #include "gba/supervisor/thread.h" +#include "platform/opengl/gl.h" -#ifdef __APPLE__ -#include -#else -#include -#endif - -#ifdef BUILD_GL -static const GLint _glVertices[] = { - 0, 0, - 256, 0, - 256, 256, - 0, 256 -}; - -static const GLint _glTexCoords[] = { - 0, 0, - 1, 0, - 1, 1, - 0, 1 -}; -#endif - -static void _doViewport(int w, int h, struct SDLSoftwareRenderer* renderer) { - int drawW = w; - int drawH = h; - if (renderer->lockAspectRatio) { - if (w * 2 > h * 3) { - drawW = h * 3 / 2; - } else if (w * 2 < h * 3) { - drawH = w * 2 / 3; - } - } - glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); - glClear(GL_COLOR_BUFFER_BIT); +static void _sdlSwap(struct VideoBackend* context) { + struct SDLSoftwareRenderer* renderer = (struct SDLSoftwareRenderer*) context->user; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_SwapWindow(renderer->window); #else SDL_GL_SwapBuffers(); #endif - glClear(GL_COLOR_BUFFER_BIT); +} + +static void _doViewport(int w, int h, struct VideoBackend* v) { + v->resized(v, w, h); + v->clear(v); + v->swap(v); + v->clear(v); } static bool GBASDLGLInit(struct SDLSoftwareRenderer* renderer); @@ -89,48 +64,24 @@ bool GBASDLGLInit(struct SDLSoftwareRenderer* renderer) { #endif #endif - renderer->d.outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); - renderer->d.outputBufferStride = VIDEO_HORIZONTAL_PIXELS; - glGenTextures(1, &renderer->tex); - glBindTexture(GL_TEXTURE_2D, renderer->tex); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - if (renderer->filter) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } -#ifndef _WIN32 - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#endif + renderer->d.outputBuffer = malloc(256 * 256 * BYTES_PER_PIXEL); + renderer->d.outputBufferStride = 256; -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); -#endif -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); -#endif + GBAGLContextCreate(&renderer->gl); + renderer->gl.d.user = renderer; + renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio; + renderer->gl.d.filter = renderer->filter; + renderer->gl.d.swap = _sdlSwap; + renderer->gl.d.init(&renderer->gl.d, 0); - _doViewport(renderer->viewportWidth, renderer->viewportHeight, renderer); + _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d); return true; } void GBASDLGLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) { SDL_Event event; + struct VideoBackend* v = &renderer->gl.d; - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_INT, 0, _glVertices); - glTexCoordPointer(2, GL_INT, 0, _glTexCoords); - glMatrixMode (GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1); while (context->state < THREAD_EXITING) { while (SDL_PollEvent(&event)) { GBASDLHandleEvent(context, &renderer->player, &event); @@ -138,37 +89,24 @@ void GBASDLGLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* rend // Event handling can change the size of the screen if (renderer->player.windowUpdated) { SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); - _doViewport(renderer->viewportWidth, renderer->viewportHeight, renderer); + _doViewport(renderer->viewportWidth, renderer->viewportHeight, v); renderer->player.windowUpdated = 0; } #endif } if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) { - glBindTexture(GL_TEXTURE_2D, renderer->tex); -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, renderer->d.outputBuffer); -#else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderer->d.outputBuffer); -#endif -#else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, renderer->d.outputBuffer); -#endif - if (context->sync.videoFrameWait) { - glFlush(); - } + v->postFrame(v, renderer->d.outputBuffer); } - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + v->drawFrame(v); GBASyncWaitFrameEnd(&context->sync); -#if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_GL_SwapWindow(renderer->window); -#else - SDL_GL_SwapBuffers(); -#endif + v->swap(v); } } void GBASDLGLDeinit(struct SDLSoftwareRenderer* renderer) { + if (renderer->gl.d.deinit) { + renderer->gl.d.deinit(&renderer->gl.d); + } free(renderer->d.outputBuffer); } diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index 80e271245..55082078d 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -12,11 +12,7 @@ #include "sdl-events.h" #ifdef BUILD_GL -#ifdef __APPLE__ -#include -#else -#include -#endif +#include "platform/opengl/gl.h" #endif #ifdef BUILD_RASPI @@ -59,7 +55,7 @@ struct SDLSoftwareRenderer { bool filter; #ifdef BUILD_GL - GLuint tex; + struct GBAGLContext gl; #endif #ifdef USE_PIXMAN diff --git a/src/platform/video-backend.h b/src/platform/video-backend.h new file mode 100644 index 000000000..bf7a43186 --- /dev/null +++ b/src/platform/video-backend.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef VIDEO_BACKEND_H +#define VIDEO_BACKEND_H + +#include "util/common.h" + +#ifdef _WIN32 +typedef HWND WHandle; +#else +typedef void* WHandle; +#endif + +struct VideoBackend { + void (*init)(struct VideoBackend*, WHandle handle); + void (*deinit)(struct VideoBackend*); + void (*swap)(struct VideoBackend*); + void (*clear)(struct VideoBackend*); + void (*resized)(struct VideoBackend*, int w, int h); + void (*postFrame)(struct VideoBackend*, const void* frame); + void (*drawFrame)(struct VideoBackend*); + void (*setMessage)(struct VideoBackend*, const char* message); + void (*clearMessage)(struct VideoBackend*); + + void* user; + + bool filter; + bool lockAspectRatio; +}; + +#endif From d05e596b380a4bc95c0cf76e0597940a7b0f431a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Thu, 4 Jun 2015 00:42:00 -0700 Subject: [PATCH 2/3] Qt: Use common OpenGL code --- src/platform/qt/CMakeLists.txt | 2 + src/platform/qt/DisplayGL.cpp | 105 ++++++++------------------------- src/platform/qt/DisplayGL.h | 9 +-- 3 files changed, 30 insertions(+), 86 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 086e3b4ac..d50e58772 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -39,6 +39,8 @@ if(NOT Qt5OpenGL_FOUND OR NOT Qt5Widgets_FOUND OR NOT OPENGL_FOUND) return() endif() +list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c) + get_target_property(QT_TYPE Qt5::Core TYPE) if(QT_TYPE STREQUAL STATIC_LIBRARY) set(QT_STATIC ON) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 3105c60b8..92bac83c4 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -14,20 +14,6 @@ extern "C" { using namespace QGBA; -static const GLint _glVertices[] = { - 0, 0, - 256, 0, - 256, 256, - 0, 256 -}; - -static const GLint _glTexCoords[] = { - 0, 0, - 1, 0, - 1, 1, - 0, 1 -}; - DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) : Display(parent) , m_gl(new EmptyGLWidget(format, this)) @@ -154,10 +140,16 @@ PainterGL::PainterGL(QGLWidget* parent) : m_gl(parent) , m_drawTimer(nullptr) , m_messageTimer(this) - , m_lockAspectRatio(false) - , m_filter(false) , m_context(nullptr) { + GBAGLContextCreate(&m_backend); + m_backend.d.swap = [](VideoBackend* v) { + PainterGL* painter = static_cast(v->user); + painter->m_gl->swapBuffers(); + }; + m_backend.d.user = this; + m_backend.d.filter = false; + m_backend.d.lockAspectRatio = false; m_messageFont.setFamily("Source Code Pro"); m_messageFont.setStyleHint(QFont::Monospace); m_messageFont.setPixelSize(13); @@ -174,16 +166,7 @@ void PainterGL::setContext(GBAThread* context) { void PainterGL::setBacking(const uint32_t* backing) { m_gl->makeCurrent(); - glBindTexture(GL_TEXTURE_2D, m_tex); -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, backing); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, backing); -#endif -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, backing); -#endif + m_backend.d.postFrame(&m_backend.d, backing); m_gl->doneCurrent(); } @@ -193,43 +176,31 @@ void PainterGL::resize(const QSize& size) { int h = m_size.height(); int drawW = w; int drawH = h; - if (m_lockAspectRatio) { + if (m_backend.d.lockAspectRatio) { if (w * 2 > h * 3) { drawW = h * 3 / 2; } else if (w * 2 < h * 3) { drawH = w * 2 / 3; } } - m_viewport = QRect((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); - m_painter.begin(m_gl->context()->device()); m_world.reset(); - m_world.translate(m_viewport.x(), m_viewport.y()); + m_world.translate((w - drawW) / 2, (h - drawH) / 2); m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS); - m_painter.setWorldTransform(m_world); - m_painter.setFont(m_messageFont); m_message.prepare(m_world, m_messageFont); - m_painter.end(); if (m_drawTimer) { forceDraw(); } } void PainterGL::lockAspectRatio(bool lock) { - m_lockAspectRatio = lock; + m_backend.d.lockAspectRatio = lock; if (m_drawTimer) { forceDraw(); } } void PainterGL::filter(bool filter) { - m_filter = filter; - m_gl->makeCurrent(); - if (m_filter) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - m_gl->doneCurrent(); + m_backend.d.filter = filter; if (m_drawTimer) { forceDraw(); } @@ -237,24 +208,7 @@ void PainterGL::filter(bool filter) { void PainterGL::start() { m_gl->makeCurrent(); - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &m_tex); - glBindTexture(GL_TEXTURE_2D, m_tex); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if (m_filter) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_INT, 0, _glVertices); - glTexCoordPointer(2, GL_INT, 0, _glTexCoords); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); + m_backend.d.init(&m_backend.d, (void*) m_gl->winId()); m_gl->doneCurrent(); m_drawTimer = new QTimer; @@ -267,19 +221,17 @@ void PainterGL::start() { void PainterGL::draw() { GBASyncWaitFrameStart(&m_context->sync, m_context->frameskip); m_painter.begin(m_gl->context()->device()); - m_painter.setWorldTransform(m_world); performDraw(); m_painter.end(); GBASyncWaitFrameEnd(&m_context->sync); - m_gl->swapBuffers(); + m_backend.d.swap(&m_backend.d); } void PainterGL::forceDraw() { m_painter.begin(m_gl->context()->device()); - m_painter.setWorldTransform(m_world); performDraw(); m_painter.end(); - m_gl->swapBuffers(); + m_backend.d.swap(&m_backend.d); } void PainterGL::stop() { @@ -287,10 +239,9 @@ void PainterGL::stop() { delete m_drawTimer; m_drawTimer = nullptr; m_gl->makeCurrent(); - glDeleteTextures(1, &m_tex); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - m_gl->swapBuffers(); + m_backend.d.clear(&m_backend.d); + m_backend.d.swap(&m_backend.d); + m_backend.d.deinit(&m_backend.d); m_gl->doneCurrent(); m_gl->context()->moveToThread(m_gl->thread()); moveToThread(m_gl->thread()); @@ -309,21 +260,11 @@ void PainterGL::unpause() { void PainterGL::performDraw() { m_painter.beginNativePainting(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glViewport(0, 0, m_size.width() * m_gl->devicePixelRatio(), m_size.height() * m_gl->devicePixelRatio()); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - QRect viewport(m_viewport.topLeft() * m_gl->devicePixelRatio(), m_viewport.size() * m_gl->devicePixelRatio()); - glViewport(viewport.x(), viewport.y(), viewport.width(), viewport.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - if (m_context->sync.videoFrameWait) { - glFlush(); - } + float r = m_gl->devicePixelRatio(); + m_backend.d.resized(&m_backend.d, m_size.width() * r, m_size.height() * r); + m_backend.d.drawFrame(&m_backend.d); m_painter.endNativePainting(); + m_painter.setWorldTransform(m_world); m_painter.setRenderHint(QPainter::Antialiasing); m_painter.setFont(m_messageFont); m_painter.setPen(Qt::black); diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 97cf72cd1..d3e31db55 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -13,6 +13,10 @@ #include #include +extern "C" { +#include "platform/opengl/gl.h" +} + struct GBAThread; namespace QGBA { @@ -94,11 +98,8 @@ private: QTimer* m_drawTimer; QTimer m_messageTimer; GBAThread* m_context; - GLuint m_tex; + GBAGLContext m_backend; QSize m_size; - bool m_lockAspectRatio; - bool m_filter; - QRect m_viewport; QTransform m_world; QFont m_messageFont; }; From a21d773ae8dd52b6e2e1e7b34f8bca4ec3d5b457 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Thu, 4 Jun 2015 00:59:13 -0700 Subject: [PATCH 3/3] OpenGL: Clear screen when resizing --- src/platform/opengl/gl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/opengl/gl.c b/src/platform/opengl/gl.c index e941f705a..3d44c3da8 100644 --- a/src/platform/opengl/gl.c +++ b/src/platform/opengl/gl.c @@ -58,6 +58,10 @@ static void GBAGLContextResized(struct VideoBackend* v, int w, int h) { drawH = w * 2 / 3; } } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); }