Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

SFML 2.0 Gubienie textury po dodaniu Sprite'u do konteneru.

Ostatnio zmodyfikowano 2014-07-15 17:40
Autor Wiadomość
arczi14
Temat założony przez niniejszego użytkownika
SFML 2.0 Gubienie textury po dodaniu Sprite'u do konteneru.
» 2014-07-15 14:44:14
Witam,
Piszę własne GUI pod SFML.
I napotkałem problem z dodawaniem klasy do wektora.
Po dodaniu "Sprajtu" do wektora ten gubi textury wyświetlany jest biały prostokąt.
Znalazłem dużo na ten temat między innymi to żeby zrobić wektor wskaźników na klasę. Tak też zrobiłem lecz efekt pozostaje ten sam.
Coś zrobiłem źle ?
Podaje wam mój jest go na tyle mało że myślę że go ogarniecie.
Z góry dzięki za pomoc.

MAIN:
C/C++
#include <SFML/Graphics.hpp>
#include <iostream>
#include "GUI.h"

/*
    #####
        GUI FOR SFML
    #####
*/

int main()
{
    const static unsigned int WIDTH = 800;
    const static unsigned int HEIGHT = 600;
   
    sf::RenderWindow WindowApp( sf::VideoMode( WIDTH, HEIGHT ), "GameCreator" );
   
    GUI::GUIMain GUI( WindowApp );
   
    if( !GUI.createButton( "ButtonOne", GUI.GUIData.size(), 1, sf::Vector2f( 200, 200 ), sf::Vector2f( 300, 100 ), "xxx", 1 ) )
    {
        cout << "Nie moge dodac" << endl;
    }
    if( !GUI.createButton( "BigButton", GUI.GUIData.size(), 1, sf::Vector2f( 200, 400 ), sf::Vector2f( 250, 75 ), "xxx", 1 ) )
    {
        cout << "Nie moge dodac" << endl;
    }
    if( !GUI.createButton( "SmallButton", GUI.GUIData.size(), 1, sf::Vector2f( 10, 10 ), sf::Vector2f( 12, 10 ), "xxx", 1 ) )
    {
        cout << "Nie moge dodac" << endl;
    }
    if( !GUI.createButton( "SmallButton", GUI.GUIData.size(), 1, sf::Vector2f( 100, 30 ), sf::Vector2f( 124, 10 ), "xxx", 1 ) )
    {
        cout << "Nie moge dodac" << endl;
    }
   
    while( WindowApp.isOpen() )
    {
        sf::Event event;
        while( WindowApp.pollEvent( event ) )
        {
            if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape )
                 WindowApp.close();
           
            if( event.type == sf::Event::Closed )
                 WindowApp.close();
           
            if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::V ) {
                cout << "Ukrywam Button o nazwie: " << GUI.GUIElementByName( "SmallButton" )->getName() << endl;
                GUI.GUIElementByName( "SmallButton" )->setVisible( false );
            }
           
            if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::B ) {
                cout << "Ujawniam Button o nazwie: " << GUI.GUIElementByName( "SmallButton" )->getName() << endl;
                GUI.GUIElementByName( "SmallButton" )->setVisible( true );
            }
        }
       
        GUI.drawGUI();
        WindowApp.display();
        WindowApp.clear();
    }
   
    WindowApp.close();
    return 0;
}


"GUI.h"
C/C++
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
#include "GUIData.h"

#define TEXT_CENTER 2
#define TEXT_LEFT 1
#define TEXT_RIGHT 3

using namespace std;

namespace GUI {
   
    class GUIMain {
    private:
        bool sorted;
       
    public:
        sf::RenderWindow * WindowApp;
        sf::Font f_normal;
        vector < GUI::GUIData * > GUIData;
        bool showConsoleError;
       
    public:
        // Constructor
        GUIMain( sf::RenderWindow & app );
       
        // Creating button
        bool createButton( string, int, int, sf::Vector2f, sf::Vector2f, string, int );
        /*
            float x = Position on scene
            float y = Position on scene
            float weigth = Button size
            float height = Button size
            string Text = Text to write in button
            int TextAlign = TEXT_LEFT, TEXT_CENTER, TEXT_RIGHT
            */
       
        void drawGUI();
       
        GUI::GUIData * GUIElementByName( string name );
       
    }; // END CLASS
   
} // END GUI NAMESPACE

GUI.cpp
C/C++
#include "GUI.h";

using namespace std;

namespace GUI {
   
    GUIMain::GUIMain( sf::RenderWindow & app ) {
       
        // SET ORGINAL WINDOW RENDER
        WindowApp = & app;
        showConsoleError = true;
        sorted = false;
       
    }
   
    bool GUIMain::createButton( string name, int ID, int priority, sf::Vector2f position, sf::Vector2f size, string text, int textAlign ) {
        if( GUIData.size() != 0 ) {
           
            // Check duplicat NAME
            for( int i = 0; i < GUIData.size(); i++ ) {
                if( name == GUIData[ i ]->getName() ) {
                    cout << "CONSOLE ERROR: NAME BUTTON ALREADY USING" << endl;
                    return false;
                }
            }
        }
       
        // Creating sprite (tymczasowe)
       
        sf::RenderTexture GUIRender;
        GUIRender.create( size.x + 1, size.y + 1 );
       
        switch( textAlign ) {
           
        case TEXT_LEFT:
            {
               
                sf::RectangleShape GUIRectangle( size );
                GUIRectangle.setFillColor( sf::Color::Red );
               
                /*
                            sf::Text GUIText;
                            GUIText.setFont(f_normal);
                            GUIText.setCharacterSize((size.y));
                            GUIText.setString(text);
                */
               
                GUIRender.draw( GUIRectangle );
                //            GUIRender.draw(GUIText);
                GUIRender.display();
               
            }
            break;
           
        }
       
        sf::Sprite GUIElement;
        GUIElement.setPosition( position );
        GUIElement.setTexture( GUIRender.getTexture() );
       
        //Add button to database
        GUIData.push_back( new GUI::GUIData( name, ID, priority, position, size, text, textAlign, GUIElement ) );
        GUIRender.clear();
       
        return true;
    }
   
