2013-09-18 2 views
0

потока Код выглядит следующим образом:Draw текстурированной четверной в фоне OPENGL сцены

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
renderScene(); 
renderTexturedQuadForBackground(); 
presentRenderbuffer(); 

Есть ли способ для меня, чтобы получить, что текстурированный четырехугольник рендеринга код, чтобы показать, за сценой, несмотря на то, что сцена делает первый? Предположим, что я не могу изменить, что рендеринг фонового текстурированного квадрата произойдет непосредственно перед представлением буфера визуализации.

Перефразированный: я не могу изменить порядок визуализации. По сути, я хочу, чтобы каждый пиксель, который был бы окрашен только glClearColor, вместо этого был бы окрашен этим текстурированным квадрантом.

+0

Вы не можете изменить порядок команд или не можете настроить квадрант? – thokra

+0

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

+0

Предполагается, что квадроцикл должен быть заполнен экраном? – thokra

ответ

4

Самым простым решением является определение четверной в нормированной координаты устройства непосредственно и установить Z-значение 1. Тогда вам не нужно проецировать четырехугольника, и это будет экран заполнения и за что-либо else - кроме материала, который также находится в z = 1 после проецирования и разрыва перспективы.

Это почти стандартная процедура для квадрантов с выравниванием по экрану, за исключением того, что, как правило, нет необходимости устанавливать квад в z = 1, а не в том, что это имеет значение. Обычно полноэкранные квадраты просто используются, чтобы обрабатывать по крайней мере один раз фрагмент на пиксель, обычно 1: 1 отображение фрагментов пикселей. Обычными подозреваемыми являются отсроченное затенение, обработка постобработки или обработка изображений в целом. Поскольку вы в большинстве случаев выполняете рендеринг квада (и ничего больше), значение глубины не имеет значения, если оно находится внутри куба единицы и не отбрасывается с помощью теста глубины, например, когда вы помещаете его в z = 1 и ваши функции глубины есть LESS.

EDIT: Я сделал небольшую ошибку. НДЦ определены в левой системе координат, что означает, что ближняя плоскость отображается на -1, а дальняя плоскость отображается на 1. Таким образом, вам необходимо определить свой квад в НДЦ с az значением 1 и установить DepthFunc на LEQUAL. В качестве альтернативы, вы можете оставить функцию глубины нетронутыми и просто вычесть очень малую величину от 1.f:

float maxZ = 1.f - std::numeric_limits<float>::epsilon();

EDIT2: Давайте предположим, что вы хотите сделать экран выровнен четверной на который обращается за всем else и с соответствующими координатами текстуры. Обратите внимание:: Я нахожусь на рабочем столе здесь, поэтому я пишу основной код GL, который не сопоставляется непосредственно с GLES 2.0. Однако в моем примере нет ничего, что нельзя сделать с GLES и GLSL ES 2.0.

Вы можете определить вершинные attribs четырехугольника, как это (без баловаться с глубины FUNC):

GLfloat maxZ = 1.f - std::numeric_limits<GLfloat>::epsilon(); 

// interleaved positions an tex coords 
GLfloat quad[] = {-1.f, -1.f, maxZ, 1.f, // v0 
        0.f, 0.f, 0.f, 0.f, // t0 
        1.f, -1.f, maxZ, 1.f, // ... 
        1.f, 0.f, 0.f, 0.f, 
        1.f, 1.f, maxZ, 1.f, 
        1.f, 1.f, 0.f, 0.f, 
        -1.f, 1.f, maxZ, 1.f, 
        0.f, 1.f, 0.f, 0.f}; 

GLubyte indices[] = {0, 1, 2, 0, 2, 3}; 

VAO и буферы настроены соответствующим образом:

// generate and bind a VAO 
gl::GenVertexArrays (1, &vao); 
gl::BindVertexArray (vao); 

// setup our VBO 
gl::GenBuffers (1, &vbo); 
gl::BindBuffer (gl::ARRAY_BUFFER, vbo); 
gl::BufferData (gl::ARRAY_BUFFER, sizeof(quad), quad, gl::STATIC_DRAW); 

// setup out index buffer 
gl::GenBuffers (1, &ibo); 
gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, ibo); 
gl::BufferData (gl::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl::STATIC_DRAW); 

// setup our vertex arrays 
gl::VertexAttribPointer (0, 4, gl::FLOAT, gl::FALSE_, 8 * sizeof(GLfloat), 0); 
gl::VertexAttribPointer (1, 4, gl::FLOAT, gl::FALSE_, 8 * sizeof(GLfloat), (GLvoid*)(4 * sizeof(GLfloat))); 
gl::EnableVertexAttribArray (0); 
gl::EnableVertexAttribArray (1); 

код шейдера приходит к очень, очень простому проходному вершинному шейдеру и, для упрощения, фрагментарный шейдер, который в моем примере просто экспортирует интерполированные текс-координаты:

// Vertex Shader 
#version 430 core 

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

out vec2 vTexCoord; 

void main() 
{ 
    vTexCoord = TexCoord.xy; 

    // you don't need to project, you're already in NDCs! 
    gl_Position = Position; 
} 

//Fragment Shader 
#version 430 core 

in vec2 vTexCoord; 
out vec4 FragColor; 

void main() 
{ 
    FragColor = vec4(vTexCoord, 0.0, 1.0); 
} 

Как вы можете видеть, значения, записанные в gl_Position, - это просто позиции вершин, переданные при вызове шейдера. Проецирование не происходит, потому что результат проекции и разрыва перспективы - это не что иное, как нормализованные координаты устройства. Поскольку мы уже находимся в НДЦ, нам не нужны проекционные и перспективные деления и поэтому просто проходят через позиции без изменений.

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

Вы можете использовать texcoords, как обычно.

Надеюсь, у вас есть идея. За исключением явных мест атрибутов, которые не поддерживаются GLES 2.0 (т. Е. Вместо этого нужно заменить элементы вызовами BindAttribLocation()), вам не нужно ничего делать.

+0

действительно кажется, что, учитывая мои орто2df (-1,1, -1,1, -1,1) z = -1.0f и глубину func lequal или менее работает даже для какой-либо произвольной проекции сцены. Я думаю, что я понял это в opengles 1.1, теперь я пытаюсь понять, как это сделать в opengles 2.0. : -/спасибо за вашу помощь, это было полезно! –

+0

@mike_haney: Я обновил ответ - довольно существенно. :) – thokra

0

Существует способ, но вы должны поставить квадрат позади сцены. Если квад построена правильно вы можете включить DEPTH_TEST с помощью

glEnable(DEPTH_TEST); 

, а затем с помощью

glDepthFunc(GL_GREATER); 

перед визуализацией фона. Ваш квад будет отображаться позади сцены. Но, как я сказал, это работает только тогда, когда ваша геометрия буквально находится за сценой.

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