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

问题描述:

我想为模拟创建一个矩形网格,其中我们根据计算结果着色矩形。我可以创建没有颜色信息的顶点缓冲区对象吗?

最初我只想构建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); 

VBO只是一块内存,您可以通过将数据存放在显卡中来使其更快运行。 (有些硬件使用VBO的系统内存,所以在这种情况下不会获得太多的收益) 我也发现它总是使用VBO更清洁,但这有点个人喜好。

无论如何,你可以创建VBOs,然后改变它们里面的数据,就像一块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 
} 

EDIT得到具有颜色的示例

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

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(创建/绑定/ 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变成别的东西也更改的数量...

免责声明 这是在飞行中做,所以龙的提防。

+0

有趣!所以海狸VBO只是几何图形,然后当你要画一帧一帧地在VBO中使用该几何图形时,只需指定其他值,如纹理/颜色?如果我想设置单个三角形的颜色,这看起来如何? – dontWatchMyProfile

+0

那么在我的情况下,我实际上改变的是几何,基本上将顶点变形为每个关键帧来实现移动。在你的情况下,你将不得不改变每一帧的颜色信息,我会给我的答案添加一些东西。 – led42

+0

感谢您的更新。仅处理2D几何时,初始数据中是否需要顶点法线?你是什​​么意思“创建/绑定/ MapBuffer后” – dontWatchMyProfile

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

+0

您能否举一个例子说明如何将顶点数据与颜色数据分离,然后将颜色分配给顶点数据(仅限几何)VBO? – dontWatchMyProfile