Ich versuche, QOpenGLBuffer als Pixel Buffer-Objekt zu verwenden. Das Ziel wäre, einen hochauflösenden Videostream (4K, 60FPS) anzuzeigen, also brauche ich eine gute Leistung.Wie verwende ich PBO mit Qt OpenGL
Da ich gerade mit OpenGL beginne, versuche ich zunächst, eine einfache 2D-Textur so gut wie möglich darzustellen. Ich habe bereits VBO und VAO aufgenommen, der nächste Schritt (wie ich es gelesen habe) wäre, ein PBO für bessere Leistung zu verwenden.
Es gibt Tutorial für PBO aber mit glGenBufferARB(), nicht mit QOpenGLBuffer.
Hier ist mein Code:
glwidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QDebug>
#include <QOpenGLTexture>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent = 0);
~GLWidget();
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
void LoadGLTextures();
private :
QOpenGLShaderProgram *program;
QOpenGLBuffer vbo;
QOpenGLVertexArrayObject vao;
GLuint tex;
GLint vertexLocation;
GLint texcoordLocation;
int tailleVerticesBytes;
int tailleCoordTexturesBytes;
float vertices[8];
float coordTexture[8];
public slots:
private slots:
};
#endif // GLWIDGET_H
glwidget.cpp
#ifndef BUFFER_OFFSET
#define BUFFER_OFFSET(offset) ((char*)NULL + (offset))
#include "glwidget.h"
#include <QElapsedTimer>
GLWidget::GLWidget(QWidget *parent) :
QOpenGLWidget(parent)
{
tailleVerticesBytes = 8*sizeof(float);
tailleCoordTexturesBytes = 8*sizeof(float);
}
GLWidget::~GLWidget(){
vao.destroy();
vbo.destroy();
delete program;
glDeleteTextures(1, &tex);
}
void GLWidget::LoadGLTextures(){
QImage img;
if(!img.load("C:\\Users\\Adrien\\Desktop\\open3.bmp")){
qDebug()<<"Image loading failed";
}
QImage t = (img.convertToFormat(QImage::Format_RGBA8888)).mirrored();
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}
void GLWidget::initializeGL(){
float verticesTmp[] = {-1.0,-1.0, 1.0,-1.0, 1.0,1.0, -1.0,1.0};
float coordTextureTmp[] = {0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0};
for(int i = 0; i<8; i++){
vertices[i] = verticesTmp[i];
coordTexture[i] = coordTextureTmp[i];
}
initializeOpenGLFunctions();
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
LoadGLTextures();
//Shader setup
QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
const char *vsrc =
"#version 150 core\n"
"in vec2 in_Vertex;\n"
"in vec2 vertTexCoord;\n"
"out vec2 fragTexCoord;\n"
"void main(void)\n"
"{\n"
" gl_Position = vec4(in_Vertex, 0.0, 1.0);\n"
" fragTexCoord = vertTexCoord;\n"
"}\n";
vshader->compileSourceCode(vsrc);
QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
const char *fsrc =
"#version 150 core\n"
"uniform sampler2D tex;\n"
"in vec2 fragTexCoord;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = texture2D(tex,fragTexCoord);\n"
"}\n";
fshader->compileSourceCode(fsrc);
program = new QOpenGLShaderProgram;
program->addShader(vshader);
program->addShader(fshader);
program->link();
program->bind();
glActiveTexture(GL_TEXTURE0);
program->setUniformValue("tex", 0);
vertexLocation = glGetAttribLocation(program->programId(), "in_Vertex");
texcoordLocation = glGetAttribLocation(program->programId(), "vertTexCoord");
//VAO setup
vao.create();
vao.bind();
//VBO setup
vbo.create();
vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
vbo.bind();
vbo.allocate(tailleVerticesBytes + tailleCoordTexturesBytes);
vbo.write(0, vertices, tailleVerticesBytes);
vbo.write(tailleVerticesBytes, coordTexture, tailleCoordTexturesBytes);
program->enableAttributeArray(vertexLocation);
program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 2);
program->enableAttributeArray(texcoordLocation);
program->setAttributeBuffer(texcoordLocation, GL_FLOAT, tailleVerticesBytes, 2);
vbo.release();
vao.release();
program->release();
}
void GLWidget::paintGL(){
glClear(GL_COLOR_BUFFER_BIT);
program->bind();
{
vao.bind();
glBindTexture(GL_TEXTURE_2D, tex);
glDrawArrays(GL_QUADS, 0, 4);
glBindTexture(GL_TEXTURE_2D, 0);
vao.release();
}
program->release();
}
void GLWidget::resizeGL(int w, int h){
glViewport(0, 0, (GLint)w, (GLint)h);
}
#endif
Also im Grunde, wie würde ich tun, in diesem Code PBO zu verwenden ?
Das erste, was zu tun wäre, ein QOpenGLBuffer-Objekt zu erstellen, während der Typ (QOpenglBuffer :: PixelUnpackBuffer) angeben, dann würde ich denke, ich müsste das Pixel auf den Puffer hochladen und schließlich anstelle von glTexImage2D verwenden? Dies ist nur die globale Idee und ich habe keine Ahnung, wie es geht.
Danke.