1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nel/3d/computed_string.h"
23 #include "nel/3d/texture.h"
24 #include "nel/3d/index_buffer.h"
25 #include "nel/3d/material.h"
26 #include "nel/3d/frustum.h"
27 #include "nel/3d/viewport.h"
28 #include "nel/3d/debug_vb.h"
30 #include "nel/misc/smart_ptr.h"
31 #include "nel/misc/debug.h"
33 #include "nel/misc/file.h"
34 #include "nel/misc/fast_mem.h"
45 /*------------------------------------------------------------------*\
47 \*------------------------------------------------------------------*/
48 CVector
CComputedString::getHotSpotVector(THotSpot hotspot
)
50 CVector
hotspotVector(0,0,0);
52 if (hotspot
==MiddleLeft
)
53 hotspotVector
= CVector(0,0,-StringHeight
/2);
56 hotspotVector
= CVector(0,0,-StringHeight
);
58 if (hotspot
==MiddleBottom
)
59 hotspotVector
= CVector(-StringWidth
/2,0,0);
61 if (hotspot
==MiddleMiddle
)
62 hotspotVector
= CVector(-StringWidth
/2,0,-StringHeight
/2);
64 if (hotspot
==MiddleTop
)
65 hotspotVector
= CVector(-StringWidth
/2,0,-StringHeight
);
67 if (hotspot
==BottomRight
)
68 hotspotVector
= CVector(-StringWidth
,0,0);
70 if (hotspot
==MiddleRight
)
71 hotspotVector
= CVector(-StringWidth
,0,-StringHeight
/2);
73 if (hotspot
==TopRight
)
74 hotspotVector
= CVector(-StringWidth
,0,-StringHeight
);
80 /*------------------------------------------------------------------*\
82 \*------------------------------------------------------------------*/
83 void CComputedString::render2D (IDriver
& driver
,
86 float scaleX
, float scaleZ
,
88 bool useScreenAR43
, bool roundToNearestPixel
91 if (Vertices
.getNumVertices() == 0)
95 uint32 wndWidth
, wndHeight
;
96 driver
.getWindowSize(wndWidth
, wndHeight
);
98 driver
.getViewport(vp
);
99 wndWidth
= (uint32
)((float)wndWidth
* vp
.getWidth());
100 wndHeight
= (uint32
)((float)wndHeight
* vp
.getHeight());
101 // scale to window size.
105 driver
.setFrustum(0, (float)wndWidth
, 0, (float)wndHeight
, -1, 1, false); // resX/resY
107 // Computing hotspot translation vector
108 CVector hotspotVector
= getHotSpotVector(hotspot
);
110 // transformation matrix initialized to identity
114 // view matrix <-> identity
115 driver
.setupViewMatrix(matrix
);
118 // centering to hotspot, then scaling, rotating, and translating.
119 matrix
.translate(CVector(x
,0,z
));
120 matrix
.rotateY(rotateY
);
121 matrix
.scale(CVector(scaleX
,1,scaleZ
));
122 // scale the string to follow window aspect Ratio
125 matrix
.scale(CVector((3.0f
*wndWidth
)/(4.0f
*wndHeight
),1,1));
127 matrix
.translate(hotspotVector
);
128 // if roundToNearestPixel, then snap the position to the nearest pixel
129 if( roundToNearestPixel
)
131 CVector pos
= matrix
.getPos();
132 pos
.x
= (float)floor(pos
.x
+0.5f
);
133 pos
.z
= (float)floor(pos
.z
+0.5f
);
137 driver
.setupModelMatrix(matrix
);
139 driver
.activeVertexBuffer(Vertices
);
141 // rendering each primitives
142 Material
->setZFunc (CMaterial::always
);
143 Material
->setZWrite (false);
144 Material
->setColor (Color
);
145 // Clamp for selection
146 uint32 nNumQuad
= Vertices
.getNumVertices()/4;
147 driver
.renderRawQuads (*Material
, SelectStart
*4, min(nNumQuad
, SelectSize
) );
151 /*------------------------------------------------------------------*\
153 \*------------------------------------------------------------------*/
154 void CComputedString::render3D (IDriver
& driver
, const CMatrix
&matrixp
, THotSpot hotspot
)
156 if (Vertices
.getNumVertices() == 0)
159 CMatrix matrix
= matrixp
;
162 uint32 wndWidth
, wndHeight
;
163 driver
.getWindowSize(wndWidth
, wndHeight
);
164 // scale according to window height (backward compatibility)
165 matrix
.scale(1.0f
/wndHeight
);
167 // Computing hotspot translation vector
168 CVector hotspotVector
= getHotSpotVector(hotspot
);
169 matrix
.translate(hotspotVector
);
172 driver
.setupModelMatrix(matrix
);
173 driver
.activeVertexBuffer(Vertices
);
175 // Rendering each primitive blocks
176 Material
->setZFunc (CMaterial::lessequal
);
177 Material
->setZWrite (true);
178 Material
->setColor (Color
);
179 // Clamp for selection
180 uint32 nNumQuad
= Vertices
.getNumVertices()/4;
181 driver
.renderRawQuads (*Material
, SelectStart
*4, min(nNumQuad
, SelectSize
) );
185 /*------------------------------------------------------------------*\
187 \*------------------------------------------------------------------*/
188 void CComputedString::render2DClip (IDriver
& driver
, CRenderStringBuffer
&rdrBuffer
,
190 float xmin
, float zmin
, float xmax
, float zmax
)
192 if (Vertices
.getNumVertices() == 0)
198 uint32 wndWidth
, wndHeight
;
199 driver
.getWindowSize(wndWidth
, wndHeight
);
200 // scale to window size.
208 // Test String Bound against clip window
209 // If entirely out skip
210 if (((x
+XMin
) > xmax
) || ((x
+XMax
) < xmin
) ||
211 ((z
+ZMin
) > zmax
) || ((z
+ZMax
) < zmin
))
214 // test if entirely in.
216 allIn
= ((x
+XMin
) >= xmin
) && ((x
+XMax
) <= xmax
) &&
217 ((z
+ZMin
) >= zmin
) && ((z
+ZMax
) <= zmax
);
220 // How many quad to render?
221 uint nNumQuadSrc
= Vertices
.getNumVertices()/4;
222 nNumQuadSrc
= min(nNumQuadSrc
, (uint
)SelectSize
);
224 // Enlarge dest Buffer if needed
225 if( (rdrBuffer
.NumQuads
+nNumQuadSrc
)*4 > rdrBuffer
.Vertices
.getNumVertices() )
227 rdrBuffer
.Vertices
.setNumVertices( (rdrBuffer
.NumQuads
+nNumQuadSrc
)*4 );
231 CVertexBuffer::TVertexColorType vtype
= driver
.getVertexColorFormat();
232 Vertices
.setVertexColorFormat (vtype
);
233 rdrBuffer
.Vertices
.setVertexColorFormat (vtype
);
234 CVertexBufferReadWrite srcvba
;
235 Vertices
.lock (srcvba
);
236 CVertexBufferReadWrite dstvba
;
237 rdrBuffer
.Vertices
.lock (dstvba
);
238 sint ofsSrcUV
= Vertices
.getTexCoordOff();
239 sint ofsDstUV
= rdrBuffer
.Vertices
.getTexCoordOff();
240 sint ofsDstColor
= rdrBuffer
.Vertices
.getColorOff();
241 uint8
*srcPtr
= (uint8
*)srcvba
.getVertexCoordPointer();
242 uint8
*dstPtr
= (uint8
*)dstvba
.getVertexCoordPointer(rdrBuffer
.NumQuads
*4);
243 sint srcSize
= Vertices
.getVertexSize();
244 sint dstSize
= rdrBuffer
.Vertices
.getVertexSize();
246 // decal src for selection
247 srcPtr
+= SelectStart
*4 * srcSize
;
255 uint numVerts
= nNumQuadSrc
*4;
258 for(uint i
=0;i
<numVerts
;i
++)
262 if(!LetterColors
.empty())
264 if(LetterColors
.getIndex(lastIndex
)==i
/4)
266 mCol
.modulateFromColor(Color
, LetterColors
.getColor(lastIndex
));
268 if(lastIndex
+1<LetterColors
.size())
278 // copy and translate pos
279 CHECK_VBA_RANGE(srcvba
, srcPtr
, Vertices
.getVertexSize());
280 CHECK_VBA_RANGE(dstvba
, dstPtr
, rdrBuffer
.Vertices
.getVertexSize())
281 ((CVector
*)dstPtr
)->x
= x
+ ((CVector
*)srcPtr
)->x
;
282 ((CVector
*)dstPtr
)->y
= ((CVector
*)srcPtr
)->y
;
283 ((CVector
*)dstPtr
)->z
= z
+ ((CVector
*)srcPtr
)->z
;
285 *((CUV
*)(dstPtr
+ofsDstUV
))= *((CUV
*)(srcPtr
+ofsSrcUV
));
287 if (vtype
== CVertexBuffer::TRGBA
)
288 *((CRGBA
*)(dstPtr
+ofsDstColor
))= mCol
;
290 *((CBGRA
*)(dstPtr
+ofsDstColor
))= mCol
;
298 // update the rdrBuffer
299 rdrBuffer
.NumQuads
+= nNumQuadSrc
;
303 uint nNumQuadClipped
= 0;
305 // the real number of vertices to compute (with selection)
306 uint numVerts
= nNumQuadSrc
*4;
308 // clip into VerticesClipped
309 CVector
*pIniPos0
= (CVector
*)srcPtr
;
310 CVector
*pIniPos2
= (CVector
*)(((uint8
*)pIniPos0
) + srcSize
*2);
311 CVector
*pClipPos0
= (CVector
*)dstPtr
;
312 CVector
*pClipPos1
= (CVector
*)(((uint8
*)pClipPos0
) + dstSize
);
313 CVector
*pClipPos2
= (CVector
*)(((uint8
*)pClipPos1
) + dstSize
);
314 CVector
*pClipPos3
= (CVector
*)(((uint8
*)pClipPos2
) + dstSize
);
315 CUV
*pClipUV0
= (CUV
*)(dstPtr
+ ofsDstUV
);
316 CUV
*pClipUV1
= (CUV
*)(((uint8
*)pClipUV0
) + dstSize
);
317 CUV
*pClipUV2
= (CUV
*)(((uint8
*)pClipUV1
) + dstSize
);
318 CUV
*pClipUV3
= (CUV
*)(((uint8
*)pClipUV2
) + dstSize
);
323 for (uint32 i
= 0; i
< numVerts
; i
+=4)
325 if (((x
+pIniPos0
->x
) > xmax
) || ((x
+pIniPos2
->x
) < xmin
) ||
326 ((z
+pIniPos0
->z
) > zmax
) || ((z
+pIniPos2
->z
) < zmin
))
328 // Totally clipped do nothing
332 if(!LetterColors
.empty())
334 if(LetterColors
.getIndex(lastIndex
)==(i
/4))
336 mCol
.modulateFromColor(Color
, LetterColors
.getColor(lastIndex
));
338 if(lastIndex
+1<LetterColors
.size())
347 *((CVector
*) (dstPtr
+ dstSize
*0))= *((CVector
*) (srcPtr
+ srcSize
*0));
348 *((CUV
*) (dstPtr
+ dstSize
*0 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*0 + ofsSrcUV
));
349 if (vtype
== CVertexBuffer::TRGBA
)
350 *((CRGBA
*) (dstPtr
+ dstSize
*0 + ofsDstColor
))= mCol
;
352 *((CBGRA
*) (dstPtr
+ dstSize
*0 + ofsDstColor
))= mCol
;
354 *((CVector
*) (dstPtr
+ dstSize
*1))= *((CVector
*) (srcPtr
+ srcSize
*1));
355 *((CUV
*) (dstPtr
+ dstSize
*1 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*1 + ofsSrcUV
));
356 if (vtype
== CVertexBuffer::TRGBA
)
357 *((CRGBA
*) (dstPtr
+ dstSize
*1 + ofsDstColor
))= mCol
;
359 *((CBGRA
*) (dstPtr
+ dstSize
*1 + ofsDstColor
))= mCol
;
361 *((CVector
*) (dstPtr
+ dstSize
*2))= *((CVector
*) (srcPtr
+ srcSize
*2));
362 *((CUV
*) (dstPtr
+ dstSize
*2 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*2 + ofsSrcUV
));
363 if (vtype
== CVertexBuffer::TRGBA
)
364 *((CRGBA
*) (dstPtr
+ dstSize
*2 + ofsDstColor
))= mCol
;
366 *((CBGRA
*) (dstPtr
+ dstSize
*2 + ofsDstColor
))= mCol
;
368 *((CVector
*) (dstPtr
+ dstSize
*3))= *((CVector
*) (srcPtr
+ srcSize
*3));
369 *((CUV
*) (dstPtr
+ dstSize
*3 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*3 + ofsSrcUV
));
370 if (vtype
== CVertexBuffer::TRGBA
)
371 *((CRGBA
*) (dstPtr
+ dstSize
*3 + ofsDstColor
))= mCol
;
373 *((CBGRA
*) (dstPtr
+ dstSize
*3 + ofsDstColor
))= mCol
;
376 pClipPos0
->x
+= x
; pClipPos1
->x
+= x
; pClipPos2
->x
+= x
; pClipPos3
->x
+= x
;
377 pClipPos0
->z
+= z
; pClipPos1
->z
+= z
; pClipPos2
->z
+= z
; pClipPos3
->z
+= z
;
378 if ((pClipPos0
->x
>= xmin
) && (pClipPos0
->z
>= zmin
) && (pClipPos2
->x
<= xmax
) && (pClipPos2
->z
<= zmax
))
386 if (pClipPos0
->x
< xmin
)
388 ratio
= ((float)(xmin
- pClipPos0
->x
))/((float)(pClipPos1
->x
- pClipPos0
->x
));
389 pClipPos3
->x
= pClipPos0
->x
= xmin
;
390 pClipUV0
->U
+= ratio
*(pClipUV1
->U
- pClipUV0
->U
);
391 pClipUV3
->U
+= ratio
*(pClipUV2
->U
- pClipUV3
->U
);
394 if (pClipPos0
->z
< zmin
)
396 ratio
= ((float)(zmin
- pClipPos0
->z
))/((float)(pClipPos3
->z
- pClipPos0
->z
));
397 pClipPos1
->z
= pClipPos0
->z
= zmin
;
398 pClipUV0
->V
+= ratio
*(pClipUV3
->V
- pClipUV0
->V
);
399 pClipUV1
->V
+= ratio
*(pClipUV2
->V
- pClipUV1
->V
);
402 if (pClipPos2
->x
> xmax
)
404 ratio
= ((float)(xmax
- pClipPos2
->x
))/((float)(pClipPos3
->x
- pClipPos2
->x
));
405 pClipPos2
->x
= pClipPos1
->x
= xmax
;
406 pClipUV2
->U
+= ratio
*(pClipUV3
->U
- pClipUV2
->U
);
407 pClipUV1
->U
+= ratio
*(pClipUV0
->U
- pClipUV1
->U
);
410 if (pClipPos2
->z
> zmax
)
412 ratio
= ((float)(zmax
- pClipPos2
->z
))/((float)(pClipPos1
->z
- pClipPos2
->z
));
413 pClipPos2
->z
= pClipPos3
->z
= zmax
;
414 pClipUV2
->V
+= ratio
*(pClipUV1
->V
- pClipUV2
->V
);
415 pClipUV3
->V
+= ratio
*(pClipUV0
->V
- pClipUV3
->V
);
421 pClipPos0
= (CVector
*)(((uint8
*)pClipPos0
) + dstSize
*4);
422 pClipPos1
= (CVector
*)(((uint8
*)pClipPos0
) + dstSize
);
423 pClipPos2
= (CVector
*)(((uint8
*)pClipPos1
) + dstSize
);
424 pClipPos3
= (CVector
*)(((uint8
*)pClipPos2
) + dstSize
);
425 pClipUV0
= (CUV
*)( ((uint8
*)pClipUV0
) + dstSize
*4 );
426 pClipUV1
= (CUV
*)(((uint8
*)pClipUV0
) + dstSize
);
427 pClipUV2
= (CUV
*)(((uint8
*)pClipUV1
) + dstSize
);
428 pClipUV3
= (CUV
*)(((uint8
*)pClipUV2
) + dstSize
);
432 pIniPos0
= (CVector
*)(((uint8
*)pIniPos0
) + srcSize
*4);
433 pIniPos2
= (CVector
*)(((uint8
*)pIniPos0
) + srcSize
*2);
437 // update the rdrBuffer
438 rdrBuffer
.NumQuads
+= nNumQuadClipped
;
442 /*------------------------------------------------------------------*\
443 render2DUnProjected()
444 \*------------------------------------------------------------------*/
445 void CComputedString::render2DUnProjected (IDriver
& driver
, CRenderStringBuffer
&rdrBuffer
, class NL3D::CFrustum
&frustum
,
446 const NLMISC::CMatrix
&scaleMatrix
, float x
, float z
, float depth
, float xmin
, float zmin
, float xmax
, float zmax
)
448 if (Vertices
.getNumVertices() == 0)
454 uint32 wndWidth
, wndHeight
;
455 driver
.getWindowSize(wndWidth
, wndHeight
);
456 // scale to window size.
464 // Test String Bound against clip window
465 // If entirely out skip
466 if (((x
+XMin
) > xmax
) || ((x
+XMax
) < xmin
) ||
467 ((z
+ZMin
) > zmax
) || ((z
+ZMax
) < zmin
))
470 // test if entirely in.
472 allIn
= ((x
+XMin
) >= (xmin
-0.001f
)) && ((x
+XMax
) <= (xmax
+0.001f
)) &&
473 ((z
+ZMin
) >= (zmin
-0.001f
)) && ((z
+ZMax
) <= (zmax
+0.001f
));
476 // How many quad to render?
477 uint nNumQuadSrc
= Vertices
.getNumVertices()/4;
478 nNumQuadSrc
= min(nNumQuadSrc
, (uint
)SelectSize
);
480 // Enlarge dest Buffer if needed
481 if( (rdrBuffer
.NumQuads
+nNumQuadSrc
)*4 > rdrBuffer
.Vertices
.getNumVertices() )
483 rdrBuffer
.Vertices
.setNumVertices( (rdrBuffer
.NumQuads
+nNumQuadSrc
)*4 );
487 CVertexBuffer::TVertexColorType vtype
= driver
.getVertexColorFormat();
488 Vertices
.setVertexColorFormat (vtype
);
489 rdrBuffer
.Vertices
.setVertexColorFormat (vtype
);
490 CVertexBufferReadWrite srcvba
;
491 Vertices
.lock (srcvba
);
492 CVertexBufferReadWrite dstvba
;
493 rdrBuffer
.Vertices
.lock (dstvba
);
494 sint ofsSrcUV
= Vertices
.getTexCoordOff();
495 sint ofsDstUV
= rdrBuffer
.Vertices
.getTexCoordOff();
496 sint ofsDstColor
= rdrBuffer
.Vertices
.getColorOff();
497 uint8
*srcPtr
= (uint8
*)srcvba
.getVertexCoordPointer();
498 uint8
*dstPtr
= (uint8
*)dstvba
.getVertexCoordPointer(rdrBuffer
.NumQuads
*4);
499 sint srcSize
= Vertices
.getVertexSize();
500 sint dstSize
= rdrBuffer
.Vertices
.getVertexSize();
502 // decal src for selection
503 srcPtr
+= SelectStart
*4 * srcSize
;
505 uint8
*dstPtrBackup
= dstPtr
;
511 uint numVerts
= nNumQuadSrc
*4;
512 for(uint i
=0;i
<numVerts
;i
++)
514 // copy and translate pos
515 CHECK_VBA_RANGE(dstvba
, dstPtr
, Vertices
.getVertexSize());
516 CHECK_VBA_RANGE(srcvba
, srcPtr
, rdrBuffer
.Vertices
.getVertexSize());
517 ((CVector
*)dstPtr
)->x
= x
+ ((CVector
*)srcPtr
)->x
;
518 ((CVector
*)dstPtr
)->z
= z
+ ((CVector
*)srcPtr
)->z
;
521 *((CUV
*)(dstPtr
+ofsDstUV
))= *((CUV
*)(srcPtr
+ofsSrcUV
));
523 if (vtype
== CVertexBuffer::TRGBA
)
524 *((CRGBA
*)(dstPtr
+ofsDstColor
))= Color
;
526 *((CBGRA
*)(dstPtr
+ofsDstColor
))= Color
;
533 // update the rdrBuffer
534 rdrBuffer
.NumQuads
+= nNumQuadSrc
;
538 uint nNumQuadClipped
= 0;
540 // the real number of vertices to compute (with selection)
541 uint numVerts
= nNumQuadSrc
*4;
543 // clip into VerticesClipped
544 CVector
*pIniPos0
= (CVector
*)srcPtr
;
545 CVector
*pIniPos2
= (CVector
*)(((uint8
*)pIniPos0
) + srcSize
*2);
546 CVector
*pClipPos0
= (CVector
*)dstPtr
;
547 CVector
*pClipPos1
= (CVector
*)(((uint8
*)pClipPos0
) + dstSize
);
548 CVector
*pClipPos2
= (CVector
*)(((uint8
*)pClipPos1
) + dstSize
);
549 CVector
*pClipPos3
= (CVector
*)(((uint8
*)pClipPos2
) + dstSize
);
550 CUV
*pClipUV0
= (CUV
*)(dstPtr
+ ofsDstUV
);
551 CUV
*pClipUV1
= (CUV
*)(((uint8
*)pClipUV0
) + dstSize
);
552 CUV
*pClipUV2
= (CUV
*)(((uint8
*)pClipUV1
) + dstSize
);
553 CUV
*pClipUV3
= (CUV
*)(((uint8
*)pClipUV2
) + dstSize
);
555 for (uint32 i
= 0; i
< numVerts
; i
+=4)
557 if (((x
+pIniPos0
->x
) > xmax
) || ((x
+pIniPos2
->x
) < xmin
) ||
558 ((z
+pIniPos0
->z
) > zmax
) || ((z
+pIniPos2
->z
) < zmin
))
560 // Totally clipped do nothing
566 *((CVector
*) (dstPtr
+ dstSize
*0))= *((CVector
*) (srcPtr
+ srcSize
*0));
567 *((CUV
*) (dstPtr
+ dstSize
*0 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*0 + ofsSrcUV
));
568 if (vtype
== CVertexBuffer::TRGBA
)
569 *((CRGBA
*) (dstPtr
+ dstSize
*0 + ofsDstColor
))= Color
;
571 *((CBGRA
*) (dstPtr
+ dstSize
*0 + ofsDstColor
))= Color
;
573 *((CVector
*) (dstPtr
+ dstSize
*1))= *((CVector
*) (srcPtr
+ srcSize
*1));
574 *((CUV
*) (dstPtr
+ dstSize
*1 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*1 + ofsSrcUV
));
575 if (vtype
== CVertexBuffer::TRGBA
)
576 *((CRGBA
*) (dstPtr
+ dstSize
*1 + ofsDstColor
))= Color
;
578 *((CBGRA
*) (dstPtr
+ dstSize
*1 + ofsDstColor
))= Color
;
580 *((CVector
*) (dstPtr
+ dstSize
*2))= *((CVector
*) (srcPtr
+ srcSize
*2));
581 *((CUV
*) (dstPtr
+ dstSize
*2 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*2 + ofsSrcUV
));
582 if (vtype
== CVertexBuffer::TRGBA
)
583 *((CRGBA
*) (dstPtr
+ dstSize
*2 + ofsDstColor
))= Color
;
585 *((CBGRA
*) (dstPtr
+ dstSize
*2 + ofsDstColor
))= Color
;
587 *((CVector
*) (dstPtr
+ dstSize
*3))= *((CVector
*) (srcPtr
+ srcSize
*3));
588 *((CUV
*) (dstPtr
+ dstSize
*3 + ofsDstUV
))= *((CUV
*)(srcPtr
+ srcSize
*3 + ofsSrcUV
));
589 if (vtype
== CVertexBuffer::TRGBA
)
590 *((CRGBA
*) (dstPtr
+ dstSize
*3 + ofsDstColor
))= Color
;
592 *((CBGRA
*) (dstPtr
+ dstSize
*3 + ofsDstColor
))= Color
;
596 pClipPos0
->x
+= x
; pClipPos1
->x
+= x
; pClipPos2
->x
+= x
; pClipPos3
->x
+= x
;
597 pClipPos0
->z
+= z
; pClipPos1
->z
+= z
; pClipPos2
->z
+= z
; pClipPos3
->z
+= z
;
598 if ((pClipPos0
->x
>= xmin
) && (pClipPos0
->z
>= zmin
) && (pClipPos2
->x
<= xmax
) && (pClipPos2
->z
<= zmax
))
606 if (pClipPos0
->x
< xmin
)
608 ratio
= ((float)(xmin
- pClipPos0
->x
))/((float)(pClipPos1
->x
- pClipPos0
->x
));
609 pClipPos3
->x
= pClipPos0
->x
= xmin
;
610 pClipUV0
->U
+= ratio
*(pClipUV1
->U
- pClipUV0
->U
);
611 pClipUV3
->U
+= ratio
*(pClipUV2
->U
- pClipUV3
->U
);
614 if (pClipPos0
->z
< zmin
)
616 ratio
= ((float)(zmin
- pClipPos0
->z
))/((float)(pClipPos3
->z
- pClipPos0
->z
));
617 pClipPos1
->z
= pClipPos0
->z
= zmin
;
618 pClipUV0
->V
+= ratio
*(pClipUV3
->V
- pClipUV0
->V
);
619 pClipUV1
->V
+= ratio
*(pClipUV2
->V
- pClipUV1
->V
);
622 if (pClipPos2
->x
> xmax
)
624 ratio
= ((float)(xmax
- pClipPos2
->x
))/((float)(pClipPos3
->x
- pClipPos2
->x
));
625 pClipPos2
->x
= pClipPos1
->x
= xmax
;
626 pClipUV2
->U
+= ratio
*(pClipUV3
->U
- pClipUV2
->U
);
627 pClipUV1
->U
+= ratio
*(pClipUV0
->U
- pClipUV1
->U
);
630 if (pClipPos2
->z
> zmax
)
632 ratio
= ((float)(zmax
- pClipPos2
->z
))/((float)(pClipPos1
->z
- pClipPos2
->z
));
633 pClipPos2
->z
= pClipPos3
->z
= zmax
;
634 pClipUV2
->V
+= ratio
*(pClipUV1
->V
- pClipUV2
->V
);
635 pClipUV3
->V
+= ratio
*(pClipUV0
->V
- pClipUV3
->V
);
641 pClipPos0
= (CVector
*)(((uint8
*)pClipPos0
) + dstSize
*4);
642 pClipPos1
= (CVector
*)(((uint8
*)pClipPos0
) + dstSize
);
643 pClipPos2
= (CVector
*)(((uint8
*)pClipPos1
) + dstSize
);
644 pClipPos3
= (CVector
*)(((uint8
*)pClipPos2
) + dstSize
);
645 pClipUV0
= (CUV
*)( ((uint8
*)pClipUV0
) + dstSize
*4 );
646 pClipUV1
= (CUV
*)(((uint8
*)pClipUV0
) + dstSize
);
647 pClipUV2
= (CUV
*)(((uint8
*)pClipUV1
) + dstSize
);
648 pClipUV3
= (CUV
*)(((uint8
*)pClipUV2
) + dstSize
);
652 pIniPos0
= (CVector
*)(((uint8
*)pIniPos0
) + srcSize
*4);
653 pIniPos2
= (CVector
*)(((uint8
*)pIniPos0
) + srcSize
*2);
657 // update the rdrBuffer
658 rdrBuffer
.NumQuads
+= nNumQuadClipped
;
661 const float OOW
= 1.f
/ (float)wndWidth
;
662 const float OOH
= 1.f
/ (float)wndHeight
;
664 while (dstPtrBackup
!= dstPtr
)
666 // preset unprojection
668 tmp
.x
= ((CVector
*)dstPtrBackup
)->x
* OOW
;
669 tmp
.y
= ((CVector
*)dstPtrBackup
)->z
* OOH
;
671 // mul by user scale matrix
672 tmp
= scaleMatrix
* tmp
;
674 *((CVector
*)dstPtrBackup
) = frustum
.unProjectZ(tmp
);
675 dstPtrBackup
+= dstSize
;
680 // ***************************************************************************
681 CRenderStringBuffer::CRenderStringBuffer()
683 // Use color per vertex
684 Vertices
.setVertexFormat (CVertexBuffer::PositionFlag
| CVertexBuffer::TexCoord0Flag
| CVertexBuffer::PrimaryColorFlag
);
685 Vertices
.setPreferredMemory (CVertexBuffer::RAMVolatile
, true);
686 Vertices
.setName("CRenderStringBuffer");
691 // ***************************************************************************
692 CRenderStringBuffer::~CRenderStringBuffer()
697 // ***************************************************************************
698 void CRenderStringBuffer::flush(IDriver
& driver
, CMaterial
*fontMat
)
704 uint32 wndWidth
, wndHeight
;
705 driver
.getWindowSize(wndWidth
, wndHeight
);
707 // **** setup driver context
708 driver
.setFrustum(0, (float)wndWidth
, 0, (float)wndHeight
, -1, 1, false); // resX/resY
710 // view matrix and model matrix <-> identity
711 driver
.setupViewMatrix (CMatrix::Identity
);
712 driver
.setupModelMatrix (CMatrix::Identity
);
715 fontMat
->setZFunc (CMaterial::always
);
716 fontMat
->setZWrite (false);
718 // setup vertices clipped
719 driver
.activeVertexBuffer (Vertices
);
722 driver
.renderRawQuads (*fontMat
, 0, NumQuads
);
729 // ***************************************************************************
730 void CRenderStringBuffer::flushUnProjected(IDriver
& driver
, CMaterial
*fontMat
, bool zwrite
)
736 fontMat
->setZFunc (CMaterial::lessequal
);
737 fontMat
->setZWrite (zwrite
);
739 // setup vertices clipped
740 driver
.activeVertexBuffer (Vertices
);
743 driver
.renderRawQuads (*fontMat
, 0, NumQuads
);