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

Author Topic: Problem with a Drawable splash to draw to window [SOLVED]  (Read 1959 times)

0 Members and 1 Guest are viewing this topic.

ralligood2

  • Newbie
  • *
  • Posts: 6
    • View Profile
Problem with a Drawable splash to draw to window [SOLVED]
« on: July 03, 2015, 11:34:56 pm »
Hi everyone, hopefully this is the right area for this post.
Could someone take a look at my code and see why the splash will not show in the window? I'm not getting any errors, it just won't show in the window. I've read the example from the docs, some other problems like what I'm trying to do but I'm stilling having some problems. Thanks for any help.

Code from splash.h
#ifndef SPLASH_H
#define SPLASH_H

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>

class Splash : public sf::Drawable
{
   
    private :

    sf::Sprite m_sprite;

        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
            target.draw(m_sprite, states);
        }

    public:
        Splash();
};

Splash::Splash()
{
    std::cout << "Entered default constructor" << std::endl;
    sf::Texture m_texture;
        m_texture.loadFromFile("resources/Splash.png");
    sf::RectangleShape m_rectangleShape;
        m_rectangleShape.setTexture(&m_texture);
    sf::Sprite m_sprite(m_texture);
        m_sprite.setTextureRect(sf::IntRect(0, 0, 300, 300));
        m_sprite.setPosition(0,0);
}
#endif
 

Code from main.cpp

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include "splash.h"

int main()
{
    Splash loadSplash;
    sf::ContextSettings contextSettings;
    contextSettings.depthBits = 24;
    int screenX = sf::VideoMode::getDesktopMode().width;
    int screenY = sf::VideoMode::getDesktopMode().height;

    sf::RenderWindow mainWin(sf::VideoMode(screenX/2, screenY), "BusbySoft", sf::Style::Default, contextSettings);
    mainWin.setVerticalSyncEnabled(true);
    mainWin.setPosition(sf::Vector2i(0, 0));
       
    while (mainWin.isOpen())
    {
        sf::Event event;  
 
        while (mainWin.pollEvent(event))
        {

            // Close window: exit
            if (event.type == sf::Event::Closed)
                mainWin.close();

            // Escape key: exit
            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
                mainWin.close();
            if(event.type == sf::Event::MouseMoved)
            {
                std::cout << "x=" << event.mouseMove.x << ", y=" << event.mouseMove.y << std::endl;
            }
        }

        // Clear the depth buffer
        glClear(GL_DEPTH_BUFFER_BIT);
       
        //mainWin.clear(sf::Color(35,44,69,255));
        mainWin.draw(loadSplash);

        // Finally, display the rendered frame on screen
        mainWin.display();
    }

    return EXIT_SUCCESS;
}

 
« Last Edit: July 04, 2015, 09:13:22 pm by ralligood2 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Problem with a Drawable splash to draw to window
« Reply #1 on: July 03, 2015, 11:49:05 pm »
Splash::Splash()
{
    sf::Texture m_texture; // Create texture
    sf::Sprite m_sprite(m_texture); // Create sprite and pass texture by reference
} // Delete texture and sprite

You might want to get your good C++ book again and read up on how class instances get created, how constructor initialization list works and how member variable are set, because you're create a whole new m_sprite within the constructor, but you never use the member variable which has the same name.
And then you don't keep the texture alive while you use it. So even if you set the texture of the member sprite, by the time the constructor is left, the texture will get destroyed and with it the whole image information is gone. ;)

I can also highly recommend the official tutorials which tackles the texture issue and many other useful things.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ralligood2

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Problem with a Drawable splash to draw to window
« Reply #2 on: July 04, 2015, 09:06:46 pm »
Thank you eXpl0it3r for all the comments about my code. :) They really helped me correct my code and got it working. I'm just getting my hands wet on programming with graphics. I'm still in school and next semester is my first OOP class which will cover most of the items you listed in your comments. Since I'm a nice person and there isn't much resources on the web that gives full code on creating a drawable class in a .h file and the main.cpp file. I'll share the full code in hopes that someone else will find it useful. This code does work and was compiled and tested running Arch Linux.

