Created
December 5, 2015 05:04
-
-
Save lxndrdagreat/da4400e23ac611ec3567 to your computer and use it in GitHub Desktop.
SFML Tile culling and drawing using sf::VertexArray
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just a rough and quick example of only drawing the map tiles that fall within the bounds of the camera.