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

Author Topic: Empty texture for vertex array quads  (Read 9073 times)

0 Members and 1 Guest are viewing this topic.

N_K

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
Empty texture for vertex array quads
« on: September 12, 2012, 05:00:59 pm »
Hello all,

Another noob problem here. The vertex array based tile system uses this method to define texture coorinates for each tile:
map[current + 0].texCoords = sf::Vector2f((tx + 0) * size, (ty + 0) * size);
map[current + 1].texCoords = sf::Vector2f((tx + 0) * size, (ty + 1) * size);
map[current + 2].texCoords = sf::Vector2f((tx + 1) * size, (ty + 1) * size);
map[current + 3].texCoords = sf::Vector2f((tx + 1) * size, (ty + 0) * size);

(int tx and int ty are the x and y coordinates of the desired part of the texture, int size is the size of the tile).

The vertex array itself is defined like this:
sf::VertexArray map(sf::Quads, layer_width * layer_height * 4);

Now the problem with this is that I can't define an empty texture. If both tx and ty are 0, the first image of the tileset will be drawn. When I modified the texture coordinate routine to this:
map[current + 0].texCoords = sf::Vector2f(0, 0);
map[current + 1].texCoords = sf::Vector2f(0, 0);
map[current + 2].texCoords = sf::Vector2f(0, 0);
map[current + 3].texCoords = sf::Vector2f(0, 0);
the empty tiles were filled with the first pixel of the tileset image, resulting in a solid color.

How can I set up the texture coordinates to render the tile untextured/completely transparent/invisible?

EDIT: Forgot to mention that when the tile map is loaded from a tile, and the app starts processing the tile IDs, the normal coordinate setup routine is used (the first code snippet) if the tile ID is larger than zero, and if it's zero or less, the empty coordinate routine should be used to texture the current tile.
« Last Edit: September 12, 2012, 05:06:07 pm by N_K »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Empty texture for vertex array quads
« Reply #1 on: September 12, 2012, 05:07:40 pm »
Untextured: don't use a texture when you draw the vertex array.
Transparent: don't draw it :P
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Empty texture for vertex array quads
« Reply #2 on: September 12, 2012, 05:13:41 pm »
Iterate through vertex array and if you find first of 4 vertices of a tile that has the '0 ID' copy 4 last vertices into these 4 and then shorten the vertex array.
Quote
Transparent: don't draw it
would sf::Color with alpha 0 do something or does texturing ignore it?
Back to C++ gamedev with SFML in May 2023

N_K

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
Re: Empty texture for vertex array quads
« Reply #3 on: September 12, 2012, 05:42:52 pm »
Thanks for your replies.

Untextured: don't use a texture when you draw the vertex array.

The problem with this is that the map processing/array setup takes place during startup, way before rendering.

So basically, the texture is assigned to the vertex array when it's rendered:
window.draw(map, &tileset);
so I can only manipulate the texture coordinates during map procecssing, but not the texture itself.

Transparent: don't draw it :P

Yeah, this would be the most logical thing to do, but if I don't draw the empty tiles, the tile array will be messed up, and everything will be out of place, I'm afraid.

Iterate through vertex array and if you find first of 4 vertices of a tile that has the '0 ID' copy 4 last vertices into these 4 and then shorten the vertex array.

Won't this slow down the map processing with larger maps? Anyway, I'll try to implement this and see how it goes.

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Empty texture for vertex array quads
« Reply #4 on: September 12, 2012, 05:46:59 pm »
Quote
Won't this slow down the map processing with larger maps? Anyway, I'll try to implement this and see how it goes.
Not really? It seems better to remove anything that isn't supposed to be there once rather than render invisible garbage 60 times per second.
Actually, how about starting with empty array and only appending vertices to array if tile number is positive?
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Empty texture for vertex array quads
« Reply #5 on: September 12, 2012, 06:09:59 pm »
Assigning a color with alpha = 0 to vertices will also hide the tile, yes.

But you can't disable texturing just by changing vertices attributes.

But what are you trying to achieve? Maybe there are other (more global) solutions to your problems.
Laurent Gomila - SFML developer

N_K

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
Re: Empty texture for vertex array quads
« Reply #6 on: September 12, 2012, 06:20:03 pm »
Actually, how about starting with empty array and only appending vertices to array if tile number is positive?

Do you know any in-depth tutorial about vertex arrays in SFML? It's a good idea, and indeed much cleaner/better than drawing untextured quads, but the code I've posted is the only one I could find in this forum.

But what are you trying to achieve? Maybe there are other (more global) solutions to your problems.

Let's assume we have a map with two layers. The map is an array of integers, each integer representing the N-th tile of the assigned tileset.

Layer one:
1 1 1 1
1 1 1 1
1 1 1 1

This layer is the ground layer, filled with the first texture of the tileset (grass texture in my case).

Layer two:
0 0 0 0
0 2 0 0
0 0 0 2

This is the first layer above the ground layer. Tiles represented with zero are empty, tiles with ID of 2 are the second image from the tileset (flowers scattered around the map, for example).

