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

Author Topic: Custom App Engine with SFML & ImGUI Not Drawing  (Read 2888 times)

0 Members and 1 Guest are viewing this topic.

TheOnlyWRT

  • Newbie
  • *
  • Posts: 9
    • View Profile
Custom App Engine with SFML & ImGUI Not Drawing
« on: February 27, 2019, 07:18:17 pm »
Hello!

I am building an engine relying on SFML for graphics/text and ImGUI for simple GUI. I have been approaching my engine in a similar way to my 2D Java engine works, as well as grabbing some tools from another tutorial online.

Essentially, there are "screens" which are different states of the game (Menu, GamePlay, etc). The main function houses the default SFML code and a screenManager, which handles all of the drawing and updating for each screen. The program runs fine, except that it does not draw any of the sprites. I get no errors for loading the files, but nothing draws. I assume my approach to drawing is not correct, so included below is the code for the necessary files.

** all ImGUI code is commented out as I am not focused on getting that to work right now **

In the ScreenSplash (a splash screen), i tried to render the sprite, and nothing happens, just a big empty background.

In main.cpp, i made a sf::Sprite test to see if that would draw normally, and it does not. A big white rectangle appears that is the size of the image, so something to do with rendering is not right.

main.cpp:
Quote


#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/Window/Event.hpp>

#include "AppConstants.hpp"
#include "imgui.h"
#include "imgui-SFML.h"
#include "ScreenManager.hpp"
#include "ScreenSplash.hpp"

//screen manager
WRT::ScreenManager screenManager;

int main() {

    sf::RenderWindow window(sf::VideoMode(WINDOW_DIMENSIONS.x, WINDOW_DIMENSIONS.y), WINDOW_TITLE);
    window.setVerticalSyncEnabled(true);
    window.setFramerateLimit(60);
    //ImGui::SFML::Init(window);
   
    // let's use char array as buffer, see next part
    // for instructions on using std::string with ImGui

    //window.resetGLStates(); // call it if you only draw ImGui. Otherwise not needed.
   
    //start the screen manager
    screenManager.PushScreen(new ScreenSplash());
   
    //test sprite
    sf::Sprite test = LoadSprite("splash.png");
   
   
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //main game loop
    sf::Clock clock;
   
    while (window.isOpen()) {
       
        sf::Time elapsed = clock.restart();
        float dt = elapsed.asSeconds();
       
        sf::Event event;
       
        while (window.pollEvent(event)) {
           
            if(screenManager.PeekScreen() == nullptr) continue;
            screenManager.PeekScreen()->HandleInput(event);
           
            //ImGui::SFML::ProcessEvent(event);
           
            if (event.type == sf::Event::Closed) {
               
                while(!screenManager.screens.empty()) screenManager.PopScreen();
                window.close();
               
            }
           
        }
       
        //update all the game data
        //ImGui::SFML::Update(window, clock.restart());
       
        //update the current screen
        if(screenManager.PeekScreen() == nullptr) continue;
        screenManager.PeekScreen()->Update(dt);
 
       
       
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //ImGui::Begin("Sample window"); // begin window
       
        // Window title text edit
        //ImGui::InputText("Window title", windowTitle, 500);
        /*
        if (ImGui::Button("Update window title")) {
            // this code gets if user clicks on the button
            // yes, you could have written if(ImGui::InputText(...))
            // but I do this to show how buttons work :)
            window.setTitle(windowTitle);
           
        }
         */
       
        //ImGui::End(); // end window
        window.clear(GREY_BK_COLOR); // fill background with color
        //ImGui::SFML::Render(window);
        screenManager.PeekScreen()->Draw(window, dt);
        window.draw(test);
        window.display();
       
    }
   
    //ImGui::SFML::Shutdown();
   
    return 0;
   
}


The LoadSprite function:
Quote
sf::Sprite LoadSprite(std::string filename) {
   
    std::string filePath = ResourcePath() + filename;
    sf::Texture tex;
    sf::Sprite sprite;
   
    tex.loadFromFile(filePath);
   
    sprite.setTexture(tex);
   
    return sprite;
   
}

Screen.hpp:
Quote
namespace WRT {
   
    class Screen {
       
    private:
       
       
       
    public:
       
        std::string SCREEN_NAME;
       
        virtual void Load() = 0;
        virtual void Update(const float dt) = 0;
        virtual void HandleInput(sf::Event event) = 0;
        virtual void Draw(sf::RenderWindow& window, const float dt) = 0;
       
    };
   
}

