我是 VBO 的新手,阅读了一些关于创建和使用 VBO 的文章。我正在开发一个应用程序,我想在其中创建十几个旋转立方体。我连接到一个服务器,该服务器将文本消息推送到我的应用程序。当我收到 6 条短信时,我使用 Pango 和 Cairo 呈现这些消息。然后我想从这 6 个渲染消息创建纹理并将它们应用到一个新的立方体。
虽然我通常只使用 2D 纹理并将它们应用到 GL_QUAD,但我不确定如何将 6 种纹理应用到使用 VBO 创建的立方体?
我找到了一个关于如何使用 VBO 创建多维数据集的示例。这些创建如下:
VBO
// v6----- v5
// /| /|
// v1------v0|
// | | | |
// | |v7---|-|v4
// |/ |/
// v2------v3
GLfloat vertices[] = {1,1,1, -1,1,1, -1,-1,1, 1,-1,1, // v0-v1-v2-v3
1,1,1, 1,-1,1, 1,-1,-1, 1,1,-1, // v0-v3-v4-v5
1,1,1, 1,1,-1, -1,1,-1, -1,1,1, // v0-v5-v6-v1
-1,1,1, -1,1,-1, -1,-1,-1, -1,-1,1, // v1-v6-v7-v2
-1,-1,-1, 1,-1,-1, 1,-1,1, -1,-1,1, // v7-v4-v3-v2
1,-1,-1, -1,-1,-1, -1,1,-1, 1,1,-1}; // v4-v7-v6-v5
// normal array
GLfloat normals[] = {0,0,1, 0,0,1, 0,0,1, 0,0,1, // v0-v1-v2-v3
1,0,0, 1,0,0, 1,0,0, 1,0,0, // v0-v3-v4-v5
0,1,0, 0,1,0, 0,1,0, 0,1,0, // v0-v5-v6-v1
-1,0,0, -1,0,0, -1,0,0, -1,0,0, // v1-v6-v7-v2
0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0, // v7-v4-v3-v2
0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1}; // v4-v7-v6-v5
// color array
GLfloat colors[] = {1,1,1, 1,1,0, 1,0,0, 1,0,1, // v0-v1-v2-v3
1,1,1, 1,0,1, 0,0,1, 0,1,1, // v0-v3-v4-v5
1,1,1, 0,1,1, 0,1,0, 1,1,0, // v0-v5-v6-v1
1,1,0, 0,1,0, 0,0,0, 1,0,0, // v1-v6-v7-v2
0,0,0, 0,0,1, 1,0,1, 1,0,0, // v7-v4-v3-v2
0,0,1, 0,0,0, 0,1,0, 0,1,1}; // v4-v7-v6-v5
glGenBuffersARB(1, &vbo_id);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_id);
glBufferDataARB(
GL_ARRAY_BUFFER_ARB
,sizeof(vertices)+sizeof(normals)+sizeof(colors)
,0
,GL_STATIC_DRAW_ARB
);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), vertices);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices), sizeof(normals),normals);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices)+sizeof(normals), sizeof(colors), colors); // copy colours after normals
s_vertices = sizeof(vertices);
s_colors = sizeof(colors);
s_normals = sizeof(colors);
cube = new Cube(vbo_id, ofxVec3f(0.0, 0.0, 0.0),0.1, s_vertices, s_colors, s_normals);
使用 VBO 的 Cube 类
#include "Cube.h"
Cube::Cube(
GLuint nVBO
,ofxVec3f oPosition
,float fSize
,int nVertices
,int nNormals
,int nColors
)
:vbo_id(nVBO)
,position(oPosition)
,size(fSize)
,s_vertices(nVertices)
,s_normals(nNormals)
,s_colors(nColors)
{
r = 0;
}
void Cube::update() {
}
void Cube::draw() {
glPushMatrix();
glTranslatef(position.x,position.y,position.z);
glRotatef((r++),0,1,0);
glScalef(size, size, size);
// bind VBOs with IDs and set the buffer offsets of the bound VBOs
// When buffer object is bound with its ID, all pointers in gl*Pointer()
// are treated as offset instead of real pointer.
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_id);
// enable vertex arrays
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
// before draw, specify vertex and index arrays with their offsets
glNormalPointer(GL_FLOAT, 0, (void*)s_vertices);
glColorPointer(3, GL_FLOAT, 0, (void*)(s_vertices+s_normals));
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_QUADS, 0, 24);
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
// it is good idea to release VBOs with ID 0 after use.
// Once bound with 0, all pointers in gl*Pointer() behave as real
// pointer, so, normal vertex array operations are re-activated
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glPopMatrix();
}
最佳答案
Though I normally just use a 2D texture and apply these to a GL_QUAD, I'm not sure how I can apply 6 textures to a cube which is created using VBOs?
最简单、最直接的方法是将它们拼接成一个大纹理,并调整纹理坐标以匹配。
或者,由于立方体非常简单,显示列表而不是 VBO 可能就足够了。
关于c++ - 如何将多个纹理应用于立方体的 VBO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3173132/