#0 

27-06-2009 00:40:06

hardcpp
Abonné
Date d'inscription: 26-04-2008
Messages: 229

Hello sa fait un baille que j'ai pas poster une ressource x), donc j'ai mit au point mon système de frustrum culling en me basant sur celui de tmyke concrètement cela sert a masquer les node non visible et donc de gagner du frame rate

FrustrumCulling.hppFrustrumCulling.cppPlane.hppPlane.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
///--------------------------------------------------------------------------------
/// @file FrustrumCulling.hpp
/// @brief Technique de culling par masquage d'objet non visible
///--------------------------------------------------------------------------------
#ifndef __FRUSTRUMCULLING_HPP_INCLUDED__
#define __FRUSTRUMCULLING_HPP_INCLUDED__

#include "Plane.hpp"
#include <irrlicht.h>

namespace App { namespace Engine { namespace Culling {

    ///--------------------------------------------------------------------------------
    /// Technique de culling par masquage d'objet non visible
    ///--------------------------------------------------------------------------------
    class FrustrumCulling
    {
        public:
            ///--------------------------------------------------------------------------------
            /// Constructeur
            ///
            /// @param _SceneManager : Gestionnaire de scene
            ///--------------------------------------------------------------------------------
            FrustrumCulling(irr::scene::ISceneManager * _SceneManager);
            ///--------------------------------------------------------------------------------
            /// Destructeur
            ///--------------------------------------------------------------------------------
            ~FrustrumCulling();

            ///--------------------------------------------------------------------------------
            /// Pour crée le culling
            ///--------------------------------------------------------------------------------
            void Create();
            ///--------------------------------------------------------------------------------
            /// Pour recrée le culling
            ///--------------------------------------------------------------------------------
            void Recreate();

            ///--------------------------------------------------------------------------------
            /// Pour mettre a jour le culling
            ///--------------------------------------------------------------------------------
            void Update();

            ///--------------------------------------------------------------------------------
            /// Pour ajouter un scene node
            ///
            /// @param _SceneNode : Pointeur vers le scene node
            ///--------------------------------------------------------------------------------
            void AddSceneNode(const irr::scene::ISceneNode * _SceneNode);
            ///--------------------------------------------------------------------------------
            /// Pour supprimer un scene node
            ///
            /// @param _SceneNode : Pointeur vers le scene node
            ///--------------------------------------------------------------------------------
            void RemoveSceneNode(const irr::scene::ISceneNode * _SceneNode);

            ///--------------------------------------------------------------------------------
            /// Pour tester si une box et visible
            ///
            /// @param _Box : Box a tester
            ///--------------------------------------------------------------------------------
            bool IsVisible(const irr::core::aabbox3d<irr::f32>& box);

        private:
            ///--------------------------------------------------------------------------------
            /// Gestionnaire de scene
            ///--------------------------------------------------------------------------------
            irr::scene::ISceneManager * m_SceneManager;
            ///--------------------------------------------------------------------------------
            /// Pour stocker les nodes
            ///--------------------------------------------------------------------------------
            irr::core::array<irr::scene::ISceneNode *> m_Nodes;
            ///--------------------------------------------------------------------------------
            /// Pour tester si un node est visible
            ///--------------------------------------------------------------------------------
            App::core::Plane m_FrustumPlane[6];
            ///--------------------------------------------------------------------------------
            /// Dernier / derniere position et cible de la camera
            ///--------------------------------------------------------------------------------
            irr::core::vector3df m_LastPosition, m_LastTarget;
    };

}    // Culling
}    // Engine
}    // App

#endif    // __FRUSTRUMCULLING_HPP_INCLUDED__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
///--------------------------------------------------------------------------------
/// @file FrustrumCulling.cpp
/// @brief Technique de culling par masquage d'objet non visible
///--------------------------------------------------------------------------------

#include "FrustrumCulling.hpp"

namespace App { namespace Engine { namespace Culling {

