Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Texture vertex array  (Lu 4275 fois)

0 Membres et 1 Invité sur ce sujet

Develog

  • Full Member
  • ***
  • Messages: 100
    • Voir le profil
    • E-mail
Texture vertex array
« le: Juin 23, 2014, 12:45:46 am »
Bonsoir/bonjour ;)

Je viens ici pour vous demander de l'aide et des conseils.
Je travaille sur un tableau de vertex array, je fais appel à un tileset pour faire un seul appel à la fonction draw mais je cherche à savoir comme est ce possible de définir une texture à un quad en particulier.

J'avais essayé en faisant ceci :

tile[4].texCoords = sf::Vector2f(40, 0);
            tile[5].texCoords = sf::Vector2f(80, 20);
            tile[6].texCoords = sf::Vector2f(40, 40);
            tile[7].texCoords = sf::Vector2f(0, 20);

Comme vous pouvez le voir j'ai donc changé "l'ID" du point en espérant que mon deuxième quad est une texture différente seulement c'est tout une ligne qui prend cette texture, c'est à dire qu'à partir du second quad toute la ligne prend la même texture et sur la ligne suivante tout redevient normal ...
Et au passage sur une "carte" de 10 sur 10 j'ai souvent un retour de std::bad_alloc ...
Je cherche donc un moyen de remédier à ça et donc je fais appel à votre grand savoir ;)

Screen à l'appui :




Merci d'avance
« Modifié: Juillet 01, 2014, 09:37:35 pm par Develog »

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : Texture vertex array
« Réponse #1 le: Juin 23, 2014, 02:11:26 am »
C'est franchement pas très compréhensible.

Y'a pas de problème dans les 4 lignes que tu présentes...
Un vertexArray utilise une seule texture. Si tu veux utiliser plusieurs textures, va falloir utiliser plusieurs vertexArray. Si tu veux juste changer les coordonnées de texture de certains vertices en gardant la même texture bah c'est comme tu le fais dans tes 4 lignes.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Texture vertex array
« Réponse #2 le: Juin 23, 2014, 07:43:43 am »
Il va falloir nous montrer un code complet et minimal qui reproduit le problème.
Laurent Gomila - SFML developer

Develog

  • Full Member
  • ***
  • Messages: 100
    • Voir le profil
    • E-mail
Re : Texture vertex array
« Réponse #3 le: Juin 23, 2014, 12:36:15 pm »
Justement c'est bien ça mon problème ;)
Pourquoi toutes les quads de la colonne prennent la même texture que le quad numéro 2.

Code minimal :

#include "Tile.h"

#define TILESIZEX 80
#define TILESIZEY 40

Tile::Tile(int width, int height)
{
    if (!texturex.loadFromFile("Resources/TileSetISO.png"))
        std::cout << "Error Loading" << std::endl;

    m_vertices.setPrimitiveType(sf::Quads);
    m_vertices.resize(width * height * 4);

    for (int i = 0; i < width; ++i)
    {
        for (int j = 0; j < height; ++j)
        {
            sf::Vertex* tile = &m_vertices[(i + j * width) * 4];

            tile[0].position = sf::Vector2f(40 + (TILESIZEX*i), (TILESIZEY * j));
            tile[1].position = sf::Vector2f(80 + (TILESIZEX*i), 20 +(TILESIZEY * j));
            tile[2].position = sf::Vector2f(40 + (TILESIZEX*i), 40 +(TILESIZEY * j));
            tile[3].position = sf::Vector2f((TILESIZEX*i), 20 +(TILESIZEY * j));


            tile[0].texCoords = sf::Vector2f(40, 0);
            tile[1].texCoords = sf::Vector2f(80, 20);
            tile[2].texCoords = sf::Vector2f(40, 40);
            tile[3].texCoords = sf::Vector2f(0, 20);

            tile[4].texCoords = sf::Vector2f(120, 0);
            tile[5].texCoords = sf::Vector2f(160, 20);
            tile[6].texCoords = sf::Vector2f(120, 40);
            tile[7].texCoords = sf::Vector2f(80, 20);

        }
    }

}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Texture vertex array
« Réponse #4 le: Juin 23, 2014, 01:05:34 pm »
Si j'ai souligné "complet" c'est pas pour rien... le but c'est d'avoir un code qu'on peut tester, et duquel on n'est sûr qu'il ne manque rien.

