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

Auteur Sujet: Définir un ordre d'affichage par vertex.  (Lu 16516 fois)

0 Membres et 3 Invités sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #15 le: Juillet 04, 2013, 03:34:49 pm »
Bon bah pas le choix alors je vais revenir à mon ancienne technique avec un seul draw par sprite, la seule technique qui marche avec SFML dans mon cas pour l'instant.
Je changerai plus tard si une version futur de la SFML permet d'utiliser le depthtest et l'alphatest correctement.
« Modifié: Juillet 04, 2013, 03:36:39 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Définir un ordre d'affichage par vertex.
« Réponse #16 le: Juillet 04, 2013, 03:41:59 pm »
Les modifs ne sont pas forcément compliquées à faire, si ça ne t'embête pas d'utiliser une version custom de SFML je peux te dire ce qu'il y a à changer.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #17 le: Juillet 04, 2013, 03:58:33 pm »
Salut,
ha bah c'est une bonne nouvelle ça.
Oui peux tu me dire ce qu'il y a a changé stp ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Définir un ordre d'affichage par vertex.
« Réponse #18 le: Juillet 04, 2013, 04:10:54 pm »
1. Vertex::position doit être un Vector3f

2. Dans RenderTarget::resetGLStates mets/change tous les glEnable et autre dont tu as besoin.

3. Dans RenderTarget::draw(const Vertex*, unsigned int, PrimitiveType, const RenderStates&), remplace ça :

glCheck(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), data + 0));
glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 8));
glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12));

Par ça :

glCheck(glVertexPointer(3, GL_FLOAT, sizeof(Vertex), data + 0));
glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 12));
glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 16));

4. A un moment donné il faut que tu forces ContextSettings::depthBits à 24 ou 32, je ne sais pas trop quel endroit serait le meilleur.

Je ne sais pas si ça va marcher du premier coup, donc n'hésite pas à donner du feedback ;D
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #19 le: Juillet 04, 2013, 04:32:37 pm »
Ok, je vais test ça et je te dis quoi après.

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #20 le: Juillet 04, 2013, 06:38:37 pm »
Mmm, pas si simple que ça a changé, j'ai modifier le vector2f en vector3f dans la classe sf::Vertex pour la position mais, le cmpilateur me sort cette erreur :

no know conversion from argument 2 from const Vector3f to const sf::transform, dans le fichier transform.hpp ligne 376.

Donc bon je dois aussi modifier la classe Transform pour que ça marche aussi avec des vector3.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Définir un ordre d'affichage par vertex.
« Réponse #21 le: Juillet 04, 2013, 07:42:59 pm »
Il faut juste ajouter un opérateur * entre sf::Transform et sf::Vector3f. Reprends le même que pour Vector2f (laisse la composante Z inchangée, sf::Transform ne transforme que X et Y).
« Modifié: Juillet 04, 2013, 10:13:45 pm par Laurent »
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #22 le: Juillet 04, 2013, 09:36:54 pm »
Bon j'ai fait plus simple, dans le draw de rendertarget j'ai carément créer un vector2f et je l'ai utilisé pour faire la transfo et puis j'ai récupérer le vector3f et je l'ai mis dans le vecteur2f vu que je m'en tape du z pour la transformation c'est juste pour le depthtest.

J'ai du modifier toutes les classes qui utilisent la classe Vertex, c'est à dire les Shapes, la classe sf::Text et la classe sf::Sprite et VertexArray aussi pour récupérer le "bound." sans me soucier du z.

Je pense même que je vais rajouter une méthode pour définir un "z-order" dans les classes Shape, text et sprite.

Bref je vais test ça demain avec mon code on verra ce que ça donne, la je viens de finir de recompiler ma version personnelle de SFML.
Je savias pas trop ou coller le paramètre pour définir la valeur pour l'alpha test par contre du coup je l'ai mis dans le resetglstates même si il aurait peut être mieux valu le mettre dans contextsetting mais bon la flemme de changer le fichier wglimpl ou je ne comprend pas grand chose. :/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Définir un ordre d'affichage par vertex.
« Réponse #23 le: Juillet 04, 2013, 10:16:17 pm »
Citer
je vais test ça demain
Pourquoi est-ce que tu ne dis jamais "tester" ? ;D

Citer
Je savias pas trop ou coller le paramètre pour définir la valeur pour l'alpha test
Je suis pas sûr qu'il faille utiliser autre chose que 0. Avec des valeurs plus grandes tu vas virer des pixels qui ne sont pas totalement transparents et donc avoir un rendu tronqué par rapport à l'image source.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #24 le: Juillet 05, 2013, 07:43:47 am »
Citer
Pourquoi est-ce que tu ne dis jamais "tester" ? ;D
Je sais pas.  :o
Citer
Je suis pas sûr qu'il faille utiliser autre chose que 0. Avec des valeurs plus grandes tu vas virer des pixels qui ne sont pas totalement transparents et donc avoir un rendu tronqué par rapport à l'image source.
Ok, super alors je vais la mettre d'office a 0.

