Сценарий
Я создаю объект буфера кадра и привязываю текстуру к прикреплению цвета 0. Я не использую буфер глубины. После создания отвязываю.
Спустя какое-то время буфер кадра связывается, ему рендерится треугольная полоса (некоторые части частично прозрачны), а затем он снова отключается. Это повторяется несколько раз с разными треугольными полосками.
В конечном счете, то, что рисуется в основном буфере кадра, представляет собой текстурированный четырехугольник с текстурой, прикрепленной к созданному мной объекту буфера кадра.
Проблема
Я обнаружил, что частично прозрачные части полос треугольника, нарисованные в текстуре, которые перекрываются с другими полосами треугольника, не смешиваются должным образом. Кажется, что они смешаны с белым, а не с цветом, который уже присутствует в текстуре. Даже если я заполню текстуру сплошным зеленым цветом (например), цвет, полученный при смешивании, все равно будет белым.
Вот несколько фрагментов кода, который я использую для всего этого:
Инициализация
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffers(1, &framebuffer_id);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Рендеринг в текстуру (повторяется)
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// On the first render iteration, do_clear is true
if (do_clear)
{
glClearColor(r, g, b, a);
glClear(GL_COLOR_BUFFER_BIT);
}
// ... render the current triangle strip ...
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Отрисовка текстуры в главный буфер кадра
// Set up the texture (making no assumptions about current state)
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Set up the vertex buffer (quad made up of triangle strip)
glBindBuffer(GL_ARRAY_BUFFER, vertices_id);
glVertexAttribPointer(VERTEX_ATTRIB_POSITION_TAG, 3, GL_FLOAT, GL_FALSE, sizeof(MyRenderVertex), BUFFER_OFFSET(0));
glEnableVertexAttribArray(VERTEX_ATTRIB_POSITION_TAG);
glVertexAttribPointer(VERTEX_ATTRIB_TEXCOORD_TAG, 2, GL_FLOAT, GL_FALSE, sizeof(MyRenderVertex), BUFFER_OFFSET(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(VERTEX_ATTRIB_TEXCOORD_TAG);
glVertexAttribPointer(VERTEX_ATTRIB_COLOR_TAG, 4, GL_FLOAT, GL_FALSE, sizeof(MyRenderVertex), BUFFER_OFFSET(5 * sizeof(GLfloat)));
glEnableVertexAttribArray(VERTEX_ATTRIB_COLOR_TAG);
glVertexAttribPointer(VERTEX_ATTRIB_NORMAL_TAG, 3, GL_FLOAT, GL_FALSE, sizeof(MyRenderVertex), BUFFER_OFFSET(9 * sizeof(GLfloat)));
glEnableVertexAttribArray(VERTEX_ATTRIB_NORMAL_TAG);
// Draw the textured geometry
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Reset everything
glDisableVertexAttribArray(VERTEX_ATTRIB_POSITION_TAG);
glDisableVertexAttribArray(VERTEX_ATTRIB_TEXCOORD_TAG);
glDisableVertexAttribArray(VERTEX_ATTRIB_COLOR_TAG);
glDisableVertexAttribArray(VERTEX_ATTRIB_NORMAL_TAG);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(target, 0);
glActiveTexture(0);
Пример того, что я вижу
В тех частях, где вы видите белые линии, пересекаются полосы треугольника. Они должны быть частично прозрачными и смешиваться с ранее нарисованным черным цветом.
Обновить
С тех пор, как опубликовал это, я сделал несколько открытий:
- «Белая» часть на самом деле полностью прозрачна, поэтому она просто показывает цвет всего, что находится за текстурой.
- Я заменил более сложные треугольные сетки произвольно расположенными квадратами, состоящими из вершин, которые меняются от полностью прозрачных на одной стороне квадрата до полностью непрозрачных на другой стороне, и я не вижу той же проблемы смешивания. Вот изображение квадратов:
Похоже, проблема связана с сетками треугольников, которые я использую, а не с смешиванием.
На самом деле, внимательно присмотревшись к изображению "Хорошее наложение", я могу увидеть, что полностью непрозрачные части квадрата фактически становятся светлее, когда поверх него рендерится другой квадрат. Так что проблема есть, просто она не такая уж серьезная.