Qt5.5.1でGLSLを扱うためにごにゃごにゃした話
はじめに
Qt5.5.1でGLSL触りたい!と思って調べてみると,以下の記事が見つかった.
早速試してみるも,glGenVertexArrays
とglBindVertexArrays
が見つからず,動かない.
解決策
-
ココによると,
QOpenGLVertexArrayObject
を使えとのこと.
サンプルコード
-
.pro
のQT
にopengl
を追記する - ↑のQiita記事のコメント欄には不要と書かれているが,環境依存っぽい
QT += core gui opengl
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = opengl
TEMPLATE = app
SOURCES += main.cpp
HEADERS += \
GLWidget.h \
vertex.h
DISTFILES += \
simple.vert \
simple.frag
次に頂点クラスを定義する
#ifndef VERTEX_H
#define VERTEX_H
#include <QVector3D>
class Vertex{
public:
Vertex();
Vertex(const QVector3D &position): m_position(position){}
static int positionOffset(){ return offsetof(Vertex, m_position); }
static int stride(){ return sizeof(Vertex); }
private:
QVector3D m_position;
};
#endif // VERTEX_H
このVertex
を用いて,描画用クラスGLWidget
を作る.
Qt5でOpenGLを扱うためには,WrapperクラスQOpenGLBuffer
, QOpenGLVertexArrayObject
, QopenGLShaderProgram
を使う必要がある.
オリジナルのOpenGLとやってることは変わらないのでわかりやすい.
GLWidget
オブジェクトの生成後にinitializeGL()
が,次にpointGL()
が内部で呼ばれる.
これらの関数の名前は変えてはいけない.
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QVector3D>
#include <QtOpenGL>
#include "vertex.h"
static const Vertex m_vertices[] = {
Vertex( QVector3D( 0.00f, 0.5f, 1.0f)),
Vertex( QVector3D( 0.5f, -0.5f, 1.0f)),
Vertex( QVector3D(-0.5f, -0.5f, 1.0f)),
};
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions{
public:
// QOpenGLWidget::initializeGL()
// paintGL()やresizeGL()が呼ばれる前に1回だけ呼ばれる
void initializeGL(){
// QOpenGLFunctions::initializeOpenGLFunctions()
// OpenGLの初期化
initializeOpenGLFunctions();
// QOpenGLFunctions::glClearColor()
// QOpenGLFunctions::glClear(GL_COLOR_BUFFER_BIT)で塗りつぶす色(背景色)の設定
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
///////////////////////////////////////////
// QOpenGLShaderProgram::QOpenGLShaderProgram()
// OpenGLのShader Programを使うのに必要.glCreateProgram()に近い.
m_program = new QOpenGLShaderProgram();
// QOpenGLShaderProgram::addShaderFromSourceFile()
// 外部ファイルを読み込んで,Shader ProgramのCompileを行う.
m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, "../opengl/simple.vert");
m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, "../opengl/simple.frag");
// QOpenGLShaderProgram::link()
// addShader()によって追加したShader Programのリンクを行う.glLinkProgram()に近い.
m_program->link();
// QOpenGLShaderProgram::bind()
// QOpenGLContext(QSurfaceにOpenGLのレンダリングを行うためのObject)にShader ProgramをBindする.
m_program->bind();
///////////////////////////////////////////
// QOpenGLBuffer::create()
// OpenGL ServerにBuffer Objectをつくる
m_vertex.create();
// QOpenGLBuffer::bind()
// OpenGLにBuffer Objectを関連付ける
m_vertex.bind();
// QOpenGLBuffer::setUsagePattern()
// Bufferに使い道を示す引数の値をセットする
m_vertex.setUsagePattern(QOpenGLBuffer::StaticDraw);
// QOpenGLBuffer::allocate()
// Bufferの領域を確保する
m_vertex.allocate(m_vertices, sizeof(m_vertices));
///////////////////////////////////////////
// QOpenGLVertexArrayObject::create()
// OpenGLのVertex Array Object(VAO)を作成する
m_object.create();
// QOpenGLVertexArrayObject::bind()
// VAOをOpenGLに紐付ける
m_object.bind();
// QOpenGLShaderProgram::enableAttributeArray()
// QOpenGLShaderProgram::setAttributeArray()でShader Programに渡す値を渡す領域の定義
m_program->enableAttributeArray(0);
// QOpenGLShaderProgram::setAttributeArray()
// Shader Programに頂点配列をセットする
m_program->setAttributeBuffer(0, GL_FLOAT, Vertex::positionOffset(), 3, Vertex::stride());
///////////////////////////////////////////
// OpenGL Contextに紐付けられたVAOを解放する
m_object.release();
// OpenGL Contextに紐付けられたBufferを解放する
m_vertex.release();
// QOpenGLContextからShader Programを解放する.glDeleteProgram()に近い.
m_program->release();
}
// QOpenGLWidget::paintGL()
// レンダリングを行う
void paintGL(){
// QOpenGLFunctions::glClear(GL_COLOR_BUFFER_BIT)
// QOpenGLFunctions::glClearColor()で設定した色で背景を塗りつぶす
glClear(GL_COLOR_BUFFER_BIT);
m_program->bind();
m_object.bind();
// QOpenGLFunctions::glDrawArrays()
// どのPrimitiveを用いてレンダリングするのか設定する
glDrawArrays(GL_TRIANGLES, 0, sizeof(m_vertices) / sizeof(m_vertices[0]));
m_object.release();
m_program->release();
}
private:
QOpenGLBuffer m_vertex;
QOpenGLVertexArrayObject m_object;
QOpenGLShaderProgram *m_program;
};
#endif // GLWIDGET_H
main.cpp
で自作HeaderのGLWidget.h
を読み込む
#include "GLWidget.h"
#include <QApplication>
int main(int argc, char *argv[]){
QApplication a(argc, argv);
GLWidget w;
w.show();
return a.exec();
}
Shaderはテキトーです.
#version 330
layout(location = 0) in vec3 position;
out vec4 vColor;
void main(){
gl_Position = vec4(position, 1.0);
vColor = vec4(position, 1.0);
}
#version 330
in vec4 vColor;
out vec4 fColor;
void main(){
fColor = vColor;
}
結果
参考
Author And Source
この問題について(Qt5.5.1でGLSLを扱うためにごにゃごにゃした話), 我々は、より多くの情報をここで見つけました https://qiita.com/mocobt/items/b43b3fe5f7d4e4eedaa5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .