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

时间:2011-11-30 21:48:54

标签: iphone ios opengl-es

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

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

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

// 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);

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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改为缓冲区var,并通过它进行交互以仅更改你需要的部分。 类似的东西:

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
 }

编辑提供颜色示例

首先是一些示例数据,在这种情况下是每个顶点数据交错的三角形:

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更改为其他内容可能更好......

<强>声明 这是在飞行中制作的,所以要小心龙。