I recently moved my GUI related code to a seperate DLL, this lead to some interesting problems of things requiring certain circumstances to render.
I'm not really sure how to provide a minimal compilable example in this case but I'll show what I think will be the most helpful.
I'm planning to put this code up on Github in the future when these problems are gone.
Before I moved the code to a seperate DLL, it was in the same project as the main EXE and everything worked fine.Here's a minimal working example of what creates the problem.
/*
Stuff has really weird problems rendering, GUI cannot render if "test" is set to false at initialization for example
GUI also cannot render if there isn't something below it, e.g if you draw shape and test is set to true
*/
#include <iostream>
#include <SFML/Graphics.hpp>
#include "SFML/System/Clock.hpp"
#include "GuiContext.h"
int main(int argc, char* argv[])
{
sf::RenderWindow window(sf::VideoMode(1280, 720), "SFML works!");
window.setFramerateLimit(125);
CGuiContext GUI;
GUI.Init(&window);
Panel::Ptr panel1(new Panel());
panel1->SetBounds(sf::Vector2i(200, 200));
panel1->SetTitle(L"test");
panel1->Move(20, 20);
GUI.AddPanel(panel1);
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Clock clock;
bool test = true;
while (window.isOpen())
{
sf::Time time = clock.restart();
float timeinseconds = time.asSeconds();
if (timeinseconds > 0.15f)
{
std::cout << timeinseconds << std::endl;
continue;
}
GUI.Update(timeinseconds);
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
{
window.close();
break;
}
case sf::Event::KeyPressed:
{
if (event.key.code == sf::Keyboard::Key::Escape)
{
window.close();
}
test = !test;
break;
}
}
GUI.HandleEvent(event);
}
window.clear();
if (test)
{
window.draw(shape);
}
window.draw(GUI);
window.display();
}
return 0;
}
window.draw(GUI) Calls this code which is in my DLL:
void CGuiContext::draw( sf::RenderTarget& target, sf::RenderStates states ) const
{
for (auto s = Panels.rbegin(); s != Panels.rend(); ++s)
{
auto panel = (*s);
if (panel)
{
if (panel->ShouldDraw)
{
panel->DrawAll(target);
}
}
}
}
Here's the definition of DrawAll which is also in the DLL:
void CBaseGUIControl::DrawAll( sf::RenderTarget& target ) const
{
target.draw(*this);
for (auto& cl : Children)
{
if (cl->ShouldDraw)
{
target.draw(*cl);
cl->DrawAll(target);
}
}
}
The declaration of CBaseGUIControl is as follows:
class CRASHGUI_API CBaseGUIControl : public sf::Drawable, public sf::Transformable
My main thought was it being a problem with OpenGL context, but as seen in the first example above it seems to follow some weird pattern. The window is created in the EXE main thread.
Here's a screenshot of what the code example above produces (
test being set to true at initialization):
Pressing any key will toggle the circle.
Here's what happens if
test is set to false at initialization (nothing will render):
Pressing any key will not do anything at all, trying to draw the circle above GUI will also produce the above screenshot.
I apologize for not having a compilable example but I feel like this is a bit specialized and bringing up all the required files would be too much.
I'm on Windows 7 with a AMD Radeon 5770 with the latest drivers.
(only including because someone would probably ask for it)Also using Visual Studio 2012 with SFML 2.1.
Thanks!