Qt 5 でインスタンス化されたレンダリングを使用しようとしていますが、問題が発生しています。私の問題は、VAO の使用にまでさかのぼると思います。私は経験豊富なプログラマーであり、これらの問題はほとんど常に私のせいであることを知っていますが、時折 Qt のバグに遭遇したので、バグ レポートを提出する前に助けを借りることができると思いました。
インスタンス化を使用しない簡単な例をまとめました (開発中の「実際の」ソフトウェアではこの問題が発生していないにもかかわらず、何らかの理由で最新バージョンの OpenGL を要求できません)。 .
初期化時に、VAO と 2 つの VBO を作成します。1 つの VBO には何らかのデータが入力され、バインドされたままになります。もう 1 つは割り当てられますが、解放されます (実際には使用しません。最終的にインスタンス化のために行列を書き込むことを計画していましたが、そこまでは行きませんでした)。
VAO または 2 番目の VBO の使用を簡単にオンまたはオフにするために、いくつかのプリプロセッサ ディレクティブを追加しました。VAO と VBO の両方を使用すると、セグメンテーション エラーが発生します。2 番目の VBO または VAO のいずれかを取り除くと、セグ フォールトはなくなり、図面は正しく表示されます (色付きの三角形の後ろに白い三角形が描かれるはずです)。
コードは次のとおりです。
glbuffertest.cpp:
######################################################################
# Automatically generated by qmake (3.0) Fri May 16 09:49:41 2014
######################################################################
TEMPLATE = app
TARGET = glbuffertest
INCLUDEPATH += .
CONFIG += qt debug
DEFINES += USE_VAO
DEFINES += USE_MATBO
# Input
SOURCES += glbuffertest.cpp glwindow.cpp
HEADERS += glwindow.h
glbuffertest.cpp:
#include <QGuiApplication>
#include <QSurfaceFormat>
#include "glwindow.h"
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
GLWindow window;
window.resize(400, 400);
window.show();
return app.exec();
}
glwindow.cpp:
#include "glwindow.h"
#include <QColor>
#include <QMatrix4x4>
#include <QVector>
#include <QVector3D>
#include <QVector4D>
#include <QDebug>
GLWindow::GLWindow(QWindow *parent)
: QWindow(parent)
, _vbo(QOpenGLBuffer::VertexBuffer)
, _matbo(QOpenGLBuffer::VertexBuffer)
, _context(0)
{
setSurfaceType(QWindow::OpenGLSurface);
create();
}
GLWindow::~GLWindow()
{}
void GLWindow::initGL()
{
if (_context) // already initialized
return;
_context = new QOpenGLContext(this);
QSurfaceFormat format(requestedFormat());
format.setDepthBufferSize(24);
_context->setFormat(format);
_context->create();
_context->makeCurrent(this);
setupShaders();
_program->bind();
_positionAttr = _program->attributeLocation("position");
_colourAttr = _program->attributeLocation("colour");
_matrixUnif = _program->uniformLocation("matrix");
_program->release();
initializeOpenGLFunctions();
QVector<QVector3D> triangles;
triangles << QVector3D(-0.5, 0.5, 1) << QVector3D(-0.5, -0.5, 1) << QVector3D(0.5, -0.5, 1);
triangles << QVector3D(0.5, 0.5, 0.5) << QVector3D(-0.5, -0.5, 0.5) << QVector3D(0.5, -0.5, 0.5);
QVector<QVector3D> colours;
colours << QVector3D(1, 0, 0) << QVector3D(0, 1, 0) << QVector3D(0, 0, 1);
colours << QVector3D(1, 1, 1) << QVector3D(1, 1, 1) << QVector3D(1, 1, 1);
#ifdef USE_VAO
_vao.create();
_vao.bind();
#endif
_vbo.create();
_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
_vbo.bind();
size_t positionSize = triangles.size() * sizeof(QVector3D);
size_t colourSize = colours.size() * sizeof(QVector3D);
_vbo.allocate(positionSize + colourSize);
_vbo.write(0, triangles.constData(), positionSize);
_vbo.write(positionSize, colours.constData(), colourSize);
_colourOffset = positionSize;
#ifdef USE_MATBO
_matbo.create();
_matbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
_matbo.bind();
_matbo.allocate(4 * sizeof(QVector4D));
qDebug() << "matrix buffer size:" << _matbo.size() << "requested:" << 4 * sizeof(QVector4D);
_matbo.release();
#endif
#ifdef USE_VAO
glVertexAttribPointer(_positionAttr, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(_colourAttr, 3, GL_FLOAT, GL_FALSE, 0, (void*)(_colourOffset));
glEnableVertexAttribArray(_positionAttr);
glEnableVertexAttribArray(_colourAttr);
_vao.release();
#else
_vbo.release();
#endif
resizeGL(width(), height());
}
void GLWindow::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void GLWindow::paintGL()
{
if (! _context) // not yet initialized
return;
_context->makeCurrent(this);
QColor background(Qt::black);
glClearColor(background.redF(), background.greenF(), background.blueF(), 1.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 matrix;
matrix.perspective(60, 4.0/3.0, 0.1, 100.0);
matrix.translate(0, 0, -2);
_program->bind();
_program->setUniformValue(_matrixUnif, matrix);
#ifdef USE_VAO
_vao.bind();
#else
_vbo.bind();
glVertexAttribPointer(_positionAttr, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(_colourAttr, 3, GL_FLOAT, GL_FALSE, 0, (void*)(_colourOffset));
glEnableVertexAttribArray(_positionAttr);
glEnableVertexAttribArray(_colourAttr);
#endif
glEnable(GL_DEPTH_TEST);
glDrawArrays(GL_TRIANGLES, 0, 6);
#ifdef USE_VAO
_vao.release();
#else
glDisableVertexAttribArray(_positionAttr);
glDisableVertexAttribArray(_colourAttr);
_vbo.release();
#endif
_program->release();
_context->swapBuffers(this);
_context->doneCurrent();
}
static const char *vertexShaderSource =
"attribute highp vec4 position;\n"
"attribute lowp vec4 colour;\n"
"uniform highp mat4 matrix;\n"
"varying lowp vec4 col;\n"
"void main() {\n"
" col = colour;\n"
" gl_Position = matrix * position;\n"
"}\n";
static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
"void main() {\n"
" gl_FragColor = col;\n"
"}\n";
void GLWindow::setupShaders()
{
_program = new QOpenGLShaderProgram(this);
_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
_program->link();
}
void GLWindow::exposeEvent(QExposeEvent *event)
{
Q_UNUSED(event);
if (isExposed())
{
if (! _context)
initGL();
paintGL();
}
}
glwindow.h:
#ifndef GL_WINDOW_H
#define GL_WINDOW_H
#include <QExposeEvent>
#include <QSurfaceFormat>
#include <QWindow>
#include <QOpenGLBuffer>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
class GLWindow : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT
public:
GLWindow(QWindow * = 0);
virtual ~GLWindow();
void initGL();
void paintGL();
void resizeGL(int, int);
protected:
virtual void exposeEvent(QExposeEvent *);
private:
void setupShaders();
QOpenGLBuffer _vbo;
QOpenGLBuffer _matbo;
QOpenGLContext *_context;
QOpenGLShaderProgram *_program;
QOpenGLVertexArrayObject _vao;
GLuint _positionAttr;
GLuint _colourAttr;
GLuint _matrixUnif;
size_t _colourOffset;
} ;
#endif
私がやっている愚かなことを誰かが見つけることができますか?