Advanced Topics

Blending

Blending is a technique to make objects transparent. We allows us to have objects like windows that can have their own color or texture but can also show objects that are behind them.

This is accomplished by enabling blend mode:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

This tells OpenGL that we want to combine the alpha of the source vector and use 1 - src_alpha for the destination vector.

There is one more thing we need to do to make this work in a scene with multiple entities. We need to make sure that we draw first all the entities that are behind the window (transparent) entity before we render it. This will allow the blending to work correctly.

This is a bit of a limitation because, now we need to make sure that things are sorted every time the camera moves and that comes with some performance limitations.

Here is an example of adding some windows to the scene:

texture WindowTexture;
Texture_Create(&WindowTexture,
               "./resources/textures/blending_transparent_window.png",
               GL_TEXTURE_2D, GL_TEXTURE0, GL_RGBA, GL_UNSIGNED_BYTE);

std::vector<texture> WindowTextures = {WindowTexture};

std::vector<glm::vec3> Windows;
Windows.push_back(glm::vec3(-1.5f, 0.0f, -0.48f));
Windows.push_back(glm::vec3(1.5f, 0.0f, 0.51f));
Windows.push_back(glm::vec3(0.0f, 0.0f, 0.7f));
Windows.push_back(glm::vec3(-0.3f, 0.0f, -2.3f));
Windows.push_back(glm::vec3(0.5f, 0.0f, -0.6f));

glm::vec3 CameraPosition = Camera.Position;
sort(Windows.begin(), Windows.end(),
     [&CameraPosition](const glm::vec3 &A, const glm::vec3 &B) {
         return length(CameraPosition - A) >= length(CameraPosition - B);
     });

mesh WindowMesh;
Mesh_CreateQuad(&WindowMesh, WindowTextures);

for (unsigned int i = 0; i < Windows.size(); i++) {
    entity Window = {
        .Type = entity_type::QuadMesh,
        .Position = Windows[i],
        .Scale = glm::vec3(1.0f),
        .Rotation = glm::vec4(0.0f),
        .Color = glm::vec4(1.0f),
        .Mesh = WindowMesh,
    };

    Scene_AddEntity(Scene, Window);
}
Squared Wave SVG