c++ - OpenGL 顶点从侧面被剪切

标签 c++ opengl opengl-3

我将顶点剪裁在边缘上,如本相册所示:

/image/a03e7.jpg

当我的地形尺寸为 400 x 400 时,我会得到裁剪,但在 40x40 或更低的尺寸下,我不会得到任何裁剪。 这是我填充位置和索引的代码:

void Terrain::fillPosition()
{
  //start from the top right and work your way down to 1,1
  double x = -1, y = 1, z = 1;
  float rowValue = static_cast<float>((1.0f / _rows) * 2.0); // .05 if 40
  float colValue = static_cast<float>((1.0f / _columns) * 2.0); // .05 if 40

 for (y; y > -1; y -= colValue)
 {
    for (x; x < 1; x += rowValue)
    {
        _vertexPosition.emplace_back(glm::vec3(x, y, z));
    }
    x = -1;
 }
}

这正确地设置了我的位置,我已经使用 GL_POINTS 对其进行了测试。它在 400x400 和 40x40 以及之间的其他值下工作正常。 索引代码:

void Terrain::fillIndices()
{
    glm::ivec3 triangle1, triangle2;
    for (int y = 0; y < _columns - 1; y++)
    {
        for (int x = 0; x < _rows - 1; x++)
        {
            // Triangle 1
            triangle1.x = x       + y       * _rows;
            triangle1.y = x       + (y + 1) * _rows;
            triangle1.z =(x + 1)  + y       * _rows;
            // Triangle 2
            triangle2.x = triangle1.y;
            triangle2.y = (x + 1) + (y + 1) * _rows;
            triangle2.z = triangle1.z;

            // add our data to the vector
            _indices.emplace_back(triangle1.x);
            _indices.emplace_back(triangle1.y);
            _indices.emplace_back(triangle1.z);

            _indices.emplace_back(triangle2.x);
            _indices.emplace_back(triangle2.y);
            _indices.emplace_back(triangle2.z);
        }
    }
}

_indices 是 std::vector。我不确定是什么原因造成的,但我很确定这是我填充网格索引的方式。我重新编写了我的算法,最终得到了相同的结果,小值工作得很好,超过 ~144 的大值被剪掉。我这样填充缓冲区:

void Terrain::loadBuffers()
{
    // generate the buffers and vertex arrays
    glGenVertexArrays(1, &_vao);
    glGenBuffers(1, &_vbo);
    glGenBuffers(1, &_ebo);
    // bind the vertex array
    glBindVertexArray(_vao);
    // bind the buffer to the vao
    glBindBuffer(GL_ARRAY_BUFFER, _vbo);
    glBufferData(GL_ARRAY_BUFFER, _vertexPosition.size() * sizeof(_vertexPosition[0]), _vertexPosition.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(_indices[0]), _indices.data(), GL_STATIC_DRAW);
    // enable the shader locations
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    // unbind our data
    glBindVertexArray(0);
}

和我的绘图调用:

void Terrain::renderTerrain(ResourceManager& manager, ResourceIdTextures id)
{
    // set the active texture
    glActiveTexture(GL_TEXTURE0);
    // bind our texture
    glBindTexture(GL_TEXTURE_2D, manager.getTexture(id).getTexture());
    _shaders.use();
    // send data the our uniforms
    glUniformMatrix4fv(_modelLoc, 1, GL_FALSE, glm::value_ptr(_model));
    glUniformMatrix4fv(_viewLoc, 1, GL_FALSE, glm::value_ptr(_view));
    glUniformMatrix4fv(_projectionLoc, 1, GL_FALSE, glm::value_ptr(_projection));
    glUniform1i(_textureLoc, 0);
    glBindVertexArray(_vao);
    // Draw our terrain;
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glDrawElements(GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, 0);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glBindVertexArray(0);
    _shaders.unuse();
}

我认为这是因为我对模型进行了转换,所以我删除了所有转换,结果是相同的。我尝试通过将 glm::vec3 转换为_string 进行调试,但数据看起来不错,我的projectionMatrix 是:

glm::perspective(glm::radians(_fov), _aspRatio, 0.1f, 1000.0f);

所以我怀疑这是我的观点进行剪辑。 _aspRatio 为 16/9。

这真的很奇怪,它适用于小行x列而不是大行x列,我真的不确定问题是什么。

最佳答案

我会检查_vertexPosition的长度;我怀疑问题是您(取决于 _rows 的数量)在内部循环(以及外部循环,取决于 _columns)末尾生成了一个额外的点>).

原因是顶点循环的终止条件取决于 float 学的确切行为。具体来说,您将范围 [-1,1] 划分为 _rows 段,然后将它们添加在一起并将它们用作终止测试。目前尚不清楚您是否期望最终点(每个内部循环产生 _rows+1 点)或不(产生不覆盖整个 [-1,1] 范围的矩形)。不幸的是,浮点并不精确,因此这会导致不可靠的行为:根据浮点错误的方向,您可能会得到其中之一。

对于较大数量的 _rows,您需要将更多(且明显更小的)数字添加到相同的初始值;这会加剧你的浮点错误。

无论如何,为了获得可靠的行为,您应该使用整数循环变量来确定循环终止。单独累加浮点坐标,因此不需要精确的精度。

关于c++ - OpenGL 顶点从侧面被剪切,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36457658/

相关文章:

c++ - 这是一个有效的向下转换吗

c++ - 基于参数的 C 预处理器宏特化

c++ - 使用 cuda_gl_interop 函数设置时是否可以检索像素缓冲区?

java - LWJGL 投影矩阵 - 什么也没发生

c++ - 如何在mac上使用cmake链接OpenGL相关库?

c++ - 眼动追踪,需要注视追踪方法

c++ - 为什么不能重载三元运算符?

c++ - 柔软、透明的笔画纹理没有像我预期的那样混合

c++ - 使用 ifstream 将文件加载到字符串会加载另一个文件的不完整拷贝?

opengl - Go Lang OpenGL 简单形状 - 空白屏幕