2015-03-22 4 views
3

Мой движок OpenGL рисует данную сцену в объект Framebuffer, а затем использует его вложение в виде текстуры. Затем он помещается на квадрат в окне просмотра.Визуальная проблема с использованием Frambuffer Объект как текстура

Проблемы заключается в том, что я вижу странный визуальный артефакт:

enter image description here

Квадратными построен с

glm::vec2 square[4]; 
square[0] = glm::vec2(0.f, 0.f); 
square[1] = glm::vec2(engWidth, 0.f); 
square[2] = glm::vec2(0.f, engHeight); 
square[3] = glm::vec2(engWidth, engHeight); 
glm::vec2 texcoords[4]; 
texcoords[0] = glm::vec2(0.f, 0.f); 
texcoords[1] = glm::vec2(1.f, 0.f); 
texcoords[2] = glm::vec2(0.f, 1.f); 
texcoords[3] = glm::vec2(1.f, 1.f); 

glGenBuffers(2, Buffer2D); 
glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[0]); 
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(glm::vec2), square, GL_STATIC_DRAW); 
glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[1]); 
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(glm::vec2), texcoords, GL_STATIC_DRAW); 

orthographicProj = glm::ortho(0.f, (float)engWidth, 0.f, (float)engHeight, -1.f, 1.f); 

Где engWidth и engHeight является фактическим размером окна.

Затем кадр отображается с

shaderProgram->setMatrix("Clip", orthographicProj); 

glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[0]); 
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[1]); 
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr); 
glEnableVertexAttribArray(1); 

glDisableVertexAttribArray(2); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

вершинных и фрагментных шейдеров для заключительной фазы являются простыми

const char *frontVertexShader = R"(
    #version 440 core 

    uniform mat4 Clip; 

    layout(location = 0) in vec2 Position; 
    layout(location = 1) in vec2 TexCoord; 

    out vec2 Tex_Coord; 

    void main() { 
     gl_Position = Clip * vec4(Position, 0.0, 1.0); 
     Tex_Coord = TexCoord; 
    } 
)"; 

const char *frontFragmentShader = R"(
    #version 440 core 

    in vec2 Tex_Coord; 
    uniform sampler2D sampler; 

    out vec4 Fragment; 

    void main() { 
     Fragment = texture(sampler, Tex_Coord); 
    } 
)"; 

Я попытался с помощью треугольников вместо треугольника полосы, но с тем же результатом.

Любая идея? При необходимости я могу отправить больше кода.

+1

Просто любопытно, почему у вас есть матрица клипов. Для чего он используется? Если геометрия, которую вы отправляете, нормализована от -1 до 1, вы просто передаете ее, а координата текстуры - * 0,5 и добавьте 0,5 к вершинной позиции, и все готово. – Robinson

+1

Прежде всего, подтвердили ли вы, что ваше содержимое текстуры является acutally corrent, т. Е. Артефакт еще не находится в текстуре? Кроме того: убедитесь, что ваши фрагменты не отбрасываются (проверка глубины, тест трафарета и т. Д.). – derhass

+0

На самом деле я этого не делал, но это нужно, так как рендеринг в FBO выполняется так же, как и в буфере. Во всяком случае, я сохраню содержимое для изображения, чтобы проверить это. – Shepard

ответ

2

Я не знаю, если это поможет, но для чего это стоит это то, что я могу сделать для полного экрана четырехугольника: с

(обратите внимание на вершину не имеет текстур компонента - это просто от -1 до 1) ,

v[0].x = -1.f; v[0].y = -1.f; v[0].z = 0.f; 
v[1].x = -1.f; v[1].y = 1.f; v[1].z = 0.f; 
v[2].x = 1.f; v[2].y = -1.f; v[2].z = 0.f; 
v[3].x = 1.f; v[3].y = 1.f; v[3].z = 0.f; 

вершинный шейдер просто:

void main() 
{ 
    attrib_Fragment_Texture = attrib_Position.xy * 0.5 + 0.5; 

    gl_Position = vec4(attrib_Position.xy, 0.0, 1.0); 
} 

со следующим пиксельным шейдером:

void main(void) 
{ 
    Out_Colour = texture2D(Map_Diffuse, attrib_Fragment_Texture); 
} 

Вам не нужна ортогональная матрица проекции.

+0

Также убедитесь, что ваш пробоотборник является точкой и зажимается до края. – Robinson

+0

Я не понимал, что могу избежать использования орфографической матрицы. Я использовал этот код, и теперь он выглядит более чистым. Тем не менее, проблема остается. – Shepard

+0

А, ок. Это выглядит странно. Сначала я думал, что это может быть проблема выборки, но край слишком груб. – Robinson

2

Найденный! Я забыл вызвать glClear на backbuffer, и по какой-то странной причине только некоторые пиксели представили проблему.