日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

qt android glsl,基于Qt的OpenGL学习(1)—— Hello Triangle

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 qt android glsl,基于Qt的OpenGL学习(1)—— Hello Triangle 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

要學習OpenGL的話,強烈安利這個教程JoeyDeVries的learnopengl,這里是中文翻譯好的版本。教程中使用OpenGL是通過GLFW這個庫,而在Qt中對OpenGL封裝得很好,并且和GUI以及IO相關的處理Qt更便捷,學習起來更輕松。這里就對每篇教程,在Qt在分別直接使用OpenGL的函數和Qt封裝好的類以作對比。

教程中使用的OpenGL版本為3.3,在Qt中需要使用此版本的OpenGL只需要繼承類QOpenGLFunctions_3_3_Core即可。如果為了在不同設備上都能用OpenGL的話,Qt提供了類QOpenGLFunctions,這個類包含了大部分公共的函數,可能會有個別函數不能用。

對比說明

教程地址

原教程地址,相關知識可以點擊鏈接學習。

我的工程地址,準備后期每篇教程一個commit,查看本篇代碼 git checkout v1.1,喜歡就點個Star吧~

不同點

原教程關于ShaderProgram的讀取、鏈接很繁瑣,后面教程還專門寫了個類Shader,這里我直接使用Qt封裝好的addShaderFromSourceFile函數更方便。

Qt提供了QOpenGLShaderProgram、QOpenGLVertexArrayObject、QOpenGLBuffer這些類來處理OpenGL中的program、VAO、VBO。

運行結果

運行結果

使用OpenGL函數版

CoreFunctionWidget.h

#ifndef COREFUNCTIONWIDGET_H

#define COREFUNCTIONWIDGET_H

#include

#include

#include

#include

#include

class CoreFunctionWidget : public QOpenGLWidget

, protected /*QOpenGLExtraFunctions*/QOpenGLFunctions_3_3_Core

{

Q_OBJECT

public:

explicit CoreFunctionWidget(QWidget *parent = nullptr);

~CoreFunctionWidget();

protected:

virtual void initializeGL();

virtual void resizeGL(int w, int h);

virtual void paintGL();

private:

QOpenGLShaderProgram shaderProgram;

};

#endif // COREFUNCTIONWIDGET_H

CoreFunctionWidget.cpp

#include "CoreFunctionWidget.h"

#include

#include

static GLuint VBO, VAO, EBO;

CoreFunctionWidget::CoreFunctionWidget(QWidget *parent) : QOpenGLWidget(parent)

{

}

CoreFunctionWidget::~CoreFunctionWidget()

{

glDeleteVertexArrays(1, &VAO);

glDeleteBuffers(1, &VBO);

// glDeleteBuffers(1, &EBO);

}

void CoreFunctionWidget::initializeGL(){

this->initializeOpenGLFunctions();

bool success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/triangle.vert");

if (!success) {

qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();

return;

}

success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/triangle.frag");

if (!success) {

qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();

return;

}

success = shaderProgram.link();

if(!success) {

qDebug() << "shaderProgram link failed!" << shaderProgram.log();

}

//VAO,VBO數據部分

float vertices[] = {

0.5f, 0.5f, 0.0f, // top right

0.5f, -0.5f, 0.0f, // bottom right

-0.5f, -0.5f, 0.0f, // bottom left

-0.5f, 0.5f, 0.0f // top left

};

unsigned int indices[] = { // note that we start from 0!

0, 1, 3, // first Triangle

1, 2, 3 // second Triangle

};

glGenVertexArrays(1, &VAO);

glGenBuffers(1, &VBO);

glGenBuffers(1, &EBO);

// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //頂點數據復制到緩沖

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);//告訴程序如何解析頂點數據

glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);//取消VBO的綁定, glVertexAttribPointer已經把頂點屬性關聯到頂點緩沖對象了

// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.

// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other

// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.

glBindVertexArray(0); //取消VAO綁定

//線框模式,QOpenGLExtraFunctions沒這函數, 3_3_Core有

// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

}

