简体   繁体   English

从侧面剪裁的 OpenGL 顶点

[英]OpenGL Vertices being clipped from the side

I'm having my vertices clipped on the edged as shown on this album:我的顶点被剪裁在边缘上,如这张专辑所示:

http://imgur.com/a/VkCrJ http://imgur.com/a/VkCrJ

When my terrain size if 400 x 400 i get clipping, yet at 40x40 or anything less, i don't get any clipping.当我的地形大小为 400 x 400 时,我会被剪裁,但在 40x40 或更少时,我不会被剪裁。 This is my code to fill the position and indices:这是我填充位置和索引的代码:

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

This properly sets my position, I've tested it with GL_POINTS.这正确地设置了我的位置,我已经用 GL_POINTS 对其进行了测试。 It works fine at 400x400 and 40x40 and other values in between.它适用于 400x400 和 40x40 以及介于两者之间的其他值。 Index code:索引代码:

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 is std::vector.I'm not sure what's causing this, But I'm pretty sure it's the way I'm filling the indices for the mesh. _indices 是 std::vector。我不确定是什么原因造成的,但我很确定这是我填充网格索引的方式。 I've re-written my algorhithm and it ends up with the same result, small values work perfectly fine, and large values over ~144 get clipped.我重新编写了我的算法,最终得到了相同的结果,小值工作得很好,超过 144 的大值被剪掉。 I fill my buffers like this:我像这样填充我的缓冲区:

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

and my draw call:和我的抽奖电话:

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

I thought it was because of my transformations to the model, so i removed all transformations and it's the same result.我认为这是因为我对模型进行了转换,所以我删除了所有转换,结果相同。 I tried debugging by casting the glm::vec3 to_string but the data looks fine, My projectionMatrix is:我尝试通过将 glm::vec3 转换为 to_string 进行调试,但数据看起来不错,我的投影矩阵是:

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

So i doubt it's my perspective doing the clipping.所以我怀疑这是我剪辑的观点。 _aspRatio is 16/9. _aspRatio 为 16/9。

It's really strange that it works fine with small rowsxcolumns and not large ones, I'm really not sure what the problem is.真的很奇怪,它适用于小行x列而不是大行,我真的不确定问题是什么。

I would check the length of _vertexPosition ;我会检查_vertexPosition的长度; I suspect the problem is that you are (depending on the number of _rows ) generating an extra point at the end of your inner loop (and your outer loop too, depending on _columns ).我怀疑问题在于您(取决于_rows的数量)在内部循环(以及外部循环,取决于_columns )的末尾生成了一个额外的点。

The reason is that the termination condition of your vertex loops depends on the exact behavior of your floating point math.原因是顶点循环的终止条件取决于浮点数学的确切行为。 Specifically, you divide up the range [-1,1] into _rows segments, then add them together and use them as a termination test.具体来说,您将范围 [-1,1] 划分为_rows段,然后将它们加在一起并将它们用作终止测试。 It is unclear whether you expect a final point (yielding _rows+1 points per inner loop) or not (yielding a rectangle which doesn't cover the entire [-1,1] range).目前尚不清楚您是否期望最终点(每个内循环产生_rows+1个点)或不(产生一个不覆盖整个 [-1,1] 范围的矩形)。 Unfortunately, floating point is not exact, so this is a recipe for unreliable behavior: depending on the direction of your floating point error, you might get one or the other.不幸的是,浮点数并不精确,因此这是不可靠行为的一个秘诀:根据浮点数错误的方向,您可能会得到一个或另一个。

For a larger number of _rows , you are adding more (and significantly smaller) numbers to the same initial value;对于更多的_rows ,您将向相同的初始值添加更多(并且明显更小)的数字; this will aggravate your floating point error.这会加剧您的浮点错误。

At any rate, in order to get reliable behavior, you should use integer loop variables to determine loop termination.无论如何,为了获得可靠的行为,您应该使用整数循环变量来确定循环终止。 Accumulate your floating point coordinates separately, so that exact accuracy is not required.单独累积您的浮点坐标,因此不需要精确的精度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM