svn merge ^/trunk/blender -r43124:43160
[blender.git] / source / gameengine / Rasterizer / RAS_MaterialBucket.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file RAS_MaterialBucket.h
29  *  \ingroup bgerast
30  */
31
32 #ifndef __RAS_MATERIALBUCKET
33 #define __RAS_MATERIALBUCKET
34
35 #include "RAS_TexVert.h"
36 #include "CTR_Map.h"
37 #include "STR_HashedString.h"
38 #include "SG_QList.h"
39
40 #include "MT_Transform.h"
41 #include "RAS_IPolygonMaterial.h"
42 #include "RAS_IRasterizer.h"
43 #include "RAS_Deformer.h"
44
45 #include <vector>
46 #include <set>
47 #include <list>
48 using namespace std;
49
50 /* Display List Slot */
51
52 class KX_ListSlot
53 {
54 protected:
55         int m_refcount;
56 public:
57         KX_ListSlot(){ m_refcount=1; }
58         virtual ~KX_ListSlot() {}
59         virtual int Release() { 
60                 if (--m_refcount > 0)
61                         return m_refcount;
62                 delete this;
63                 return 0;
64         }
65         virtual KX_ListSlot* AddRef() {
66                 m_refcount++;
67                 return this;
68         }
69         virtual void SetModified(bool mod)=0;
70 };
71
72 class RAS_DisplayArray;
73 class RAS_MeshSlot;
74 class RAS_MeshMaterial;
75 class RAS_MaterialBucket;
76 struct DerivedMesh;
77
78 /* An array with data used for OpenGL drawing */
79
80 class RAS_DisplayArray
81 {
82 public:
83         vector<RAS_TexVert> m_vertex;
84         vector<unsigned short> m_index;
85         /* LINE currently isnt used */
86         enum { LINE = 2, TRIANGLE = 3, QUAD = 4 } m_type;
87         //RAS_MeshSlot *m_origSlot;
88         
89         /* Number of RAS_MeshSlot using this array */
90         int m_users;
91
92         enum { BUCKET_MAX_INDEX = 65535 };
93         enum { BUCKET_MAX_VERTEX = 65535 };
94 };
95
96 /* Entry of a RAS_MeshObject into RAS_MaterialBucket */
97 typedef std::vector<RAS_DisplayArray*>  RAS_DisplayArrayList;
98
99 // The QList is used to link the mesh slots to the object
100 // The DList is used to link the visible mesh slots to the material bucket
101 class RAS_MeshSlot : public SG_QList
102 {
103         friend class RAS_ListRasterizer;
104 private:
105         //  indices into display arrays
106         int                                                     m_startarray;
107         int                                                     m_endarray;
108         int                                                     m_startindex;
109         int                                                     m_endindex;
110         int                                                     m_startvertex;
111         int                                                     m_endvertex;
112         RAS_DisplayArrayList            m_displayArrays;
113
114         // for construction only
115         RAS_DisplayArray*                       m_currentArray;
116
117 public:
118         // for rendering
119         RAS_MaterialBucket*             m_bucket;
120         RAS_MeshObject*                 m_mesh;
121         void*                                   m_clientObj;
122         RAS_Deformer*                   m_pDeformer;
123         DerivedMesh*                    m_pDerivedMesh;
124         double*                                 m_OpenGLMatrix;
125         // visibility
126         bool                                    m_bVisible;
127         bool                                    m_bCulled;
128         // object color
129         bool                                    m_bObjectColor;
130         MT_Vector4                              m_RGBAcolor;
131         // display lists
132         KX_ListSlot*                    m_DisplayList;
133         bool                                    m_bDisplayList;
134         // joined mesh slots
135         RAS_MeshSlot*                   m_joinSlot;
136         MT_Matrix4x4                    m_joinInvTransform;
137         list<RAS_MeshSlot*>             m_joinedSlots;
138
139         RAS_MeshSlot();
140         RAS_MeshSlot(const RAS_MeshSlot& slot);
141         virtual ~RAS_MeshSlot();
142         
143         void init(RAS_MaterialBucket *bucket, int numverts);
144
145         struct iterator {
146                 RAS_DisplayArray *array;
147                 RAS_TexVert *vertex;
148                 unsigned short *index;
149                 size_t startvertex;
150                 size_t endvertex;
151                 size_t totindex;
152                 size_t arraynum;
153         };
154
155         void begin(iterator& it);
156         void next(iterator& it);
157         bool end(iterator& it);
158
159         /* used during construction */
160         void SetDisplayArray(int numverts);
161         RAS_DisplayArray *CurrentDisplayArray();
162         void SetDeformer(RAS_Deformer* deformer);
163
164         void AddPolygon(int numverts);
165         int AddVertex(const RAS_TexVert& tv);
166         void AddPolygonVertex(int offset);
167
168         /* optimization */
169         bool Split(bool force=false);
170         bool Join(RAS_MeshSlot *target, MT_Scalar distance);
171         bool Equals(RAS_MeshSlot *target);
172 #ifdef USE_SPLIT
173         bool IsCulled();
174 #else
175         bool IsCulled() { return m_bCulled; }
176 #endif
177         void SetCulled(bool culled) { m_bCulled = culled; }
178         
179         
180 #ifdef WITH_CXX_GUARDEDALLOC
181 public:
182         void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_MeshSlot"); }
183         void operator delete( void *mem ) { MEM_freeN(mem); }
184 #endif
185 };
186
187 /* Used by RAS_MeshObject, to point to it's slots in a bucket */
188
189 class RAS_MeshMaterial
190 {
191 public:
192         RAS_MeshSlot *m_baseslot;
193         class RAS_MaterialBucket *m_bucket;
194         CTR_Map<CTR_HashedPtr,RAS_MeshSlot*> m_slots;
195
196
197 #ifdef WITH_CXX_GUARDEDALLOC
198 public:
199         void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_MeshMaterial"); }
200         void operator delete( void *mem ) { MEM_freeN(mem); }
201 #endif
202 };
203
204 /* Contains a list of display arrays with the same material,
205  * and a mesh slot for each mesh that uses display arrays in
206  * this bucket */
207
208 class RAS_MaterialBucket
209 {
210 public:
211         RAS_MaterialBucket(RAS_IPolyMaterial* mat);
212         virtual ~RAS_MaterialBucket();
213         
214         /* Bucket Sorting */
215         struct less;
216         typedef set<RAS_MaterialBucket*, less> Set;
217
218         /* Material Properties */
219         RAS_IPolyMaterial*              GetPolyMaterial() const;
220         bool                                    IsAlpha() const;
221         bool                                    IsZSort() const;
222                 
223         /* Rendering */
224         bool ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
225                 RAS_IRenderTools *rendertools);
226         void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
227                 RAS_IRenderTools* rendertools, RAS_MeshSlot &ms);
228         
229         /* Mesh Slot Access */
230         list<RAS_MeshSlot>::iterator msBegin();
231         list<RAS_MeshSlot>::iterator msEnd();
232
233         class RAS_MeshSlot*     AddMesh(int numverts);
234         class RAS_MeshSlot* CopyMesh(class RAS_MeshSlot *ms);
235         void                            RemoveMesh(class RAS_MeshSlot* ms);
236         void                            Optimize(MT_Scalar distance);
237         void                            ActivateMesh(RAS_MeshSlot* slot)
238         {
239                 m_activeMeshSlotsHead.AddBack(slot);
240         }
241         SG_DList&                       GetActiveMeshSlots()
242         {
243                 return m_activeMeshSlotsHead;
244         }
245         RAS_MeshSlot*           GetNextActiveMeshSlot()
246         {
247                 return (RAS_MeshSlot*)m_activeMeshSlotsHead.Remove();
248         }
249
250 private:
251         list<RAS_MeshSlot>                      m_meshSlots;                    // all the mesh slots
252         RAS_IPolyMaterial*                      m_material;
253         SG_DList                                        m_activeMeshSlotsHead;  // only those which must be rendered
254         
255
256 #ifdef WITH_CXX_GUARDEDALLOC
257 public:
258         void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_MaterialBucket"); }
259         void operator delete( void *mem ) { MEM_freeN(mem); }
260 #endif
261 };
262
263 #endif //__RAS_MATERIAL_BUCKET
264