I want to use uniform buffer for Matrices of model、view and projection in Qt.I chose QOpenGLExtraFunctions for calling glBindBufferRange function.But I found it no use.My floor.vert and object.vert shows 'model'、'projection' and 'view' were not declare in this scope and my program output was "QOpenGLFunctions created with non-current context". I thought the reason might be introduced by not calling glBindBuffer when I bind uniform buffer,but I found there is no glBindBuffer function in QOpenGLExtraFunctions. Although QOpenGlFunctions has glBindBuffer but there is no glBindBufferRange function in it.So how can I fix it?
showcasewidget.cpp
#include "showcasewidget.h"
#include "ui_showcasewidget.h"
Showcasewidget::Showcasewidget(QWidget *parent) :
QOpenGLWidget(parent), QOpenGLExtraFunctions(nullptr),
ui(new Ui::Showcasewidget)
{
ui->setupUi(this);
}
Showcasewidget::~Showcasewidget()
{
objectVbo.release();
objectVao.release();
delete ui;
}
void Showcasewidget::make_object()
{
objectVbo.create();
objectVbo.bind();
objectVbo.allocate(this->vertices.constData(), sizeof(GLfloat) * this->vertices.count());
objectVao.create();
objectVao.bind();
objectShader->objectProgram.setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(GLfloat)*3);
objectShader->objectProgram.enableAttributeArray(0);
}
void Showcasewidget::store_matrices()
{
matricesVbo.create();
matricesVbo.bind();
matricesVbo.allocate(3*4*4*sizeof(GLfloat));
glBindBufferRange(GL_UNIFORM_BUFFER, 0, matricesVbo.bufferId(), 0, 3*4*4*sizeof(GLfloat));
}
void Showcasewidget::initializeGL()
{
this->initializeOpenGLFunctions();
objectShader = new Shader(":/shaders/object.vert", ":/shaders/object.frag");
floorShader = new Shader(":/shaders/floor.vert", ":/shaders/floor.frag");
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
camera = new Camera(QVector3D(0.0f, 0.0f, 5.0f));
}
void Showcasewidget::paintGL()
{
QDateTime currentFrame = QDateTime::currentDateTime();
this->deltaTime = this->lastTime.msecsTo(currentFrame);
this->lastTime = currentFrame;
camera->processKeyInput(this->keys, this->deltaTime);
QMatrix4x4 model;
model.setToIdentity();
QMatrix4x4 projection;
projection.perspective(camera->zoom, (GLfloat)this->width()/(GLfloat)this->height(), 0.1f, 200.0f);
QMatrix4x4 view;
view = camera->getViewMatrix();
store_matrices();
glBufferSubData(GL_UNIFORM_BUFFER, 0, 4 * 4 * sizeof(GLfloat), &projection);
glBufferSubData(GL_UNIFORM_BUFFER, 4 * 4 * sizeof(GLfloat), 4 * 4 * sizeof(GLfloat), &view);
glBufferSubData(GL_UNIFORM_BUFFER, 2 * 4 * 4 * sizeof(GLfloat), 4 * 4 * sizeof(GLfloat), &model);
floorShader->use();
glDrawArrays(GL_LINE_LOOP, 0, 6);
objectShader->use();
make_object();
objectVao.bind();
for(int i = 0;i < this->vertices.count()/3;i += 3)
glDrawArrays(GL_LINE_LOOP, i, 3);
}
void Showcasewidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void Showcasewidget::mousePressEvent(QMouseEvent* e)
{
if(e->button() == Qt::LeftButton)
{
this->lastx = e->x();
this->lasty = e->y();
}
this->update();
}
void Showcasewidget::mouseMoveEvent(QMouseEvent* e)
{
if(e->buttons() & Qt::LeftButton)
{
int cur_x = e->x();
int cur_y = e->y();
float xoffset = cur_x - this->lastx;
float yoffset = this->lasty - cur_y;
this->lastx = cur_x;
this->lasty = cur_y;
this->camera->processMouseMovement(xoffset, yoffset);
}
this->update();
}
showcasewidget.h
#ifndef SHOWCASEWIDGET_H
#define SHOWCASEWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLExtraFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QDebug>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QVector>
#include <QDateTime>
#include "shader.h"
#include "camera.h"
namespace Ui {
class Showcasewidget;
}
class Showcasewidget : public QOpenGLWidget, protected QOpenGLExtraFunctions
{
Q_OBJECT
public:
explicit Showcasewidget(QWidget *parent = nullptr);
~Showcasewidget();
QVector<GLfloat> vertices;
QDateTime lastTime = QDateTime::currentDateTime();
GLfloat deltaTime;
Camera *camera;
int lastx, lasty;
QList<int> keys;
void make_object();
void store_matrices();
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
void mousePressEvent(QMouseEvent* e) override;
void mouseMoveEvent(QMouseEvent* e) override;
private:
QOpenGLBuffer objectVbo, matricesVbo;
QOpenGLVertexArrayObject objectVao;
Ui::Showcasewidget *ui;
Shader *objectShader, *floorShader;
};
#endif // SHOWCASEWIDGET_H
floor.vert
#version 420 core
layout(std140, binding = 0) uniform Matrices
{
mat4 model;
mat4 projection;
mat4 view;
};
vec3 gridPlane[6] = vec3[](
vec3(1, 1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
vec3(-1, -1, 0), vec3(1, 1, 0), vec3(1, -1, 0)
);
void main()
{
gl_Position = projection * view * model * vec4(gridPlane[gl_VertexID], 1.0);
}
floor.frag
#version 420 core
out vec4 outColor;
void main()
{
outColor = vec4(1.0, 0.0, 0.0, 1.0);
}
object.vert
#version 420 core
layout (location = 0) in vec3 aPos;
layout(std140, binding = 0) uniform Matrices
{
mat4 projection;
mat4 view;
mat4 model;
};
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0f);
}
object.frag
#version 420 core
out vec4 FragColor;
void main()
{
if(gl_FragCoord.x < 300)
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
FragColor = vec4(0.0, 1.0, 0.0, 1.0f);
}
I want to use uniform buffer in QT with OpenGL.