При рендеринге в текстуру (вторичный кадровый буфер) в OpenGL , все прозрачное перезаписывает прозрачность того, что ниже, а не добавляет прозрачность, как должна прозрачность. Это означает, что если я рендерим прозрачный объект поверх существующего непрозрачного объекта, результатом будет прозрачная текстура, даже если она должна быть непрозрачной.
На этом рисунке пространство отображается как фон, затем framebuffer
изменяется, а затем отображается непрозрачный синий, а затем зеленый / красный. Текстура, на которую framebuffer
рендерится, используется для рендеринга на исходную framebuffer
(окно), и результат такой, какой вы видите.
Код:
Создание кадрового буфера / текстуры:
int texture = glGenTextures();
framebufferID = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER,framebufferID);
glBindTexture(GL_TEXTURE_2D, texture);
int width,height;
width = (int)(getMaster().getWindow().getWidth()*(xscale/(16f*getMaster().getGuiCamera().getWidth()))*1.2f);
height = (int)(getMaster().getWindow().getHeight()*(yscale/9f)*1.15f);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,0);
int depth = glGenTextures();
glBindTexture(GL_TEXTURE_2D, depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
this.texture = new Texture(texture,width,height,true);
glDrawBuffer(GL_FRONT_AND_BACK);
Здесь я пытался заставить работать буфер глубины, но он не оказал влияния на текстуру вывода.
Код рендеринга:
getMaster().returnToViewportAfterFunction(new Vector2i(texture.getWidth(),texture.getHeight()),
() -> getMaster().returnToFramebufferAfterFunction(framebufferID, () -> {
shapeShader.bind();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
model.bind();
shapeShader.setUniform("color", 0f, 0f, 1f, 1f); //Blue
shapeShader.setUniform("projection", this.camera.getProjectionForGuiWindow(vec2zero, xscale, yscale));
glDrawElements(GL_TRIANGLES, model.getVerticeCount(), GL_UNSIGNED_INT, 0);
shapeShader.setUniform("color", 0f, 1f, 0f, 0.5f); //Green
shapeShader.setUniform("projection", this.camera.getProjectionForGuiWindow(vec2zero, xscale/2f, yscale/2f));
glDrawElements(GL_TRIANGLES, model.getVerticeCount(), GL_UNSIGNED_INT, 0);
shapeShader.setUniform("color", 1f, 0f, 0f, .2f); //Red
shapeShader.setUniform("projection", this.camera.getProjectionForGuiWindow(vec2zero, xscale/4f, yscale/2f));
glDrawElements(GL_TRIANGLES, model.getVerticeCount(), GL_UNSIGNED_INT, 0);
glDisable(GL_BLEND);
model.unbind();
})
);
//Renders the texture we just made
shader.bind();
model.bind();
textureCoords.bind(texture);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
shader.setUniform("color", 1f, 1f, 1f, 1f);
shader.setUniform("projection", camera.getProjectionForGuiWindow(getPosition(), xscale, yscale));
glDrawElements(GL_TRIANGLES, model.getVerticeCount(), GL_UNSIGNED_INT, 0);
glDisable(GL_BLEND);
model.unbind();
Рендеринг поверх непрозрачных объектов в framebuffer
0 с прозрачным объектом не приводит к тому, что результирующие пиксели становятся прозрачными, иначе они будут выглядеть как смесь glClearColor
и непрозрачного объекта, так почему это происходит в framebuffer
в котором я использую для рендеринга текстуры? Разве это не должно быть последовательным? Я чувствую, что, может быть, мне не хватает какой-то привязанности к моему framebuffer
, но я не уверен, что именно. Я видел решение, в котором говорилось, что используется glColorMask(true,true,true,false)
, последнее ложное значение без альфа-записи, которое на первый взгляд кажется эффективным, но почему я должен отключать прозрачность, если прозрачность - то, к чему я стремлюсь? Это также, кажется, вызывает много проблем, если оставить его включенным. Кто-нибудь может дать некоторое понимание? Заранее спасибо!
РЕДАКТИРОВАТЬ: glColorMask не был решением после дальнейшего анализа.