qt: Initial OpenGL 3.0 renderer implementation

This commit is contained in:
ts-korhonen
2022-02-27 14:56:51 +02:00
parent f4587949a7
commit d2a9389ce7
15 changed files with 1558 additions and 209 deletions

View File

@@ -0,0 +1,117 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Header file for OpenGL renderer
*
* Authors:
* Teemu Korhonen
*
* Copyright 2022 Teemu Korhonen
*/
#ifndef QT_OPENGLRENDERER_HPP
#define QT_OPENGLRENDERER_HPP
#include <QOpenGLContext>
#include <QOpenGLFunctions_3_0>
#include <QResizeEvent>
#include <QTimer>
#include <QWidget>
#include <QWindow>
#include <QtOpenGLExtensions/QOpenGLExtensions>
#include <atomic>
#include <tuple>
#include <vector>
#include "qt_opengloptions.hpp"
#include "qt_renderercommon.hpp"
class OpenGLRenderer : public QWindow, protected QOpenGLFunctions_3_0, public RendererCommon {
Q_OBJECT
public:
QOpenGLContext *context;
OpenGLRenderer(QWidget *parent = nullptr);
~OpenGLRenderer();
std::vector<std::tuple<uint8_t *, std::atomic_flag *>> getBuffers() override;
void finalize() override final;
bool hasOptions() const override { return true; }
QDialog *getOptions(QWidget *parent) override;
signals:
void initialized();
void errorInitializing();
public slots:
void onBlit(int buf_idx, int x, int y, int w, int h);
protected:
void exposeEvent(QExposeEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
bool event(QEvent *event) override;
private:
static constexpr int INIT_WIDTH = 640;
static constexpr int INIT_HEIGHT = 400;
static constexpr int ROW_LENGTH = 2048;
static constexpr int BUFFERPIXELS = 4194304;
static constexpr int BUFFERBYTES = 16777216; /* Pixel is 4 bytes. */
static constexpr int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */
OpenGLOptions *options;
QTimer *renderTimer;
bool isInitialized = false;
bool isFinalized = false;
GLuint unpackBufferID = 0;
GLuint vertexArrayID = 0;
GLuint vertexBufferID = 0;
GLuint textureID = 0;
int frameCounter = 0;
void *unpackBuffer = nullptr;
void initialize();
void setupExtensions();
void setupBuffers();
void applyOptions();
void applyShader(const OpenGLShaderPass &shader);
bool notReady() const { return !isInitialized || isFinalized; }
/* GL_ARB_buffer_storage */
bool hasBufferStorage = false;
PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr;
/* GL_ARB_debug_output */
bool hasDebugOutput = false;
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = nullptr;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = nullptr;
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = nullptr;
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = nullptr;
/* GL_ARB_sync */
bool hasSync = false;
PFNGLFENCESYNCPROC glFenceSync = nullptr;
PFNGLISSYNCPROC glIsSync = nullptr;
PFNGLDELETESYNCPROC glDeleteSync = nullptr;
PFNGLCLIENTWAITSYNCPROC glClientWaitSync = nullptr;
PFNGLWAITSYNCPROC glWaitSync = nullptr;
PFNGLGETINTEGER64VPROC glGetInteger64v = nullptr;
PFNGLGETSYNCIVPROC glGetSynciv = nullptr;
private slots:
void render();
void updateOptions(OpenGLOptions *newOptions);
};
#endif