Commit 14d916c7 by Ludmány Balázs

First working version

parent 67e94d7e
Pipeline #130 skipped in 0 seconds
......@@ -19,7 +19,7 @@ QML_IMPORT_PATH =
include(deployment.pri)
unix|win32: LIBS += -L$$PWD/../libvnc/libvncclient/.libs/ -lvncclient
unix|win32: LIBS += -L$$PWD/../libvnc/libvncclient/.libs/ -lvncclient -lEGL
INCLUDEPATH += $$PWD/../libvnc
DEPENDPATH += $$PWD/../libvnc
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2016-07-08T15:41:58. -->
<!-- Written by QtCreator 3.5.1, 2016-07-11T16:48:08. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
......
......@@ -172,6 +172,7 @@ void Dispatcher::open(QString host, int port)
m_client->GotBitmap = Dispatcher::GotBitmap;
m_client->GotJpeg = Dispatcher::GotJpeg;
m_client->FinishedFrameBufferUpdate = Dispatcher::FinishedFrameBufferUpdate;
m_client->appData.useRemoteCursor = TRUE;
rfbClientSetClientData(m_client, 0, this);
......
uniform sampler2D texture;
varying highp vec2 vartexcoord;
varying lowp vec2 vartexcoord;
varying lowp vec3 varcolor;
void main(void)
{
gl_FragColor = vec4(texture2D(texture, vartexcoord).rgb, 1.0);
gl_FragColor = vec4(texture2D(texture, vartexcoord).rgb + varcolor, 1.0);
}
uniform highp mat4 ortho;
uniform lowp vec3 colormax;
attribute highp vec2 position;
attribute highp vec2 texcoord;
varying highp vec2 vartexcoord;
attribute lowp vec3 color;
attribute lowp vec2 texcoord;
varying lowp vec3 varcolor;
varying lowp vec2 vartexcoord;
void main(void)
{
gl_Position = ortho * vec4(position, 0.0, 1.0);
varcolor = color / colormax;
vartexcoord = texcoord;
}
#define QT_OPENGL_ES_2 1
#include <QGuiApplication>
#include <QtQml>
#include <QQmlApplicationEngine>
......@@ -6,6 +8,7 @@
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES, true);
QGuiApplication app(argc, argv);
qmlRegisterType<QVnc>("thinclient", 1, 3, "QVnc");
......
......@@ -30,9 +30,13 @@ ApplicationWindow {
width: 1024
height: 768
/* Keys {
onPressed:
}*/
MouseArea {
anchors.fill: parent
cursorShape: Qt.BlankCursor
// cursorShape: Qt.BlankCursor
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
onPositionChanged: vnc.setMouse(mouse.x,
......
......@@ -18,7 +18,8 @@ QVnc::QVnc()
connect(m_dispatcher, &Dispatcher::updateFramebuffer, this, &QVnc::update);
connect(m_dispatcher, &Dispatcher::error, this, &QVnc::dispatch_error);
QThreadPool::globalInstance()->reserveThread();
// QThreadPool::globalInstance()->reserveThread();
qDebug() << QThreadPool::globalInstance()->maxThreadCount();
m_dispatcher_thread.start();
}
......@@ -80,10 +81,8 @@ Dispatcher *QVnc::dispatcher() const
QQuickFramebufferObject::Renderer *QVnc::createRenderer() const
{
VncRenderer *renderer = new VncRenderer(window(),
m_dispatcher->uploader().fill_buffer(),
m_dispatcher->uploader().vertices(),
m_dispatcher->uploader().copy_textures(),
m_dispatcher->uploader().copy_buffer(),
m_dispatcher->uploader().draw_buffer(),
m_dispatcher->uploader().draw_textures());
connect(renderer, &VncRenderer::finishedRendering, m_dispatcher, &Dispatcher::refresh);
connect(renderer, &VncRenderer::FBOTextureChanged, &(m_dispatcher->uploader()), &Uploader::changeFBOTexture);
......
#include "uploader.h"
#include <cstring>
Uploader::Uploader(QObject *parent) : QObject(parent), m_uploader_context(this), m_copyProgram(this)
{
......@@ -14,6 +15,7 @@ Uploader::Uploader(QObject *parent) : QObject(parent), m_uploader_context(this),
m_copy_data.reserve(5);
m_copy_textures->reserve(5);
m_draw_textures->reserve(5);
m_vertices = QSharedPointer<QOpenGLBuffer>(new QOpenGLBuffer);
}
Uploader::~Uploader()
......@@ -36,14 +38,14 @@ void Uploader::create_context(QOpenGLContext *context)
m_copyProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "copy_shader.vsh");
m_copyProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "copy_shader.fsh");
m_copyProgram.bind();
m_copyProgram.setUniformValue("texture", GL_TEXTURE_2D);
m_functions->glActiveTexture(GL_TEXTURE0);
m_copyProgram.setUniformValue("texture", 0);
m_copyProgram.enableAttributeArray("position");
m_copyProgram.enableAttributeArray("texcoord");
m_copyProgram.setAttributeArray("position", GL_FLOAT, position, 2);
m_fill_buffer.create();
m_copy_buffer.create();
m_draw_buffer.create();
m_vertices->create();
m_vertices->setUsagePattern(QOpenGLBuffer::DynamicDraw);
}
void Uploader::startedUpdate()
......@@ -64,6 +66,7 @@ void Uploader::startedUpdate()
m_draw_textures->clear();
m_draw_data.clear();
m_draw_count = 0;
}
void Uploader::gotCopyRect(const int src_x, const int src_y, const int width, const int height, const int dest_x, const int dest_y)
......@@ -75,9 +78,13 @@ void Uploader::gotCopyRect(const int src_x, const int src_y, const int width, co
QOpenGLFramebufferObject fbo(width, height);
fbo.bind();
m_functions->glBindTexture(GL_TEXTURE_2D, m_FBOTexture);
m_functions->glViewport(0, 0, width, height);
m_copyProgram.setAttributeArray("texcoord", GL_FLOAT, texcoord, 2);
m_functions->glBindTexture(GL_TEXTURE_2D, m_FBOTexture);
m_functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
m_functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
m_functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
m_functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
m_copy_textures->append(fbo.takeTexture());
m_functions->glBindTexture(GL_TEXTURE_2D, 0);
......@@ -85,21 +92,41 @@ void Uploader::gotCopyRect(const int src_x, const int src_y, const int width, co
// bottom left
m_copy_data.append((float) dest_x);
m_copy_data.append((float) (dest_y + height));
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
// top left
m_copy_data.append((float) dest_x);
m_copy_data.append((float) dest_y);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(1.0f);
// bottom right
m_copy_data.append((float) (dest_x + width));
m_copy_data.append((float) (dest_y + height));
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(1.0f);
m_copy_data.append(0.0f);
// top right
m_copy_data.append((float) (dest_x + width));
m_copy_data.append((float) dest_y);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(0.0f);
m_copy_data.append(1.0f);
m_copy_data.append(1.0f);
......@@ -121,83 +148,132 @@ void Uploader::gotFillRect(const int x, const int y, const int width, const int
m_fill_data.append(red);
m_fill_data.append(green);
m_fill_data.append(blue);
m_fill_data.append(0.0f);
m_fill_data.append(0.0f);
// top left
m_fill_data.append((float) x);
m_fill_data.append((float) y);
m_fill_data.append(red);
m_fill_data.append(green);
m_fill_data.append(blue);
m_fill_data.append(0.0f);
m_fill_data.append(0.0f);
// bottom right
m_fill_data.append((float) (x + width));
m_fill_data.append((float) (y + height));
m_fill_data.append(red);
m_fill_data.append(green);
m_fill_data.append(blue);
m_fill_data.append(0.0f);
m_fill_data.append(0.0f);
// top right
m_fill_data.append((float) (x + width));
m_fill_data.append((float) y);
m_fill_data.append(red);
m_fill_data.append(green);
m_fill_data.append(blue);
m_fill_data.append(0.0f);
m_fill_data.append(0.0f);
m_fill_count++;
}
void Uploader::gotBitmap(const QImage &image, const int x, const int y, const int width, const int height)
void Uploader::gotBitmap(const QImage &image, const quint32 x, const quint32 y, const quint32 width, const quint32 height)
{
// TODO: use power of 2 textures
QImage img = image.convertToFormat(QImage::Format_RGBA8888);
// "This function returns the nearest power of two greater than value."
// We need greater than or equal
quint32 real_width = qNextPowerOfTwo(width - 1);
quint32 real_height = qNextPowerOfTwo(height - 1);
float bottom = (float) height / (float) real_height;
float right = (float) width / (float) real_width;
m_functions->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
QOpenGLTexture * tex = new QOpenGLTexture(QOpenGLTexture::Target2D);
tex->setSize(real_width, real_height);
tex->setMipLevels(1);
tex->setFormat(QOpenGLTexture::RGBAFormat);
tex->setMinMagFilters(QOpenGLTexture::Nearest, QOpenGLTexture::Nearest);
tex->setWrapMode(QOpenGLTexture::ClampToEdge);
tex->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
tex->bind();
m_functions->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, img.constBits());
tex->release();
// TODO: use a single texture
m_draw_textures->append(new QOpenGLTexture(image.mirrored(), QOpenGLTexture::DontGenerateMipMaps));
m_draw_textures->append(tex);
// bottom left
m_draw_data.append((float) x);
m_draw_data.append((float) (y + height));
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(bottom);
// top left
m_draw_data.append((float) x);
m_draw_data.append((float) y);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(1.0f);
// bottom right
m_draw_data.append((float) (x + width));
m_draw_data.append((float) (y + height));
m_draw_data.append(1.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(right);
m_draw_data.append(bottom);
// top right
m_draw_data.append((float) (x + width));
m_draw_data.append((float) y);
m_draw_data.append(1.0f);
m_draw_data.append(1.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(0.0f);
m_draw_data.append(right);
m_draw_data.append(0.0f);
m_draw_count++;
}
void Uploader::finishedUpdate()
{
// TODO: calculate texture atlas and upload
// TODO: use a single buffer
// TODO: reuse buffer, don't reallocate
if(m_fill_count > 0) {
m_fill_buffer.bind();
m_fill_buffer.allocate(m_fill_data.constData(), m_fill_data.size() * sizeof(float));
m_fill_buffer.release();
}
unsigned int fillSize = m_fill_data.size() * sizeof(float);
unsigned int copySize = m_copy_data.size() * sizeof(float);
unsigned int drawSize = m_draw_data.size() * sizeof(float);
unsigned int sumSize = fillSize + copySize + drawSize;
if(m_copy_count > 0) {
m_copy_buffer.bind();
m_copy_buffer.allocate(m_copy_data.constData(), m_copy_data.size() * sizeof(float));
m_copy_buffer.release();
}
m_vertices->bind();
if(m_draw_count > 0) {
m_draw_buffer.bind();
m_draw_buffer.allocate(m_draw_data.data(), m_draw_data.size() * sizeof(float));
m_draw_buffer.release();
if(sumSize > m_allocated) {
m_vertices->allocate(sumSize);
m_allocated = sumSize;
}
m_functions->glFlush();
if(fillSize > 0)
m_vertices->write(0, m_fill_data.constData(), fillSize);
if(copySize > 0)
m_vertices->write(fillSize, m_copy_data.constData(), copySize);
if(drawSize > 0)
m_vertices->write(fillSize + copySize, m_draw_data.constData(), drawSize);
m_functions->glGetError();
m_vertices->release();
m_functions->glFinish();
}
unsigned int Uploader::fill_count() const
......@@ -215,29 +291,19 @@ unsigned int Uploader::draw_count() const
return m_draw_count;
}
QOpenGLBuffer Uploader::fill_buffer()
{
return m_fill_buffer;
}
QSharedPointer<QVector<GLuint>> Uploader::copy_textures()
{
return m_copy_textures;
}
QOpenGLBuffer Uploader::copy_buffer()
{
return m_copy_buffer;
}
QOpenGLBuffer Uploader::draw_buffer()
QSharedPointer<QVector<QOpenGLTexture *>> Uploader::draw_textures()
{
return m_draw_buffer;
return m_draw_textures;
}
QSharedPointer<QVector<QOpenGLTexture *>> Uploader::draw_textures()
QSharedPointer<QOpenGLBuffer> Uploader::vertices() const
{
return m_draw_textures;
return m_vertices;
}
void Uploader::changeFBOTexture(const unsigned int FBOTexture, const QMatrix4x4 &ortho)
......
......@@ -10,11 +10,14 @@
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLPixelTransferOptions>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#include <QThreadPool>
#include <QtAlgorithms>
#include <QSharedPointer>
#include <QtMath>
// #include <GLES/gl2ext.h>
class Uploader : public QObject
{
......@@ -26,7 +29,7 @@ public:
void startedUpdate();
void gotCopyRect(const int src_x, const int src_y, const int width, const int height, const int dest_x, const int dest_y);
void gotFillRect(const int x, const int y, const int width, const int height, const float red, const float green, const float blue);
void gotBitmap(const QImage &image, const int x, const int y, const int width, const int height);
void gotBitmap(const QImage &image, const quint32 x, const quint32 y, const quint32 width, const quint32 height);
void finishedUpdate();
void setFramebufferHeight(int framebufferHeight);
......@@ -35,34 +38,32 @@ public:
unsigned int copy_count() const;
unsigned int draw_count() const;
QOpenGLBuffer fill_buffer();
QSharedPointer<QVector<GLuint>> copy_textures();
QOpenGLBuffer copy_buffer();
QOpenGLBuffer draw_buffer();
QSharedPointer<QVector<QOpenGLTexture *>> draw_textures();
QSharedPointer<QOpenGLBuffer> vertices() const;
private:
int m_framebufferHeight;
QOffscreenSurface m_surface;
QOpenGLContext m_uploader_context;
QOpenGLFunctions *m_functions;
QSharedPointer<QOpenGLBuffer> m_vertices;
unsigned int m_allocated;
QOpenGLShaderProgram m_copyProgram;
GLuint m_FBOTexture;
unsigned int m_fill_count;
QVector<float> m_fill_data;
QOpenGLBuffer m_fill_buffer;
unsigned int m_copy_count;
QVector<float> m_copy_data;
QSharedPointer<QVector<GLuint>> m_copy_textures;
QOpenGLBuffer m_copy_buffer;
unsigned int m_draw_count;
QVector<float> m_draw_data;
QOpenGLBuffer m_draw_buffer;
QSharedPointer<QVector<QOpenGLTexture*>> m_draw_textures;
uchar m_decoders_running;
......
#include "vncrenderer.h"
#include <cstring>
VncRenderer::VncRenderer(QQuickWindow *window,
QOpenGLBuffer fill_buffer,
QSharedPointer<QOpenGLBuffer> vertices,
QSharedPointer<QVector<GLuint>> copy_textures,
QOpenGLBuffer copy_buffer,
QOpenGLBuffer draw_buffer,
QSharedPointer<QVector<QOpenGLTexture*>> draw_textures,
QObject *parent) :
QObject(parent), m_window(window), m_clear(true), m_fill_buffer(fill_buffer), m_copy_textures(copy_textures),
m_copy_buffer(copy_buffer), m_draw_buffer(draw_buffer), m_draw_textures(draw_textures)
QObject(parent), m_clear(true), m_window(window), m_vertices(vertices), m_copy_textures(copy_textures), m_draw_textures(draw_textures)
{
m_fill_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "fill_shader.vsh");
m_fill_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "fill_shader.fsh");
m_fill_program.link();
m_draw_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "draw_shader.vsh");
m_draw_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "draw_shader.fsh");
m_draw_program.bind();
m_draw_program.setUniformValue("texture", GL_TEXTURE_2D);
m_draw_program.release();
m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "draw_shader.vsh");
m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "draw_shader.fsh");
m_program.bind();
m_program.setUniformValue("texture", 0);
m_program.release();
m_functions = QOpenGLContext::currentContext()->functions();
m_functions->glActiveTexture(GL_TEXTURE0);
}
void VncRenderer::render()
{
/*if(m_frameCount == 0)
m_time.start();
else
qDebug() << (float(m_frameCount) / (float(m_time.elapsed()) / 1000.0f));
m_frameCount++;*/
if(m_clear) {
m_functions->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
m_functions->glClear(GL_COLOR_BUFFER_BIT);
m_clear = false;
}
if(m_fill_count > 0) {
m_fill_program.bind();
m_fill_program.enableAttributeArray("position");
m_fill_program.enableAttributeArray("color");
m_fill_buffer.bind();
m_fill_program.setAttributeBuffer("position", GL_FLOAT, 0 * sizeof(float), 2, 5 * sizeof(float));
m_fill_program.setAttributeBuffer("color", GL_FLOAT, 2 * sizeof(float), 3, 5 * sizeof(float));
m_program.bind();
m_vertices->bind();
m_program.setAttributeBuffer("position", GL_FLOAT, 0 * sizeof(float), 2, 7 * sizeof(float));
m_program.setAttributeBuffer("color", GL_FLOAT, 2 * sizeof(float), 3, 7 * sizeof(float));
m_program.setAttributeBuffer("texcoord", GL_FLOAT, 5 * sizeof(float), 2, 7 * sizeof(float));
m_program.enableAttributeArray("position");
m_program.enableAttributeArray("color");
m_program.enableAttributeArray("texcoord");
for(unsigned int i = 0; i < m_fill_count; i++)
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);
m_fill_buffer.release();
m_fill_program.release();
}
if(m_copy_count > 0 || m_draw_count > 0)
m_draw_program.bind();
m_draw_program.enableAttributeArray("position");
m_draw_program.enableAttributeArray("texcoord");
if(m_copy_count > 0){
m_copy_buffer.bind();
m_draw_program.setAttributeBuffer("position", GL_FLOAT, 0 * sizeof(float), 2, 4 * sizeof(float));
m_draw_program.setAttributeBuffer("texcoord", GL_FLOAT, 2 * sizeof(float), 2, 4 * sizeof(float));
for(unsigned int i = 0; i < m_copy_count; i++) {
m_functions->glBindTexture(GL_TEXTURE_2D, m_copy_textures->at(i));
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);
}
m_functions->glBindTexture(GL_TEXTURE_2D, 0);
m_copy_buffer.release();
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, (m_fill_count + i) * 4, 4);
}
if(m_draw_count > 0) {
m_draw_buffer.bind();
m_draw_program.setAttributeBuffer("position", GL_FLOAT, 0 * sizeof(float), 2, 4 * sizeof(float));
m_draw_program.setAttributeBuffer("texcoord", GL_FLOAT, 2 * sizeof(float), 2, 4 * sizeof(float));
for(unsigned int i = 0; i < m_draw_count; i++) {
m_draw_textures->at(i)->bind();
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, (m_fill_count + m_copy_count + i) * 4, 4);
m_draw_textures->at(i)->release();
}
m_draw_buffer.release();
}
m_vertices->release();
m_program.release();
if(m_copy_count > 0 || m_draw_count > 0)
m_draw_program.release();
m_functions->glFlush();
m_window->resetOpenGLState();
......@@ -88,11 +68,9 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size
{
QMatrix4x4 ortho;
ortho.ortho(QRect(QPoint(0, size.height()), QSize(size.width(), -1 * size.height())));
m_fill_program.bind();
m_fill_program.setUniformValue("ortho", ortho);
m_draw_program.bind();
m_draw_program.setUniformValue("ortho", ortho);
m_draw_program.release();
m_program.bind();
m_program.setUniformValue("ortho", ortho);
m_program.release();
QOpenGLFramebufferObject *framebufferObject = new QOpenGLFramebufferObject(size);
emit FBOTextureChanged(framebufferObject->texture(), ortho);
......@@ -107,7 +85,7 @@ void VncRenderer::synchronize(QQuickFramebufferObject *object)
m_copy_count = dispatcher->copy_count();
m_draw_count = dispatcher->draw_count();
m_fill_program.bind();
m_fill_program.setUniformValue("colormax", dispatcher->colorMax());
m_fill_program.release();
m_program.bind();
m_program.setUniformValue("colormax", dispatcher->colorMax());
m_program.release();
}
......@@ -11,6 +11,7 @@
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QSharedPointer>
#include <QTime>
#include "qvnc.h"
......@@ -19,10 +20,8 @@ class VncRenderer : public QObject, public QQuickFramebufferObject::Renderer
Q_OBJECT
public:
VncRenderer(QQuickWindow *window,
QOpenGLBuffer fill_buffer,
QSharedPointer<QOpenGLBuffer> vertices,
QSharedPointer<QVector<GLuint>> copy_textures,
QOpenGLBuffer copy_buffer,
QOpenGLBuffer draw_buffer,
QSharedPointer<QVector<QOpenGLTexture*>> draw_textures,
QObject *parent = 0);
protected:
......@@ -30,21 +29,19 @@ protected:
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
void synchronize(QQuickFramebufferObject *) override;
private:
QSharedPointer<QOpenGLBuffer> m_vertices;
QOpenGLShaderProgram m_program;
QQuickWindow *m_window;
QOpenGLFunctions *m_functions;
bool m_clear;
int m_frameCount;
QTime m_time;
unsigned int m_fill_count;
QOpenGLShaderProgram m_fill_program;
QOpenGLBuffer m_fill_buffer;
unsigned int m_copy_count;
QSharedPointer<QVector<GLuint>> m_copy_textures;
QOpenGLBuffer m_copy_buffer;
unsigned int m_draw_count;
QOpenGLShaderProgram m_draw_program;
QOpenGLBuffer m_draw_buffer;
QSharedPointer<QVector<GLuint>> m_copy_textures;
QSharedPointer<QVector<QOpenGLTexture*>> m_draw_textures;
signals:
void FBOTextureChanged(const unsigned int FBOTexture, const QMatrix4x4 &ortho);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment