Qt는 OpenGL을 사용하여 직사각형, 3D 카메라를 그립니다.

1. 소개

Qt는 OpenGL을 사용하여 직사각형, 3D 카메라를 그립니다.

2. 소프트웨어 환경

2.1QT 5.14.1

QT 컴파일러는 MSVC2017 64비트를 사용합니다.

2.2 코드

링크: https://pan.baidu.com/s/1Fn6UpF0HLWD_mSSKe_36wA?pwd=1234(직사각형)
링크: https://pan.baidu.com/s/1PV4sYk_WgnhUiBhyyCy4iA?pwd=1234(3차원)

3. 주요 공정

3.1 인터페이스 설정

qt에서 opengl을 직접 지원하는 창은 있는데 그에 대한 코드를 작성한 다음 클래스를 생성하고 QOpenGLWidget 클래스를 상속한 다음 창을 생성된 클래스로 업그레이드할 방법이 없습니다. 세 가지 가상 함수를 다시 작성해야 합니다
여기에 이미지 설명 삽입
.

#ifndef QQQOPENGLWIDGET_H
#define QQQOPENGLWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>

class QQQOpenGLWidget : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{
    
    
    Q_OBJECT
public:
    explicit QQQOpenGLWidget(QWidget *parent = nullptr);
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
};
#endif // QQQOPENGLWIDGET_H

이 생성자는 다음을 추가해야 합니다: QOpenGLWidget(부모), 그렇지 않으면 그릴 방법이 없습니다.

QQQOpenGLWidget::QQQOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
    
    

}
void QQQOpenGLWidget::initializeGL() {
    
    
	// 这个是都要加的初始化一下,不然程序指针都是空的,调用显卡的函数
	initializeOpenGLFunctions();
}
void QQQOpenGLWidget::resizeGL(int w, int h)
{
    
    

}
void QQQOpenGLWidget::paintGL()
{
    
    
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}

그러면 이미지가 나타나고 창 설정이 정상입니다.
여기에 이미지 설명 삽입

3.2 코드 설명

여기서는 블록으로 설명하고, 학습할 때 이해하기 어려웠던 부분에 대해서만 이야기하겠습니다.
첫 번째 단계는 VAO, VBO, EBO를 먼저 만드는 것입니다.
VAO의 기능은 버퍼 영역에서 포인트를 읽는 방법을 기록하는 것입니다.EBO는 포인트의 읽기 순서를 기록하고 VAO는 EBO의 위치도 기억하므로 나중에 읽을 때 편리합니다.EBO가 바인딩되지 않은 경우 VAO는 할 수 없습니다. 그러나 VBO는 그렇지 않습니다. VBO는 임의로 바인딩 해제할 수 있습니다.
VBO와 EBO는 그래픽 카드의 비디오 메모리 조각이고,
GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER는 서로 다른 버퍼 영역이며, 버퍼 영역은 점의 좌표를 저장하는 데 사용되며, VBO를 바인딩합니다. 버퍼 영역에 EBO는 해당 버퍼 영역에서 데이터를 어디에 써야 하는지 알려주고
마지막으로 해당 블록을 바인딩 해제하여 후속 작업이 이미 설정된 상태를 변경하지 못하도록 하고 VAO 상태 변경을 방지하고 VBO의 데이터를 방지합니다. EBO가 다시 작성되지 않도록

    // 状态设置
    //创建VBO和VAO对象,并赋予ID
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    //绑定VBO和VAO对象
    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(float), (void*)0);
    //开启VAO管理的第一个属性值
    glEnableVertexAttribArray(0);

    // 这个是状态设置完成
    // VAO会记录EBO的绑定状态,而不会记录VBO的,如果EBO提前解绑,就会找不到EBO
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

이것은 셰이더, 고정 형식을 설정하는 코드이며 그 안에 분석도 작성됩니다.

    // 设置着色器
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // 设置片段着色器
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // glPolygonMode 是一个用于控制多边形的绘制模式的函数。它可以设置多边形的绘制模式,包括填充模式、线框模式和点模式。
    // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    // 删除着色器对象的主要原因是释放内存和资源。当你将着色器对象链接到程序对象后,它们的内容已经被复制到了程序对象中,并且不再需要单独的着色器对象来执行渲染。
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

그림

void QQQOpenGLWidget::paintGL()
{
    
    
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // 设定着色器
    glUseProgram(shaderProgram);
    // VAO初始化状态
    glBindVertexArray(VAO);
    // glDrawArrays(GL_TRIANGLES, 0, 3);
    // 重复绘图也不会被覆盖的,都是在一个上面的
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

여기에 이미지 설명 삽입
여기에 이미지 설명 삽입
오물 소각로

    // 获取当前状态
    makeCurrent();
    // 1是个数
    glDeleteVertexArrays(1,&VAO);
    glDeleteBuffers(1,&VBO);
    glDeleteBuffers(1,&EBO);
    glDeleteProgram(shaderProgram);
    // 退出当前状态
    doneCurrent();

외부에서 그리기를 호출하는 방법에는 두 가지가 있습니다
.

void QQQOpenGLWidget::draw()
{
    
    
    // 获取当前状态
    makeCurrent();
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // 设定着色器
    glUseProgram(shaderProgram);
    // VAO初始化状态
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    // 退出当前状态
    doneCurrent();
}

두 번째는

    // 会调用paintGL(),进行重绘
    update();

3.3 3D 3D 카메라, 추후 업데이트 예정

사진을 먼저 올립니다. 코드가 맨 위에 있습니다 버튼에 문제가 있습니다 살펴 보겠습니다
여기에 이미지 설명 삽입

4. 참조

https://ke.qq.com/webcourse/3999604/104150693#taid=12078191069693812&vid=3701925924839353164

Supongo que te gusta

Origin blog.csdn.net/qq_45179361/article/details/131026144
Recomendado
Clasificación