Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Transparent RenderTexture  (Read 2444 times)

0 Members and 1 Guest are viewing this topic.

Blackdrazon

  • Newbie
  • *
  • Posts: 2
    • View Profile
Transparent RenderTexture
« on: July 30, 2018, 09:16:24 am »
I'm trying to follow an old Flash/AS3 tutorial using SFML instead. The objective is to render tiled maps in a series of layers, based on a Tiled editor map. The end result is supposed to looks like this:



The back-most layer will fill the entire area with grass and dirt. Next, the Foreground layer will be drawn, which includes obstructions like the tree stump and bushes. Because most of the layer is empty, it should be transparent. Next, the player is drawn, then the tree's leaves. If the player moves behind the tree, the tree will obscure them. Standard stuff.

My thinking was to draw each layer (except the player) to a RenderTexture, convert the Texture to a Sprite and then draw the Sprite to the Window.  Here's the code:

// Preparing the map
for(int i = 0; i < game->tiles.size(); i++) {
    sf::RenderTexture rtex;
    if(!rtex.create(game->mapWidth * game->tileWidth,
        game->mapHeight * game->tileHeight)) {
        std::cout << "Error creating map render texture.";
        return;
    }

    // The bottom layer is opaque by default. The rest are transparent.
    if(i == 0) rtex.clear();
    else rtex.clear(sf::Color(0, 0, 0, 0));

    [...identify the tiles and draw them to rtex...]

    // Finalize.
    rtex.display();

    // Store the texture and convert it to a sprite that will be used during draw.
    mapLayerTextures.push_back(rtex.getTexture());
    mapLayers.push_back(new sf::Sprite(mapLayerTextures.back()));
}

[...]

// Drawing the layers.
for(int i = 0; i<mapLayers.size(); i++) {
    game->window.draw(*mapLayers[i]);
}
 

Unfortunately, the result is this:



Obviously I screwed up the transparency somehow, so the topmost layer (layer 3, the leaves) became opaque white. Checking the other layers, the background is just fine, and the second layer shows similar problems. I think the brown rectangle below the tree, and the fact that layer 2's tree trunk showed up even though everything else is from layer 3, are just side effects of the above problem, but I guess we'll see.

This thread seems to suggests the problem might be Blend Modes (hard to say if we're in the same situation when the images are broken), but I haven't had any luck with BlendNone, as suggested.

Any other suggestions?
« Last Edit: July 30, 2018, 09:21:42 am by Blackdrazon »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Transparent RenderTexture
« Reply #1 on: July 30, 2018, 09:21:26 am »
First, your code is very inefficient (why do you copy textures? why do you allocate sprites dynamically? are you sure that your graphics card can create render-textures as big as your entire tilemap? ...). What's the benefit of rendering to layers, compared to drawing everything directly to the window? If it's done in the right order, it should give the same results -- with less headache ;)
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Transparent RenderTexture
« Reply #2 on: July 30, 2018, 09:32:41 am »
A RT isn't transparent by default, so your check with i == 0 doesn't make sense and when calling clear without a color, SFML uses sf::Color::Black.

In your loop you also use temporary RT which is very inefficient.

But without more details, i.e. more code, it's hard to say what the issue really is.
Maybe it also helps if you sit down and think about how the layering should work and how is currently implemented.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Blackdrazon

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Transparent RenderTexture
« Reply #3 on: July 30, 2018, 09:41:11 am »
First, your code is very inefficient (why do you copy textures? why do you allocate sprites dynamically? ...). What's the benefit of rendering to layers, compared to drawing everything directly to the window? If it's done in the right order, it should give the same results -- with less headache ;)

The answer to most of these questions is "because I'm bad at this language / programming in general" but I had inadequate reasons. It doesn't really matter, though, since you're right and there's no need to use the layer system at all.  Drawing to layers was the tutorial's idea, I just didn't question it.

I suppose that's what I'll do, nothing more to say, really.

In your loop you also use temporary RT which is very inefficient.

I'll keep that in mind too in case something similar comes up, thanks!
« Last Edit: July 30, 2018, 09:53:43 am by Blackdrazon »