我可以创建没有颜色信息的顶点缓冲对象吗?



我想为模拟创建一个矩形网格,我们根据计算结果为矩形上色。

最初我只想构建VBO来定义网格。然后在每一帧中简单地为矩形指定颜色。

这是可能的吗?还是VBO总是"硬连接"一组颜色?因为我在网上找到的所有例子都是这样做的。它们将VBO与颜色一起初始化,而不仅仅是顶点位置数据,像这样:

// allocate a new buffer
glGenBuffers(1, &cubeVBO);
// bind the buffer object to use
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
const GLsizeiptr vertex_size = NUMBER_OF_CUBE_VERTICES*NUMBER_OF_CUBE_COMPONENTS_PER_VERTEX*sizeof(GLfloat);
const GLsizeiptr color_size = NUMBER_OF_CUBE_COLORS*NUMBER_OF_CUBE_COMPONENTS_PER_COLOR*sizeof(GLubyte);
// allocate enough space for the VBO
glBufferData(GL_ARRAY_BUFFER, vertex_size + color_size, 0, GL_STATIC_DRAW);

VBO只是一块内存,通过将数据驻留在显卡中,您可以使用它来使程序运行得更快。(有些硬件将系统内存用于VBO,所以在这种情况下并没有获得太多好处)我还发现总是使用vbo更简洁,但这只是个人偏好。

无论如何,你可以创建VBO,然后改变他们里面的数据,相同的一块RAM,如果你需要改变每帧VBO上的一切再次没有性能的好处,但如果你只需要改变的东西不时,或者一些数据是固定的(说你的顶点数据),那么你开始得到一些好处…

例如:

glGenBuffers(1, &vboObjects[vboGroupBeaver]);
glBindBuffer(GL_ARRAY_BUFFER, vboObjects[vboGroupBeaver]);
glBufferData(GL_ARRAY_BUFFER, beaverVerts*8*sizeof(GLfloat), 0, GL_STATIC_DRAW);
GLvoid*  vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
NSString *path;
path = [[NSBundle mainBundle] pathForResource:@"beaver01" ofType:@"bin"];
NSFileHandle *model = [NSFileHandle fileHandleForReadingAtPath:path];
float vertice[8];
int counter = 0;
while (read([model fileDescriptor], &vertice, 8*sizeof(float))) {
    memcpy(vbo_buffer, vertice, 8*sizeof(GLfloat));        // 0
    vbo_buffer += 8*sizeof(GLfloat);
    counter++;
}
NSLog(@"Vertices %1i",counter);
glUnmapBufferOES(GL_ARRAY_BUFFER); 

这段代码将模型加载到VBO (vboGroupBeaver)中,在本例中它是动画的第一个关键帧。所有的数据现在都在VBO中,如果我在

之后执行此操作:
    glVertexPointer(3, GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL));
    glNormalPointer(GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
    glTexCoordPointer(2, GL_FLOAT,8*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat))); 
    glDrawArrays(GL_TRIANGLES, 0, beaverVerts);

我画了一只海狸…(注意,我使用交错顶点数据,这就是为什么指针调用有额外的信息)。在你的情况下,你会有一个颜色指针而不是纹理指针。

现在,如果你想改变的东西,你所要做的就是glMapBufferOES到一个缓冲区变量,并通过它进行交互,只改变你需要的部分。比如:

vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
for (int i = start; i < end; i++) {
   vbo_buffer += 6*sizeof(GLfloat); // offset to position
   memcpy(vbo_buffer, whatYouWantToChange, 2*sizeof(GLfloat));  // change what you want, watch the size
 }

EDIT给出一个color

的例子

首先是一些示例数据,在本例中是每个顶点数据交错的三角形:

static const ColoredTriangle vertexData[] = {
    {
        {0.0, 0.0, 0.0},           // Vertex 0
        {0.0, 0.0, 1.0},           // Normal 
        {1.0, 0.0, 0.0, 1.0}       // Color  
    },
    {
        {0.0, 480.0, 0.0},            // Vertex 1
        {0.0,   0.0, 1.0},            // Normal 
        {1.0, 1.0, 0.0, 1.0}          // Color  
    },
    {
        {320.0, 0.0, 0.0},           // Vertex 2
        {0.0, 0.0, 1.0},             // Normal
        {1.0, 1.0, 1.0, 1.0}         // Color 
    }

复制文件到vbo(创建/binding/MapBuffer后)

memcpy(vbo_buffer, vertexData, 10*3*sizeof(float));

画东西

glVertexPointer(3, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glColorPointer(4, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)))   
glDrawArrays(GL_TRIANGLES, 0, beaverVerts);

所以现在你有一个三角形被绘制与交错的数据从VBO。

现在在每一帧你想做的只是改变数据。

GLvoid*  vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
vbo_buffer += 6*sizeof(GLfloat); // position the buffer at the first vertex color data
for (int i = 0; i < 3; i++) {
    memcpy(vbo_buffer, newColor, 4*sizeof(GLfloat));
    vbo_buffer += 10*sizeof(GLfloat); // skip the stripe
}
glUnmapBufferOES(GL_ARRAY_BUFFER);

然后再画一次,你只是改变了颜色信息。根据您要进行的更改的数量,最好将GL_STATIC_DRAW更改为其他内容…

免责声明这是在飞行中制作的,所以要小心龙。

你可以在一个VBO中定义顶点坐标,在另一个VBO中定义顶点颜色,然后你可以使用glVertexAttribPointer(或glVertexPointer, glColorPointer)来设置渲染的顶点属性

最新更新