【OpenGL】--- 使用OpenGL和Qt创建多个带透视效果的立方体

在本教程中,我们将使用OpenGL和Qt框架创建一个简单的应用程序,该应用程序绘制多个带有纹理的立方体。我们将使用单独的顶点着色器和片段着色器文件,以便更好地组织我们的代码。

1. 引言

OpenGL是一个强大的图形渲染库,广泛用于创建3D应用程序。Qt是一个跨平台的C++应用程序开发框架,提供了OpenGL的封装,方便我们在Qt应用程序中集成OpenGL。

2. 准备工作

首先,确保你已经安装了Qt,并创建了一个Qt Widgets应用程序项目。我们将在这个项目中添加OpenGL渲染窗口。

3. 编写顶点和片段着色器

创建两个文件,一个用于顶点着色器(vertexshader.vert),一个用于片段着色器(fragmentshader.frag)。

vertexshader.vert

#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    TexCoord = aTexCoord;
}

fragment_shader.frag:

#version 330 core

in vec2 TexCoord;

out vec4 FragColor;

uniform sampler2D texture1;

void main()
{
    FragColor = texture(texture1, TexCoord);
}

接下来,创建一个Qt的QOpenGLWidget类,用于在OpenGL中绘制立方体。在这个类中,我们加载纹理、读取顶点和纹理坐标数据,以及使用着色器程序绘制多个带透视的立方体。

myopenglwidget.h:

#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H

#include 
#include 
#include 
#include 

class MyOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    MyOpenGLWidget(QWidget *parent = nullptr);
    ~MyOpenGLWidget() override {}

protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;

private:
    GLuint VAO, VBO;
    QOpenGLShaderProgram shaderProgram;
    QMatrix4x4 model, view, projection;
    QOpenGLTexture *texture;
};

#endif // MYOPENGLWIDGET_H

myopenglwidget.cpp:

#include "myopenglwidget.h"
#include 

MyOpenGLWidget::MyOpenGLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{
}

void MyOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();

    // Set up vertex data and buffers
    GLfloat vertices[] = {
        // Positions           // Texture Coords
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        // Add more vertices for additional cubes...
    };

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // Position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // Texture attribute
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    // Load and create a texture
    texture = new QOpenGLTexture(QImage(":/path/to/your/texture/image.jpg").mirrored());

    // Load shaders from file
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vertex_shader.vert");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fragment_shader.frag");

    // Link shader program
    shaderProgram.link();

    // Set up perspective projection matrix
    resizeGL(width(), height());
}

void MyOpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
    projection.setToIdentity();
    projection.perspective(45.0f, static_cast(w) / static_cast(h), 0.1f, 100.0f);
}

void MyOpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shaderProgram.bind();
    shaderProgram.setUniformValue("model", model);
    shaderProgram.setUniformValue("view", view);
    shaderProgram.setUniformValue("projection", projection);

    // Bind texture
    glActiveTexture(GL_TEXTURE0);
    texture->bind();
    shaderProgram.setUniformValue("texture1", 0);

    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);  // Assuming 36 vertices for a single cube

    // Draw more cubes...
}

你可能感兴趣的:(OpenGL,计算机视觉,图形渲染)