Bon me reste encore une chose à améliorer maintenant que j'ai activé le depthtest, c'est rendre le paramètre z facultatif et si je ne spécifie rien alors ça s'affichera dans l'ordre avec lequel je dessine les entités.
Et normalement ça devrait être bon.  :)

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #25 le: Juillet 05, 2013, 11:13:50 am »
Bon après un 1er essai et en ayant bien fait ce que tu m'as dis (un vector3f pour la position, activer le depthtest dans resetGlStates ainsi que l'alphatest, changer ce que tu m'as dis de changer dans draw, etc...)

Ca ne marche pas avec le depthtest activé ça ne m'affiche rien du tout. (Ecran tout noir.)

La position en z de la caméra à de l'importance dans ce cas la ?

Car tout ce qui se trouve en z = 0 ça s'affiche bien, mais pas les vertex qui ont une coordonnée supérieur à 0.

Et une autre question, peut on jouer avec l'activation du depthtest si je veux faire par exemple un depthtest pour certains vertex mais pas pour d'autre.

En fait je voudrais faire ceci, si la valeur de z est négative, pas de depthtest, ça s'affiche l'un sur l'autre, sinon, depthtest.

Y'a moyen de changer la position de la view en Z ???

Sinon au pire, je mettrai des coordonnées z qui seront uniquement <=0 et je désative le depthtest si le z est positif. (l'inverse donc.)
Ou alors non j'ai mieux :
Tourner la vue pour qu'elle regarde vers des z positif et non des z négatif, comment je peux faire ça ?
« Modifié: Juillet 05, 2013, 11:18:10 am par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Définir un ordre d'affichage par vertex.
« Réponse #26 le: Juillet 05, 2013, 11:40:01 am »
Citer
La position en z de la caméra à de l'importance dans ce cas la ?
Ah oui, puisque la vue (sf::View) utilise un sf::Transform, elle ne modifie pas l'intervalle de validité pour la coordonnée Z. C'est donc par défaut [-1, 1] si je ne me trompe pas. Il faut donc utiliser des valeurs Z dans cet intervalle.

Citer
Et une autre question, peut on jouer avec l'activation du depthtest si je veux faire par exemple un depthtest pour certains vertex mais pas pour d'autre.
Pas si les vertex en question se trouvent tous dans le même vertex array, puisqu'il faut insérer un appel à glEnable(GL_DEPTH_TEST).

Citer
En fait je voudrais faire ceci, si la valeur de z est négative, pas de depthtest, ça s'affiche l'un sur l'autre, sinon, depthtest.
Ca me paraît difficile à faire sans shader.

Citer
Sinon au pire, je mettrai des coordonnées z qui seront uniquement <=0 et je désative le depthtest si le z est positif. (l'inverse donc.)
Ou alors non j'ai mieux :
Tourner la vue pour qu'elle regarde vers des z positif et non des z négatif
Et ça changerait quoi de faire ça ?
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #27 le: Juillet 05, 2013, 11:45:09 am »
Citer
Ah oui, puisque la vue (sf::View) utilise un sf::Transform, elle ne modifie pas l'intervalle de validité pour la coordonnée Z. C'est donc par défaut [-1, 1] si je ne me trompe pas. Il faut donc utiliser des valeurs Z dans cet intervalle.

Ok j'ai essayer d'utiliser des valeurs dans cet interval mais malgré ça ça ne marche pas avec le depthtest même si je met toutes les coordonnées de Z à 0 ça ne m'affiche rien.

Citer
Pas si les vertex en question se trouvent tous dans le même vertex array, puisqu'il faut insérer un appel à glEnable(GL_DEPTH_TEST).

Ok donc seulement pour les vertex qui ne se trouvent pas dans le même vertex array, justement c'est mon cas donc ça va.




Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Définir un ordre d'affichage par vertex.
« Réponse #28 le: Juillet 05, 2013, 12:10:19 pm »
Bon, bizarre, ça m'affiche quelque chose au 1er affichage et puis ça disparait.

C'est pas grâve si je mets les glDisable et Enable pour le depthtest dans le draw ??? (Si la composante z est négative (c'est le cas par défaut.) alors pas de depthtest, sinon, j'active le depthtest.)

J'ai restreint la position de z dans un intervale entre 0 et 1 quand j'active le depth test mais toujours le même problème. :/

PS : les méthode draw et resetGlStates :

////////////////////////////////////////////////////////////
void RenderTarget::draw(const Vertex* vertices, unsigned int vertexCount,
                        PrimitiveType type, const RenderStates& states)
{
    // Nothing to draw?
    if (!vertices || (vertexCount == 0))
        return;

    if (activate(true))
    {
        // First set the persistent OpenGL states if it's the very first call
        if (!m_cache.glStatesSet)
            resetGLStates();

        // Check if the vertex count is low enough so that we can pre-transform them
        bool useVertexCache = (vertexCount <= StatesCache::VertexCacheSize);
        if (useVertexCache)
        {
            // Pre-transform the vertices and store them into the vertex cache
            for (unsigned int i = 0; i < vertexCount; ++i)
            {
                Vertex& vertex = m_cache.vertexCache[i];
                Vector2f v2Pos = states.transform * Vector2f(vertices[i].position.x, vertices[i].position.y);
                (vertices[i].position.z < 0) ? glCheck(glDisable(GL_DEPTH_TEST)) : glCheck(glEnable(GL_DEPTH_TEST));
                (vertices[i].position.z > 1) ? vertex.position = Vector3f(v2Pos.x, v2Pos.y, 1) :  vertex.position = Vector3f(v2Pos.x, v2Pos.y, vertices[i].position.z);
                vertex.color = vertices[i].color;
                vertex.texCoords = vertices[i].texCoords;
            }

            // Since vertices are transformed, we must use an identity transform to render them
            if (!m_cache.useVertexCache)
                applyTransform(Transform::Identity);
        }
        else
        {
            applyTransform(states.transform);
        }

        // Apply the view
        if (m_cache.viewChanged)
            applyCurrentView();

        // Apply the blend mode
        if (states.blendMode != m_cache.lastBlendMode)
            applyBlendMode(states.blendMode);

        // Apply the texture
        Uint64 textureId = states.texture ? states.texture->m_cacheId : 0;
        if (textureId != m_cache.lastTextureId)
            applyTexture(states.texture);

        // Apply the shader
        if (states.shader)
            applyShader(states.shader);

        // If we pre-transform the vertices, we must use our internal vertex cache
        if (useVertexCache)
        {
            // ... and if we already used it previously, we don't need to set the pointers again
            if (!m_cache.useVertexCache)
                vertices = m_cache.vertexCache;
            else
                vertices = NULL;
        }

        // Setup the pointers to the vertices' components
        if (vertices)
        {
            const char* data = reinterpret_cast<const char*>(vertices);
            glCheck(glVertexPointer(3, GL_FLOAT, sizeof(Vertex), data + 0));
            glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 12));
            glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 16));
        }

        // Find the OpenGL primitive type
        static const GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES,
                                       GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS};
        GLenum mode = modes[type];

        // Draw the primitives
        glCheck(glDrawArrays(mode, 0, vertexCount));

        // Unbind the shader, if any
        if (states.shader)
            applyShader(NULL);

        // Update the cache
        m_cache.useVertexCache = useVertexCache;
    }
}
 

