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