152 lines
5.0 KiB
C++
152 lines
5.0 KiB
C++
//Utils to make easy SFML based demos with Maze library
|
|
|
|
#pragma once
|
|
|
|
#include "Grid.h"
|
|
|
|
#include <SFML/Graphics.hpp>
|
|
#include <cmath>
|
|
|
|
namespace utils {
|
|
namespace sfml {
|
|
//From: https://github.com/SFML/SFML/wiki/Source:-Line-segment-with-thickness
|
|
class sfLine : public sf::Drawable
|
|
{
|
|
public:
|
|
sfLine(const sf::Vector2f& point1, const sf::Vector2f& point2, const sf::Color& color = sf::Color::Yellow):
|
|
color(color), thickness(5.f)
|
|
{
|
|
sf::Vector2f direction = point2 - point1;
|
|
sf::Vector2f unitDirection = direction/std::sqrt(direction.x*direction.x+direction.y*direction.y);
|
|
sf::Vector2f unitPerpendicular(-unitDirection.y,unitDirection.x);
|
|
|
|
sf::Vector2f offset = (thickness/2.f)*unitPerpendicular;
|
|
|
|
vertices[0].position = point1 + offset;
|
|
vertices[1].position = point2 + offset;
|
|
vertices[2].position = point2 - offset;
|
|
vertices[3].position = point1 - offset;
|
|
|
|
for (int i=0; i<4; ++i)
|
|
vertices[i].color = color;
|
|
}
|
|
|
|
void draw(sf::RenderTarget &target, sf::RenderStates states) const
|
|
{
|
|
target.draw(vertices,4,sf::Quads);
|
|
}
|
|
|
|
|
|
private:
|
|
sf::Vertex vertices[4];
|
|
float thickness;
|
|
sf::Color color;
|
|
};
|
|
|
|
sf::Color interpolateColors(const sf::Color& c1, const sf::Color& c2, float t) {
|
|
auto r = static_cast<sf::Uint8>((1 - t) * c1.r + t * c2.r);
|
|
auto g = static_cast<sf::Uint8>((1 - t) * c1.g + t * c2.g);
|
|
auto b = static_cast<sf::Uint8>((1 - t) * c1.b + t * c2.b);
|
|
return {r, g, b};
|
|
}
|
|
|
|
void lineTo(sf::RenderTexture& render_texture, int x1, int y1, int x2, int y2, const sf::Color& color) {
|
|
sfLine line(sf::Vector2f(x1, y1), sf::Vector2f(x2, y2), color);
|
|
render_texture.draw(line);
|
|
}
|
|
|
|
void drawGridLinesToTexture(sf::RenderTexture& render_texture, const Grid& grid, int cell_size) {
|
|
const auto wall = sf::Color::Black;
|
|
for (auto& cell : grid) {
|
|
auto x1 = cell.getCol() * cell_size;
|
|
auto y1 = cell.getRow() * cell_size;
|
|
auto x2 = (cell.getCol() + 1) * cell_size;
|
|
auto y2 = (cell.getRow() + 1) * cell_size;
|
|
if (!cell.hasNorth()) {
|
|
lineTo(render_texture, x1, y1, x2, y1, wall);
|
|
}
|
|
if (!cell.hasWest()) {
|
|
lineTo(render_texture, x1, y1, x1, y2, wall);
|
|
}
|
|
if (!cell.isLinked(cell.east)) {
|
|
lineTo(render_texture, x2, y1, x2, y2, wall);
|
|
}
|
|
if (!cell.isLinked(cell.south)) {
|
|
lineTo(render_texture, x1, y2, x2, y2, wall);
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawDistanceGridBackgroundsToTexture(sf::RenderTexture& render_texture, const DistanceGrid& grid, int cell_size) {
|
|
const auto start = sf::Color::Blue;
|
|
const auto goal = sf::Color::Red;
|
|
for (auto& cell : grid) {
|
|
auto x1 = cell.getCol() * cell_size;
|
|
auto y1 = cell.getRow() * cell_size;
|
|
auto x2 = (cell.getCol() + 1) * cell_size;
|
|
auto y2 = (cell.getRow() + 1) * cell_size;
|
|
|
|
sf::Color color = interpolateColors(start, goal, grid.intensityAt(cell));
|
|
sf::RectangleShape rectangle(sf::Vector2f(cell_size, cell_size));
|
|
rectangle.setPosition(x1, y1);
|
|
rectangle.setFillColor(color);
|
|
render_texture.draw(rectangle);
|
|
}
|
|
}
|
|
|
|
void drawMaskedGridBackgroundsToTexture(sf::RenderTexture& render_texture, const MaskedGrid& grid, int cell_size) {
|
|
const auto disabled = sf::Color::Black;
|
|
for (auto& cell : grid) {
|
|
if (!grid.isCellEnabled(cell)) {
|
|
auto x1 = cell.getCol() * cell_size;
|
|
auto y1 = cell.getRow() * cell_size;
|
|
sf::RectangleShape rectangle(sf::Vector2f(cell_size, cell_size));
|
|
rectangle.setPosition(x1, y1);
|
|
rectangle.setFillColor(disabled);
|
|
render_texture.draw(rectangle);
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawGridToTexture(sf::RenderTexture& render_texture, const MaskedGrid& grid, int cell_size) {
|
|
const auto width = grid.getCols() * cell_size;
|
|
const auto height = grid.getRows() * cell_size;
|
|
if (!render_texture.create(width, height)) {
|
|
throw std::runtime_error("Failed to create render texture");
|
|
}
|
|
|
|
auto background = sf::Color::White;
|
|
render_texture.clear(background);
|
|
drawGridLinesToTexture(render_texture, grid, cell_size);
|
|
drawMaskedGridBackgroundsToTexture(render_texture, grid, cell_size);
|
|
render_texture.display();
|
|
}
|
|
|
|
void drawGridToTexture(sf::RenderTexture& render_texture, const DistanceGrid& grid, int cell_size) {
|
|
const auto width = grid.getCols() * cell_size;
|
|
const auto height = grid.getRows() * cell_size;
|
|
if (!render_texture.create(width, height)) {
|
|
throw std::runtime_error("Failed to create render texture");
|
|
}
|
|
|
|
auto background = sf::Color::White;
|
|
render_texture.clear(background);
|
|
drawDistanceGridBackgroundsToTexture(render_texture, grid, cell_size);
|
|
drawGridLinesToTexture(render_texture, grid, cell_size);
|
|
render_texture.display();
|
|
}
|
|
|
|
void drawGridToTexture(sf::RenderTexture& render_texture, const Grid& grid, int cell_size) {
|
|
const auto width = grid.getCols() * cell_size;
|
|
const auto height = grid.getRows() * cell_size;
|
|
if (!render_texture.create(width, height)) {
|
|
throw std::runtime_error("Failed to create render texture");
|
|
}
|
|
|
|
auto background = sf::Color::White;
|
|
render_texture.clear(background);
|
|
drawGridLinesToTexture(render_texture, grid, cell_size);
|
|
render_texture.display();
|
|
}
|
|
}
|
|
} |