使用VBO通过加载wavefront对象绘制立方体

时间:2018-05-16 17:06:51

标签: c++ opengl wavefront

我需要使用VBO通过加载wavefront对象来绘制立方体。 通过绘制三角形。 这是对象:

v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
f 2//1 3//1 1//1
f 4//2 7//2 3//2
f 8//3 5//3 7//3
f 6//4 1//4 5//4
f 7//5 1//5 3//5
f 4//6 6//6 8//6
f 2//1 4//1 3//1
f 4//2 8//2 7//2
f 8//3 6//3 5//3
f 6//4 2//4 1//4
f 7//5 5//5 1//5
f 4//6 2//6 6//6  

我也有一个由我自己填充的冷却器阵列,相当于3个面数,即36个指数

float colours[] = {
    0.583f,  0.771f,  0.014f,
    0.609f,  0.115f,  0.436f,
    0.327f,  0.483f,  0.844f,
    0.822f,  0.569f,  0.201f,
    0.435f,  0.602f,  0.223f,
    0.310f,  0.747f,  0.185f,
    0.597f,  0.770f,  0.761f,
    0.559f,  0.436f,  0.730f,
    0.359f,  0.583f,  0.152f,
    0.483f,  0.596f,  0.789f,
    0.559f,  0.861f,  0.639f,
    0.195f,  0.548f,  0.859f,
    }

我将顶点,法线,颜色信息存储到一个绑定到VBO缓冲区的数组中:

 float* vbo = new float[78]

是顶点|法线|颜色的顺序,它是24个指标| 18个指标| 36个指标,我已经测试过它的效果非常好

我使用另一个数组存储顶点索引信息,这些信息是36个指示符,例如:f 2 // 1 3 // 1 1 // 1我在数组中存储为2/3/1

 int *element = new int[36];

我一直在测试它是否运作良好,我将我的vbo初始化如下:

 static void init(void){
 .......
Gluint vbo_id,index_id;

glGenBuffers(1,&vbo_id);
glGenBuffers(1,&index_id);
glBindBuffer(GL_ARRAY_BUFFER,vbo_id); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,index_id);

glBufferData(GL_ARRAY_BUFFER,sizeof(vbo),vbo,GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(element),element,GL_STATIC_DRAW); } 

我的绘画就在这里

 static void display(void){
  .......
 glBindBuffer(GL_ARRAY_BUFFER,vbo_id);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,index_id);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glVertexPointer(3,GL_FLOAT,0,0);
    glNormalPointer(GL_FLOAT,0,(void*)(24*sizeof(float)));//binding 
    glColorPointer(3,GL_FLOAT,0,(void*)(42*sizeof(float)));

    for(int i=0;i<12;i++){

    glBegin(GL_TRIANGLES);
    glArrayElement(element[i]);
    glArrayElement(element[i+1]);
    glArrayElement(element[i+2]);
    glEnd();

    }
    /* have try this one too:
    glDrawElements(GL_TRIANGLES,3,GL_INT,0) */


    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER,0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
    }
然而,屏幕上没有显示任何内容。我的绑定方法是正确的,我的指导员告诉我当我用索引绘制时,如果我绑定顶点和法线,并且颜色正确,它将通过绘图与顶点索引自动匹配。

1 个答案:

答案 0 :(得分:1)

vbo的类型为float*,因此sizeof(vbo)不是vbo指向的数组的大小,但它的大小是float* vbo = new float[78]指针。请参阅sizeof
注意,glBufferData的第3个参数必须是缓冲区的大小(以字节为单位)。

78 * sizeof(float)的尺寸为78 * sizeof(*vbo)int *element = new int[36]
36 * sizeof(int)的尺寸为36 * sizeof(*element)sizeof(vbo)
sizeof(float*)是指向数组的指针的大小,或与glBufferData(GL_ARRAY_BUFFER, 78*sizeof(float), vbo, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36*sizeof(int), element, GL_STATIC_DRAW); 相同。

这意味着你必须改变这样的代码:

GL_UNSIGNED_BYTE

glDrawElements的第二个参数必须是索引的数量,第三个参数必须是GL_UNSIGNED_SHORTGL_UNSIGNED_INTglDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL); ,具体取决于数据类型指数:

unsigned int *