Whan I'm trying to achieve is to either skip drawing or make invisible the tiles represented with zero, since they are empty spaces.

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Empty texture for vertex array quads
« Reply #7 on: September 12, 2012, 06:34:09 pm »
Quote
Do you know any in-depth tutorial about vertex arrays in SFML? It's a good idea, and indeed much cleaner/better than drawing untextured quads, but the code I've posted is the only one I could find in this forum.
I didn't see a single tutorial about that.
Make a class that holds tile ids mapped to texture coords and have a function FillQuad(int tilex,int tiley,int tileid,sf::VertexArray& garray)?
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Empty texture for vertex array quads
« Reply #8 on: September 12, 2012, 06:35:13 pm »
And why do you create vertices for these empty tiles? Can the contents of the layers change?
Laurent Gomila - SFML developer

N_K

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
Re: Empty texture for vertex array quads
« Reply #9 on: September 12, 2012, 10:11:11 pm »
And why do you create vertices for these empty tiles? Can the contents of the layers change?

I create the vertices for the empty tiles because at the moment, I need them to keep the tiles in the correct array.

The coordinates for the quads are being calculated by adding the dimensions of a tile to the previous one. So, assuming the tile size is 32(x32), it goes like 0, 32, 64, 96 ..., and without creating a quad for the empty tiles, I don't know how to position the ones that are not empty.

(Okay, this probably doesn't make any sense, but I can't explain it better...  :-[ )

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Empty texture for vertex array quads
« Reply #10 on: September 12, 2012, 10:22:53 pm »
Make a class that stores info about what id is what texturepos and with a function that takes , x,y, vertex array and tile id.
A bit like that loop but I'm doing with strings as ids and 2d vector of vertex arrays.
        for (int iy=0;iy<map_y;++iy)
        {//1
                for (int ix=0;ix<map_x;++ix)
                {//4
                        std::getline(gstream,tile_name);
                        m_tileset.AddVertices(ix,iy,my_chunks[ix/chunksize][iy/chunksize],tile_name);
                }//4
        }//1
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Empty texture for vertex array quads
« Reply #11 on: September 12, 2012, 10:27:53 pm »
Quote
The coordinates for the quads are being calculated by adding the dimensions of a tile to the previous one. So, assuming the tile size is 32(x32), it goes like 0, 32, 64, 96 ..., and without creating a quad for the empty tiles, I don't know how to position the ones that are not empty.
Seriously? ???

If a tile is located in the fourth column of the layer, its X position is 4 * 32. You don't need to create the previous tile to calculate that.
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Empty texture for vertex array quads
« Reply #12 on: September 12, 2012, 10:35:52 pm »
Quote
...it goes like 0, 32, 64,96 ...
Seriously? ???

If a tile is located in the fourth column of the layer, its X position is 4 * 32.
I see.  ;D
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Empty texture for vertex array quads
« Reply #13 on: September 12, 2012, 10:41:26 pm »
Okay, 3 because counting starts at 0... :P
Laurent Gomila - SFML developer

N_K

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
Re: Empty texture for vertex array quads
« Reply #14 on: September 13, 2012, 01:59:52 am »
Accidentally, I discovered that this works:

sf::VertexArray layer2(sf::Quads, layer_width * layer_height * 4);

for(int x2=0; x2 < layer_width; ++x2)
{
        for(int y2=0; y2 < layer_height; ++y2)
        {
                int current2 = (x2 + y2 * layer_width) * 4;

                if(spriteLayer->GetTileId(x2, y2) != 0)
                {
                        layer2[current2 + 0].position = sf::Vector2f((x2 + 0) * size, (y2 + 0) * size);
                        layer2[current2 + 1].position = sf::Vector2f((x2 + 0) * size, (y2 + 1) * size);
                        layer2[current2 + 2].position = sf::Vector2f((x2 + 1) * size, (y2 + 1) * size);
                        layer2[current2 + 3].position = sf::Vector2f((x2 + 1) * size, (y2 + 0) * size);

                        int currentTile2 = spriteLayer->GetTileId(x2, y2);
                        int tx2 = currentTile2 % horizontalTiles;
                        int ty2 = currentTile2 / horizontalTiles;

                        layer2[current2 + 0].texCoords = sf::Vector2f((tx2 + 0) * size, (ty2 + 0) * size);
                        layer2[current2 + 1].texCoords = sf::Vector2f((tx2 + 0) * size, (ty2 + 1) * size);
                        layer2[current2 + 2].texCoords = sf::Vector2f((tx2 + 1) * size, (ty2 + 1) * size);
                        layer2[current2 + 3].texCoords = sf::Vector2f((tx2 + 1) * size, (ty2 + 0) * size);
                }
        }
}

layer_width and layer_height are the width and height of the tile layer (measured in tile units)

spriteLayer is the map layer that is being processed

GetTileId(int x, int y) is a function of tmx-parser, which returns the ID of the tile at the given XY coordinate

So, this basically does what I wanted to do, if the tile ID is zero, it doesn't create a quad for it. But I can't believe it was so easy, is it safe to use at all?

And is there a built-in way to render the quads as wireframe, or draw some kind of bouding box around them to see how the layer looks like on the polygon level?