    ///--------------------------------------------------------------------------------
    /// Constructeur
    ///
    /// @param _SceneManager : Gestionnaire de scene
    ///--------------------------------------------------------------------------------
    FrustrumCulling::FrustrumCulling(irr::scene::ISceneManager * _SceneManager)
        : m_SceneManager(_SceneManager)
    {

    }
    ///--------------------------------------------------------------------------------
    /// Destructeur
    ///--------------------------------------------------------------------------------
    FrustrumCulling::~FrustrumCulling()
    {

    }

    ///--------------------------------------------------------------------------------
    /// Pour crée le culling
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::Create()
    {
        m_SceneManager->getSceneNodesFromType(irr::scene::ESNT_ANY, m_Nodes);

        for (irr::u32 __I = 0 ; __I < m_Nodes.size() ; __I++)
            m_Nodes[__I]->setAutomaticCulling(irr::scene::EAC_OFF);
    }
    ///--------------------------------------------------------------------------------
    /// Pour recrée le culling
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::Recreate()
    {
        m_Nodes.clear();
        Create();
    }

    ///--------------------------------------------------------------------------------
    /// Pour mettre a jour le culling
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::Update()
    {
        if (m_LastPosition == m_SceneManager->getActiveCamera()->getAbsolutePosition() && m_LastTarget == m_SceneManager->getActiveCamera()->getTarget())
            return;

        irr::core::matrix4 __MatrixProj, __MatrixView;

        __MatrixProj = m_SceneManager->getActiveCamera()->getProjectionMatrix();
        __MatrixView = m_SceneManager->getActiveCamera()->getViewMatrix();
        
        irr::core::matrix4 __VPI = __MatrixProj * __MatrixView;

        App::core::Plane __col0(__VPI(0,0), __VPI(1,0), __VPI(2,0), __VPI(3,0));
        App::core::Plane __col1(__VPI(0,1), __VPI(1,1), __VPI(2,1), __VPI(3,1));
        App::core::Plane __col2(__VPI(0,2), __VPI(1,2), __VPI(2,2), __VPI(3,2));
        App::core::Plane __col3(__VPI(0,3), __VPI(1,3), __VPI(2,3), __VPI(3,3));

        m_FrustumPlane[0] = __col2;         
        m_FrustumPlane[1] = (__col3 - __col2);
        m_FrustumPlane[2] = (__col3 + __col0);
        m_FrustumPlane[3] = (__col3 - __col0);
        m_FrustumPlane[4] = (__col3 - __col1);
        m_FrustumPlane[5] = (__col3 + __col1);
        
        for(int __I = 0 ; __I < 6 ; __I++)       
        {
            m_FrustumPlane[__I].Normalize();
        }

        for (irr::u32 __I = 0 ; __I < m_Nodes.size() ; ++__I)
        {
            if (m_Nodes[__I]->getType() == irr::scene::ESNT_ANIMATED_MESH
                || m_Nodes[__I]->getType() == irr::scene::ESNT_BILLBOARD
                || m_Nodes[__I]->getType() == irr::scene::ESNT_CUBE
                || m_Nodes[__I]->getType() == irr::scene::ESNT_MESH
                || m_Nodes[__I]->getType() == irr::scene::ESNT_OCT_TREE
                || m_Nodes[__I]->getType() == irr::scene::ESNT_PARTICLE_SYSTEM
                || m_Nodes[__I]->getType() == irr::scene::ESNT_SHADOW_VOLUME
                || m_Nodes[__I]->getType() == irr::scene::ESNT_SKY_BOX
                || m_Nodes[__I]->getType() == irr::scene::ESNT_SPHERE
                || m_Nodes[__I]->getType() == irr::scene::ESNT_TERRAIN
                || m_Nodes[__I]->getType() == irr::scene::ESNT_WATER_SURFACE
                )
            {
                irr::core::aabbox3d<irr::f32> _Box    = m_Nodes[__I]->getBoundingBox();
                irr::core::matrix4 _MatrixMesh    = m_Nodes[__I]->getAbsoluteTransformation();

                _MatrixMesh.transformBoxEx(_Box);
                if(IsVisible(_Box) == 0)
                    m_Nodes[__I]->setVisible(false);
                else
                    m_Nodes[__I]->setVisible(true);
            }
        }
    }