Enfin, là l'erreur est assez évidente, donc ça suffira ;)

Ton code se trouve dans une boucle, donc ce n'est pas un quad que tu vas modifier, mais tous -- mention spéciale pour le dernier qui est en dehors du tableau et pourrait tout autant faire planter ton appli.

Si c'est un seul quad que tu veux modifier, fais-le en dehors de la boucle, et avec les bons indices bien sûr.
Laurent Gomila - SFML developer

Develog

  • Full Member
  • ***
  • Messages: 100
    • Voir le profil
    • E-mail
Re : Texture vertex array
« Réponse #5 le: Juin 23, 2014, 01:24:47 pm »
Je tiens tout d'abord à vous remercier pour votre aide efficace et rapide.

Mais du coup comment cela fait-il que toute la colonne prenne la même texture sachant que j'ai bien défini les indices pour le  deuxième quad ?

Develog

  • Full Member
  • ***
  • Messages: 100
    • Voir le profil
    • E-mail
Re : Texture vertex array
« Réponse #6 le: Juin 23, 2014, 02:10:36 pm »
Voici donc un code minimal :

#include "Scene.h"
#include "Tile.h"

#define SIZE 10

Scene::Scene()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "[V0.1] ISO CityDev", sf::Style::Default);
    window.setFramerateLimit(60);

    Tile tiles(11, 11);
    tiles.setTexture(1, 2);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
            {
                window.close();
            }
        }

        window.clear();
        window.draw(tiles);
        window.display();
    }
}

#include "Tile.h"

#define TILESIZEX 80
#define TILESIZEY 40

Tile::Tile(int width, int height)
{
    if (!texturex.loadFromFile("Resources/TileSetISO.png"))
        std::cout << "Error Loading" << std::endl;

    m_vertices.setPrimitiveType(sf::Quads);
    m_vertices.resize(width * height * 4);

    for (int i = 0; i < width; ++i)
    {
        for (int j = 0; j < height; ++j)
        {
            tile = &m_vertices[(i + j * width) * 4];

            tile[0].position = sf::Vector2f(40 + (TILESIZEX*i), (TILESIZEY * j));
            tile[1].position = sf::Vector2f(80 + (TILESIZEX*i), 20 +(TILESIZEY * j));
            tile[2].position = sf::Vector2f(40 + (TILESIZEX*i), 40 +(TILESIZEY * j));
            tile[3].position = sf::Vector2f((TILESIZEX*i), 20 +(TILESIZEY * j));


            tile[0].texCoords = sf::Vector2f(40, 0);
            tile[1].texCoords = sf::Vector2f(80, 20);
            tile[2].texCoords = sf::Vector2f(40, 40);
            tile[3].texCoords = sf::Vector2f(0, 20);

        }
    }

}

void Tile::setTexture(int IDTile, int ID)
{
    int line = ID % 10;
    int column = ID / 10;

    ///Permet de voir à quoi l'ID correspond sur le TILESET
    //std::cout << "line : " << line << " | column : " << column << std::endl;

    tile[4 * IDTile].texCoords = sf::Vector2f(40 + (80 * line), 0);
    tile[(4 * IDTile) + 1].texCoords = sf::Vector2f(80 + (80 * line), 20);
    tile[(4 * IDTile) + 2].texCoords = sf::Vector2f(40 + (80 * line), 40);
    tile[(4 * IDTile) + 3].texCoords = sf::Vector2f((80 * line), 20);
}
 

#ifndef TILE_H
#define TILE_H

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

class Tile : public sf::Drawable, public sf::Transformable
{
    public:
        Tile(int width, int height);

       void setTexture(int IDTile, int ID);

    protected:
    private:
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
            states.transform *= getTransform();
            states.texture = &texturex;

            target.draw(m_vertices, states);
        }

        sf::Vertex* tile;
        sf::VertexArray m_vertices;
        sf::Texture texturex;
};

#endif // TILE_H
 

