1 /***********************************************************************
2     created:    Tue Mar 10 2009
3     author:     Paul D Turner (parts based on code by Keith Mok)
4 *************************************************************************/
5 /***************************************************************************
6  *   Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
7  *
8  *   Permission is hereby granted, free of charge, to any person obtaining
9  *   a copy of this software and associated documentation files (the
10  *   "Software"), to deal in the Software without restriction, including
11  *   without limitation the rights to use, copy, modify, merge, publish,
12  *   distribute, sublicense, and/or sell copies of the Software, and to
13  *   permit persons to whom the Software is furnished to do so, subject to
14  *   the following conditions:
15  *
16  *   The above copyright notice and this permission notice shall be
17  *   included in all copies or substantial portions of the Software.
18  *
19  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  *   OTHER DEALINGS IN THE SOFTWARE.
26  ***************************************************************************/
27 #include "CEGUI/RendererModules/DirectFB/GeometryBuffer.h"
28 #include "CEGUI/RendererModules/DirectFB/Texture.h"
29 #include "CEGUI/RenderEffect.h"
30 #include "CEGUI/Vertex.h"
31 
32 // Start of CEGUI namespace section
33 namespace CEGUI
34 {
35 //----------------------------------------------------------------------------//
DirectFBGeometryBuffer(DirectFBRenderer & owner)36 DirectFBGeometryBuffer::DirectFBGeometryBuffer(DirectFBRenderer& owner) :
37     d_owner(owner),
38     d_activeTexture(0),
39     d_clipRect(0, 0, 0, 0),
40     d_clippingActive(true),
41     d_translation(0, 0, 0),
42     d_rotation(0, 0, 0),
43     d_pivot(0, 0, 0),
44     d_effect(0),
45     d_matrixValid(false)
46 {
47 }
48 
49 //----------------------------------------------------------------------------//
~DirectFBGeometryBuffer()50 DirectFBGeometryBuffer::~DirectFBGeometryBuffer()
51 {
52 }
53 
54 //----------------------------------------------------------------------------//
draw() const55 void DirectFBGeometryBuffer::draw() const
56 {
57     IDirectFBSurface* target_surface = &d_owner.getTargetSurface();
58 
59     DFBRegion saved_clip;
60     target_surface->GetClip(target_surface, &saved_clip);
61 
62     // setup clip region
63     const DFBRegion clip_region = {
64         static_cast<int>(d_clipRect.left()),
65         static_cast<int>(d_clipRect.top()),
66         static_cast<int>(d_clipRect.right()),
67         static_cast<int>(d_clipRect.bottom()) };
68 
69     // apply the transformations we need to use.
70     if (!d_matrixValid)
71         updateMatrix();
72 
73     target_surface->SetMatrix(target_surface, d_matrix);
74 
75     const int pass_count = d_effect ? d_effect->getPassCount() : 1;
76     for (int pass = 0; pass < pass_count; ++pass)
77     {
78         // set up RenderEffect
79         if (d_effect)
80             d_effect->performPreRenderFunctions(pass);
81 
82         // draw the batches
83         size_t pos = 0;
84         BatchList::const_iterator i = d_batches.begin();
85         for ( ; i != d_batches.end(); ++i)
86         {
87             if (i->clip)
88                 target_surface->SetClip(target_surface, &clip_region);
89 
90             target_surface->TextureTriangles(target_surface, i->texture,
91                                             &d_vertices[pos], 0, i->vertexCount,
92                                             DTTF_LIST);
93             pos += i->vertexCount;
94 
95             if (i->clip)
96                 target_surface->SetClip(target_surface, &saved_clip);
97         }
98     }
99 
100     // clean up RenderEffect
101     if (d_effect)
102         d_effect->performPostRenderFunctions();
103 }
104 
105 //----------------------------------------------------------------------------//
setTranslation(const Vector3f & v)106 void DirectFBGeometryBuffer::setTranslation(const Vector3f& v)
107 {
108     d_translation = v;
109     d_matrixValid = false;
110 }
111 
112 //----------------------------------------------------------------------------//
setRotation(const Quaternion & r)113 void DirectFBGeometryBuffer::setRotation(const Quaternion& r)
114 {
115     d_rotation = r;
116     d_matrixValid = false;
117 }
118 
119 //----------------------------------------------------------------------------//
setPivot(const Vector3f & p)120 void DirectFBGeometryBuffer::setPivot(const Vector3f& p)
121 {
122     d_pivot = p;
123     d_matrixValid = false;
124 }
125 
126 //----------------------------------------------------------------------------//
setClippingRegion(const Rectf & region)127 void DirectFBGeometryBuffer::setClippingRegion(const Rectf& region)
128 {
129     d_clipRect.top(ceguimax(0.0f, region.top()));
130     d_clipRect.bottom(ceguimax(0.0f, region.bottom()));
131     d_clipRect.left(ceguimax(0.0f, region.left()));
132     d_clipRect.right(ceguimax(0.0f, region.right()));
133 }
134 
135 //----------------------------------------------------------------------------//
appendVertex(const Vertex & vertex)136 void DirectFBGeometryBuffer::appendVertex(const Vertex& vertex)
137 {
138     appendGeometry(&vertex, 1);
139 }
140 
141 //----------------------------------------------------------------------------//
appendGeometry(const Vertex * const vbuff,uint vertex_count)142 void DirectFBGeometryBuffer::appendGeometry(const Vertex* const vbuff,
143                                             uint vertex_count)
144 {
145     IDirectFBSurface* t =
146         d_activeTexture ? d_activeTexture->getDirectFBSurface() : 0;
147 
148     // create a new batch if there are no batches yet, or if the active texture
149     // differs from that used by the current batch.
150     if (d_batches.empty() ||
151         t != d_batches.back().texture ||
152         d_clippingActive != d_batches.back().clip)
153     {
154         const BatchInfo batch = {t, 0, d_clippingActive};
155         d_batches.push_back(batch);
156     }
157 
158     // update size of current batch
159     d_batches.back().vertexCount += vertex_count;
160 
161     // buffer these vertices
162     DFBVertex vd;
163     const Vertex* vs = vbuff;
164     for (uint i = 0; i < vertex_count; ++i, ++vs)
165     {
166         // copy vertex info the buffer, converting from CEGUI::Vertex to
167         // something directly usable by DirectFB as needed.
168         vd.x       = vs->position.d_x;
169         vd.y       = vs->position.d_y;
170         vd.z       = vs->position.d_z;
171         vd.w       = 1.0f;
172         //vd.diffuse = vs->colour_val.getARGB();
173         vd.s       = vs->tex_coords.d_x;
174         vd.t       = vs->tex_coords.d_y;
175         d_vertices.push_back(vd);
176     }
177 }
178 
179 //----------------------------------------------------------------------------//
setActiveTexture(Texture * texture)180 void DirectFBGeometryBuffer::setActiveTexture(Texture* texture)
181 {
182     d_activeTexture = static_cast<DirectFBTexture*>(texture);
183 }
184 
185 //----------------------------------------------------------------------------//
reset()186 void DirectFBGeometryBuffer::reset()
187 {
188     d_batches.clear();
189     d_vertices.clear();
190     d_activeTexture = 0;
191 }
192 
193 //----------------------------------------------------------------------------//
getActiveTexture() const194 Texture* DirectFBGeometryBuffer::getActiveTexture() const
195 {
196     return d_activeTexture;
197 }
198 
199 //----------------------------------------------------------------------------//
getVertexCount() const200 uint DirectFBGeometryBuffer::getVertexCount() const
201 {
202     return d_vertices.size();
203 }
204 
205 //----------------------------------------------------------------------------//
getBatchCount() const206 uint DirectFBGeometryBuffer::getBatchCount() const
207 {
208     return d_batches.size();
209 }
210 
211 //----------------------------------------------------------------------------//
setRenderEffect(RenderEffect * effect)212 void DirectFBGeometryBuffer::setRenderEffect(RenderEffect* effect)
213 {
214     d_effect = effect;
215 }
216 
217 //----------------------------------------------------------------------------//
getRenderEffect()218 RenderEffect* DirectFBGeometryBuffer::getRenderEffect()
219 {
220     return d_effect;
221 }
222 
223 //----------------------------------------------------------------------------//
updateMatrix() const224 void DirectFBGeometryBuffer::updateMatrix() const
225 {
226     // TODO:
227 
228     d_matrix[0] = 0x00010000;
229     d_matrix[1] = 0x00000000;
230     d_matrix[2] = 0x00000000;
231     d_matrix[3] = 0x00000000;
232     d_matrix[4] = 0x00010000;
233     d_matrix[5] = 0x00000000;
234     d_matrix[6] = 0x00000000;
235     d_matrix[7] = 0x00000000;
236     d_matrix[8] = 0x00010000;
237 
238     d_matrixValid = true;
239 }
240 
241 //----------------------------------------------------------------------------//
setClippingActive(const bool active)242 void DirectFBGeometryBuffer::setClippingActive(const bool active)
243 {
244     d_clippingActive = active;
245 }
246 
247 //----------------------------------------------------------------------------//
isClippingActive() const248 bool DirectFBGeometryBuffer::isClippingActive() const
249 {
250     return d_clippingActive;
251 }
252 
253 //----------------------------------------------------------------------------//
254 
255 } // End of  CEGUI namespace section
256