1
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
1
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
3
* This library is open source and may be redistributed and/or modified under
4
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
3
* This library is open source and may be redistributed and/or modified under
4
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5
5
* (at your option) any later version. The full license is in LICENSE file
6
6
* included with this distribution, and on the openscenegraph.org website.
8
8
* This library is distributed in the hope that it will be useful,
9
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
* OpenSceneGraph Public License for more details.
14
14
#include <osgText/Text3D>
15
16
#include <osg/io_utils>
22
22
_renderMode(PER_GLYPH)
26
26
Text3D::Text3D(const Text3D & text3D, const osg::CopyOp & copyop):
27
27
osgText::TextBase(text3D, copyop),
29
_characterDepth(text3D._characterDepth),
30
28
_renderMode(text3D._renderMode)
32
30
computeGlyphRepresentation();
35
//void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const
40
//void Text3D::accept(osg::PrimitiveFunctor& /*pf*/) const
45
void Text3D::setFont(osg::ref_ptr<Font3D> font)
33
float Text3D::getCharacterDepth() const
35
if (!_style) return _characterHeight*0.1f;
36
else return _characterHeight * _style->getThicknessRatio();
39
void Text3D::setCharacterDepth(float characterDepth)
41
getOrCreateStyle()->setThicknessRatio(characterDepth / _characterHeight);
49
43
computeGlyphRepresentation();
52
void Text3D::setFont(const std::string & fontfile)
54
setFont(readRefFont3DFile(fontfile));
46
void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const
48
// ** for each line, do ...
49
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
50
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
52
// ** for each glyph in the line, do ...
53
LineRenderInfo::const_iterator it, end = itLine->end();
54
for (it = itLine->begin(); it!=end; ++it)
56
// ** apply the vertex array
57
af.apply(osg::Drawable::VERTICES, it->_glyphGeometry->getVertexArray()->size(), &(it->_glyphGeometry->getVertexArray()->front()));
61
void Text3D::accept(osg::PrimitiveFunctor& pf) const
63
// ** for each line, do ...
64
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
65
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
67
// ** for each glyph in the line, do ...
68
LineRenderInfo::const_iterator it, end = itLine->end();
69
for (it = itLine->begin(); it!=end; ++it)
71
osg::Vec3Array* vertices = it->_glyphGeometry->getVertexArray();
73
if (!vertices || vertices->empty())
74
continue; //skip over spaces
76
//pf.setVertexArray(it->_glyph->getVertexArray()->size(),&(it->_glyph->getVertexArray()->front()));
77
//////////////////////////////////////////////////////////////////////////
78
// now apply matrix to the glyphs.
79
osg::ref_ptr<osg::Vec3Array> transformedVertices = new osg::Vec3Array;
80
osg::Matrix matrix = _autoTransformCache[0]._matrix;//osg::Matrix();
81
matrix.preMultTranslate(it->_position);
82
transformedVertices->reserve(vertices->size());
83
for (osg::Vec3Array::iterator itr=vertices->begin(); itr!=vertices->end(); itr++)
85
transformedVertices->push_back((*itr)*matrix);
87
//////////////////////////////////////////////////////////////////////////
88
pf.setVertexArray(transformedVertices->size(),&(transformedVertices->front()));
90
// ** render the front face of the glyph
91
osg::Geometry::PrimitiveSetList & pslFront = it->_glyphGeometry->getFrontPrimitiveSetList();
92
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr)
97
// ** render the wall face of the glyph
98
osg::Geometry::PrimitiveSetList & pslWall = it->_glyphGeometry->getWallPrimitiveSetList();
99
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr)
104
// ** render the back face of the glyph
105
osg::Geometry::PrimitiveSetList & pslBack = it->_glyphGeometry->getBackPrimitiveSetList();
106
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr)
57
114
String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last)
64
121
String::iterator lastChar = first;
66
std::set<unsigned int> deliminatorSet;
67
deliminatorSet.insert(' ');
68
deliminatorSet.insert('\n');
69
deliminatorSet.insert(':');
70
deliminatorSet.insert('/');
71
deliminatorSet.insert(',');
72
deliminatorSet.insert(';');
73
deliminatorSet.insert(':');
74
deliminatorSet.insert('.');
76
float maximumHeight = _maximumHeight / _font->getScale();
77
float maximumWidth = _maximumWidth / _font->getScale();
123
float maximumHeight = _maximumHeight;
124
float maximumWidth = _maximumWidth;
79
129
for(bool outOfSpace=false;lastChar!=last;++lastChar)
81
131
unsigned int charcode = *lastChar;
83
133
if (charcode=='\n')
88
Font3D::Glyph3D* glyph = _font->getGlyph(charcode);
138
Glyph3D* glyph = _font->getGlyph3D(charcode);
91
141
const osg::BoundingBox & bb = glyph->getBoundingBox();
143
if (_layout==RIGHT_TO_LEFT)
145
cursor.x() -= glyph->getHorizontalAdvance() * wr;
93
148
// adjust cursor position w.r.t any kerning.
94
if (previous_charcode)
149
if (kerning && previous_charcode)
97
if (_layout == RIGHT_TO_LEFT)
99
cursor.x() -= glyph->getHorizontalAdvance();
108
cursor += _font->getKerning(previous_charcode, charcode, _kerningType);
113
cursor -= _font->getKerning(charcode, previous_charcode, _kerningType);
117
break; // no kerning when vertical.
127
cursor.x() -= glyph->getHorizontalBearing().x();
132
cursor.x() -= bb.xMax();
155
osg::Vec2 delta(_font->getKerning(previous_charcode,charcode,_kerningType));
156
cursor.x() += delta.x() * wr;
157
cursor.y() += delta.y() * hr;
162
osg::Vec2 delta(_font->getKerning(charcode,previous_charcode,_kerningType));
163
cursor.x() -= delta.x() * wr;
164
cursor.y() -= delta.y() * hr;
168
break; // no kerning when vertical.
172
osg::Vec2 local = cursor;
145
176
case LEFT_TO_RIGHT:
147
if (maximumWidth>0.0f && cursor.x()+bb.xMax()>maximumWidth) outOfSpace=true;
148
if(maximumHeight>0.0f && cursor.y()<-maximumHeight) outOfSpace=true;
178
if (maximumWidth>0.0f && local.x()+bb.xMax()>maximumWidth) outOfSpace=true;
179
if(maximumHeight>0.0f && local.y()<-maximumHeight) outOfSpace=true;
151
182
case RIGHT_TO_LEFT:
153
if (maximumWidth>0.0f && cursor.x()+bb.xMin()<-maximumWidth) outOfSpace=true;
154
if(maximumHeight>0.0f && cursor.y()<-maximumHeight) outOfSpace=true;
184
if (maximumWidth>0.0f && local.x()+bb.xMin()<-maximumWidth) outOfSpace=true;
185
if(maximumHeight>0.0f && local.y()<-maximumHeight) outOfSpace=true;
158
if (maximumHeight>0.0f && cursor.y()<-maximumHeight) outOfSpace=true;
189
if (maximumHeight>0.0f && local.y()<-maximumHeight) outOfSpace=true;
162
193
// => word boundary detection & wrapping
163
194
if (outOfSpace) break;
165
196
// move the cursor onto the next character.
168
case LEFT_TO_RIGHT: cursor.x() += glyph->getHorizontalAdvance(); break;
199
case LEFT_TO_RIGHT: cursor.x() += glyph->getHorizontalAdvance() * wr; break;
169
200
case RIGHT_TO_LEFT: break;
170
case VERTICAL: cursor.y() -= glyph->getVerticalAdvance(); break;
201
case VERTICAL: cursor.y() -= glyph->getVerticalAdvance() * hr; break;
173
204
previous_charcode = charcode;
179
210
// word boundary detection & wrapping
180
211
if (lastChar!=last)
182
if (deliminatorSet.count(*lastChar)==0)
184
String::iterator lastValidChar = lastChar;
185
while (lastValidChar!=first && deliminatorSet.count(*lastValidChar)==0)
213
String::iterator lastValidChar = lastChar;
214
String::iterator prevChar;
215
while (lastValidChar != first){
216
prevChar = lastValidChar - 1;
218
// last char is after a hyphen
219
if(*lastValidChar == '-')
220
return lastValidChar + 1;
222
// last char is start of whitespace
223
if((*lastValidChar == ' ' || *lastValidChar == '\n') && (*prevChar != ' ' && *prevChar != '\n'))
224
return lastValidChar;
226
// Subtract off glyphs from the cursor position (to correctly center text)
189
//Substract off glyphs from the cursor position (to correctly center text)
190
Font3D::Glyph3D* glyph = _font->getGlyph(*lastValidChar);
229
Glyph3D* glyph = _font->getGlyph3D(*prevChar);
195
case LEFT_TO_RIGHT: cursor.x() -= glyph->getHorizontalAdvance(); break;
196
case RIGHT_TO_LEFT: cursor.x() += glyph->getHorizontalAdvance(); break;
197
case VERTICAL: cursor.y() += glyph->getVerticalAdvance(); break;
234
case LEFT_TO_RIGHT: cursor.x() -= glyph->getHorizontalAdvance() * wr; break;
235
case RIGHT_TO_LEFT: cursor.x() += glyph->getHorizontalAdvance() * wr; break;
236
case VERTICAL: cursor.y() += glyph->getVerticalAdvance() * wr; break;
202
if (first!=lastValidChar)
205
lastChar = lastValidChar;
241
lastValidChar = prevChar;
213
248
void Text3D::computeGlyphRepresentation()
215
250
if (_font.valid() == false) return;
217
252
_textRenderInfo.clear();
222
257
_textBB.set(0,0,0, 0,0,0);//no size text
223
258
TextBase::computePositions(); //to reset the origin
227
262
// initialize bounding box, it will be expanded during glyph position calculation
230
269
osg::Vec2 startOfLine_coords(0.0f,0.0f);
231
270
osg::Vec2 cursor(startOfLine_coords);
232
271
osg::Vec2 local(0.0f,0.0f);
233
272
osg::Vec2 startOffset(0.0f,0.0f);
235
274
unsigned int previous_charcode = 0;
236
275
unsigned int linelength = 0;
237
276
bool kerning = true;
239
278
unsigned int lineNumber = 0;
243
280
for(String::iterator itr=_text.begin(); itr!=_text.end(); )
245
282
_textRenderInfo.resize(lineNumber + 1);
246
283
LineRenderInfo & currentLineRenderInfo = _textRenderInfo.back();
248
285
// record the start of the current line
249
286
String::iterator startOfLine_itr = itr;
251
288
// find the end of the current line.
252
289
osg::Vec2 endOfLine_coords(cursor);
253
290
String::iterator endOfLine_itr = computeLastCharacterOnLine(endOfLine_coords, itr,_text.end());
255
// ** position the cursor function to the Layout and the alignement
292
// ** position the cursor function to the Layout and the alignement
256
293
TextBase::positionCursor(endOfLine_coords, cursor, (unsigned int) (endOfLine_itr - startOfLine_itr));
259
296
if (itr!=endOfLine_itr)
261
298
for(;itr!=endOfLine_itr;++itr)
263
300
unsigned int charcode = *itr;
265
Font3D::Glyph3D* glyph = _font->getGlyph(charcode);
302
Glyph3D* glyph = _font->getGlyph3D(charcode);
268
305
const osg::BoundingBox & bb = glyph->getBoundingBox();
307
if (_layout==RIGHT_TO_LEFT)
309
cursor.x() -= glyph->getHorizontalAdvance() * wr;
270
312
// adjust cursor position w.r.t any kerning.
271
if (previous_charcode)
313
if (kerning && previous_charcode)
273
if (_layout == RIGHT_TO_LEFT)
275
cursor.x() -= glyph->getHorizontalAdvance();
284
cursor += _font->getKerning(previous_charcode, charcode, _kerningType);
289
cursor -= _font->getKerning(charcode, previous_charcode, _kerningType);
293
break; // no kerning when vertical.
303
cursor.x() -= glyph->getHorizontalBearing().x();
308
cursor.x() -= bb.xMax();
313
// cursor.y() += glyph->getVerticalBearing().y();
319
osg::Vec2 delta(_font->getKerning(previous_charcode,charcode,_kerningType));
320
cursor.x() += delta.x() * wr;
321
cursor.y() += delta.y() * hr;
326
osg::Vec2 delta(_font->getKerning(charcode,previous_charcode,_kerningType));
327
cursor.x() -= delta.x() * wr;
328
cursor.y() -= delta.y() * hr;
332
break; // no kerning when vertical.
322
if (_layout==VERTICAL)
324
local.x() += -glyph->getVerticalBearing().x();
325
local.y() += -glyph->getVerticalBearing().y();
330
338
// move the cursor onto the next character.
331
339
// also expand bounding box
334
342
case LEFT_TO_RIGHT:
335
_textBB.expandBy(osg::Vec3(cursor.x() + bb.xMin(), cursor.y() + bb.yMin(), 0.0f)); //lower left corner
336
_textBB.expandBy(osg::Vec3(cursor.x() + bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner
337
cursor.x() += glyph->getHorizontalAdvance();
343
_textBB.expandBy(osg::Vec3(cursor.x() + bb.xMin()*wr, cursor.y() + bb.yMin()*hr, 0.0f)); //lower left corner
344
_textBB.expandBy(osg::Vec3(cursor.x() + bb.xMax()*wr, cursor.y() + bb.yMax()*hr, 0.0f)); //upper right corner
345
cursor.x() += glyph->getHorizontalAdvance() * wr;
340
348
_textBB.expandBy(osg::Vec3(cursor.x(), cursor.y(), 0.0f)); //upper left corner
341
_textBB.expandBy(osg::Vec3(cursor.x() + glyph->getWidth(), cursor.y() - glyph->getHeight(), 0.0f)); //lower right corner
342
cursor.y() -= glyph->getVerticalAdvance();
349
_textBB.expandBy(osg::Vec3(cursor.x() + glyph->getWidth()*wr, cursor.y() - glyph->getHeight()*hr, 0.0f)); //lower right corner
350
cursor.y() -= glyph->getVerticalAdvance() * hr;
344
352
case RIGHT_TO_LEFT:
345
_textBB.expandBy(osg::Vec3(cursor.x()+bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner
346
_textBB.expandBy(osg::Vec3(cursor.x()+bb.xMin(), cursor.y()+bb.yMin(), 0.0f)); //lower left corner
353
_textBB.expandBy(osg::Vec3(cursor.x()+bb.xMax()*wr, cursor.y() + bb.yMax()*hr, 0.0f)); //upper right corner
354
_textBB.expandBy(osg::Vec3(cursor.x()+bb.xMin()*wr, cursor.y()+bb.yMin()*hr, 0.0f)); //lower left corner
351
359
osg::Vec3 pos = osg::Vec3(local.x(), local.y(), 0.0f);
352
currentLineRenderInfo.push_back(Text3D::GlyphRenderInfo(glyph, pos));
360
GlyphGeometry* glyphGeometry = glyph->getGlyphGeometry(_style.get());
361
currentLineRenderInfo.push_back(Text3D::GlyphRenderInfo(glyphGeometry, pos));
355
363
previous_charcode = charcode;
446
447
case LEFT_BASE_LINE: _offset.set(0.0f,0.0f,0.0f); break;
447
448
case CENTER_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,0.0f,0.0f); break;
448
449
case RIGHT_BASE_LINE: _offset.set(_textBB.xMax(),0.0f,0.0f); break;
450
451
case LEFT_BOTTOM_BASE_LINE: _offset.set(0.0f,-_characterHeight*(_lineCount-1),0.0f); break;
451
452
case CENTER_BOTTOM_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,-_characterHeight*(_lineCount-1),0.0f); break;
452
453
case RIGHT_BOTTOM_BASE_LINE: _offset.set(_textBB.xMax(),-_characterHeight*(_lineCount-1),0.0f); break;
455
456
AutoTransformCache& atc = _autoTransformCache[contextID];
456
457
osg::Matrix& matrix = atc._matrix;
459
float scale = _font->getScale();
460
osg::Vec3 scaleVec(scale * _characterHeight, scale * _characterHeight / _characterAspectRatio, _characterDepth);
460
osg::Vec3 scaleVec(_characterHeight / getCharacterAspectRatio(), _characterHeight , _characterHeight);
461
462
matrix.makeTranslate(-_offset);
462
463
matrix.postMultScale(scaleVec);
463
464
matrix.postMultRotate(_rotation);
464
465
matrix.postMultTranslate(_position);
467
468
_normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix);
468
469
_normal.normalize();
470
const_cast<Text3D*>(this)->dirtyBound();
471
const_cast<Text3D*>(this)->dirtyBound();
473
474
void Text3D::drawImplementation(osg::RenderInfo& renderInfo) const
475
476
osg::State & state = *renderInfo.getState();
476
477
unsigned int contextID = state.getContextID();
479
479
// ** save the previous modelview matrix
480
osg::ref_ptr<osg::RefMatrix> previous(new osg::RefMatrix(state.getModelViewMatrix()));
480
osg::Matrix previous(state.getModelViewMatrix());
482
482
// ** get the modelview for this context
483
osg::ref_ptr<osg::RefMatrix> modelview(new osg::RefMatrix(_autoTransformCache[contextID]._matrix));
483
osg::Matrix modelview(_autoTransformCache[contextID]._matrix);
485
485
// ** mult previous by the modelview for this context
486
modelview->postMult(*previous.get());
486
modelview.postMult(previous);
488
488
// ** apply this new modelview matrix
489
state.applyModelViewMatrix(modelview.get());
492
if (_drawMode & TEXT)
494
renderInfo.getState()->disableAllVertexArrays();
496
glPushAttrib(GL_TRANSFORM_BIT);
497
glEnable(GL_RESCALE_NORMAL);
501
case PER_FACE: renderPerFace(*renderInfo.getState()); break;
503
default: renderPerGlyph(*renderInfo.getState()); break;
489
state.applyModelViewMatrix(modelview);
491
osg::GLBeginEndAdapter& gl = (state.getGLBeginEndAdapter());
509
493
if (_drawMode & BOUNDINGBOX)
511
495
if (_textBB.valid())
497
gl.Color4fv(_color.ptr());
513
499
osg::Vec3 c000(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMax()));
514
500
osg::Vec3 c100(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMax()));
515
501
osg::Vec3 c110(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax()));
516
502
osg::Vec3 c010(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMax()));
518
504
osg::Vec3 c001(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()));
519
505
osg::Vec3 c101(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()));
520
506
osg::Vec3 c111(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()));
521
507
osg::Vec3 c011(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()));
523
glBegin(GL_LINE_LOOP);
524
glVertex3fv(c000.ptr());
525
glVertex3fv(c100.ptr());
526
glVertex3fv(c110.ptr());
527
glVertex3fv(c010.ptr());
530
glBegin(GL_LINE_LOOP);
531
glVertex3fv(c001.ptr());
532
glVertex3fv(c011.ptr());
533
glVertex3fv(c111.ptr());
534
glVertex3fv(c101.ptr());
538
glVertex3fv(c000.ptr());
539
glVertex3fv(c001.ptr());
541
glVertex3fv(c100.ptr());
542
glVertex3fv(c101.ptr());
544
glVertex3fv(c110.ptr());
545
glVertex3fv(c111.ptr());
547
glVertex3fv(c010.ptr());
548
glVertex3fv(c011.ptr());
509
gl.Begin(GL_LINE_LOOP);
510
gl.Vertex3fv(c000.ptr());
511
gl.Vertex3fv(c100.ptr());
512
gl.Vertex3fv(c110.ptr());
513
gl.Vertex3fv(c010.ptr());
516
gl.Begin(GL_LINE_LOOP);
517
gl.Vertex3fv(c001.ptr());
518
gl.Vertex3fv(c011.ptr());
519
gl.Vertex3fv(c111.ptr());
520
gl.Vertex3fv(c101.ptr());
524
gl.Vertex3fv(c000.ptr());
525
gl.Vertex3fv(c001.ptr());
527
gl.Vertex3fv(c100.ptr());
528
gl.Vertex3fv(c101.ptr());
530
gl.Vertex3fv(c110.ptr());
531
gl.Vertex3fv(c111.ptr());
533
gl.Vertex3fv(c010.ptr());
534
gl.Vertex3fv(c011.ptr());
553
539
if (_drawMode & ALIGNMENT)
559
545
osg::Vec3 vt(osg::Vec3(_offset.x(),_offset.y()-cursorsize,_offset.z()));
560
546
osg::Vec3 vb(osg::Vec3(_offset.x(),_offset.y()+cursorsize,_offset.z()));
563
glVertex3fv(hl.ptr());
564
glVertex3fv(hr.ptr());
565
glVertex3fv(vt.ptr());
566
glVertex3fv(vb.ptr());
548
gl.Color4fv(_color.ptr());
551
gl.Vertex3fv(hl.ptr());
552
gl.Vertex3fv(hr.ptr());
553
gl.Vertex3fv(vt.ptr());
554
gl.Vertex3fv(vb.ptr());
559
if (_drawMode & TEXT)
561
state.disableColorPointer();
562
state.Color(_color.r(),_color.g(),_color.b(),_color.a());
564
renderInfo.getState()->disableAllVertexArrays();
566
#if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
567
renderInfo.getState()->applyMode(GL_NORMALIZE, true);
572
case PER_FACE: renderPerFace(*renderInfo.getState()); break;
574
default: renderPerGlyph(*renderInfo.getState()); break;
571
579
// restore the previous modelview matrix
572
state.applyModelViewMatrix(previous.get());
580
state.applyModelViewMatrix(previous);
577
583
void Text3D::renderPerGlyph(osg::State & state) const
585
osg::Matrix original_modelview = state.getModelViewMatrix();
579
587
// ** for each line, do ...
580
588
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
581
589
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
584
592
LineRenderInfo::const_iterator it, end = itLine->end();
585
593
for (it = itLine->begin(); it!=end; ++it)
590
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
596
osg::Matrix matrix(original_modelview);
597
matrix.preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z()));
598
state.applyModelViewMatrix(matrix);
600
state.lazyDisablingOfVertexAttributes();
592
602
// ** apply the vertex array
593
state.setVertexPointer(it->_glyph->getVertexArray());
595
// ** render the front face of the glyph
596
glNormal3f(0.0f,0.0f,1.0f);
598
osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList();
603
state.setVertexPointer(it->_glyphGeometry->getVertexArray());
604
state.setNormalPointer(it->_glyphGeometry->getNormalArray());
606
state.applyDisablingOfVertexAttributes();
609
osg::Geometry::PrimitiveSetList & pslFront = it->_glyphGeometry->getFrontPrimitiveSetList();
599
610
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr)
602
612
(*itr)->draw(state, false);
605
615
// ** render the wall face of the glyph
606
state.setNormalPointer(it->_glyph->getNormalArray());
607
osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList();
616
osg::Geometry::PrimitiveSetList & pslWall = it->_glyphGeometry->getWallPrimitiveSetList();
608
617
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr)
610
619
(*itr)->draw(state, false);
613
// ** render the back face of the glyph
614
glNormal3f(0.0f,0.0f,-1.0f);
616
osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList();
622
osg::Geometry::PrimitiveSetList & pslBack = it->_glyphGeometry->getBackPrimitiveSetList();
617
623
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr)
619
625
(*itr)->draw(state, false);
627
631
void Text3D::renderPerFace(osg::State & state) const
633
osg::Matrix original_modelview = state.getModelViewMatrix();
629
635
// ** render all front faces
630
glNormal3f(0.0f,0.0f,1.0f);
636
state.Normal(0.0f,0.0f,1.0f);
632
639
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
633
640
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
635
642
// ** for each glyph in the line, do ...
636
643
LineRenderInfo::const_iterator it, end = itLine->end();
637
for (it = itLine->begin(); it!=end; ++it)
644
for (it = itLine->begin(); it!=end; ++it)
640
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
641
state.setVertexPointer(it->_glyph->getVertexArray());
646
osg::Matrix matrix(original_modelview);
647
matrix.preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z()));
648
state.applyModelViewMatrix(matrix);
650
state.setVertexPointer(it->_glyphGeometry->getVertexArray());
651
state.setNormalPointer(it->_glyphGeometry->getNormalArray());
643
653
// ** render the front face of the glyph
644
osg::Geometry::PrimitiveSetList & psl = it->_glyph->getFrontPrimitiveSetList();
654
osg::Geometry::PrimitiveSetList & psl = it->_glyphGeometry->getFrontPrimitiveSetList();
645
655
for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr)
647
657
(*itr)->draw(state, false);
654
663
// ** render all wall face of the text
655
664
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
658
667
LineRenderInfo::const_iterator it, end = itLine->end();
659
668
for (it = itLine->begin(); it!=end; ++it)
662
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
663
state.setVertexPointer(it->_glyph->getVertexArray());
664
state.setNormalPointer(it->_glyph->getNormalArray());
666
osg::Geometry::PrimitiveSetList & psl = it->_glyph->getWallPrimitiveSetList();
670
osg::Matrix matrix(original_modelview);
671
matrix.preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z()));
672
state.applyModelViewMatrix(matrix);
674
state.setVertexPointer(it->_glyphGeometry->getVertexArray());
675
state.setNormalPointer(it->_glyphGeometry->getNormalArray());
677
const osg::Geometry::PrimitiveSetList & psl = it->_glyphGeometry->getWallPrimitiveSetList();
667
678
for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr)
669
680
(*itr)->draw(state, false);
685
state.disableNormalPointer();
676
687
// ** render all back face of the text
677
glNormal3f(0.0f,0.0f,-1.0f);
688
state.Normal(0.0f,0.0f,-1.0f);
679
690
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
681
692
// ** for each glyph in the line, do ...
682
693
LineRenderInfo::const_iterator it, end = itLine->end();
683
694
for (it = itLine->begin(); it!=end; ++it)
686
glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
687
state.setVertexPointer(it->_glyph->getVertexArray());
696
osg::Matrix matrix(original_modelview);
697
matrix.preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z()));
698
state.applyModelViewMatrix(matrix);
700
state.setVertexPointer(it->_glyphGeometry->getVertexArray());
701
state.setNormalPointer(it->_glyphGeometry->getNormalArray());
689
703
// ** render the back face of the glyph
690
osg::Geometry::PrimitiveSetList & psl = it->_glyph->getBackPrimitiveSetList();
704
const osg::Geometry::PrimitiveSetList & psl = it->_glyphGeometry->getBackPrimitiveSetList();
691
705
for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr)
693
707
(*itr)->draw(state, false);