Hello,
So I'm messing with another concept, threads. I was trying to follow the SFML tutorial on threads, but it's not doing what I thought it would. I have no experience dealing with threads and just know roughly what Mutex and a Thread are.
I have this demo of a 500x500 tilemap of rectangles. And my original concept was finding ways to do tile culling. I solved, but I still get the white window until it loads everything up, then it runs perfectly. So I thought this would be a good time to try out threads and see if I can display a "Loading" sf::Text until it has gathered all the sprites up.
Also, I tried to use std::bind when initializing the thread, but it doesn't work because it is a deleted function. I'm using msvc19. But I got it to work with a lambda, but the results were the same. I put a comment giving the error when I try the std::bind and when I use the lambda. I
/*Failed to activate the window's context Failed to activate OpenGL context: The requested resource is in use.*/
So I'm assuming it obviously is trying to access data that's being used? ...Right
? Any help would be appreciated, have a nice day!
#include <SFML/Graphics.hpp>
#include <iostream>
#include <functional>
sf::Vector2u WINDOW_SIZE{1400,900};
constexpr unsigned TPS = 60; //ticks per seconds
const sf::Time timePerUpdate = sf::seconds(1.0f / float(TPS));
sf::Vector2f TILE_SIZE{64.f,64.f};
struct Tile
{
sf::RectangleShape spr;
};
void loadingText(sf::RenderWindow& window, sf::Font& font, const std::string& text) {
sf::Text loadText{ text,font,25 };
loadText.setPosition((float)window.getSize().x / 2.f, (float)window.getSize().y / 2.f);
loadText.setFillColor(sf::Color{ 88,225,0 });
loadText.setOutlineThickness(1.f);
loadText.setStyle(sf::Text::Style::Underlined | sf::Text::Style::Bold);
window.draw(loadText);
}
int main() {
sf::RenderWindow window{ sf::VideoMode{WINDOW_SIZE.x,WINDOW_SIZE.y},"" };
// window.setFramerateLimit(60);
window.setPosition(sf::Vector2i{ window.getPosition().x,0 });
bool lostFocus = false;
sf::Clock clock;
auto lastTime = sf::Time::Zero;
auto lag = sf::Time::Zero;
auto dt = 0.f;
unsigned ticks = 0;
auto view = window.getDefaultView();
sf::Font font;
if (!font.loadFromFile("fonts/arial.ttf"))
std::cout << "Failed to load arial.ttf\n";
sf::Thread thread([&]() {
loadingText(window, font, "Loading");
});
/*Failed to activate the window's context Failed to activate OpenGL context: The requested resource is in use.*/
thread.launch();
//***sf::Thread thread(std::bind(&loadingText, window, font, "Loading...")); *** (Doesn't Work)
/*Severity Code Description Project File Line Suppression State
Error C2280 'std::_Binder<std::_Unforced,void (__cdecl *)(sf::RenderWindow &,sf::Font &,
const std::string &),
sf::RenderWindow &,sf::Font &,
const char (&)[11]>::_Binder(const std::_Binder<std::_Unforced,void (__cdecl *)(sf::RenderWindow &,
sf::Font &,
const std::string &),
sf::RenderWindow &,sf::Font &,
const char (&)[11]> &)'
: attempting to reference a deleted function E:\Libaries\SFML\include\SFML\System\Thread.inl 70
*/
constexpr int Map_Width = 500;
constexpr int Map_Height = 500;
std::vector<Tile> tiles;
sf::RectangleShape camera{ TILE_SIZE };
camera.setFillColor({ 255,255,255,100 });
camera.setOutlineThickness(1.f);
camera.setOutlineColor(sf::Color::White);
for(auto y = 0; y < Map_Height; ++y)
for (auto x = 0; x < Map_Width; ++x) {
auto tile = new Tile;
tile->spr.setSize(TILE_SIZE);
tile->spr.setFillColor({ 0,255,0,15 });
tile->spr.setOutlineColor(sf::Color::White);
tile->spr.setOutlineThickness(1.f);
tile->spr.setPosition(x * TILE_SIZE.x, y * TILE_SIZE.y);
if (y >= 240 && y <= 260 && x >= 240 && y <= 260)
tile->spr.setFillColor({ 200,25,22 });
tiles.emplace_back(*tile);
}
view.setCenter(Map_Width / 2.f * TILE_SIZE.x, Map_Height / 2.f * TILE_SIZE.y);
while (window.isOpen()) {
auto time = clock.getElapsedTime();
auto elapsed = time - lastTime;
lastTime = time;
lag += elapsed;
//Fixed time update
while (lag >= timePerUpdate)
{
ticks++;
lag -= timePerUpdate;
//x fixedUpdate(elapsed);
}
sf::Event event{};
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed ||
event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
window.close();
if (event.type == sf::Event::KeyPressed) {
switch (event.key.code) {
case sf::Keyboard::Enter: std::cout << "Enter Pressed\n"; break;
case sf::Keyboard::Space: std::cout << "Space Pressed\n"; break;
default: break;
}
}
if (event.type == sf::Event::Resized) {
// update the view to the new size of the window
view.setSize(static_cast<float>(event.size.width),
static_cast<float>(event.size.height));
}
if (event.type == sf::Event::LostFocus) { lostFocus = true; }
if (event.type == sf::Event::GainedFocus) { lostFocus = false; }
}
if (!lostFocus) {
auto mousePos = sf::Mouse::getPosition(window);
auto mouseWorldPos = window.mapPixelToCoords(mousePos, view);
window.setTitle("Mouse Position: (" + std::to_string(int(mouseWorldPos.x / 64.f)) + ", " +
std::to_string(int(mouseWorldPos.y / 64.f)) + ")");
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
if (mouseWorldPos.x >= 0 && mouseWorldPos.y >= 0 &&
mouseWorldPos.x < WINDOW_SIZE.x &&
mouseWorldPos.y < WINDOW_SIZE.y) {
}
}
//! ** INPUT SECTION **
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
view.move(0, -100 * elapsed.asSeconds());
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
view.move( -100 * elapsed.asSeconds(),0);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
view.move(0, 100 * elapsed.asSeconds());
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
view.move(100 * elapsed.asSeconds(), 0);
}
//! ** UPDATE SECTION**
window.setView(view);
}
//! ** DRAW SECTION **
window.clear();
camera.setPosition(view.getCenter());
int cam_posX = camera.getPosition().x;
int cam_posY = camera.getPosition().y;
cam_posX /= TILE_SIZE.x;
cam_posY /= TILE_SIZE.y;
int minMaxWidth = 12;
int minMaxHeight = 12;
//std::cout << "Camera: " << camera.getPosition().x << ", " << camera.getPosition().y << "\n";
//std::cout << "View: " << view.getCenter().x << ", " << view.getCenter().y << "\n";
//std::cout << "posX: " << posX << "\n";
//std::cout << "posY: " << posY << "\n";
for (auto y = cam_posY - minMaxHeight < 0 ? 0 : cam_posY - minMaxHeight;
y <= cam_posY + minMaxHeight && y < WINDOW_SIZE.y; y++) {
for (auto x = cam_posX - minMaxWidth < 0 ? 0 : cam_posX - minMaxWidth;
x <= cam_posX + minMaxWidth && x < WINDOW_SIZE.x; x++) {
window.draw(tiles[y * Map_Width + x].spr);
}
}
window.draw(camera);
window.setView(window.getDefaultView());
window.display();
}
return EXIT_SUCCESS;
}