Qt: Use common OpenGL code

This commit is contained in:
Jeffrey Pfau 2015-06-04 00:42:00 -07:00
parent ea0b6a14cc
commit d05e596b38
3 changed files with 30 additions and 86 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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;
};