    ///--------------------------------------------------------------------------------
    /// Pour ajouter un scene node
    ///
    /// @param _SceneNode : Pointeur vers le scene node
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::AddSceneNode(const irr::scene::ISceneNode * _SceneNode)
    {
        ((irr::scene::ISceneNode*)_SceneNode)->setAutomaticCulling(irr::scene::EAC_OFF);
        m_Nodes.insert((irr::scene::ISceneNode*)_SceneNode);
    }
    ///--------------------------------------------------------------------------------
    /// Pour supprimer un scene node
    ///
    /// @param _SceneNode : Pointeur vers le scene node
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::RemoveSceneNode(const irr::scene::ISceneNode * _SceneNode)
    {
        for (irr::u32 __I = 0 ; __I < m_Nodes.size() ; __I++)
        {
            if (m_Nodes[__I] == _SceneNode)
                m_Nodes.erase(__I);
        }
    }

    ///--------------------------------------------------------------------------------
    /// Pour tester si une box et visible
    ///
    /// @param _Box : Box a tester
    ///--------------------------------------------------------------------------------
    bool FrustrumCulling::IsVisible(const irr::core::aabbox3d<irr::f32>& _Box)
    {
        float __P[3];
        float __Q[3];

        float __Min[3];    memcpy( __Min, &_Box.MinEdge.X, sizeof(float)*3);
        float __Max[3];    memcpy( __Max, &_Box.MaxEdge.X, sizeof(float)*3);
        
        for(int __I = 0 ; __I < 6 ; ++__I)
        {
            for(int __J = 0 ; __J < 3 ; ++__J)
            {

                if( m_FrustumPlane[__I][__J] >= 0.0f )
                {
                    __P[__J] = __Min[__J];
                    __Q[__J] = __Max[__J];
                }
                else
                {
                    __P[__J] = __Max[__J];
                    __Q[__J] = __Min[__J];
                }
            }
            if( m_FrustumPlane[__I].DotCoord(__Q) < 0.0f  )
                return false;
        }

        return true;
    }

}    // Culling
}    // Engine
}    // App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
///--------------------------------------------------------------------------------
/// @file Plane.hpp
/// @brief Plane pour les test
///--------------------------------------------------------------------------------
#ifndef __FPLANE_HPP_INCLUDED__
#define __FPLANE_HPP_INCLUDED__

#include <math.h>

namespace App { namespace core {

    ///--------------------------------------------------------------------------------
    /// Plane pour les test
    ///--------------------------------------------------------------------------------
    class Plane
    {
        public:
            ///--------------------------------------------------------------------------------
            /// Constructeur
            ///--------------------------------------------------------------------------------
            Plane();
            ///--------------------------------------------------------------------------------
            /// Constructeur
            ///
            /// @param _a : Point a
            /// @param _b : Point b
            /// @param _c : Point c
            /// @param _d : Point d
            ///--------------------------------------------------------------------------------
            Plane(float _a, float _b, float _c, float _d);

            ///--------------------------------------------------------------------------------
            /// Operateur de soustraction
            ///
            /// @param _Other : Autre Plan
            ///--------------------------------------------------------------------------------
            Plane operator-(const Plane& _Other) const;
            ///--------------------------------------------------------------------------------
            /// Operateur d'addition
            ///
            /// @param _Other : Autre Plan
            ///--------------------------------------------------------------------------------
            Plane operator+(const Plane& _Other) const;
            ///--------------------------------------------------------------------------------
            /// Operateur de tableau
            ///
            /// @param _I : Index
            ///--------------------------------------------------------------------------------
            float operator[](unsigned _I) const;

