Skip to content

Instantly share code, notes, and snippets.

@lxndrdagreat
Created December 5, 2015 05:04
Show Gist options
  • Save lxndrdagreat/da4400e23ac611ec3567 to your computer and use it in GitHub Desktop.
Save lxndrdagreat/da4400e23ac611ec3567 to your computer and use it in GitHub Desktop.
SFML Tile culling and drawing using sf::VertexArray
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main() {
sf::RenderWindow window(sf::VideoMode(640, 480), "Tile Culling");
// our view
sf::View camera;
camera.setSize(320,240);
camera.setCenter(160, 120);
int mapWidth = 20;
int mapHeight = 15;
// a silly little map
std::vector<int> intMap {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
while (window.isOpen()){
sf::Event event;
while (window.pollEvent(event)){
if (event.type == sf::Event::Closed){
window.close();
}
}
window.clear(sf::Color::Magenta);
window.setView(camera);
int tileSize = 32;
// get our starting x/y in tile coordinates
int startX = (int)floorf(camera.getViewport().left / tileSize);
int startY = (int)floorf(camera.getViewport().top / tileSize);
// The +1 is a buffer. I like having a little bit of a buffer.
int across = (int)camera.getSize().x / tileSize + 1;
int down = (int)camera.getSize().y / tileSize + 1;
sf::VertexArray tileVertexArray(sf::Quads, 4);
tileVertexArray.resize(4 * across * down);
int totalTilesDrawn = 0;
int vertexPosition = 0;
for (int x = startX; x < startX + across; ++x){
for (int y = startY; y < startY + down; ++y){
// convert 2D coordinate to 1D array index
int index = y * mapWidth + x;
int tileHere = intMap[index];
// Set the four corners that make up the quad for this tile:
tileVertexArray[vertexPosition].position = sf::Vector2f(x * tileSize, y * tileSize); // top left corner
tileVertexArray[vertexPosition + 1].position = sf::Vector2f(x * tileSize + tileSize, y * tileSize); // top right corner
tileVertexArray[vertexPosition + 2].position = sf::Vector2f(x * tileSize + tileSize, y * tileSize + tileSize); // bottom right corner
tileVertexArray[vertexPosition + 3].position = sf::Vector2f(x * tileSize, y * tileSize + tileSize); // bottom left corner
// I'm just going to draw colors for this example, but the textured version
// is very similar.
if (tileHere == 0){
tileVertexArray[vertexPosition].color = sf::Color::White;
tileVertexArray[vertexPosition + 1].color = sf::Color::White;
tileVertexArray[vertexPosition + 2].color = sf::Color::White;
tileVertexArray[vertexPosition + 3].color = sf::Color::White;
}
else if (tileHere == 1){
tileVertexArray[vertexPosition].color = sf::Color::Black;
tileVertexArray[vertexPosition + 1].color = sf::Color::Black;
tileVertexArray[vertexPosition + 2].color = sf::Color::Black;
tileVertexArray[vertexPosition + 3].color = sf::Color::Black;
}
++totalTilesDrawn;
vertexPosition += 4;
}
}
// we've figured out the tiles, now draw once
window.draw(tileVertexArray);
window.setView(window.getDefaultView());
window.display();
}
return 0;
}
@lxndrdagreat
Copy link
Author

Just a rough and quick example of only drawing the map tiles that fall within the bounds of the camera.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment