2017-11-03 3 views
0

Ich brauche ein NxN-Auflösung Gitter in der XY-Ebene mit OpenGL. Die endgültigen Gitter muss durch Dreiecke (GL_TRIANGLES) gemacht werden, so sollte es, wie das folgende Beispiel scheint:Erstellen Sie ein Gitter in OpenGL

^
* | ---------- 
* | |\ |\ |\ | 
* | | \| \| \| 
* | ---------- 
* | |\ |\ |\ | 
* y | | \| \| \| 
* | ---------- 
* | |\ |\ |\ | 
* | | \| \| \| 
* | ---------- 
* | 
* |--------------> 
*   x 

beachte, dass ich das Gitter in Vertex-Indexform speichern muß (die Strukturen durch Parameter angegeben).

an dieser Stelle mein Code:

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(); 
} 

Jede Beratung? Grüße.

Antwort

1

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); 
+0

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

+1

@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

+0

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

Verwandte Themen