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

Author Topic: tile glich.  (Read 4949 times)

0 Members and 1 Guest are viewing this topic.

Silderan

  • Newbie
  • *
  • Posts: 17
    • View Profile
    • Email
tile glich.
« on: January 20, 2015, 12:18:21 am »
I've write down this code and when tiles are 23x23 or more, one of them begins to flash:
const int tileW = 10;
const int tileH = 10;
const int tilesX = 23;
const int tilesY = 23;
void TileMap::renderMap()
{
        window = new sf::RenderWindow(sf::VideoMode(800, 600, 32), "Tile Map");
        int x, y;
        sf::RectangleShape tiles[tilesX][tilesY];
        for (x = 0; x < tilesX; x++)
        {
                for (y = 0; y < tilesY; y++)
                {
                        tiles[x][y].setSize(sf::Vector2f(tileH, tileW));
                        tiles[x][y].setFillColor(sf::Color(x * (255/tilesX), y * (255/tilesY), 0));
                        tiles[x][y].setPosition(sf::Vector2f(x * tileW, y * tileH));
                }
        }
        while (window->isOpen())
        {
                sf::Event event;
                while (window->pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window->close();
                }

                window->clear();
                for (x = 0; x < tilesX; x++)
                        for (y = 0; y < tilesY; y++)
                                window->draw(tiles[x][y]);
                window->display();
        }
}


What is wrong with my code?

EDIT: I think the error is in color as when I use a fixed color for entire tiles, works fine.
But, just fixing color of flashing tile, don't solve:
                        if (x == 22 && y == 19)
                                tiles[x][y].setFillColor(sf::Color::White);
                        else
                                tiles[x][y].setFillColor(sf::Color(((x * (255/tilesX)) % 254), ((y * (255/tilesY)) % 254), 0));
 
« Last Edit: January 20, 2015, 12:30:08 am by Silderan »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: tile glich.
« Reply #1 on: January 20, 2015, 12:31:11 am »
Wouldn't have been too hard to edit a few lines to make it compilable out of the box, right? ;)

#include <SFML/Graphics.hpp>

const int tileW = 10;
const int tileH = 10;
const int tilesX = 260;
const int tilesY = 260;

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Tile Map");
    int x, y;
    sf::RectangleShape tiles[tilesX][tilesY];
    for (x = 0; x < tilesX; x++)
    {
        for (y = 0; y < tilesY; y++)
        {
            tiles[x][y].setSize(sf::Vector2f(tileH, tileW));
            tiles[x][y].setFillColor(sf::Color(x * (255/tilesX), y * (255/tilesY), 0));
            tiles[x][y].setPosition(sf::Vector2f(x * tileW, y * tileH));
        }
    }
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();
        for (x = 0; x < tilesX; x++)
            for (y = 0; y < tilesY; y++)
                window.draw(tiles[x][y]);
        window.display();
    }
}
 

Also it seems to work fine for me:





So I guess your other part of the code is cause issues?
Or maybe your graphics driver isn't uptodate?

Also note, once tilesX or tilesY get too large, your application might crash because the array on stack would get too big.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: tile glich.
« Reply #2 on: January 20, 2015, 03:41:38 am »
As eXpl0it3r said, your array is on the stack. It would make more sense to use a vector to store these rectangles as vectors store on the heap. It's a tad slower here but there are a lot more tiles...
#include <SFML/Graphics.hpp>
#include <vector> // include this to be able to create the vector

const int tileW = 1;
const int tileH = 1;
const int tilesX = 800; // using the vector, we can use higher numbers here
const int tilesY = 600; // using the vector, we can use higher numbers here

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Tile Map");
        int x, y;
        std::vector<std::vector<sf::RectangleShape>> tiles(tilesX, std::vector<sf::RectangleShape>(tilesY)); // create 2d vector instead of 2d array
        for (x = 0; x < tilesX; x++)
        {
                for (y = 0; y < tilesY; y++)
                {
                        tiles[x][y].setSize(sf::Vector2f(tileH, tileW));
                        tiles[x][y].setFillColor(sf::Color(x * 255 / tilesX, y * 255 / tilesY, 0)); // removed brackets to allow usage of higher values for tilesX and tilesY
                        tiles[x][y].setPosition(sf::Vector2f(x * tileW, y * tileH));
                       
                }
        }
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                window.clear();
                for (x = 0; x < tilesX; x++)
                        for (y = 0; y < tilesY; y++)
                                window.draw(tiles[x][y]);
                window.display();
        }
}
I commented the only lines that were changed from eXpl0it3r's example.

First, it would be better to use a one-dimensional vector rather than a two-dimensional one and then access using modulus and division for the rows and columns.
Second, you're drawing each rectangle individually. In my version of this code, that's over 480 thousand draw calls! Multiple rectangles can be drawn using a single draw call if you use a vertex array. You may enjoy reading this tutorial which explains vertex arrays and even gives you a Tile Map example! :)

