首页 > 解决方案 > 布局内存供 OpenGL 使用的问题(需要 glBufferSubData 帮助)

问题描述

所以今天我想学习如何使用 Vector2 和 Color 类以非常简洁的语法将数据发送到 OpenGL。

计划是这样的。

/*
Vector2 (8 bytes)
Color (16 bytes)
Vector2 + Color = 24 bytes
    
How can memory be laid out like this?

{Vector2, Color},
{Vector2, Color},
{Vector2, Color}
*/

所以我有我的两个数据数组。

Vector2 vertices[] = {
    Vector2(0.0f, 0.5f),
    Vector2(0.5f, -0.5f),
    Vector2(-0.5f, -0.5f)
};

// colors would be mapped to there respective indexes in the vertices array (i.e colors[0] is mapped to vertices[0])
Color colors[] = {
    Color(1.0f, 0.3f, 0.3f),
    Color(0.3f, 1.0f, 0.3f),
    Color(0.3f, 0.3f, 1.0f)
};

我能够在正确的点上得到一个正三角形渲染, 在此处输入图像描述

但是发送颜色数据对我来说非常困难。

我目前得到的结果是这样的。 在此处输入图像描述

这是代码片段。


    // positions on screen
    Vector2 vertices[] = {
        Vector2(0.0f, 0.5f),
        Vector2(0.5f, -0.5f),
        Vector2(-0.5f, -0.5f)
    };

    // colors for each position
    Color colors[] = {
        Color(1.0f, 0.3f, 0.3f),
        Color(0.3f, 1.0f, 0.3f),
        Color(0.3f, 0.3f, 1.0f)
    };

    // create vertex and array buffers (each bound automatically)
    unsigned int vertexArray = createVertexArray();
    unsigned int vertexBuffer = createBuffer(GL_ARRAY_BUFFER);

    // allocate the data
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), nullptr, GL_STATIC_DRAW);

    // fill up allocated memory 
    for (int i = 0; i < 3; ++i) {
        glBufferSubData(GL_ARRAY_BUFFER, sizeof(Vector2) * i, sizeof(Vector2), &vertices[i]);
        glBufferSubData(GL_ARRAY_BUFFER, (sizeof(Vector2) + sizeof(Color)) * (i + 1), sizeof(Color), &colors[i]);
    }

    // set up vertex attributes
    glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(Vector2) + sizeof(Color), nullptr);
    glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof(Vector2) + sizeof(Color), (const void*)( sizeof(Vector2) ));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

标签: c++openglmemory

解决方案


您需要向缓冲区交替添加 1 个顶点和 1 种颜色:

for (int i = 0; i < 3; ++i)
{    
    GLintptr offsetV = i * (sizeof(Vector2) + sizeof(Color)); 
    glBufferSubData(GL_ARRAY_BUFFER, offsetV, sizeof(Vector2), &vertices[i]);
 
    GLintptr offsetC = offsetV + sizeof(Vector2); 
    glBufferSubData(GL_ARRAY_BUFFER, offsetC, sizeof(Color), &colors[i]);
} 

推荐阅读