Zamaster
6th March 2014, 21:54
So I'm trying to make a QGLWidget function with Qt Creator and I'm running into a strange issue trying to use regular OpenGL functions. My program ASSERTS and crashes with: "QGLFunctions::isInitialized(d_ptr)" in "c:\work\build\qt5_workdir\w\s\qtbase\include\qtope ngl\../../src/opengl/qglfunctions.h, line 722"
I found this is called from the "glGenBuffers" call in my cpp code. Ill post the .h and .cpp here:
myglwidget.h
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include <QGLWidget>
#include <QGLFunctions>
#include <QGLShaderProgram>
class MyGLWidget : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
explicit MyGLWidget(QWidget *parent = 0);
~MyGLWidget();
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
private:
int width;
int height;
GLuint back_texture;
GLuint* vboid;
QGLShaderProgram default_prog;
};
#endif // MYGLWIDGET_H
myglwidget.cpp
#include "myglwidget.h"
#include <QDebug>
#include <QVector3D>
#include <QVector2D>
#include "locale.h"
#define BACK_TILE_S 48
struct VertexData
{
QVector3D position;
QVector2D texCoord;
};
MyGLWidget::MyGLWidget(QWidget *parent) :
QGLWidget(parent)
{
glGenBuffers(2, vboid);
}
MyGLWidget::~MyGLWidget(){
glDeleteBuffers(2, vboid);
}
void MyGLWidget::initializeGL(){
VertexData verts[] = {
{QVector3D(0, 0, 0), QVector2D(0, 0)},
{QVector3D(1, 0, 0), QVector2D(1, 0)},
{QVector3D(0, 1, 0), QVector2D(0, 1)},
{QVector3D(1, 1, 0), QVector2D(1, 1)}
};
GLushort indices[] = {
0, 1, 2, 3
};
setlocale(LC_NUMERIC, "C");
default_prog.addShaderFromSourceFile(QGLShader::Ve rtex, ":/shaders/default.vert");
default_prog.addShaderFromSourceFile(QGLShader::Fr agment, ":/shaders/default.frag");
default_prog.link();
default_prog.bind(); // this is in initgl since this is the
// only shader we use... FOR NOW, therefore
// we dont have to do it elsewhere
setlocale(LC_ALL, "");
glEnable(GL_TEXTURE_2D);
// normally here we would have the QImage buffered up already
// and would bind as needed, but again, this is the only
// texture we use for now
back_texture = bindTexture(QImage(":/gfx/gfx/back.png"));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindBuffer(GL_ARRAY_BUFFER, vboid[0]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(VertexData), verts, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboid[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLushort), indices, GL_STATIC_DRAW);
}
void MyGLWidget::paintGL(){
int texw;
int texh;
QMatrix4x4 proj;
QMatrix2x2 scale;
quintptr offset;
int vertexLoc;
int texcoordLoc;
texw = (floor(width / ((double) BACK_TILE_S)) + 1);
texh = (floor(height / ((double) BACK_TILE_S)) + 1);
proj.setToIdentity();
proj.scale(texw * BACK_TILE_S, texh * BACK_TILE_S);
proj.ortho(0, width, 0, height, -1, 1);
scale.setToIdentity();
scale(0,0) = texw;
scale(1,1) = texh;
default_prog.setUniformValue("texScale", scale);
default_prog.setUniformValue("mvp_matrix", proj);
default_prog.setUniformValue("texture", 0);
glBindBuffer(GL_ARRAY_BUFFER, vboid[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboid[1]);
offset = 0;
vertexLoc = default_prog.attributeLocation("a_position");
default_prog.enableAttributeArray(vertexLoc);
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void*) offset);
offset += sizeof(QVector3D);
texcoordLoc = default_prog.attributeLocation("a_texcoord");
default_prog.enableAttributeArray(texcoordLoc);
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void*) offset);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
}
void MyGLWidget::resizeGL(int width, int height){
this->width = width;
this->height = height;
}
I found this is called from the "glGenBuffers" call in my cpp code. Ill post the .h and .cpp here:
myglwidget.h
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include <QGLWidget>
#include <QGLFunctions>
#include <QGLShaderProgram>
class MyGLWidget : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
explicit MyGLWidget(QWidget *parent = 0);
~MyGLWidget();
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
private:
int width;
int height;
GLuint back_texture;
GLuint* vboid;
QGLShaderProgram default_prog;
};
#endif // MYGLWIDGET_H
myglwidget.cpp
#include "myglwidget.h"
#include <QDebug>
#include <QVector3D>
#include <QVector2D>
#include "locale.h"
#define BACK_TILE_S 48
struct VertexData
{
QVector3D position;
QVector2D texCoord;
};
MyGLWidget::MyGLWidget(QWidget *parent) :
QGLWidget(parent)
{
glGenBuffers(2, vboid);
}
MyGLWidget::~MyGLWidget(){
glDeleteBuffers(2, vboid);
}
void MyGLWidget::initializeGL(){
VertexData verts[] = {
{QVector3D(0, 0, 0), QVector2D(0, 0)},
{QVector3D(1, 0, 0), QVector2D(1, 0)},
{QVector3D(0, 1, 0), QVector2D(0, 1)},
{QVector3D(1, 1, 0), QVector2D(1, 1)}
};
GLushort indices[] = {
0, 1, 2, 3
};
setlocale(LC_NUMERIC, "C");
default_prog.addShaderFromSourceFile(QGLShader::Ve rtex, ":/shaders/default.vert");
default_prog.addShaderFromSourceFile(QGLShader::Fr agment, ":/shaders/default.frag");
default_prog.link();
default_prog.bind(); // this is in initgl since this is the
// only shader we use... FOR NOW, therefore
// we dont have to do it elsewhere
setlocale(LC_ALL, "");
glEnable(GL_TEXTURE_2D);
// normally here we would have the QImage buffered up already
// and would bind as needed, but again, this is the only
// texture we use for now
back_texture = bindTexture(QImage(":/gfx/gfx/back.png"));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindBuffer(GL_ARRAY_BUFFER, vboid[0]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(VertexData), verts, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboid[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLushort), indices, GL_STATIC_DRAW);
}
void MyGLWidget::paintGL(){
int texw;
int texh;
QMatrix4x4 proj;
QMatrix2x2 scale;
quintptr offset;
int vertexLoc;
int texcoordLoc;
texw = (floor(width / ((double) BACK_TILE_S)) + 1);
texh = (floor(height / ((double) BACK_TILE_S)) + 1);
proj.setToIdentity();
proj.scale(texw * BACK_TILE_S, texh * BACK_TILE_S);
proj.ortho(0, width, 0, height, -1, 1);
scale.setToIdentity();
scale(0,0) = texw;
scale(1,1) = texh;
default_prog.setUniformValue("texScale", scale);
default_prog.setUniformValue("mvp_matrix", proj);
default_prog.setUniformValue("texture", 0);
glBindBuffer(GL_ARRAY_BUFFER, vboid[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboid[1]);
offset = 0;
vertexLoc = default_prog.attributeLocation("a_position");
default_prog.enableAttributeArray(vertexLoc);
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void*) offset);
offset += sizeof(QVector3D);
texcoordLoc = default_prog.attributeLocation("a_texcoord");
default_prog.enableAttributeArray(texcoordLoc);
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void*) offset);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
}
void MyGLWidget::resizeGL(int width, int height){
this->width = width;
this->height = height;
}