    void GUIMain::drawGUI()
    {
        for( int i = 0; i < GUIData.size(); i++ ) {
            if( GUIData[ i ]->getVisible() == true )
                 WindowApp->draw( GUIData[ i ]->GUIElement );
           
        }
    }
   
    GUI::GUIData * GUIMain::GUIElementByName( string name ) {
        for( int i = 0; i < GUIData.size(); i++ ) {
            if( name == GUIData[ i ]->getName() )
                 return GUIData[ i ];
           
        }
    }
}


GUIData.h
C/C++
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>

using namespace std;

namespace GUI {
   
    class GUIData {
       
    private:
        int ID;
        string name;
        int priority;
        sf::Vector2f position;
        sf::Vector2f size;
        string text;
        int textAlign;
        bool visible;
       
    public:
        sf::Sprite GUIElement;
       
       
    public:
        GUIData( string /*name of button*/,
        int /*ID*/,
        int /*Priority*/,
        sf::Vector2f /*position*/,
        sf::Vector2f /*size*/,
        string /*text*/,
        int /*textAlign*/,
        sf::Sprite Construct_GUIElement /*GUIElement*/ );
       
        void IncreasePriority();
        void downgradePriority();
        void setPriority( unsigned int );
        string getName();
        int getID();
        int getPriority();
        bool setVisible( bool );
        bool getVisible();
        sf::Vector2f getPosition();
        sf::Vector2f getSize();
        sf::Sprite getGUIElement();
    };
   
}

GUIData.cpp
C/C++
#include "GUIData.h"

using namespace std;

namespace GUI {
   
    GUIData::GUIData( string Construct_name, int Construct_ID, int Construct_Priority,
    sf::Vector2f Construct_position, sf::Vector2f Construct_size,
    string Construct_text, int Construct_textAlign, sf::Sprite Construct_GUIElement ) {
       
        priority = Construct_Priority;
        ID = Construct_ID;
        name = Construct_name;
        position = Construct_position;
        size = Construct_size;
        text = Construct_text;
        textAlign = Construct_textAlign;
        visible = true;
        GUIElement = Construct_GUIElement;
       
    }
    string GUIData::getName() {
        return name;
    }
   
    int GUIData::getID() {
        return ID;
    }
   
    int GUIData::getPriority() {
        return priority;
    }
   
    bool GUIData::setVisible( bool visible_argument ) {
        visible = visible_argument;
    }
   
    bool GUIData::getVisible() {
        return visible;
    }
   
    sf::Vector2f GUIData::getPosition() {
        return position;
    }
   
    sf::Vector2f GUIData::getSize() {
        return size;
    }
   
    sf::Sprite GUIData::getGUIElement() {
        return GUIElement;
    }
   
}
P-113821
unkn9wn
» 2014-07-15 16:29:38
Jak sam wspomniałeś "sprajt gubi textury". A gubi gdyż tworząc nowy element

GUIData.push_back( new GUI::GUIData( name, ID, priority, position, size, text, textAlign, GUIElement ) );

jako argument wysyłasz tylko sprite. I tu właśnie gubi texturę, a przecież później jej używa, aby narysować się.

w GUIData.h masz

sf::Sprite GUIElement;
 
więc potrzebujesz dla niego dodatkowo texturki, którą będzie miał "obok siebie"

C/C++
sf::Sprite GUIElement;
sf::Texture GUIElementTexture; // texturka dla sprite'a powyżej

i dodatkowego argumentu w konstruktorze

C/C++
GUIData::GUIData( /*...*/, sf::Texture textura )

którą przypiszesz w kostruktorze dla sprite'u

C/C++
GUIElementTexture = textura;
GUIElement.setTexture( GUIElementTexture );

więc w sumie zamiast wysyłać sprite dla nowego elementu w vectorze

mógłbyś wysyłać tylko texturę

GUIData.push_back( new GUI::GUIData( name, ID, priority, position, size, text, textAlign, GUIRender.getTexture() ) );
P-113823
arczi14
Temat założony przez niniejszego użytkownika
» 2014-07-15 17:17:03
Taaaak teraz śmiga. Ciekawe dlaczego programiści SFML nie zrobili dla klasy Sprite kopiowania tekstury.
Dzięki za pomoc! :)
P-113825
unkn9wn
» 2014-07-15 17:40:39
gdybyś miał kontener sprite'ów, i każdy przetrzymywałby teksturę, która i tak w większości spriteów się pojawia, traciłbyś pamięć bez potrzeby

W związku że sprite przetrzymuje jedynie wskaźnik do tekstury, możesz sobie stworzyć kontener z teksturkami, których będziesz używał i oddzielny kontener z sprite'ami, gdzie wybierzesz jedynie teksturkę której będzie sprite używał i odpowiednio przerobisz dla niego ( obrót, zeskalowanie itp. ) bez potrzeby kopiowania jednej z tekstur dla każdego sprite'a

tak mi się przynajmniej zdaje ;)

P-113826
« 1 »
  Strona 1 z 1