Quand je fais appel à mon .setTexture j'ai une erreur de std::bad_alloc "terminate called after throwing an instance of "std::bad_alloc" what():

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Texture vertex array
« Réponse #7 le: Juin 23, 2014, 04:39:34 pm »
Dans setTexture ce n'est pas la variable "tile" qu'il faut utiliser (celle-là ne sert que localement dans la boucle du constructeur), mais m_vertices.
Laurent Gomila - SFML developer

Develog

  • Full Member
  • ***
  • Messages: 100
    • Voir le profil
    • E-mail
Re : Texture vertex array
« Réponse #8 le: Juin 23, 2014, 04:59:34 pm »
Merci beaucoup !
Ce forum est vraiment génial et il y a une très grosse réactivité je trouve ;)

Develog

  • Full Member
  • ***
  • Messages: 100
    • Voir le profil
    • E-mail
Re : Texture vertex array
« Réponse #9 le: Juillet 01, 2014, 09:40:21 pm »
Bonjour,

(J'ai honte de venir poster un message pour une "erreur" aussi bête)
Ca fait deux jours que je tourne autour du pot, mes .texcoords ne veulent pas afficher ma texture ... et pareil pour les .setColor ...
Donc je viens vous demander de l'aide, le problème doit venir d'une simple erreur d'étourderie et je m'en excuse ;)

Voici le code minimal :

#include <iostream>
#include <SFML/Graphics.hpp>
#include "Tile.h"

using namespace std;

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "[V0.01]CityDev", sf::Style::Default);

    Tile tiles(10, 10);

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

            window.clear();
            window.draw(tiles);
            window.display();
        }
}
}
 

#include "Tile.h"

#define TILESIZE 64

Tile::Tile(int width, int height)
{
    if (!textureTileset.loadFromFile("Resources/Tileset.png"))
        std::cout << "Error Loading" << std::endl;

    vertices.setPrimitiveType(sf::Quads);
    vertices.resize(width * height * 4);

    for (int i = 0; i < width; ++i)
    {
        for (int j = 0; j < height; ++j)
        {
            tile = &vertices[(i + j * width) * 4];

            tile[0].position = sf::Vector2f(TILESIZE * i, TILESIZE * j);
            tile[1].position = sf::Vector2f(TILESIZE * (i + 1), TILESIZE * j);
            tile[2].position = sf::Vector2f(TILESIZE * (i + 1), TILESIZE * j);
            tile[3].position = sf::Vector2f(TILESIZE * i, TILESIZE * j);

            tile[0].texCoords = sf::Vector2f(128, 0);
            tile[1].texCoords = sf::Vector2f(192, 0);
            tile[2].texCoords = sf::Vector2f(192, 64);
            tile[3].texCoords = sf::Vector2f(128, 64);
        }
    }

}
 

#ifndef TILE_H
#define TILE_H

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

class Tile : public sf::Drawable, public sf::Transformable
{
    public:
        Tile(int width, int height);

    private:
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
            states.transform *= getTransform();
            states.texture = &textureTileset;

            target.draw(vertices, states);
        }

        sf::Vertex* tile;
        sf::VertexArray vertices;
        sf::Texture textureTileset;
};

#endif // TILE_H
 

Le tileset qui va avec :

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Texture vertex array
« Réponse #10 le: Juillet 01, 2014, 10:39:14 pm »
Citer
            tile[0].position = sf::Vector2f(TILESIZE * i, TILESIZE * j);
            tile[1].position = sf::Vector2f(TILESIZE * (i + 1), TILESIZE * j);
            tile[2].position = sf::Vector2f(TILESIZE * (i + 1), TILESIZE * j);
            tile[3].position = sf::Vector2f(TILESIZE * i, TILESIZE * j);
Tu n'as que deux paires de coordonnées différentes pour 4 points. Ca peut difficilement faire un carré.
Laurent Gomila - SFML developer

Develog

  • Full Member
  • ***
  • Messages: 100
    • Voir le profil
    • E-mail
Re : Texture vertex array
« Réponse #11 le: Juillet 01, 2014, 10:49:15 pm »
En effet grosse erreur de ma part ;) Je savais que ça allait être une erreur bête.

Merci Laurent !