            ///--------------------------------------------------------------------------------
            /// Pour normaliser le plan
            ///--------------------------------------------------------------------------------
            void Normalize();
            ///--------------------------------------------------------------------------------
            /// Retourne l'addition de la multiplication des 4 point par une valeur
            ///
            /// @param _V : Facteur de multiplication
            ///--------------------------------------------------------------------------------
            float DotCoord(float *_V);

            ///--------------------------------------------------------------------------------
            /// Point a
            ///--------------------------------------------------------------------------------
            float a;
            ///--------------------------------------------------------------------------------
            /// Point b
            ///--------------------------------------------------------------------------------
            float b;
            ///--------------------------------------------------------------------------------
            /// Point c
            ///--------------------------------------------------------------------------------
            float c;
            ///--------------------------------------------------------------------------------
            /// Point d
            ///--------------------------------------------------------------------------------
            float d;
    };

}    // Engine
}    // App

#endif    // __FPLANE_HPP_INCLUDED__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
///--------------------------------------------------------------------------------
/// @file Plane.cpp
/// @brief Plane pour les test
///--------------------------------------------------------------------------------

#include "Plane.hpp"

namespace App { namespace core {

    ///--------------------------------------------------------------------------------
    /// Constructeur
    ///--------------------------------------------------------------------------------
    Plane::Plane()
        : a(0),b(0),c(0),d(0)
    {
    }
    ///--------------------------------------------------------------------------------
    /// Constructeur
    ///
    /// @param _a : Point a
    /// @param _b : Point b
    /// @param _c : Point c
    /// @param _d : Point d
    ///--------------------------------------------------------------------------------
    Plane::Plane(float _a, float _b, float _c, float _d)
        : a(_a), b(_b), c(_c), d(_d)
    {
    }

    ///--------------------------------------------------------------------------------
    /// Operateur de soustraction
    ///
    /// @param _Other : Autre Plan
    ///--------------------------------------------------------------------------------
    Plane Plane::operator-(const Plane& _Other) const
    {
        return Plane(a - _Other.a, b - _Other.b, c - _Other.c, d - _Other.d);
    }
    ///--------------------------------------------------------------------------------
    /// Operateur d'addition
    ///
    /// @param _Other : Autre Plan
    ///--------------------------------------------------------------------------------
    Plane Plane::operator+(const Plane& _Other) const
    {
        return Plane(a + _Other.a, b + _Other.b, c + _Other.c, d + _Other.d);
    }
    ///--------------------------------------------------------------------------------
    /// Operateur de tableau
    ///
    /// @param _I : Index
    ///--------------------------------------------------------------------------------
    float Plane::operator[](unsigned _I) const     
    {
        switch(_I)
        {
            case 0:
                return a;
            case 1:
                return b;
            case 2:
                return c;
            case 3:
                return d;
            default:
                return 0;   
        }   
    }

    ///--------------------------------------------------------------------------------
    /// Pour normaliser le plan
    ///--------------------------------------------------------------------------------
    void Plane::Normalize()
    {
        float _M;   
        _M = sqrt( a*a + b*b + c*c + d*d );   
        a = a / _M;   
        b = b / _M;   
        c = c / _M;   
        d = d / _M;   
    }

    ///--------------------------------------------------------------------------------
    /// Retourne l'addition de la multiplication des 4 point par une valeur
    ///
    /// @param _V : Facteur de multiplication
    ///--------------------------------------------------------------------------------
    float Plane::DotCoord(float *_V)
    {   
        return (a * _V[0] + b * _V[1] + c * _V[2] + d);   
    }
               
}    // Engine
}    // App


Donc voila alors pour l'utilisation ajouter juste avant la boucle de rendu

Code c++ :

App::Engine::Culling::FrustrumCulling * m_FrustrumCulling = new App::Engine::Culling::FrustrumCulling(m_SceneManager);
m_FrustrumCulling->Create();


