我需要使用OpenGL在xy平面中生成NxN分辨率网格。最终网格需要由三角形(GL_TRIANGLES
)制作,所以它应该如下例所示:
^
* | ----------
* | |\ |\ |\ |
* | | \| \| \|
* | ----------
* | |\ |\ |\ |
* y | | \| \| \|
* | ----------
* | |\ |\ |\ |
* | | \| \| \|
* | ----------
* |
* |-------------->
* x
请注意,我需要以顶点索引形式存储网格(通过参数给出结构)。
我的代码:
void generate_grid(
std::uint32_t N,
std::vector<glm::vec3>* vertices,
std::vector<glm::uvec3>* indices)
{
for (int i = 0; i < N; i++) {
glBegin(GL_TRIANGLES);
for (int j = 0; j < N; j++) {
int vertexNum = indices; // Index for vertex j of face i.
double[] vertexCoords = vertices[vertexNum]; // The vertex itself.
glVertex3f(vertexCoords, 0);
}
glEnd();
}
有什么建议吗?问候。
答案 0 :(得分:2)
由于语言是C ++并且你使用的是std::vector
,你应该更改函数签名并通过引用而不是指针传递参数。
void generate_grid(int N, std::vector<glm::vec3> &vertices, std::vector<glm::uvec3> &indices);
首先,你必须填充顶点数组。请注意,对于N*N
字段,您需要(N+1)*(N+1)
个顶点。其次,您必须为每个字段生成三角形索引,您必须生成2个三角形:
float f(float x, float y)
{
// use any curve function you want
return sin(x*2.0f*3.141526f) * sin(y*2.0f*3.141526f) * 0.1f;
}
void generate_grid(int N, std::vector<glm::vec3> &vertices, std::vector<glm::uvec3> &indices)
{
for (int j=0; j<=N; ++j)
{
for (int i=0; i<=N; ++i)
{
float x = (float)i/(float)N;
float y = (float)j/(float)N;
float z = f(x, y);
vertices.push_back(glm::vec3(x, y, z));
}
}
for (int j=0; j<N; ++j)
{
for (int i=0; i<N; ++i)
{
int row1 = j * (N+1);
int row2 = (j+1) * (N+1);
// triangle 1
indices.push_back(glm::uvec3(row1+i, row1+i+1, row2+i+1));
// triangle 2
indices.push_back(glm::uvec3(row1+i, row2+i+1, row2+i));
}
}
}
旧学校和弃用的方式来绘制这个,就像这样:
void draw_grid(const std::vector<glm::vec3> &vertices, const std::vector<glm::uvec3> &indices)
{
glBegin(GL_TRIANGLES);
for ( auto i : indices )
{
glVertex3fv(glm::value_ptr(vertices[i.x]));
glVertex3fv(glm::value_ptr(vertices[i.y]));
glVertex3fv(glm::value_ptr(vertices[i.z]));
}
glEnd();
}
绘制几何体的常用方法是创建Vertex Array Object:
GLuint generate_vao(const std::vector<glm::vec3> &vertices, const std::vector<glm::uvec3> &indices)
{
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
GLuint vbo;
glGenBuffers( 1, &vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, vertices.size()*sizeof(glm::vec3), glm::value_ptr(vertices[0]), GL_STATIC_DRAW );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, nullptr );
GLuint ibo;
glGenBuffers( 1, &ibo );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(glm::uvec3), glm::value_ptr(indices[0]), GL_STATIC_DRAW );
glBindVertexArray( 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
return vao;
}
void draw_vao( GLuint vao, GLsizei n )
{
glBindVertexArray( vao );
glDrawElements( GL_TRIANGLES, (GLsizei)n, GL_UNSIGNED_INT, NULL );
glBindVertexArray( 0 );
}
std::vector<glm::vec3> vertices;
std::vector<glm::uvec3> indices;
GLuint vao = generate_vao( vertices, indices );
.....
draw_vao( vao, (GLsizei)indices.size()*3 );