如何在OpenGL中创建网格并使用线条绘制它 [英] How to create a grid in OpenGL and drawing it with lines

查看:207
本文介绍了如何在OpenGL中创建网格并使用线条绘制它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个像这样的网格:

I need to create a grid like this:

  ----------------
  |  |  |  |  |  |
  ----------------
  |  |  |  |  |  |
  ----------------
  |  |  |  |  |  |
  ----------------

并仅使用线条进行渲染. 这是创建顶点和索引的方法:

and rendering it just with lines. This is how I create the vertices and the indices:

  std::vector<glm::vec3> vertices;
  std::vector<glm::uvec3> indices;

  for(int j=0; j<=slices; ++j) {
    for(int i=0; i<=slices; ++i) {
      float x = (float)i/(float)slices;
      float y = 0;
      float z = (float)j/(float)slices;
      vertices.push_back(glm::vec3(x, y, z));
    }
  }

  for(int j=0; j<slices; ++j) {
    for(int i=0; i<slices; ++i) {

      int row1 = j * (slices+1);
      int row2 = (j+1) * (slices+1);

      indices.push_back(glm::uvec3(row1+i, row1+i+1, row2+i+1));
      indices.push_back(glm::uvec3(row1+i, row2+i+1, row2+i));

    }
  }

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

  lenght = (GLuint)indices.size()*3;

这是我的渲染方式:

  glBindVertexArray(vao);

  glDrawElements(GL_LINES, lenght, GL_UNSIGNED_INT, NULL);

  glBindVertexArray(0);

结果不是我想要的. 我也尝试使用GL_LINE_LOOP等 我认为问题在于顶点和索引的创建

The results is not what I want. I also try with GL_LINE_LOOP etc I think that the problems is in the creation of the vertices and indices

更新:

我使Rabbit76建议的更改看起来很完美!

I made the changes suggested by Rabbit76 looks perfect!!

这是创建顶点和索引的最终代码:

Here the final code to create the vertices and the indices:

  std::vector<glm::vec3> vertices;
  std::vector<glm::uvec4> indices;

  for(int j=0; j<=slices; ++j) {
    for(int i=0; i<=slices; ++i) {
      float x = (float)i/(float)slices;
      float y = 0;
      float z = (float)j/(float)slices;
      vertices.push_back(glm::vec3(x, y, z));
    }
  }

  for(int j=0; j<slices; ++j) {
    for(int i=0; i<slices; ++i) {

      int row1 =  j    * (slices+1);
      int row2 = (j+1) * (slices+1);

      indices.push_back(glm::uvec4(row1+i, row1+i+1, row1+i+1, row2+i+1));
      indices.push_back(glm::uvec4(row2+i+1, row2+i, row2+i, row1+i));

    }
  }

  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::uvec4), glm::value_ptr(indices[0]), GL_STATIC_DRAW);

  glBindVertexArray(0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  lenght = (GLuint)indices.size()*4;

这是渲染网格的代码:

  glEnable(GL_DEPTH_TEST);

  glBindVertexArray(vao);

  glDrawElements(GL_LINES, lenght, GL_UNSIGNED_INT, NULL);

  glBindVertexArray(0);

  glDisable(GL_DEPTH_TEST);

推荐答案

[...]我需要渲染线栅格[...]

[...] I need to render a line raster [...]

有很多可能性.基于此代码,几乎没有任何更改的选项是为每个四边形创建线段.

There are a lot of possibilities. Based on this code, an option with with very few changes is to create for line segments for each quad.

更改索引的类型:

std::vector<glm::uvec4> indices;

添加线段:

indices.push_back(glm::uvec4(row1+i, row1+i+1, row1+i+1, row2+i+1));
indices.push_back(glm::uvec4(row2+i+1, row2+i, row2+i, row1+i));

创建并初始化缓冲区的数据存储时,请注意更改的类型:

Take care of the changed type when you create the and initialize the data store of the buffer:

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(glm::uvec4),
             indices.data(), GL_STATIC_DRAW);

分别(甚至更优雅)

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(*indices.data()),
             indices.data(), GL_STATIC_DRAW);

最后计算正确的索引数

lenght = (GLuint)indices.size()*4;

绘制线段

glBindVertexArray(vao);
glDrawElements(GL_LINES, lenght, GL_UNSIGNED_INT, NULL);


另一种选择是在整个网格上渲染线段:


An other option would be to render line segments across the entire grid:

std::vector<glm::uvec2> indices;

int rowLen = slices+1;
int noVert = (int)vertices.size();
for(int j=0; j<slices; ++j) {
    indices.push_back(glm::uvec2(j * rowLen, (j+1) * rowLen - 1));
    indices.push_back(glm::uvec2(j, noVert - rowLen + j));
}

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(*indices.data()),
             indices.data(), GL_STATIC_DRAW);
lenght = (GLuint)indices.size()*2;

这篇关于如何在OpenGL中创建网格并使用线条绘制它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