2017-11-03 16 views
0

OpenGL을 사용하여 xy 평면에 NxN 해상도 격자를 생성해야합니다. 마지막 그리드는 삼각형 (GL_TRIANGLES)에 의해 만들어 질 필요가있다, 그래서 다음의 예처럼 보일한다 : 나는 (매개 변수에 의해 구조 주어진) 정점 인덱스 형태로 격자를 저장해야OpenGL에서 격자 만들기

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

어떤 조언을? 문안 인사.

답변

1

언어가 C++이고 std::vector을 사용하고 있으므로 함수 서명을 변경하고 포인터 대신 참조로 매개 변수를 전달해야합니다.

void generate_grid(int N, std::vector<glm::vec3> &vertices, std::vector<glm::uvec3> &indices); 

먼저 버텍스 배열을 채워야합니다. N*N 필드의 경우 (N+1)*(N+1) 정점이 필요합니다. 이렇게 될 것이다,

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

일반적인에게 두 번째로 각 필드에 대해 당신이 개 삼각형을 생성 할 수 있고, 삼각형 인덱스를 생성해야

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

: 형상을 그리는 방법은 Vertex Array Object을 만드는 것입니다
+0

나는 당신이 그것을 만들었던 추측을 이해하지만, 나는 여전히 언어 자체에 문제가있다. 참조 대신 포인터를 사용할 수 있습니까? – giorgioW

+1

@giorgioW 물론 그렇습니다.하지만 그렇게하지 마십시오. 만약 당신이 그것을한다면 다음과 같이해야합니다 :'void generate_grid (int N, std :: vector * vertices, std :: vector * indices)''glm :: vec3 v; vertex-> push_back (v)','glm :: vec3 v = (* vertices) [i]','int i; index => push_back (i)','int i = (* indices) [j]'. 포인터가 가리키는 값에 접근하기 위해서는 그것을 참조 해제해야한다. – Rabbid76

+0

'std :: vector *'를 사용하여'indices'를 저장하면 유효합니다 :'indices-> push_back (glm ::) ('vertex)','vertices-> size uvec3 (row1 + i, row1 + i + 1, row2 + i + 1)); – giorgioW