opengl VAO,VBO,EBO

VAO

不同物体需要进行不同操作时,需要各自的VAO和Shader;

VBO

VBO在初始化函数中绑定之后,在绘制函数中不需要再绑定,只需要绑定和这个VBO绑定的VAO即可。

EBO

glDrawElements函数

链接

offsetof

`offsetof` 是一个 C/C++ 语言标准库中的宏,它用于计算结构体中某个成员的偏移量,返回的是 `std::size_t` 类型的值,即表示偏移量的无符号整型数。例如,如果有一个名为 `myStruct` 的结构体,其中的一个名为 `myMember` 的成员变量的偏移量可以这样计算:`std::size_t offset = offsetof(myStruct, myMember);`

需要注意,`offsetof` 宏不受编译器或者操作系统的影响,因此在不同的机器上使用 `offsetof` 宏计算得到的偏移量是相同的。这使得 `offsetof` 宏在编写跨平台代码时非常有用。

结构体存储顶点数据

必须使用两个大括号

    vertex_{   //后面
              {{-0.5,-0.5,-0.5}},
              {{-0.5,0.5,-0.5}},
              {{0.5,0.5,-0.5}},
              {{0.5,-0.5,-0.5}},
              //左面
              {{-0.5,-0.5,0.5}},
              {{-0.5,0.5,0.5}},
              {{-0.5,0.5,-0.5}},
              {{-0.5,-0.5,-0.5}},
              //底面
              {{-0.5,-0.5,-0.5}},
              {{-0.5,-0.5,0.5}},
              {{0.5,-0.5,0.5}},
              {{0.5,-0.5,-0.5}},
              //右面
              {{0.5,-0.5,-0.5}},
              {{0.5,0.5,-0.5}},
              {{0.5,0.5,0.5}},
              {{0.5,-0.5,0.5}},
            //上面
            {{-0.5,0.5,-0.5}},
            {{-0.5,0.5,0.5}},
            {{0.5,0.5,0.5}},
            {{0.5,0.5,-0.5}},
            //正面
            {{0.5,-0.5,0.5}},
            {{0.5,0.5,0.5}},
            {{-0.5,0.5,0.5}},
            {{-0.5,-0.5,0.5}}
      }

利用结构体给VBO初始化和设置VAO

    object_VAO_->bind();
    object_VBO_->bind();
    object_VBO_->allocate(vertex_.data(),sizeof(Vertex)*vertex_.size());//这里不能直接sizeof(vertex_),因为vector开辟的内存不一定用完了
    object_shader_.bind();
    object_shader_.setAttributeBuffer("aPos",GL_FLOAT,(int)offsetof(Vertex,position_),3,sizeof(Vertex));
    object_shader_.enableAttributeArray("aPos");
    object_shader_.release();
    object_VAO_->release();
    object_VBO_->release();

offsetof的结果转不转都行。

初始化OpenGL当前上下文

initializeOpenGLFunctions()函数的作用

初始化和加载OpenGL上下文资源。

initializeOpenGLFunctions() 函数是一个从 QOpenGLFunctions 类继承而来的函数,一般在使用 OpenGL 函数之前调用。

这个函数会将当前 OpenGL 活动上下文中所有可用的 OpenGL 函数指针,同时绑定到类中固定的函数指针上。在通过这些函数指针去调用相应的 OpenGL 函数时,就会调用到正确的函数。

如果在使用 OpenGL 函数的时候没有调用 initializeOpenGLFunctions(),就会导致运行时错误,从而使程序崩溃或行为不可预知。因此,尤其在使用 QOpenGLWidget 和其他 Qt 绘图组件时,一定要在使用 OpenGL 函数之前调用 initializeOpenGLFunctions(),确保所有可用的 OpenGL 函数都被正确地加载到程序中,以保证程序的正确性。

示例代码:

```cpp
void initializeGL()
{
    if (!initializeOpenGLFunctions()) {
        qWarning("初始化OpenGL函数失败");
        exit(1);
    }
    // 恢复 OpenGL 状态
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    // 其他 OpenGL 状态设置
}

void paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // 在这里调用 OpenGL 函数进行绘制
}

多次调用initializeOpenGLFunctions()函数会怎样

在同一个类中,不应该多次调用 initializeOpenGLFunctions() 函数。这个函数应该在初始化 OpenGL 上下文时被调用,以确保所有可用的 OpenGL 函数都被正确地加载到程序中。如果多次调用 initializeOpenGLFunctions() 函数,就会导致运行时错误,从而使程序崩溃或行为不可预知。

在某些情况下,可能存在多个 OpenGL 上下文,例如在使用多个 QOpenGLWidget 组件时。在这种情况下,应该在每个 OpenGL 上下文中调用一次 initializeOpenGLFunctions() 函数,以确保每个上下文中的 OpenGL 函数都被正确地加载。

示例代码:

```cpp
void MyOpenGLWidget::initializeGL()
{
    if (!initializeOpenGLFunctions()) {
        qWarning("初始化OpenGL函数失败");
        exit(1);
    }
    // 初始化其他 OpenGL 状态和资源
}

void OtherOpenGLWidget::initializeGL()
{
    if (!initializeOpenGLFunctions()) {
        qWarning("初始化OpenGL函数失败");
        exit(1);
    }
    // 初始化其他 OpenGL 状态和资源
}
```

因此,应该根据情况在正确的地方调用 initializeOpenGLFunctions() 函数,确保 OpenGL 函数指针被正确地绑定到函数中。

什么是OpengL上下文

OpenGL 上下文(OpenGL Context)是指 OpenGL 在执行过程中所需的状态信息和资源。OpenGL 上下文包含了当前绑定的渲染缓冲区、纹理对象、着色器程序、程序管线状态等重要信息。

在使用 OpenGL 进行绘制之前,需要先创建一个 OpenGL 上下文,并将其绑定到当前线程或设备上,以便 OpenGL 可以在这个上下文中执行绘图操作。通常情况下,创建 OpenGL 上下文需要使用一些窗口系统相关的 API,如:Win32 API、Xlib 或 Cocoa。这些 API 可以创建一个窗口并关联一个相应的 OpenGL 上下文。

在 Qt 中,可以使用 QOpenGLContext 类来创建和管理 OpenGL 上下文。创建一个 QOpenGLContext 对象后,需要调用其 create() 函数来创建一个 OpenGL 上下文,同时还需为该上下文设置一个表面(Surface),如 QWindow 或 QOffscreenSurface。创建 QOpenGLContext 并设置窗口表面的示例代码如下:

```cpp
QOpenGLContext *context = new QOpenGLContext;
context->setFormat(format); // 设置 OpenGL 版本和配置特性
if (!context->create()) {
    qFatal("Failed to create OpenGL context");
}
QWindow *window = new QWindow;
window->setSurfaceType(QSurface::OpenGLSurface); // 设置表面类型为 OpenGL 表面
window->create(); // 创建窗口
context->makeCurrent(window); // 将上下文绑定到窗口表面上
```

一旦创建并绑定了 OpenGL 上下文,就可以在其中执行 OpenGL 操作,包括设置顶点数据、设置纹理、设置着色器程序、绘制几何图形等操作,以实现所需的渲染效果。完整的 OpenGL 上下文管理需要考虑到线程安全、多窗口支持、上下文资源共享等方面的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值