我可以创建没有颜色信息的顶点缓冲区对象吗?
我想为模拟创建一个矩形网格,其中我们根据计算结果着色矩形。我可以创建没有颜色信息的顶点缓冲区对象吗?
最初我只想构建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变成别的东西也更改的数量...
免责声明 这是在飞行中做,所以龙的提防。
您可以定义一个VBO而在另一个顶点颜色顶点坐标,那么你可以使用glVertexAttribPointer(或glVertexPointer, glColorPointer)来设置渲染的顶点属性。
您能否举一个例子说明如何将顶点数据与颜色数据分离,然后将颜色分配给顶点数据(仅限几何)VBO? – dontWatchMyProfile
有趣!所以海狸VBO只是几何图形,然后当你要画一帧一帧地在VBO中使用该几何图形时,只需指定其他值,如纹理/颜色?如果我想设置单个三角形的颜色,这看起来如何? – dontWatchMyProfile
那么在我的情况下,我实际上改变的是几何,基本上将顶点变形为每个关键帧来实现移动。在你的情况下,你将不得不改变每一帧的颜色信息,我会给我的答案添加一些东西。 – led42
感谢您的更新。仅处理2D几何时,初始数据中是否需要顶点法线?你是什么意思“创建/绑定/ MapBuffer后” – dontWatchMyProfile