OpenGL: Make video dimensions customizable
Jeffrey Pfau jeffrey@endrift.com
Mon, 08 Feb 2016 20:48:01 -0800
7 files changed,
63 insertions(+),
25 deletions(-)
M
src/platform/opengl/gl.c
→
src/platform/opengl/gl.c
@@ -21,7 +21,7 @@ 1, 1,
0, 1 }; -static void GBAGLContextInit(struct VideoBackend* v, unsigned width, unsigned height, WHandle handle) { +static void GBAGLContextInit(struct VideoBackend* v, WHandle handle) { UNUSED(handle); struct GBAGLContext* context = (struct GBAGLContext*) v; glGenTextures(1, &context->tex);@@ -31,9 +31,14 @@ #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 +} + +static void GBAGLContextSetDimensions(struct VideoBackend* v, unsigned width, unsigned height) { + struct GBAGLContext* context = (struct GBAGLContext*) v; v->width = width; v->height = height; + glBindTexture(GL_TEXTURE_2D, context->tex); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);@@ -113,6 +118,7 @@
void GBAGLContextCreate(struct GBAGLContext* context) { context->d.init = GBAGLContextInit; context->d.deinit = GBAGLContextDeinit; + context->d.setDimensions = GBAGLContextSetDimensions; context->d.resized = GBAGLContextResized; context->d.swap = 0; context->d.clear = GBAGLContextClear;
M
src/platform/opengl/gles2.c
→
src/platform/opengl/gles2.c
@@ -71,25 +71,13 @@ 1.f, 1.f,
1.f, -1.f, }; -static void GBAGLES2ContextInit(struct VideoBackend* v, unsigned width, unsigned height, WHandle handle) { +static void GBAGLES2ContextInit(struct VideoBackend* v, WHandle handle) { UNUSED(handle); struct GBAGLES2Context* context = (struct GBAGLES2Context*) v; glGenTextures(1, &context->tex); glBindTexture(GL_TEXTURE_2D, context->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - v->width = width; - v->height = height; - -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); -#endif -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); -#endif glClearColor(0.f, 0.f, 0.f, 1.f);@@ -142,6 +130,23 @@ glDeleteFramebuffers(1, &context->finalShader.fbo);
glDeleteTextures(1, &context->finalShader.tex); context->finalShader.fbo = 0; context->finalShader.tex = 0; +} + +static void GBAGLES2ContextSetDimensions(struct VideoBackend* v, unsigned width, unsigned height) { + struct GBAGLES2Context* context = (struct GBAGLES2Context*) v; + v->width = width; + v->height = height; + + glBindTexture(GL_TEXTURE_2D, context->tex); +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); +#endif +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); +#endif } static void GBAGLES2ContextDeinit(struct VideoBackend* v) {@@ -312,6 +317,7 @@
void GBAGLES2ContextCreate(struct GBAGLES2Context* context) { context->d.init = GBAGLES2ContextInit; context->d.deinit = GBAGLES2ContextDeinit; + context->d.setDimensions = GBAGLES2ContextSetDimensions; context->d.resized = GBAGLES2ContextResized; context->d.swap = 0; context->d.clear = GBAGLES2ContextClear;
M
src/platform/qt/DisplayGL.cpp
→
src/platform/qt/DisplayGL.cpp
@@ -221,7 +221,7 @@ m_gl->makeCurrent();
#if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif - m_backend->init(m_backend, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, reinterpret_cast<WHandle>(m_gl->winId())); + m_backend->init(m_backend, reinterpret_cast<WHandle>(m_gl->winId())); #if !defined(_WIN32) || defined(USE_EPOXY) if (m_supportsShaders) { m_shader.preprocessShader = static_cast<void*>(&reinterpret_cast<GBAGLES2Context*>(m_backend)->initialShader);@@ -262,6 +262,19 @@ }
void PainterGL::setContext(mCoreThread* context) { m_context = context; + + if (!context) { + return; + } + + m_gl->makeCurrent(); +#if defined(_WIN32) && defined(USE_EPOXY) + epoxy_handle_external_wglMakeCurrent(); +#endif + unsigned width, height; + context->core->desiredVideoDimensions(context->core, &width, &height); + m_backend->setDimensions(m_backend, width, height); + m_gl->doneCurrent(); } void PainterGL::setMessagePainter(MessagePainter* messagePainter) {@@ -374,7 +387,9 @@ buffer = m_queue.dequeue();
} else { buffer = m_free.takeLast(); } - memcpy(buffer, backing, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); + unsigned width, height; + m_context->core->desiredVideoDimensions(m_context->core, &width, &height); + memcpy(buffer, backing, width * height * BYTES_PER_PIXEL); m_queue.enqueue(buffer); m_mutex.unlock(); }
M
src/platform/qt/GameController.cpp
→
src/platform/qt/GameController.cpp
@@ -34,8 +34,8 @@ using namespace std;
GameController::GameController(QObject* parent) : QObject(parent) - , m_drawContext(new uint32_t[VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS]) - , m_frontBuffer(new uint32_t[VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS]) + , m_drawContext(nullptr) + , m_frontBuffer(nullptr) , m_threadContext() , m_activeKeys(0) , m_inactiveKeys(0)@@ -116,7 +116,9 @@ };
m_threadContext.frameCallback = [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); - memcpy(controller->m_frontBuffer, controller->m_drawContext, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); + unsigned width, height; + controller->m_threadContext.core->desiredVideoDimensions(controller->m_threadContext.core, &width, &height); + memcpy(controller->m_frontBuffer, controller->m_drawContext, width * height * BYTES_PER_PIXEL); QMetaObject::invokeMethod(controller, "frameAvailable", Q_ARG(const uint32_t*, controller->m_frontBuffer)); if (controller->m_pauseAfterFrame.testAndSetAcquire(true, false)) { mCoreThreadPauseFromThread(context);@@ -208,8 +210,6 @@ disconnect();
clearMultiplayerController(); closeGame(); GBACheatDeviceDestroy(&m_cheatDevice); - delete[] m_drawContext; - delete[] m_frontBuffer; delete m_backupLoadState; }@@ -300,12 +300,17 @@ m_threadContext.core = GBACoreCreate();
} m_threadContext.core->init(m_threadContext.core); + unsigned width, height; + m_threadContext.core->desiredVideoDimensions(m_threadContext.core, &width, &height); + m_drawContext = new uint32_t[width * height]; + m_frontBuffer = new uint32_t[width * height]; + if (!biosOnly) { mCoreLoadFile(m_threadContext.core, m_fname.toUtf8().constData()); mCoreAutoloadSave(m_threadContext.core); } - m_threadContext.core->setVideoBuffer(m_threadContext.core, m_drawContext, VIDEO_HORIZONTAL_PIXELS); + m_threadContext.core->setVideoBuffer(m_threadContext.core, m_drawContext, width); if (!m_bios.isNull() && m_useBios) { VFile* bios = VFileDevice::open(m_bios, O_RDONLY);@@ -324,7 +329,7 @@ patch->close(patch);
} m_inputController->recalibrateAxes(); - memset(m_drawContext, 0xF8, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * 4); + memset(m_drawContext, 0xF8, width * height * 4); m_threadContext.core->setAVStream(m_threadContext.core, m_stream);@@ -422,6 +427,9 @@ mCoreThreadEnd(&m_threadContext);
mCoreThreadJoin(&m_threadContext); // Make sure the event queue clears out before the thread is reused QCoreApplication::processEvents(); + + delete[] m_drawContext; + delete[] m_frontBuffer; m_patch = QString();
M
src/platform/sdl/gl-sdl.c
→
src/platform/sdl/gl-sdl.c
@@ -42,7 +42,8 @@ renderer->gl.d.user = renderer;
renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio; renderer->gl.d.filter = renderer->filter; renderer->gl.d.swap = mSDLGLCommonSwap; - renderer->gl.d.init(&renderer->gl.d, renderer->width, renderer->height, 0); + renderer->gl.d.init(&renderer->gl.d, 0); + renderer->gl.d.setDimensions(&renderer->gl.d, renderer->width, renderer->height); _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d); return true;
M
src/platform/sdl/gles2-sdl.c
→
src/platform/sdl/gles2-sdl.c
@@ -102,6 +102,7 @@ renderer->gl2.d.lockAspectRatio = renderer->lockAspectRatio;
renderer->gl2.d.filter = renderer->filter; renderer->gl2.d.swap = mSDLGLCommonSwap; renderer->gl2.d.init(&renderer->gl2.d, 0); + renderer->gl2.d.setDimensions(&renderer->gl2.d, renderer->width, renderer->height); return true; }
M
src/platform/video-backend.h
→
src/platform/video-backend.h
@@ -16,8 +16,9 @@ typedef void* WHandle;
#endif struct VideoBackend { - void (*init)(struct VideoBackend*, unsigned width, unsigned height, WHandle handle); + void (*init)(struct VideoBackend*, WHandle handle); void (*deinit)(struct VideoBackend*); + void (*setDimensions)(struct VideoBackend*, unsigned width, unsigned height); void (*swap)(struct VideoBackend*); void (*clear)(struct VideoBackend*); void (*resized)(struct VideoBackend*, unsigned w, unsigned h);