et dans le boucle de rendu

Code c++ :

m_FrustrumCulling->Update();
m_Driver->beginScene(.........


=========================================

Exemple complet :

Code c++ :

#include <irrlicht.h>
#include "FrustrumCulling.hpp"

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

int main()
{
    irr::SIrrlichtCreationParameters m_IrrlichtCreationParameters;
    m_IrrlichtCreationParameters.AntiAlias            = true;
    m_IrrlichtCreationParameters.Bits                = 32;
    m_IrrlichtCreationParameters.DriverType            = irr::video::EDT_DIRECT3D9;
    m_IrrlichtCreationParameters.Fullscreen            = false;
    m_IrrlichtCreationParameters.HighPrecisionFPU    = true;
    m_IrrlichtCreationParameters.Stencilbuffer        = true;
    m_IrrlichtCreationParameters.WindowSize            = irr::core::dimension2di(800,600);

    irr::IrrlichtDevice            * m_Device            = irr::createDeviceEx(m_IrrlichtCreationParameters);
    irr::video::IVideoDriver    * m_Driver            = m_Device->getVideoDriver();
    irr::scene::ISceneManager    * m_SceneManager    = m_Device->getSceneManager();

    for( int x = 0 ; x != 10 ; x++)
        for( int y = 0 ; y != 10 ; y++)
            for( int z = 0 ; z != 10 ; z++)
                m_SceneManager->addCubeSceneNode(1, 0 , -1, irr::core::vector3df(x * 10 ,y* 10, z* 10));

    irr::scene::ICameraSceneNode * m_Camera = m_SceneManager->addCameraSceneNodeFPS(0, 40.f, 0.01f);
    m_Camera->setPosition(m_Camera->getPosition() + irr::core::vector3df(0,20,0));
   
    App::Engine::Culling::FrustrumCulling * m_FrustrumCulling = new App::Engine::Culling::FrustrumCulling(m_SceneManager);

    m_FrustrumCulling->Create();
    int __LastFPS = -1;

    while(m_Device->run())
    {
        if (m_Device->isWindowActive())
        {
            m_FrustrumCulling->Update();
            m_Driver->beginScene(true, true, irr::video::SColor(0,200,200,200));
            m_SceneManager->drawAll();
            m_Driver->endScene();
           
            int __Fps = m_Driver->getFPS();
            if (__LastFPS != __Fps)
            {
                core::stringw __Str;
                __Str += "FPS:";
                __Str += __Fps;
                m_Device->setWindowCaption(__Str.c_str());
                __LastFPS = __Fps;
            }

        }
    }
    delete m_FrustrumCulling;
    m_Device->drop();

    return 0;
}

Dernière modification par hardcpp (31-08-2009 01:33:42)

Hors ligne


#1 

27-06-2009 09:07:25

tmyke
Administrateur
Date d'inscription: 24-03-2008
Messages: 1025

Merci pour le partage de ces codes wink et cool de te voir passer dans le coin.

Irrlicht a bien besoin de ce genre de code pour améliorer ses performances wink

Merci.


Force et sagesse...

Hors ligne


#2 

27-06-2009 14:17:54

hardcpp
Abonné
Date d'inscription: 26-04-2008
Messages: 229

^^

Hors ligne


#3 

29-06-2009 19:53:55

Copland
Modérateur
Lieu: ZarbiLand
Date d'inscription: 22-09-2006
Messages: 657
Site web

Je croyais qu'irrlicht avait déjà son propre frustum culling, je comprends plus là :s


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#4 

29-06-2009 21:06:12

hardcpp
Abonné
Date d'inscription: 26-04-2008
Messages: 229

oui ca peut paraitre enbicieu mais mon system et plus performent environ 34fps sur une scene avec 1000 cube , celui de irrlicht bug un peu il faut carement que le node soit derriere la camera pour qui soit detecter comme non visible

Hors ligne


#5 

29-06-2009 21:47:29

tmyke
Administrateur
Date d'inscription: 24-03-2008
Messages: 1025

Je confirme.


Force et sagesse...

Hors ligne


#6 

30-06-2009 11:56:40

Metallizer
Abonné
Lieu: Région Parisienne
Date d'inscription: 07-01-2007
Messages: 100
Site web

J'ai pas encore testé ton code mais justement, si Irrlicht attend qu'un node soit bien derrière la caméra pour le cacher, ça doit être pour éviter le cas où le node est très grand.

Moi aussi en tout cas je suis interloqué, je croyais que le frustrum culling de Irrlicht agissait sur les triangles (et non les nodes) grâce à un octree... ou alors j'ai vraiment rien pigé.

Hors ligne


#7 

30-06-2009 17:05:17

hardcpp
Abonné
Date d'inscription: 26-04-2008
Messages: 229

il y a plusieur type de culling : frustrum, ambient, oclusion...

Dernière modification par hardcpp (01-07-2009 11:44:01)

Hors ligne


#8 

14-08-2011 22:36:31

thoced
Membre
Date d'inscription: 02-08-2010
Messages: 65

Allais je relance ce topic.

Et dans la version actuel d'Irrlicht. Ce probleme de Frustum est-t-il corrigé ?.

Car effectivement j'ai l'impression qu'avec la version 1.7.2, effectivement les nodes de l'octree ne sont pas visibile si seulement ils sont derrière la caméra.

Si je ne me trompe pas, ce probleme sera-t-il corrigé dans la version futur ?

merci

a+, thoced

Hors ligne


#9 

15-08-2011 05:04:50

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 904
Corrections: 2
Site web

le probleme est corriger sur le svn (1.8)
enfin sa bug encore un peut

Dernière modification par Magun (15-08-2011 05:07:22)

Hors ligne


#10 

15-08-2011 09:32:36

thoced
Membre
Date d'inscription: 02-08-2010
Messages: 65

Justement je viens juste de de compiler la version 1.8 (SVN) et j'ai toujours le meme probleme.

Mais bon pour être sur de ne pas dire de bètise: voici exactement comment je procède

1) je charge un mesh (petit terrain au format b3d)
2) je crée une node avec smgr->addOctreeSceneNode(...);
3) je spécifie le type culling node->setAutomaticCulling(EAC_FRUSTUM_BOX);

