【问题标题】:Using OpenGL VBOs with custom classes/datatructures将 OpenGL VBO 与自定义类/数据结构一起使用
【发布时间】:2018-09-29 10:55:40
【问题描述】:

我正在尝试优化四边形的绘制(目前使用glBeginglEnd),我读到VBO 是一种更好的方法。我的问题是我没有带有索引数组的GLuint 基本数组,而是自定义类来保存值:

Location.hpp:保存 x、y 和 z 信息

class Location {
public:
    Location(int x_, int y_, int z_);
    ~Location();

    int x;
    int y;
    int z;
}; 

Face.hpp:持有 4 个标记角的 Location*s

class Face {
public:
    Face(Location* bl_, Location* br_, Location* tr_, Location* tl_); // Using point
    Face(int bl_[3], int br_[3], int tr_[3], int tl_[3]); // Using {x, y, z} int array
    ~Face();
    Location* bl = NULL; // Bottom Left
    Location* br = NULL; // Bottom Right
    Location* tr = NULL; // Top Right
    Location* tl = NULL; // Top Left
};

我的问题是,我想在屏幕上显示一个人脸向量 (std::vector<Face*> facesToRender;)。

现在我有一个循环来执行此操作:

信息:

Chunk 类创建了一个facesToRender,我相信这是我可以放置vboId 的地方

chunksChunk*s 的数组

glPushMatrix();
    for (int i = 0; i < chunks.size(); i++) {
        Chunk* chunk = chunks[i];
        for (int j = 0; j < chunk->facesToRender.size(); j++) {
            Face* f = chunk->facesToRender[j];
            srand(i); // Create a color per chunk
            glColor3ub(rand()%255, rand()%255, rand()%255);
            glBegin(GL_QUADS);
            glVertex3i(f->bl->x, f->bl->y, f->bl->z);
            glVertex3i(f->br->x, f->br->y, f->br->z);
            glVertex3i(f->tr->x, f->tr->y, f->tr->z);
            glVertex3i(f->tl->x, f->tl->y, f->tl->z);
            glEnd();
        }
    }
glPopMatrix();

我的问题是如何将这个 facesToRender 向量处理成 VBO 以使其显示。我是 OpenGL 和 C++ 的初学者(虽然我知道其他语言,如果我在课程中犯了一些大错误,请见谅)。

如果需要任何其他信息,请发表评论!

【问题讨论】:

    标签: c++ opengl glut vbo


    【解决方案1】:

    首先你要确保顶点坐标在内存中一个连续的连续区域,不会被分割成很多小块。使用Location bl, br, tr, tl 代替Location *bl ...std::vector&lt;Face&gt; 代替std::vector&lt;Face*&gt;。然后你有一个可以绑定到顶点缓冲区对象的连续顶点坐标列表:

    class Face {
    public:
        Location bl;
        Location br;
        Location tr;
        Location tl;
    };
    
    std::vector<Location> faces;
    

    创建顶点数组对象并绑定数据

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

    绘制网格:

    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glVertexPointer( 3, GL_INT, sizeof(Location), nullptr );
    glEnableClientState( GL_VERTEX_ARRAY );    
    
    glPushMatrix();
    for (int i = 0; i < chunks.size(); i++) {
        Chunk* chunk = chunks[i];
        for (int j = 0; j < chunk->facesToRender.size(); j++) {
            Face* f = chunk->facesToRender[j];
            srand(i); // Create a color per chunk
    
            glColor3ub(rand()%255, rand()%255, rand()%255);            
            glDrawArrays(GL_QUADS, j*4, 4);
        }
    }
    glPopMatrix();
    
    glDisableClientState( GL_VERTEX_ARRAY );
    



    作为替代方案,您可以创建一个顶点坐标列表和一个面列表,每个面都包含角坐标的 4 个索引。

    std::vector<Location> vertices;
    
    struct Face
    {
        int bl;
        int br;
        int tr;
        int tl;
    };
    
    std::vector<Face> faces;
    

    索引顶点cordiaten可以由glDrawElements绘制。

    【讨论】:

    • 应该是std::vector&lt;Location&gt; faces还是std::vector&lt;Face&gt; faces
    • @Minebomber 当然,在第二种情况下,它必须是std::vector&lt;Face&gt; faces。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    相关资源
    最近更新 更多