FILE: splash.h
#ifndef SPLASH_H
#define SPLASH_H

#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>

class Splash : public sf::Drawable
{
   
    private:
        sf::Sprite m_sprite;
        sf::Texture m_texture;
        sf::RectangleShape m_rectangleShape;
        int screenX;
        int screenY;
        float winX;
        float winY;

            virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
            {
                target.draw(m_sprite, states);
            }
    public:
        Splash();
        void loadTexture();
        sf::Sprite setSprite();
};

Splash::Splash()
{
        screenX = sf::VideoMode::getDesktopMode().width;
        screenY = sf::VideoMode::getDesktopMode().height;
        winX = 800;
        winY = 600;
}

void Splash::loadTexture()
{
    if (!m_texture.loadFromFile("resources/Splash.png", sf::IntRect(0, 0, winX, winY)))
    {
        std::cout << "Could not load texture." << std::endl;
    }
}

sf::Sprite Splash::setSprite()
{
    std::cout << "setSprite Member Function was called" << std::endl;
    m_sprite.setTexture(m_texture);
    m_sprite.setPosition(((screenX/2)-winX)/2, (screenY-winY)/2);
return m_sprite;
}

#endif
 

FILE: main.cpp

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include "splash.h"

int main()
{
    Splash loadSplash;
        loadSplash.loadTexture();
     
        sf::Sprite mySprite;
            mySprite = loadSplash.setSprite();

    sf::ContextSettings contextSettings;
    contextSettings.depthBits = 24;
    int screenX = sf::VideoMode::getDesktopMode().width;
    int screenY = sf::VideoMode::getDesktopMode().height;

    sf::RenderWindow mainWin(sf::VideoMode(screenX/2, screenY), "Main Window", sf::Style::Default, contextSettings);
    mainWin.setVerticalSyncEnabled(true);
    mainWin.setPosition(sf::Vector2i(0, 0));    

    while (mainWin.isOpen())
    {
        sf::Event event;  
 
        while (mainWin.pollEvent(event))
        {

            // Close window: exit
            if (event.type == sf::Event::Closed)
                mainWin.close();

            // Escape key: exit
            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
                mainWin.close();
            if(event.type == sf::Event::MouseMoved)
            {
                std::cout << "x=" << event.mouseMove.x << ", y=" << event.mouseMove.y << std::endl;
            }
        }

        // Clear the depth buffer
        glClear(GL_DEPTH_BUFFER_BIT);
       
        mainWin.clear(sf::Color(35,44,69,255));
        mainWin.draw(mySprite);

        // Finally, display the rendered frame on screen
        mainWin.display();
    }

    return 0;
}
 

« Last Edit: July 04, 2015, 09:13:08 pm by ralligood2 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Problem with a Drawable splash to draw to window
« Reply #3 on: July 04, 2015, 10:45:44 pm »
Since you're in for learning things, here's how I would refactor the posted code:

Splash.hpp
#ifndef SPLASH_HPP
#define SPLASH_HPP

#include <SFML/Graphics.hpp>
#include <iostream>

class Splash : public sf::Drawable
{
public:
    Splash();
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
   
private:
    sf::Sprite m_sprite;
    sf::Texture m_texture;
    sf::Vector2u m_screenSize;
    sf::Vector2u m_windowSize;
};

#endif // SPLASH_HPP
 

Spalsh.cpp
#include "Splash.hpp"

Splash::Splash()
: m_sprite(m_texture)
, m_screenSize(sf::VideoMode::getDesktopMode().width, sf::VideoMode::getDesktopMode().height)
, m_windowSize(800, 600)
{
    m_sprite.setPosition(((m_screenSize.x / 2.f) - m_windowSize.x) / 2.f, (m_screenSize.y - m_windowSize.y) / 2.f);
   
    if (!m_texture.loadFromFile("resources/Splash.png", sf::IntRect(0, 0, m_windowSize.x, m_windowSize.y)))
    {
        std::cout << "Could not load texture." << std::endl;
    }
}

