C 从使用两个不同缓冲区填充的缓冲区将数据读入应用程序内存

C 从使用两个不同缓冲区填充的缓冲区将数据读入应用程序内存,c,opengl,C,Opengl,我正在尝试(作为练习)将数据从使用两个不同缓冲区填充的缓冲区读取到应用程序内存中,这两个缓冲区本身是从应用程序内存填充的 以下是我如何实现这一目标的: // Two arrays that contatain Vertex data that will be used to populate two different buffers static const GLfloat positions[] = { -1, -1, 0, 1, 1, -1, 0, 1, 1,

我正在尝试(作为练习)将数据从使用两个不同缓冲区填充的缓冲区读取到应用程序内存中,这两个缓冲区本身是从应用程序内存填充的

以下是我如何实现这一目标的:

// Two arrays that contatain Vertex data that will be used to populate two different buffers
static const GLfloat positions[] = {
    -1, -1, 0, 1,
     1, -1, 0, 1,
     1,  1, 0, 1,
    -1,  1, 0, 1
};

static const GLfloat colors[] = {
    1, 0, 0,
    0, 1, 0,
    0, 0, 1,
    1, 1, 1
};

// The buffer object that will be populated by using two other buffers.
// After it will be populated with the data,
// we will try to read it into Application memory and use it to render a square.
GLuint vbo;

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

//Usage hint is GL_STATIC_COPY since we will populate the buffer with data copied from OpenGL buffers
glBufferData(GL_ARRAY_BUFFER, sizeof(positions) + sizeof(colors), nullptr, GL_STATIC_COPY);

// The buffers that will be populated with the data coming from the arrays positions and colors respectively
GLuint pvbo, cvbo;

glGenBuffers(1, &pvbo);
glBindBuffer(GL_COPY_READ_BUFFER, pvbo);
glBufferData(GL_COPY_READ_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

glGenBuffers(1, &cvbo);
glBindBuffer(GL_COPY_READ_BUFFER, cvbo);
glBufferData(GL_COPY_READ_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);

// Copying the data from the buffer pvbo into the first part of the buffer vbo
glBindBuffer(GL_COPY_READ_BUFFER, pvbo);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER, 0, 0, sizeof(positions));

// Copying the data from the buffer cvbo into the second part of the buffer vbo
glBindBuffer(GL_COPY_READ_BUFFER, cvbo);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER, 0, sizeof(positions), sizeof(colors));

//Now we will read back the data from the buffer vbo into Application memory and printf it
GLfloat* readback = (GLfloat*)malloc(sizeof(positions) + sizeof(colors));

glGetBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(positions) + sizeof(colors), readback);

for (int i = 0; i < (sizeof(positions) + sizeof(colors)) / sizeof(GLfloat); i++)
    printf("%.1f ", readback[i]);
putchar('\n');

    ...

    // After that I setup the VAO and I use the buffer to render some colored square by using glDrawArrays()
并且彩色方块被渲染到屏幕上


关键是,当我启用调试时,会收到几个警告(即调用
glEnable(GL\u DEBUG\u输出)
)。以下是我在NVIDIA GPU(GeForce 525M)上收到的警告列表:

(1)OpenGL:Other[LOW](131188):缓冲区使用警告:对缓冲区对象2(绑定到GL_数组_Buffer_ARB)使用情况的分析表明CPU正在使用缓冲区对象数据。与此缓冲区对象GL_STATIC_COPY一起提供的用法提示与此用法模式不一致。尝试改用GL_STREAM_READ_ARB、GL_STATIC_READ_ARB或GL_DYNAMIC_READ_ARB。
(2) OpenGL:Performance[MED](131186):缓冲区性能警告:正在将缓冲区对象2(绑定到GL_数组_Buffer_ARB,使用提示为GL_STATIC_COPY)从视频内存复制/移动到DMA缓存内存。
当我将绑定到GL_数组_缓冲区绑定点的vbo缓冲区的用法从GL_STATIC_COPY更改为GL_STATIC_READ(如上述警告中所述)时,我会收到另一个警告:

OpenGL:Other[LOW] (131188): Buffer usage warning: BufferData for buffer 2 was called with <usage> set to GL_STATIC_READ.
OpenGL:Other[LOW](131188):缓冲区使用警告:调用缓冲区2的缓冲区数据时设置为GL_STATIC_READ。

我正在关注OpenGL红皮书第8版,它在第100页上写道:

当然,可以使用glGetBufferSubData()简单地读取数据 返回以前放入缓冲区对象的数据


但不幸的是,它没有显示如何执行此操作的任何示例。

缓冲区使用提示是一个提示;您可以读取和写入使用任何提示创建的缓冲区,但它可能没有可能的那么快。我不认为有任何关于将数据写入缓冲区并将其读回的提示,因为这通常不是一件有用的事情。@immibis感谢您的解释。