2016-04-06 4 views
2

Я имею мои вершины обрезается на обрезной, как показано на этом альбоме:OpenGL Вершины обрезаемый со стороны

http://imgur.com/a/VkCrJ

Когда мой размер местности при 400 х 400 я получаю отсечение, но при 40х40 или что-нибудь меньшее, я не получаю никаких обрезков. Это мой код, чтобы заполнить положение и показатели:

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 и других значениях между ними. код Index:

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 является станд :: vector.I'm не уверен, что причиной этого, но я уверен, что это так, как я заполняю индексы для сетки. Я переписал свой алгоритм, и он заканчивается тем же результатом, небольшие значения работают отлично, а большие значения более ~ 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 to_string, но данные выглядят отлично, Моя проекцияМатрикс:

glm :: перспектива (glm :: radians (_fov), _aspRatio, 0.1f, 1000.0f);

Так что я сомневаюсь, что это моя перспектива, делающая обрезку. _aspRatio - 16/9.

Странно, что он отлично работает с небольшими рядами xcolumns и не большими, я действительно не уверен, в чем проблема.

ответ

2

Я бы уточнил длину _vertexPosition; Я подозреваю, что проблема в том, что вы (в зависимости от числа _rows) генерируете дополнительную точку в конце вашего внутреннего цикла (и ваш внешний цикл тоже, в зависимости от _columns).

Причина в том, что условие завершения ваших вершинных циклов зависит от точного поведения вашей математики с плавающей запятой. В частности, вы разделите диапазон [-1,1] на сегменты _rows, затем добавьте их вместе и используйте их в качестве теста завершения. Неясно, ожидаете ли вы конечную точку (даете _rows+1 точек на внутренний цикл) или нет (с получением прямоугольника, который не охватывает весь диапазон [-1,1]). К сожалению, плавающая точка не является точной, поэтому это рецепт ненадежного поведения: в зависимости от направления вашей ошибки с плавающей точкой вы можете получить тот или иной.

Для большего количества _rows вы добавляете больше (и значительно меньше) чисел к одному и тому же начальному значению; это усугубит вашу ошибку с плавающей запятой.

Во всяком случае, чтобы получить надежное поведение, вы должны использовать целочисленные переменные цикла для определения завершения цикла. Аккумулируйте ваши координаты с плавающей точкой отдельно, чтобы точность не требовалась.

+0

Это было, спасибо, я не должен был использовать счетчик с плавающей запятой, поскольку он округлялся по действительно очень маленьким значениям (1/400); Спасибо за помощь ^^ –

Смежные вопросы