void Splash::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    target.draw(m_sprite, states);
}
 

main.cpp

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include "Splash.hpp"

int main()
{
    Splash splash;

    sf::ContextSettings contextSettings;
    contextSettings.depthBits = 24;
    sf::Vector2u screenSize(sf::VideoMode::getDesktopMode().width, sf::VideoMode::getDesktopMode().height);

    sf::RenderWindow mainWin(sf::VideoMode(screenSize.x / 2.f, screenSize.y), "Main Window", sf::Style::Default, contextSettings);
    mainWin.setVerticalSyncEnabled(true);
    mainWin.setPosition(sf::Vector2i(0, 0));    

    while (mainWin.isOpen())
    {
        sf::Event event;  
 
        while (mainWin.pollEvent(event))
        {
            // Close window: exit
            if (event.type == sf::Event::Closed)
                mainWin.close();

            // Escape key: exit
            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
                mainWin.close();
               
            if(event.type == sf::Event::MouseMoved)
                std::cout << "x=" << event.mouseMove.x << ", y=" << event.mouseMove.y << std::endl;
        }

        // Clear the depth buffer
        glClear(GL_DEPTH_BUFFER_BIT);
       
        mainWin.clear(sf::Color(35,44,69,255));
        mainWin.draw(splash);

        // Finally, display the rendered frame on screen
        mainWin.display();
    }
}
 

Here a few comments on what I changed:

  • Splash is a draw able, don't "extract" a sprite and draw that, but draw the Splash object directly.
  • When you deal with two "connected" numbers, use a vector for them and pick the right type.
  • Make use of a header and source file.
  • Use the class' initialization list to initialize member variables.
  • Use the constructor to directly load the texture and set the sprite's position

One thing I don't understand is your OpenGL code to clear the depth buffer. What's that for?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ralligood2

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Problem with a Drawable splash to draw to window [SOLVED]
« Reply #4 on: July 04, 2015, 11:25:58 pm »
That is some old code that I was playing around before all this. I've deleted that code already after posting the last posting. Thanks for the comments, I'll surely take a look at what you changed.

ralligood2

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Problem with a Drawable splash to draw to window [SOLVED]
« Reply #5 on: July 05, 2015, 05:57:46 am »
Ok so I created the files and tried to compile and during linking I got some errors.

main.o: In function `main':
main.cpp:(.text+0xb6): undefined reference to `Splash::Splash()'
main.o: In function `Splash::~Splash()':
main.cpp:(.text._ZN6SplashD2Ev[_ZN6SplashD5Ev]+0xe): undefined reference to `vtable for Splash'
collect2: error: ld returned 1 exit status

Here are the commands that I used:
g++ -c main.cpp
g++ main.o -o Main -lsfml-graphics -lsfml-window -lsfml-system -lglut -lGLU -lGL -lXmu -lX11

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: Problem with a Drawable splash to draw to window [SOLVED]
« Reply #6 on: July 05, 2015, 08:00:57 am »
You didn't compile the Splash.cpp.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ralligood2

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Problem with a Drawable splash to draw to window [SOLVED]
« Reply #7 on: July 05, 2015, 05:03:54 pm »
Right that would help. Thanks again. The window is working but the spalsh isn't showing. Any idea?
Thanks

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Problem with a Drawable splash to draw to window [SOLVED]
« Reply #8 on: July 05, 2015, 05:14:13 pm »
I'd blame your math. I just refactored the code, didn't really check the logic. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ralligood2

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Problem with a Drawable splash to draw to window [SOLVED]
« Reply #9 on: July 06, 2015, 02:34:54 am »
I'll admit that my math isn't the best :), but it wasn't my math this time....LOL When you refactored the code you placed the sprite to set the texture before the block of code to loadfromfile, so the constructor was trying to set the texture that wasn't even loaded yet. Once I placed setTexture after that block of code, it appeared. Thanks for your help.