////////////////////////////////////////////////////////////
void RenderTarget::resetGLStates()
{
    if (activate(true))
    {
        // Make sure that GLEW is initialized
        priv::ensureGlewInit();

        // Define the default OpenGL states
        glCheck(glDisable(GL_CULL_FACE));
        glCheck(glDisable(GL_LIGHTING));
        glCheck(glDisable(GL_DEPTH_TEST));
        glCheck(glDisable(GL_ALPHA_TEST));
        glCheck(glEnable(GL_TEXTURE_2D));
        glCheck(glEnable(GL_BLEND));
        glCheck(glMatrixMode(GL_MODELVIEW));
        glCheck(glEnableClientState(GL_VERTEX_ARRAY));
        glCheck(glEnableClientState(GL_COLOR_ARRAY));
        glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
        glCheck(glEnable(GL_ALPHA_TEST));
        glCheck(glAlphaFunc(GL_GREATER, 0));
        m_cache.glStatesSet = true;

        // Apply the default SFML states
        applyBlendMode(BlendAlpha);
        applyTransform(Transform::Identity);
        applyTexture(NULL);
        if (Shader::isAvailable())
            applyShader(NULL);
        m_cache.useVertexCache = false;

        // Set the default view
        setView(getView());
    }
}
 
« Modifié: Juillet 05, 2013, 12:13:49 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Définir un ordre d'affichage par vertex.
« Réponse #29 le: Juillet 05, 2013, 12:12:00 pm »
Dans RenderTarget::clear il faut ajouter GL_DEPTH_BIT à glClear, et dans RenderTarget::resetGLStates il faut ajouter glClearDepth(0).
Laurent Gomila - SFML developer