(click to show/hide)
« Last Edit: January 20, 2015, 04:01:48 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Silderan

  • Newbie
  • *
  • Posts: 17
    • View Profile
    • Email
Re: tile glich.
« Reply #3 on: January 20, 2015, 10:37:56 pm »
Thank you very much to both...

I didn't read all SFML docs. I saw other forum thread about tile map and get that code. But, vertex is much more impressive approach :)

eXpl0it3r, you're right. I didn't modify code for your use out of the box. I appology.
This code is not for "real" use. Tile map matrix, of course, must not be into stack. But, for testing, it works.
I agree. Must be the graphic driver as there is no "other code". TileMap class has only the renderMap() function  called from main(). I will test this program on other computer.

Hapax, thanks again for your tip. For sure, I will use vertex :)
Can you please tell me why do you prefer 1D vector instead 2D matrix?
Maybe because I won't need double "for" anymore?

Thanks again!

Silderán.

EDIT: I've compiled with DLL, and statically with the same tile flashing. As I don't have another computer in home to test it, i've uploaded on my GDrive. Here it is if you like to test: https://drive.google.com/file/d/0BzTQYbPFSWp2dEZJd1hBa3g3dDA/view?usp=sharing

EDIT2: XDDD I run it ussing my NVIDIA graphic card instead intel embedded and tile doesn't flash. So, here is the problem :P
« Last Edit: January 20, 2015, 11:12:44 pm by Silderan »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: tile glich.
« Reply #4 on: January 21, 2015, 12:42:22 am »
Glad you found the problem. It ended up being a graphics card problem after all! :D

It's not necessary to use a one-dimensional vector instead of a two-dimensional one but with the access of a single-dimensional one being pretty easy to do, I can't find a reason to use a two-dimensional one. Not using two fors is just a bonus. The creation of a single dimensional vector is also a lot more simple than a multi-dimensional vector.
I'm sure there's also a technical reason to use a one-dimensional vector but I can't remember what it is. Hopefully, one of the awesome people around here might read this and remind me ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

SpeCter

  • Full Member
  • ***
  • Posts: 151
    • View Profile
Re: tile glich.
« Reply #5 on: January 21, 2015, 09:43:50 am »
Glad you found the problem. It ended up being a graphics card problem after all! :D

It's not necessary to use a one-dimensional vector instead of a two-dimensional one but with the access of a single-dimensional one being pretty easy to do, I can't find a reason to use a two-dimensional one. Not using two fors is just a bonus. The creation of a single dimensional vector is also a lot more simple than a multi-dimensional vector.
I'm sure there's also a technical reason to use a one-dimensional vector but I can't remember what it is. Hopefully, one of the awesome people around here might read this and remind me ;)

Using a 1D array instead a 2D array could potentially increase the speed.With a 1D array the memory is laid out in one continuous chunk which makes it  easier for the cpu to read it(or prefetch it).A normal 2D array should be laid out the same, but only if it is a normal 2D array and not a vector of vectors.

Austin J

  • Newbie
  • *
  • Posts: 29
    • View Profile
    • Email
Re: tile glich.
« Reply #6 on: January 22, 2015, 05:54:54 am »
I've personally had a lot of experience with tile engines, and I'd say one-dimensional array on the heap is certainly the best way to go. For really large tile maps as a warning though you might not be able to just use any STL container such as a vector, because such are limited to one contiguous memory chunk. So I often times found myself hitting a wall with tile sizes with 1000x1000 dimensions using STL containers. I was able to optimize it a bit hand rolling my container but it honestly didn't make much of a difference. I'm pretty sure there are containers out there that aren't limited to one chunk though, I haven't personally tried one however.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: tile glich.
« Reply #7 on: January 22, 2015, 08:22:15 am »
I'm pretty sure there are containers out there that aren't limited to one chunk though, I haven't personally tried one however.

If it helps, I'm pretty sure std::deque is normally implemented "with multiple chunks".

Silderan

  • Newbie
  • *
  • Posts: 17
    • View Profile
    • Email
Re: tile glich.
« Reply #8 on: January 26, 2015, 09:06:51 pm »
Maybe I'm saying some stupid thing but... what about tile *tileArray = new tile[1000x1000];?
Sometimes we understimate c++ basis or overstimate stl, if you prefer xD

By the way, out of topic but... I've tried a million tile map (1000x1000) using vertex tutorial and FPS drops to less than 40. Must I perform some kind of map render clip? I though that was the SFML rendering engine (through it's View coords) who does that. Maybe I've coded something wrong.
I've tested another game engine based on SDL (not OpenGL directly like SFML) and doesn't care map size at all.

Silderán.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: tile glich.
« Reply #9 on: January 26, 2015, 11:00:59 pm »
what about tile *tileArray = new tile[1000x1000];?
Preferably not due to manual memory management.
I think you may find Nexus' article on RAII informative.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything