mirror of https://github.com/mgba-emu/mgba.git
Qt: Use common OpenGL code
This commit is contained in:
parent
ea0b6a14cc
commit
d05e596b38
|
@ -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)
|
||||
|
|
|
@ -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<PainterGL*>(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);
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue