将 OpenGL VBO 与自定义 classes/datatructures 结合使用
Using OpenGL VBOs with custom classes/datatructures
我正在尝试优化四边形的绘制(目前使用 glBegin
和 glEnd
),我读到 VBO 是更好的方法。我的问题是我没有带有索引数组的 GLuint
基本数组,而是自定义 classes 来保存值:
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*
标记角
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
class 创建一个 facesToRender
我相信这是我可以放置 vboId
)
的地方
chunks
是 Chunk*
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++ 的初学者(虽然我知道其他语言,如果我在 classes 上犯了一些大错误,我很抱歉)。
如果需要任何其他信息,请发表评论!
首先你要保证顶点坐标在内存中是连续且连续的区域,不会被分割成很多小块。使用 Location bl, br, tr, tl
代替 Location *bl ...
,使用 std::vector<Face>
代替 std::vector<Face*>
。然后你有一个连续的顶点坐标列表,可以绑定到顶点缓冲区对象:
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
绘制。
我正在尝试优化四边形的绘制(目前使用 glBegin
和 glEnd
),我读到 VBO 是更好的方法。我的问题是我没有带有索引数组的 GLuint
基本数组,而是自定义 classes 来保存值:
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*
标记角
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
class 创建一个 facesToRender
我相信这是我可以放置 vboId
)
chunks
是 Chunk*
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++ 的初学者(虽然我知道其他语言,如果我在 classes 上犯了一些大错误,我很抱歉)。
如果需要任何其他信息,请发表评论!
首先你要保证顶点坐标在内存中是连续且连续的区域,不会被分割成很多小块。使用 Location bl, br, tr, tl
代替 Location *bl ...
,使用 std::vector<Face>
代替 std::vector<Face*>
。然后你有一个连续的顶点坐标列表,可以绑定到顶点缓冲区对象:
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
绘制。