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

Author Topic: [SOLVED] Problem rendering after moving GUI to DLL, weird rendering rules(?)  (Read 2161 times)

0 Members and 1 Guest are viewing this topic.

CRASH FORT

  • Newbie
  • *
  • Posts: 5
    • View Profile
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!
« Last Edit: March 30, 2014, 02:39:59 pm by CRASH FORT »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem rendering after moving GUI to DLL, weird rendering rules(?)
« Reply #1 on: March 26, 2014, 04:28:29 pm »
Do you have some global or static SFML objects (textures, windows, OpenGL contexts, ...)? If so, avoid them.

Otherwise it might be possible that some OpenGL states are not set when you render your GUI. How is the GUI rendered? Just with SFML objects?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

CRASH FORT

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Problem rendering after moving GUI to DLL, weird rendering rules(?)
« Reply #2 on: March 26, 2014, 04:33:21 pm »
Do you have some global or static SFML objects (textures, windows, OpenGL contexts, ...)? If so, avoid them.

Otherwise it might be possible that some OpenGL states are not set when you render your GUI. How is the GUI rendered? Just with SFML objects?

No static or global SFML objects.

The GUI only uses SFML objects (sf::Rectangleshape, sf::Text ...).
« Last Edit: March 29, 2014, 05:04:16 pm by CRASH FORT »

CRASH FORT

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Problem rendering after moving GUI to DLL, weird rendering rules(?)
« Reply #3 on: March 29, 2014, 04:55:38 pm »
bump

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem rendering after moving GUI to DLL, weird rendering rules(?)
« Reply #4 on: March 29, 2014, 05:11:04 pm »
Okay, then we need the usual minimal complete example.

Of course, if the error is related to the DLL, then you have one .cpp file with main() and one .hpp/.cpp pair for the library being exported. But get rid of all the specific GUI stuff that's not relevant for the problem.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

CRASH FORT

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Problem rendering after moving GUI to DLL, weird rendering rules(?)
« Reply #5 on: March 29, 2014, 09:17:53 pm »
I think I forgot to mention I'm using SFML statically in both the EXE and DLL.
Anyway, here's everything stripped away:
https://dl.dropboxusercontent.com/u/60585947/GUI%20Problem.rar
It contains 3 files, 1 for the exe and 2 related to the DLL.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Problem rendering after moving GUI to DLL, weird rendering rules(?)
« Reply #6 on: March 30, 2014, 11:37:55 am »
I think I forgot to mention I'm using SFML statically in both the EXE and DLL.
Yes, that's quite an important detail.

Don't do that. You will end up with two separate libraries (one in the executable and one in the DLL) that conflict with each other because of CRT resources. See also here.

The solution is simple: link SFML dynamically.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

CRASH FORT

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Problem rendering after moving GUI to DLL, weird rendering rules(?)
« Reply #7 on: March 30, 2014, 02:39:44 pm »
Solved!
That was the issue, thanks a lot!
Now when I think about it, it makes a lot of sense with two static libraries conflicting with each other, compared to both loading the same SFML DLLs.
« Last Edit: March 30, 2014, 02:43:03 pm by CRASH FORT »

 

anything