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

Author Topic: Need an idea how to display only X amount of vertices from sf::VertexArray  (Read 4173 times)

0 Members and 1 Guest are viewing this topic.

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Hello.
Currently i am loading a map intro a vertex array(sf::...::Quads, 100x100x4).

They are representation of 32x32 tile.
What is my issue? well i don't want to draw the whole 100x100 vertexes, instead i would like to draw only those on the screen.
Also the tiles can have offset ranging from 0 - 31 pixels.

The issues:
As stated above i have 100x100map size of 1 tile is 32x32 pixels the size in pixels is 3200:3200,
but the size of my window is 1028x768, how can i move the map around? without repositioning each vertex that is gonna be drawn?
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Quote
What is my issue? well i don't want to draw the whole 100x100 vertexes, instead i would like to draw only those on the screen.
Is it because it's too slow, or because you think that eventually it might be slow?
And the answer is no, you can't, unless you subdivide your map into multiple vertex arrays.

Quote
how can i move the map around?
Have a look at the vertex array tutorial > "Transforming vertex arrays".
Laurent Gomila - SFML developer

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Is it because it's too slow, or because you think that eventually it might be slow?
And the answer is no, you can't, unless you subdivide your map into multiple vertex arrays.
Yes it is slow, 500x500 at 50-60% cpu usage, and VSync on provides only ~35 fps.
For a 2d game that should run on weak machines, its unacceptable.

I am gonna invest some time intro this for sure.
I will post my "invention" when am done if someone will be experiencing same issue.
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
If you will just move around, use sf::View for a camera.

If you actually want to transform the whole vertex array without changing the vertices, use sf::Transform.

If you want to draw only a part of the array, then draw it manually and use glDrawArrays(Primitive, StartVertex, NumVertices); (can only draw contiguous vertices)

That's it, there is always a solution. For maps, better to divide it in multiple regions, and draw them whole only if they are within the screen, moving around with a sf::View only. Try

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
There are two solutions:
1. Use spritebatch and redraw tiles (visible ones) every frame.
2. Use my TileRenderer from wiki.
SFML.Utils - useful extensions for SFML.Net

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Quote
If you want to draw only a part of the array, then draw it manually and use glDrawArrays(Primitive, StartVertex, NumVertices); (can only draw contiguous vertices)
You can draw a part of a vertex array with SFML (window.draw(verticesPtr, count, primitiveType)), no need to use OpenGL.
Laurent Gomila - SFML developer

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
If you will just move around, use sf::View for a camera.

If you actually want to transform the whole vertex array without changing the vertices, use sf::Transform.

If you want to draw only a part of the array, then draw it manually and use glDrawArrays(Primitive, StartVertex, NumVertices); (can only draw contiguous vertices)

That's it, there is always a solution. For maps, better to divide it in multiple regions, and draw them whole only if they are within the screen, moving around with a sf::View only. Try
I am making a 2d "shooter"? but with swords&magic era. Projectiles, and real time actions.
What i am afraid off is how will i handle projectiles positioning, and pathing.
Also doing AI... that is gonna be a new.

As you suggested, i will use sf::View for position drawing.
For the map, i will cut it in regions... that will be pretty simple, and fast enough.

Quote
If you want to draw only a part of the array, then draw it manually and use glDrawArrays(Primitive, StartVertex, NumVertices); (can only draw contiguous vertices)
You can draw a part of a vertex array with SFML (window.draw(verticesPtr, count, primitiveType)), no need to use OpenGL.
I am wondering, if i pass verticesPtr, a pointer to a vertex that is in middle of vertexArray, count to fill that row until end of screen. primitiveType = Quads. That should work...

UPDATE::
Its possible to pass a vertex that is in middle of vertex array, and draw only limited amount! so cool.
Got it textures and all.
But, it isen't safe. In case of memory  corruption or something i will cause huge error that will require handling.

EDIT::
If someone needs / requires a example, here is code:

Make a "map.txt" file and copy this intro it.
Don't copy -> "" <- quotation marks
"1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10 "

also make sure you have image "img.png" for texture...

const int TILE_SIZE = 32;
int main()
{
        //Main window
        sf::RenderWindow renWin;
        renWin.create(sf::VideoMode(1024, 768, 32), "hy");
        //Texture
        sf::Texture tex;
        tex.loadFromFile("img.png");
        int imageWidth = tex.getSize().x / TILE_SIZE;

        //Map
        sf::VertexArray verArr(sf::PrimitiveType::Quads, 10 * 10 * 4);

        std::ifstream ifstream;
        ifstream.open("map.txt");

        if(ifstream.is_open() == true)
        {
                //Loading map 10x10 size
                for(int y = 0; y < 10; y++)
                {
                        for(int x = 0; x < 10; x++)
                        {
                                int readTile;
                                ifstream >> readTile;

                                int ID = (x + y * 10) * 4;

                                verArr[ID].position = sf::Vector2f(x * TILE_SIZE, y * TILE_SIZE);
                                verArr[ID+1].position = sf::Vector2f(x * TILE_SIZE + TILE_SIZE, y * TILE_SIZE);
                                verArr[ID+2].position = sf::Vector2f(x * TILE_SIZE + TILE_SIZE, y * TILE_SIZE + TILE_SIZE);
                                verArr[ID+3].position = sf::Vector2f(x * TILE_SIZE, y * TILE_SIZE + TILE_SIZE);

                                readTile -=1;//Quick fix for getting correct tile in math
                                verArr[ID].texCoords = sf::Vector2f((readTile % imageWidth) * TILE_SIZE, (readTile / imageWidth) * TILE_SIZE);
                                verArr[ID+1].texCoords = sf::Vector2f((readTile % imageWidth) * TILE_SIZE +TILE_SIZE, (readTile / imageWidth) * TILE_SIZE);
                                verArr[ID+2].texCoords = sf::Vector2f((readTile % imageWidth) * TILE_SIZE + TILE_SIZE, (readTile / imageWidth) * TILE_SIZE + TILE_SIZE);
                                verArr[ID+3].texCoords = sf::Vector2f((readTile % imageWidth) * TILE_SIZE, (readTile / imageWidth) * TILE_SIZE + TILE_SIZE);
                        }
                }
        }
        //Vertex to be drawn
        //sf::Vertex *ver = &verArr[12];

        //Render state that hold texture
        sf::RenderStates state;
        state.texture = &tex;

        while(renWin.isOpen())
        {
                //Event handling
                sf::Event event;
                while(renWin.pollEvent(event))
                {
                        switch(event.type)
                        {
                        case sf::Event::Closed: renWin.close(); break;
                        default: break;
                        }
                }
                //Clear
                renWin.clear();
                //Drawing vertex/vertices
                sf::Vertex *ver;
                for(int i = 0; i < 5; i++)
                {
                        ver = &verArr[i * 10 * 4 + 12];
                        renWin.draw(ver, 12, sf::PrimitiveType::Quads, state);
                }
                //feed buffer
                renWin.display();
        }

        return 0;
}
« Last Edit: May 04, 2013, 10:57:35 pm by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0