ScreenManager.cpp:
Quote
#include "ScreenManager.hpp"


WRT::ScreenManager::ScreenManager() {
   
   
   
}

WRT::ScreenManager::~ScreenManager() {
   
    while(!this->screens.empty()) PopScreen();
   
}

void WRT::ScreenManager::PushScreen(Screen* screen) {
   
    this->screens.push(screen);
   
    return;
}

void WRT::ScreenManager::PopScreen() {
   
    delete this->screens.top();
    this->screens.pop();
   
    return;
}

void WRT::ScreenManager::ChangeScreen(Screen* screen) {
   
    if(!this->screens.empty())
        PopScreen();
    PushScreen(screen);
   
    return;
}

WRT::Screen* WRT::ScreenManager::PeekScreen() {
   
    if(this->screens.empty()) return nullptr;
    return this->screens.top();
}


and ScreenSplash.cpp:
Quote
#include <SFML/Window/Event.hpp>
#include <iostream>

#include "ScreenSplash.hpp"
#include "ResourcePath.hpp"
#include "AppConstants.hpp"


void ScreenSplash::Load() {
   
    //set up the view
    sf::Vector2f pos = sf::Vector2f(WINDOW_DIMENSIONS);
    this->view.setSize(pos);
    pos *= 0.5f;
    this->view.setCenter(pos);
   
    splash = LoadSprite("splash.png");
   
}

void ScreenSplash::Update(const float dt) {
   
   
   
}

void ScreenSplash::HandleInput(sf::Event event) {
   
   
   
}

void ScreenSplash::Draw(sf::RenderWindow& window, const float dt) {
   
    //prep the view to draw
    window.setView(view);
    window.clear(GREY_BK_COLOR);
   
    //draw
    splash.setScale(float(sf::VideoMode::getDesktopMode().width) / float(splash.getTexture()->getSize().x), float(sf::VideoMode::getDesktopMode().height) / float(splash.getTexture()->getSize().y));
    window.draw(splash);
   
   
}

ScreenSplash::ScreenSplash() {
   
    Load();
   
}

So, sorry it's a lot of code, I'm just not sure where the error lies, and you kinda need all of it to be able to find the error. Thank you so much for your help!

« Last Edit: February 27, 2019, 07:21:23 pm by TheOnlyWRT »

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: Custom App Engine with SFML & ImGUI Not Drawing
« Reply #1 on: February 27, 2019, 10:33:39 pm »

TheOnlyWRT

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Custom App Engine with SFML & ImGUI Not Drawing
« Reply #2 on: February 27, 2019, 11:36:10 pm »
Thank you! That worked great!

Just a quick question, I made a TextureManager class to handle all the textures. Is there a way I can define a TextureManager in main and access it in other screen files?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Custom App Engine with SFML & ImGUI Not Drawing
« Reply #3 on: February 28, 2019, 12:10:15 am »
You can pass a reference to your texture manager to the different screens. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

TheOnlyWRT

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Custom App Engine with SFML & ImGUI Not Drawing
« Reply #4 on: February 28, 2019, 12:32:29 am »
Ok, how would I do that? I am still relatively new to C++, so Im not exactly sure what you mean.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Custom App Engine with SFML & ImGUI Not Drawing
« Reply #5 on: February 28, 2019, 12:48:41 am »
You can add a constructor to your Screen class that takes a reference to the texture manager. For example like this:
Screen(TextureManager& textureManager);

Then you can have the reference as member variable and initialize it in the initialization list, like this for example:
class Screen {
// ...
protected:
    TextureManager& m_textureManager;
};
// ...
Screen::Screen(TextureManager& textureManager)
: m_textureManager(textureManager)
{
}
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

TheOnlyWRT

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Custom App Engine with SFML & ImGUI Not Drawing
« Reply #6 on: February 28, 2019, 01:14:49 am »
ok, here is the screen class:

Quote
class Screen {
       
    private:
       
       
       
    public:
       
        //name
        std::string SCREEN_NAME;
       
        //functions
        virtual void Load() = 0;
        virtual void Update(const float dt) = 0;
        virtual void HandleInput(sf::Event event) = 0;
        virtual void Draw(sf::RenderWindow& window, const float dt) = 0;
       
        Screen(ScreenManager& screenManager);
       
    };

And i get the following error:
Quote
Unknown type name 'ScreenManager'

Why does it not recognize this even though I have included "ScreenManager.hpp"?