OpenGl 中的顶点缓冲区抽象

Vertex Buffer Abstraction in OpenGl

我一直在尝试编写一些 classes 来抽象 OpenGl。到目前为止,我已经编写了一个 VertexArray class,它使用目前运行良好的模板函数。但是,我遇到了我无法修复的 VertexBuffer class 问题。 C++ 和 OpenGl 对我来说还很陌生,所以解决方案可能非常简单。

每当我尝试用 VertexBuffer 的构造函数替换 Vertex Buffer 创建代码时 class 事情就会出错,即使构造函数的代码和直接写在网格 class 是(我相信)相同的。

代码如下:

VertexBuffer.h:

#ifndef VERTEX_BUFFER_H
#define VERTEX_BUFFER_H

class VertexBuffer {
private:
public:
    unsigned int ID;
    VertexBuffer(const void* data, unsigned int size);
    VertexBuffer();
    ~VertexBuffer();
    void bind();
    void unbind();
};

#endif

VertexBuffer.cpp:

#include "VertexBuffer.h"

#define GLEW_STATIC
#include <GL/glew.h>
#include <iostream>

VertexBuffer::VertexBuffer(const void* data, unsigned int size) {
    glGenBuffers(1, &ID);
    glBindBuffer(GL_ARRAY_BUFFER, ID);
    glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);

    std::cout << "ID = " << ID << std::endl;
    std::cout << "data = " << data << std::endl;
    std::cout << "size = " << size << std::endl << std::endl;
}

VertexBuffer::VertexBuffer() {}

VertexBuffer::~VertexBuffer() {
    glDeleteBuffers(1, &ID);
}

void VertexBuffer::bind() {
    glBindBuffer(GL_ARRAY_BUFFER, ID);
}

void VertexBuffer::unbind() {
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

Mesh 构造函数,我一直在尝试通过 class:

实现它
Mesh::Mesh(std::vector<Vertex> vertices) {

    model = glm::mat4(1.0f);
    indicesSize = vertices.size();

    // generate vertex array object
    va = VertexArray();
    va.bind();

    //============================================================

    //This code works:
    /*
    glGenBuffers(1, &vb.ID);
    glBindBuffer(GL_ARRAY_BUFFER, vb.ID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &vertices[0], GL_STATIC_DRAW);
    */

    //------------------------------------------------------------

    //This code does not work:
    vb = VertexBuffer(&vertices[0], sizeof(Vertex) * vertices.size());

    //============================================================

    // points
    va.push<float>(3, 9, false);

    // colors
    va.push<float>(3, 9, false);

    // normals
    va.push<float>(3, 9, false);
};

如果有人能帮助我,我会很高兴。提前致谢!

您必须将 vb 存储在某种智能指针中或将移动语义添加到 VertexBuffer

vb = VertexBuffer(&vertices[0], sizeof(Vertex) * vertices.size());
     ^^^ [1]

[1]中创建临时VertexBuffer,然后由运算符=,成员ID以浅层方式复制到vb中,最后在表达式临时 VertexBuffer 的末尾随着删除生成的 ID 被销毁(通过临时实例的析构函数),它仍然存储在 vb 中,但它不再有效。

具有移动语义的解决方案可能是这样的:

class VertexBuffer {
    std::unique_ptr<unsigned int> ID;
public:
    VertexBuffer& operator=(VertexBuffer&& other) {
        ID = std::move(other.ID);
        return *this;
    }

    ~VertexBuffer() {
        if (ID)
            glDeleteBuffers(1, ID.get() );
    }
};