4) j'affiche le nombre de polygones qui s'affichent.

Et la je constate que lorsque je positionne ma camera sur le terrain, effectivement le nombre de poly diminue lorsque les nodes crée par l'octree se trouvent derrière la camera mais par contre lorsque je positionne la camera en hauteur en regardant vers le bas (un peu à la façon d'un jeu RTS), je constate que dés que qu'un node de l'octree se trouve dans le cone de visibilité, c'est l'ensemble du mesh qui est affiché parceque justement tous les nodes de l'octree se trouvent devant la camera.

merci de m'indiquer si je me trompe

a+, thoced

Hors ligne


#11 

16-08-2011 11:01:50

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 904
Corrections: 2
Site web

non c'est sa, mais dans ce cas intéresse toi a l'oclusion culling, en gros tu fait un raytest entre la camera et les tout nodes pour déterminer leur visibiliter
par contre c'est lent, mais facil a interfacer dans un thread séparé

Hors ligne


#12 

17-08-2011 23:38:04

thoced
Membre
Date d'inscription: 02-08-2010
Messages: 65

Je trouve franchement dommage que dans un moteur graphique, le Frustum culling ne soit pas encore complètement correctement implémenté.
C'est quand même les bases je pense surtout si l'on veut que le moteur perdure dans le temps.

Attention je n'ai pas dit que c'était facile a développer mais je trouve que les choix pris pour l'amélioration du moteur sont parfois étrange.

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
Analysé par
880 membres
1424 sujets
11113 messages
Dernier membre inscrit: mandrifidy
21 invités en ligne
Aucun membre connecté
RSS Feed