注意,您应该使用int*而不是element作为索引数组的数据类型(#include <vector> )。

你的假设是错误的。您不能将24个顶点坐标,18个法向量和36个颜色与不同的索引数组合在一起Vertex Array Object

每个顶点位置的顶点属性形成一组数据。这意味着您必须创建顶点坐标,法线向量和颜色的元组。

进一步查看Rendering meshes with multiple indices

我建议使用std::vector并以某种方式执行此操作:

// 8  vertex coordiantes: 8 * 3 float 
std::vector<float> v{
  -1.0f, -1.0f,  1.0f,
  -1.0f,  1.0f,  1.0f,
  -1.0f, -1.0f, -1.0f,
  -1.0f,  1.0f, -1.0f,
   1.0f, -1.0f,  1.0f,
   1.0f,  1.0f,  1.0f,
   1.0f, -1.0f, -1.0f,
   1.0f,  1.0f, -1.0f };

// 6  normal vectors: 6 * 3 float
std::vector<float> nv{
   -1.0f,  0.0f,  0.0f,
    0.0f,  0.0f, -1.0f,
    1.0f,  0.0f,  0.0f,
    0.0f,  0.0f,  1.0f,
    0.0f, -1.0f,  0.0f,
    0.0f,  1.0f,  0.0f };

// 12 colors coordiantes: 12 * 3 float 
std::vector<float> c{
    0.583f,  0.771f,  0.014f,
    0.609f,  0.115f,  0.436f,
    0.327f,  0.483f,  0.844f,
    0.822f,  0.569f,  0.201f,
    0.435f,  0.602f,  0.223f,
    0.310f,  0.747f,  0.185f,
    0.597f,  0.770f,  0.761f,
    0.559f,  0.436f,  0.730f,
    0.359f,  0.583f,  0.152f,
    0.483f,  0.596f,  0.789f,
    0.559f,  0.861f,  0.639f,
    0.195f,  0.548f,  0.859f };

// 12 faces 3*2 indices/face: 12 * 3 * 2 unsigned int 
std::vector<unsigned int> indices{
    2, 1,    3, 1,    1, 1,
    4, 2,    7, 2,    3, 2,
    8, 3,    5, 3,    7, 3,
    6, 4,    1, 4,    5, 4,
    7, 5,    1, 5,    3, 5,
    4, 6,    6, 6,    8, 6,
    2, 1,    4, 1,    3, 1,
    4, 2,    8, 2,    7, 2,
    8, 3,    6, 3,    5, 3,
    6, 4,    2, 4,    1, 4,
    7, 5,    5, 5,    1, 5,
    4, 6,    2, 6,    6, 6 };

// final vertex attributes 12 * 3 *(3 + 3 + 3) floats
// x0 y0 z0    nvx0 nvy0 nvz0    cr0 cg0 cb0
// x1 y1 z1    nvx1 nvy1 nvz1    cr1 cg1 cb1
std::vector<float> va; 

const unsigned int no_of_faces = 12;
for (unsigned int f=0; f<no_of_faces; ++f )
{
    for (unsigned int t=0; t<3; ++t )
    {
        unsigned int vi = indices[(f*3+t)*2]-1;   // vertex index
        unsigned int ni = indices[(f*3+t)*2+1]-1; // normal vector index
        unsigned int ci = f;                      // color index

        va.insert(va.end(), v.begin()  + vi*3, v.begin()  + vi*3+3); // insert vertex coordinate
        va.insert(va.end(), nv.begin() + ni*3, nv.begin() + ni*3+3); // insert normal vector
        va.insert(va.end(), c.begin()  + ci*3, c.begin()  + ci*3+3); // insert color
    }
}

创建顶点数组数据

GLuint vbo;
glGenBuffers( 1, &vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, va.size()*sizeof(*va.data()), va.data(), GL_STATIC_DRAW );

创建Vertex Buffer Object

glVertexPointer( 3, GL_FLOAT, 9*sizeof(*va.data()), 0 );
glEnableClientState( GL_VERTEX_ARRAY );
glNormalPointer( GL_FLOAT, 9*sizeof(*va.data()), (void*)(3*sizeof(*va.data())) ); 
glEnableClientState( GL_NORMAL_ARRAY );
glColorPointer( 3, GL_FLOAT, 9*sizeof(*va.data()), (void*)(6*sizeof(*va.data())) ); 
glEnableClientState( GL_COLOR_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 );

定义通用顶点属性数据的数组:

glDrawArrays( GL_TRIANGLES, 0, 36 );

绘制数组:

for table in ['messages', 'conversations']:
    Operator1 with operator1.task_id = 'operator1_{}'.format(table)
    Operator1 does kwargs['ti'].xcom_push(key='file_name', value='y')

    Operator2 is a BashOperator that needs to run:
    bash_command = "echo {{ ti.xcom_pull(task_ids='operator1_{}', key='file_name') }}".format(table)       

    Operator1 >> Operator2

预览:

cube