B
B
bongerka2020-06-14 11:16:55
C++ / C#
bongerka, 2020-06-14 11:16:55

What to do if graphics are not being rendered in a separate SFML thread?

The problem is that my objects slow down over time, so I decided to do the rendering in a separate thread. (Also thought about shaders, don't know which is better). the function is called at the bottom of the attached code, If called without a thread everything compiles fine, if I add a thread there is no rendering and an error is spammed to the console:
Failed to activate the window's context
Failed to activate OpenGL context:

Thanks in advance for any response, I am new to SFML.

#include <iostream>
#include <SFML/Graphics.hpp>
#include <time.h>
#include <random>
#include "Food.h"
#include "Cell.h"
#include "World.h"
using namespace std;
sf::Mutex mutex;
int
height = 900,//Высота окна
width = 1800,//Ширина окна
cell_size = 6,//Размер клеток
cell_types_limit = 1000,//Лимит клеток
food_limit = 2000;//Лимит еды
 
sf::VertexArray dot(sf::Quads, 4);
sf::VertexArray bg(sf::Quads, 4);
sf::VertexArray vertex_render(sf::Points, food_limit);
 
// define the position of the triangle's points
 
double
food_rate = 0.0001;//Период появления еды
 
bool
render_food = 1,
render_cells = 1;
 
sf::RenderWindow window(sf::VideoMode(width, height), "SFML");
World world(&width, &height, &food_rate, &cell_types_limit, &food_limit);
 
// Конвертирует тип int в string
string toString(int n)
{
    char buf[40];
    sprintf_s(buf, "%d", n);
    return buf;
};
 
 
void drawing() {
    bg[0].position = sf::Vector2f(0.f, 0.f);
    bg[1].position = sf::Vector2f(1800.f, 0.f);
    bg[2].position = sf::Vector2f(1800.f, 900.f);
    bg[3].position = sf::Vector2f(0.f, 900.f);
 
    // define the color of the triangle's points
    bg[0].color = sf::Color::White;
    bg[1].color = sf::Color::White;
    bg[2].color = sf::Color::White;
    bg[3].color = sf::Color::White;
    window.clear();
    //mutex.lock();
    if (render_cells or render_food) {
        window.draw(bg);
    }
 
 
    //Отрисовка еды
    if (render_food) {
        for (int r = 0; r < 4; r++) {
            for (int i = 0; i < world.food_count; i++) {
                vertex_render[i].color = sf::Color::Black;
                vertex_render[i].position = sf::Vector2f(world.food[i].x + r / 2, world.food[i].y + r % 2);
            }
            window.draw(vertex_render);
        }
    }
    //отрисовка клеток
    if (render_cells) {
        for (int i = 0; i < world.cell_types; i++) {
            dot[0].color = sf::Color(world.cells[i].r, world.cells[i].g, world.cells[i].b, 255);
            dot[1].color = sf::Color(world.cells[i].r, world.cells[i].g, world.cells[i].b, 255);
            dot[2].color = sf::Color(world.cells[i].r, world.cells[i].g, world.cells[i].b, 255);
            dot[3].color = sf::Color(world.cells[i].r, world.cells[i].g, world.cells[i].b, 255);
            //dot.setFillColor(sf::Color(world.cells[i].r, world.cells[i].g, world.cells[i].b, 255));
            for (int j = 0; j < world.cells[i].cells_count; j++) {
                if (world.cells[i].units[j].x != -1) {
                    dot[0].position = sf::Vector2f(world.cells[i].units[j].x, world.cells[i].units[j].y);
                    dot[1].position = sf::Vector2f(world.cells[i].units[j].x + cell_size, world.cells[i].units[j].y);
                    dot[2].position = sf::Vector2f(world.cells[i].units[j].x + cell_size, world.cells[i].units[j].y + cell_size);
                    dot[3].position = sf::Vector2f(world.cells[i].units[j].x, world.cells[i].units[j].y + cell_size);
                    //dot.setPosition(sf::Vector2f(world.cells[i].units[j].x, world.cells[i].units[j].y));
                    window.draw(dot);
                }
                else break;
            }
        }
    }
    window.setActive(false);
    //mutex.unlock();
    //sf::sleep(sf::milliseconds(1));
 
}
 
 
int main() {
    //Инициализация элементов
    sf::Font font;
    string ttt = "jdjd";
    font.loadFromFile("GADUGI.TTF");
 
 
 
    sf::Clock clock;
    
    
    float timer = 0;
 
    std::srand(std::time(nullptr));
 
    //Инициализация мирa
    //Основной цикл
    while (window.isOpen()) {
        sf::Event e;
        while (window.pollEvent(e)) {
            if (e.type == sf::Event::Closed) {
                window.close();
            }
 
            if (e.type == sf::Event::KeyReleased) {
                if (e.key.code == sf::Keyboard::Enter) render_food = !render_food;
                else if (e.key.code == sf::Keyboard::RShift) render_cells = !render_cells;
                else if (e.key.code == sf::Keyboard::Down and cell_size > 1) cell_size--;
                else if (e.key.code == sf::Keyboard::Up) cell_size++;
            }
        }
 
        float dt = clock.restart().asSeconds();
        timer += dt;
        char buff[64];
 
        //Запуск тика симуляции
        world.simulate_tick(dt);
    
        //drawing();       // обычное обращение к функции с отрисовкой
        sf::Thread thread(&drawing); 
        thread.launch();  // запуск потока
        
        //FPS
        
        window.display();
    }
 
    return 0;
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question