Hello again
I was advised to use vertexes and views in my Tile Map engine(bleh again I know). Reading this forum I got impression that they are supposed to be fast. So I've written sample code to test this and I can not get decent fps and using View causes horizontal lines disorder on image. Possibly I don't understand how to use Vertexes. I am trying to get 300fps+ on 1680x1050 resolution which means I have to display around 360 tiles each frame + possible other objects later one.
Here is what I'm doing:
1. setup 2d vector of VertexArrays as sf::Quads
2. ONCE for each Tilemap[][] setup 4 vertexes(position and texture coords)
3. in main loop go though all Tilemap[][] and call draw(Tilemap
Resulting in around 30 fps, which is by far not enough, especially if I wanted to add more sprites on top of that later on.
Am I doing it wrong or It just has to be this way? Maybe using
this method would be faster?
#include <SFML/Graphics.hpp>
#define TILE_IMG_W 64
#define TILE_IMG_H 64
//function declarations
//Getting rect defining part of texture to use
sf::Rect<int> GetSourceRectangle(int tileIndex);
//converting index numbers to Draw position
sf::Vector2i IndxToIso(int x, int y);
void Draw();
//Preparing Map
void init();
sf::RenderWindow window;
sf::Texture tileTexture;
sf::View* Cam;
std::vector< std::vector< sf::VertexArray > > Tilemap;
//MapSize = size*size
int size = 50;
int main()
{
Cam = new sf::View(sf::FloatRect(0, 0, 1680, 1050));
//Load Texture
tileTexture.loadFromFile("part4_tileset.png");
//Initialize window
window.create(sf::VideoMode(1680, 1050),"");
window.setActive(false);
//Setup map,
init();
//thread for draw function
sf::Thread RenderThread(&Draw);
RenderThread.launch();
//GameLoop
while(window.isOpen())
{
//Event Handling
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
if(event.type == sf::Event::KeyPressed)
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
window.close();
}
}
}
return 0;
}
void Draw()
{
int counter = 0;
int fps = 0;
sf::Text fpsText;
sf::Clock clk;
window.setActive(true);
window.setVerticalSyncEnabled(false);
while(window.isOpen())
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
Cam->move(-10, 0);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
Cam->move(10, 0);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
Cam->move(0, -10);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
Cam->move(0, 10);
window.setView(*Cam);
window.clear();
//Drawing loops
for(int y=0; y<size; y++)
{
for(int x=0; x<size; x++)
{
window.draw(Tilemap[x][y], &tileTexture);
}
}
//fps
counter++;
if(clk.getElapsedTime().asSeconds()>=1)
{
fps = counter/clk.getElapsedTime().asSeconds();
counter=0;
clk.restart();
std::string sss;
char tempB[20];
sprintf(tempB, "%d", fps);
sss = tempB;
fpsText.setString(sss);
}
window.setView(window.getDefaultView());
window.draw(fpsText);
window.display();
}
};
void init()
{
//Temp Quad
sf::Vertex vertices[4];
//preparing vectors
Tilemap.resize(size);
for(int i=0; i<size; i++)
Tilemap[i].resize(size);
//setting VertexArrays for each tle
for(int y=0; y<size; y++)
{
for(int x=0; x<size; x++)
{
sf::Vector2i position = IndxToIso(x, y);
sf::Rect<int> TexPos = GetSourceRectangle(0);
Tilemap[x][y].setPrimitiveType(sf::Quads);
Tilemap[x][y].append(sf::Vertex(sf::Vector2f(position.x, position.y), sf::Vector2f(TexPos.left, TexPos.top)));
Tilemap[x][y].append(sf::Vertex(sf::Vector2f(position.x + TILE_IMG_W, position.y), sf::Vector2f(TexPos.left + TexPos.width, TexPos.top)));
Tilemap[x][y].append(sf::Vertex(sf::Vector2f(position.x + TILE_IMG_W, position.y + TILE_IMG_H), sf::Vector2f(TexPos.left + TexPos.width, TexPos.top + TexPos.height)));
Tilemap[x][y].append(sf::Vertex(sf::Vector2f(position.x, position.y + TILE_IMG_H), sf::Vector2f(TexPos.left, TexPos.top + TexPos.height)));
}
}
};
sf::Rect<int> GetSourceRectangle(int tileIndex)
{
sf::Vector2u TileSetSize = tileTexture.getSize();
int tileY = tileIndex / (TileSetSize.x / TILE_IMG_W);
int tileX = tileIndex % (TileSetSize.x / TILE_IMG_W);
sf::Rect<int> tempR(tileX * TILE_IMG_W, tileY * TILE_IMG_H, TILE_IMG_W, TILE_IMG_H);
return tempR;
};
sf::Vector2i IndxToIso(int x, int y)
{
sf::Vector2i temp;
temp.x = (x-y) * 33;
temp.y = (x+y) * 17;
return temp;
};