代码之家  ›  专栏  ›  技术社区  ›  Matthew Mitchell

OpenGL顶点缓冲区对象代码输出错误

  •  1
  • Matthew Mitchell  · 技术社区  · 16 年前

    我的顶点缓冲区对象代码应该很好地渲染纹理,但取而代之的是渲染一些奇怪的三角形形状的纹理。

    会发生什么- http://godofgod.co.uk/my_files/wrong.png

    http://godofgod.co.uk/my_files/right.png

    此函数用于创建VBO并设置顶点和纹理坐标数据:

    extern "C" GLuint create_box_vbo(GLdouble size[2]){
        GLuint vbo;
        glGenBuffers(1,&vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        GLsizeiptr data_size = 8*sizeof(GLdouble);
        GLdouble vertices[] = {0,0,  0,size[1],  size[0],0,  size[0],size[1]};
        glBufferData(GL_ARRAY_BUFFER, data_size, vertices, GL_STATIC_DRAW);
        data_size = 8*sizeof(GLint);
        GLint textcoords[] = {0,0,  0,1,  1,0, 1,1};
        glBufferData(GL_ARRAY_BUFFER, data_size, textcoords, GL_STATIC_DRAW);
        return vbo;
    }
    

    下面是来自另一个函数的一些相关代码,该函数应该使用VBO绘制纹理。

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glColor4d(1,1,1,a/255);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTranslated(offset[0],offset[1],0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexPointer(2, GL_DOUBLE, 0, 0);
    glEnableClientState(GL_VERTEX_ARRAY);
    glTexCoordPointer (2, GL_INT, 0, 0);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDrawArrays(GL_TRIANGLES, 1, 3);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    

    我希望代码使用前三个坐标(左上、左下、右上)和后三个坐标(左下、右上、右下)以最有效的方式正确地绘制带有纹理数据的三角形。我不明白为什么三角形应该使它更有效,但显然这是一种方式去。当然,它失败是有原因的。

    非常感谢。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Ivan Baldin    16 年前

    typedef struct {
        GLdouble x, y;
        GLint    s, t;
    } VertexData;
    
    VertexData data[] = {
    //  x        y        s  t
        {0.0,     0.0,     0, 0},
        {0.0,     size[1], 0, 1},
        {size[0], 0.0,     1, 0},
        {size[0], size[1], 1, 1}
    };
    

    将其复制到VBO中:

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), (GLvoid*)data, GL_STATIC_DRAW);
    

    设置指针。请注意,跨距是结构的大小,指针本身用作偏移量:

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexPointer(2, GL_DOUBLE, sizeof(VertexData), (GLvoid*)offsetof(VertexData, x));
    glTexCoordPointer(2, GL_INT, sizeof(VertexData), (GLvoid*)offsetof(VertexData, s));
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    

    EDIT:按照Bahbar的建议,用offsetof()实现了offset。

        2
  •  0
  •   Bahbar    16 年前

    您正在向vbo加载两次数据。对glBufferData的第二个调用正在替换第一个调用。那么在调用draw时,对gl*指针的两个调用实际上使用相同的数据。