Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Fx8qkaoy

Pages: [1]
1
Window / How to recreate the window when using SFML ImGui?
« on: February 11, 2020, 07:46:40 pm »
I want to add to my game the functionality to change window stuff, and in this example I will refer to resolution. I did it some months / years ago, but now I'm failing. Below is some code to understand what I'm doing. Comments before each block exaplains where the calls happen

Code: [Select]
// Beginning of main()
scene::window = new sf::RenderWindow(sf::VideoMode(1600, 900), "Test");
scene::view = new sf::View(scene::window->getView());
scene::view->setSize(sf::Vector2f(scene::size.x, scene::size.y)); // Pixel-art game, so I want bigger units (size.x < 1600)

// In a network thread
void setPos(float x) {
player->sprite->setPosition(x, scene::band * 1.5f);
scene::view->setCenter(x, 0);
scene::window->setView(*scene::view); // All of these makes the camera follow the local player; also is the first one who sets a custom sf::View on the window
}

// After handling window events, clearing the screen, drawing SFML related stuff, but before drawing (ImGUI is a lib that handles button clicks at the same time with drawing, and I draw ImGui stuff after all my sprites); happens on a click
scene::window->create(sf::VideoMode(900, 900), "Test");

The usage of network *thread* doesn't seem to have negative impact, since before pressing everything works right. What happens: after the last block is ran, the window is recreated with the right resolution, but everything is black. I tried resetting the view:

Code: [Select]
scene::window->create(sf::VideoMode(900, 900), "Test");
scene::view = new sf::View(scene::window->getView());
scene::view->setSize(sf::Vector2f(scene::size.x, scene::size.y));
scene::window->setView(*scene::view); // I assure that at (0, 0) is stuff drawn

I tried recreatting a sprite with its texture:

Code: [Select]
scene::window->create(sf::VideoMode(900, 900), "Test");
scene::view = new sf::View(scene::window->getView());
scene::view->setSize(sf::Vector2f(scene::size.x, scene::size.y));
scene::window->setView(*scene::view);

// The block is copied from the initial generation, only the final instruction is changed from push_back() to modifying the original one, so I can assure there's no problems with loading it
auto bgTex = new sf::Texture;
bgTex->loadFromFile("texs/bg.png");
auto bg = new sf::Sprite(*bgTex);
bg->setPosition(sf::Vector2f(-scene::size.x / 2.f, -scene::size.y / 2.f));
scene::metal[0] = bg; // The background is supposed to take the whole screen on (1600, 900)

The same result. If it helps, ImGui actually still works like nothing happened, it's just on top of a black screen. Everything is up to date, running on VS2019, SFML_STATIC. I have another SFML instance in the system background since the server uses its network capabilities (no window)

2
General / How to approach multiple windows over multiple threads
« on: February 01, 2020, 05:28:58 pm »
To be honest, I work right now on a cheat for a specific game. I have to use threads as I need to perform different instructions at regular time intervals and I also don't want to block the main thread. While some of them are just for computation (such as a console, fetching game data, etc) I also have some that should handle different windows. As example: I need to make a thread which creates a window that will draw a radar. I managed it to open, but not to close, which means it works partially. Below is a resume of the part that involves SFML:

Code: [Select]
void modifyRadar() {
if (radarActive) {
radarWindow = new sf::RenderWindow(sf::VideoMode(200, 200), "", sf::Style::None);
radarWindow->setFramerateLimit(fps);
radarDrawThread = new std::thread([&]() {
while (radarWindow->isOpen()) {
radarWindow->clear();
for (auto circle : radar)
if (circle->getPosition().x != -99999)
radarWindow->draw(*circle);
radarWindow->display();
}
delete radarWindow;
radarWindow = 0;
});
return;
}
radarWindow->close();
radarDrawThread->join();
delete radarDrawThread;
}

All the variable are available in the outer scope. I did read posts about what I want to do and tried changes such as:

Code: [Select]
radarDrawThread = new std::thread([&]() {
sf::Context context;
radarWindow->setActive();
while (radarWindow->isOpen()) {
radarWindow->clear();
for (auto circle : radar)

In the first example, this is what stdout shows:

Code: [Select]
...

An internal OpenGL call failed in RenderTarget.cpp(152).
Expression:
   glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

An internal OpenGL call failed in RenderTarget.cpp(153).
Expression:
   glClear(GL_COLOR_BUFFER_BIT)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

An internal OpenGL call failed in Texture.cpp(782).
Expression:
   glBindTexture(GL_TEXTURE_2D, 0)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

...

The functions in the while loop are not hit anymore since the window has closed (expected behavior). When I use the example with sf::Context, when the sf::Context object has to destruct itself an exception is thrown:

Code: [Select]
Exception thrown: read access violation.
this-> was 0xFFFFFFFFFFFFFFE7.

I do realize that there may be better options for the thing I want to do, especially that I didn't shown the full code due to its size, and while I appreciate very much the opinions, I would like to know how to render different windows in different threads at least for knowledge. I tried different combinations of the sf::Context, setActive(), and the order the windows are created. Before the exception is thrown, this is what stdout has:

Code: [Select]
Failed to activate OpenGL context: The operation completed successfully.

From what I understand: to draw multiple windows u can use the default sf::Context and use setActive() to manage where the OpenGL calls go, or use multiple sf::Context and no need for setActive() since every window has its context. I also seen that setActive() shall be called also when I render a specific window in another thread rather than where it was made

Pages: [1]