Da die Sprache C++ ist und Sie eine std::vector
verwenden, sollten Sie die Funktionssignatur ändern und die Parameter durch Verweis anstelle von Zeiger übergeben.
void generate_grid(int N, std::vector<glm::vec3> &vertices, std::vector<glm::uvec3> &indices);
Zuerst müssen Sie das Vertex-Array füllen. Beachten Sie, dass Sie für ein Feld N*N
(N+1)*(N+1)
Vertices benötigen. Zweitens müssen Sie die Dreieck-Indizes erzeugen, für jedes Feld, das Sie zwei Dreiecke generieren:
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));
}
}
}
Die alte Schule und veraltete Weg, dies zu ziehen, so sein würde:
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();
}
die gemeinsame Weg Geometrie zu zeichnen ist, eine Vertex Array Object zu erzeugen:
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);
Ich verstehe die Argumentation, die Sie verwendet haben, aber ich habe immer noch Probleme mit der Sprache selbst. Gibt es eine Möglichkeit, Zeiger anstelle von Referenzen zu verwenden? – giorgioW
@giorgioW Ja natürlich, aber tu das nicht. Wenn Sie es tun würden, müssen Sie es folgendermaßen machen: 'void generate_grid (int N, std :: Vektor * Vertices, std :: vector * Indizes)' 'glm :: vec3 v; Vertices-> push_back (v) ',' glm :: vec3 v = (* Vertices) [i] ',' int i; indices-> push_back (i) ',' int i = (* indices) [j] '.Hinweis: Um auf die Werte zuzugreifen, auf die ein Zeiger zeigt, müssen Sie diese z. '(* Vertices)', 'Vertices-> size()' –
Rabbid76
Wenn ich einen 'std :: vector *' benutze, um meine 'Indizes' zu speichern, ist dies gültig:' indexes-> push_back (glm :: uvec3 (row1 + i, row1 + i + 1, row2 + i + 1)); '? –
giorgioW