void CoreFunctionWidget::resizeGL(int w, int h){

glViewport(0, 0, w, h);

}

void CoreFunctionWidget::paintGL(){

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT);

shaderProgram.bind();

glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized

// glDrawArrays(GL_TRIANGLES, 0, 6);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

shaderProgram.release();

}

使用Qt相關函數版

QtFunctionWidget.h

#ifndef QTFUNCTIONWIDGET_H

#define QTFUNCTIONWIDGET_H

#include

#include

#include

#include

#include

#include

#include

#include

class QtFunctionWidget : public QOpenGLWidget, protected QOpenGLFunctions

{

public:

QtFunctionWidget(QWidget *parent = nullptr);

~QtFunctionWidget() Q_DECL_OVERRIDE;

protected:

virtual void initializeGL() Q_DECL_OVERRIDE;

virtual void resizeGL(int w, int h) Q_DECL_OVERRIDE;

virtual void paintGL() Q_DECL_OVERRIDE;

private:

QOpenGLShaderProgram shaderProgram;

QOpenGLBuffer vbo, ebo;

QOpenGLVertexArrayObject vao;

};

#endif // QTFUNCTIONWIDGET_H

QtFunctionWidget.cpp

#include "QtFunctionWidget.h"

#include

QtFunctionWidget::QtFunctionWidget(QWidget *parent) : QOpenGLWidget (parent),

vbo(QOpenGLBuffer::VertexBuffer),

ebo(QOpenGLBuffer::IndexBuffer)

{

}

QtFunctionWidget::~QtFunctionWidget(){

makeCurrent();

vbo.destroy();

ebo.destroy();

vao.destroy();

doneCurrent();

}

void QtFunctionWidget::initializeGL(){

this->initializeOpenGLFunctions();

bool success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/triangle.vert");

if (!success) {

qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();

return;

}

success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/triangle.frag");

if (!success) {

qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();

return;

}

success = shaderProgram.link();

if(!success) {

qDebug() << "shaderProgram link failed!" << shaderProgram.log();

}

//VAO,VBO數據部分

GLfloat vertices[] = {

0.5f, 0.5f, 0.0f, // top right

0.5f, -0.5f, 0.0f, // bottom right

-0.5f, -0.5f, 0.0f, // bottom left

-0.5f, 0.5f, 0.0f // top left

};

unsigned int indices[] = { // note that we start from 0!

0, 1, 3, // first Triangle

1, 2, 3 // second Triangle

};

QOpenGLVertexArrayObject::Binder vaoBind(&vao);

vbo.create();

vbo.bind();

vbo.allocate(vertices, sizeof(vertices));

ebo.create();

ebo.bind();

ebo.allocate(indices, sizeof(indices));

int attr = -1;

attr = shaderProgram.attributeLocation("aPos");

shaderProgram.setAttributeBuffer(attr, GL_FLOAT, 0, 3, sizeof(GLfloat) * 3);

shaderProgram.enableAttributeArray(attr);

vbo.release();

// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.

// ebo.release();

}

void QtFunctionWidget::resizeGL(int w, int h){

glViewport(0, 0, w, h);

}

void QtFunctionWidget::paintGL(){

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT);

shaderProgram.bind();

{

QOpenGLVertexArrayObject::Binder vaoBind(&vao);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

}

shaderProgram.release();

}

GLSL

triangle.vert

#version 330 core

layout(location = 0) in vec3 aPos;

void main(){

gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0f);

}

triangle.frag

#version 330 core

out vec4 FragColor;

void main(){

FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);

}

main.cpp

#include

#include "MainWindow.h"

#include "QtFunctionWidget.h"

#include "CoreFunctionWidget.h"

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

// MainWindow w;

QtFunctionWidget w1;

CoreFunctionWidget w2;

w1.setWindowTitle(QObject::tr("QtFunction"));

w2.setWindowTitle(QObject::tr("CoreFunction"));

w1.show();

w2.show();

return a.exec();

}

總結

以上是生活随笔為你收集整理的qt android glsl,基于Qt的OpenGL学习(1)—— Hello Triangle的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。