nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "GLResource.h" 00024 #include "IOpenGLResource.h" 00025 #include "GLResourceManager.h" 00026 #include "IOpenGLBaseTexture.h" 00027 #include "GpuDevice.h" 00028 #include "GLTextureResourceManager.h" 00029 00030 #include "GraphicsEngine.h" 00031 00032 #include "FontRenderer.h" 00033 00034 namespace nux 00035 { 00036 00037 const int CURSOR_OFFSET = 0; 00038 static int CURSOR_SIZE = 2; 00039 00040 // On NVidia system: 00041 // - declare the vertex attribute name before any other attribute. 00042 // - Give the vertex attribute a name that comes before any other attribute name. For instance prefix the vertex attribute name with "_". 00043 00044 NString gFontVtxShader = TEXT ("#version 110 \n\ 00045 attribute vec4 _Position; \n\ 00046 attribute vec4 iOffset; \n\ 00047 attribute vec4 iScale; \n\ 00048 attribute vec4 iTexUV; \n\ 00049 uniform mat4 ViewProjectionMatrix; \n\ 00050 varying vec4 oTexCoord0; \n\ 00051 void main() \n\ 00052 { \n\ 00053 oTexCoord0 = iTexUV; \n\ 00054 vec4 myvertex = _Position * iScale + iOffset; \n\ 00055 gl_Position = ViewProjectionMatrix * myvertex; \n\ 00056 }"); 00057 00058 NString gFontFragShader = TEXT ("#version 110 \n\ 00059 #extension GL_ARB_texture_rectangle : enable \n\ 00060 uniform sampler2DRect FontTexture; \n\ 00061 uniform vec4 TextColor; \n\ 00062 varying vec4 oTexCoord0; \n\ 00063 void main() \n\ 00064 { \n\ 00065 vec4 diffuse = texture2DRect(FontTexture, oTexCoord0.st); \n\ 00066 gl_FragColor = vec4(TextColor.x, TextColor.y, TextColor.z, diffuse.w); \n\ 00067 }"); 00068 00069 NString FontAsmVtx = TEXT ("!!ARBvp1.0 \n\ 00070 ATTRIB iScale = vertex.attrib[9]; \n\ 00071 ATTRIB iOffset = vertex.attrib[10]; \n\ 00072 OUTPUT oPos = result.position; \n\ 00073 OUTPUT oTexCoord0 = result.texcoord[0]; \n\ 00074 # Transform the vertex to clip coordinates. \n\ 00075 TEMP temp; \n\ 00076 MAD temp, vertex.position, iScale, iOffset; \n\ 00077 DP4 oPos.x, state.matrix.mvp.row[0], temp; \n\ 00078 DP4 oPos.y, state.matrix.mvp.row[1], temp; \n\ 00079 DP4 oPos.z, state.matrix.mvp.row[2], temp; \n\ 00080 DP4 oPos.w, state.matrix.mvp.row[3], temp; \n\ 00081 MOV oTexCoord0, vertex.attrib[8]; \n\ 00082 END"); 00083 00084 NString FontAsmFrg = TEXT ("!!ARBfp1.0 \n\ 00085 PARAM color = program.local[0]; \n\ 00086 TEMP temp; \n\ 00087 TEMP tex0; \n\ 00088 TEX tex0, fragment.texcoord[0], texture[0], 2D; \n\ 00089 MOV temp, color; \n\ 00090 MUL temp.w, color, tex0; \n\ 00091 MOV result.color, temp; \n\ 00092 END"); 00093 00094 NString FontAsmFrgRect = TEXT ("!!ARBfp1.0 \n\ 00095 PARAM color = program.local[0]; \n\ 00096 TEMP temp; \n\ 00097 TEMP tex0; \n\ 00098 TEX tex0, fragment.texcoord[0], texture[0], RECT; \n\ 00099 MOV temp, color; \n\ 00100 MUL temp.w, color, tex0; \n\ 00101 MOV result.color, temp; \n\ 00102 END"); 00103 00104 00105 FontRenderer::FontRenderer (GraphicsEngine &graphics_engine) 00106 : _graphics_engine (graphics_engine) 00107 { 00108 if(_graphics_engine.UsingGLSLCodePath()) 00109 { 00110 _pixel_shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); 00111 _vertex_shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); 00112 _shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); 00113 00114 _vertex_shader_prog->SetShaderCode (TCHAR_TO_ANSI (*gFontVtxShader) ); 00115 _pixel_shader_prog->SetShaderCode (TCHAR_TO_ANSI (*gFontFragShader) ); 00116 00117 _shader_prog->ClearShaderObjects(); 00118 _shader_prog->AddShaderObject (_vertex_shader_prog); 00119 _shader_prog->AddShaderObject (_pixel_shader_prog); 00120 //CHECKGL (glBindAttribLocation(_shader_prog->GetOpenGLID(), 0, "_Position")); 00121 _shader_prog->Link(); 00122 } 00123 else 00124 { 00125 _asm_shader_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); 00126 00127 _asm_shader_prog->LoadVertexShader (TCHAR_TO_ANSI (*FontAsmVtx) ); 00128 _asm_shader_prog->LoadPixelShader (TCHAR_TO_ANSI (*FontAsmFrg) ); 00129 _asm_shader_prog->Link(); 00130 00131 _asm_font_texture_rect_prog = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram(); 00132 _asm_font_texture_rect_prog->LoadVertexShader (TCHAR_TO_ANSI (*FontAsmVtx) ); 00133 _asm_font_texture_rect_prog->LoadPixelShader (TCHAR_TO_ANSI (*FontAsmFrgRect) ); 00134 _asm_font_texture_rect_prog->Link(); 00135 } 00136 } 00137 00138 FontRenderer::~FontRenderer() 00139 { 00140 } 00141 00142 int FontRenderer::DrawColorString (ObjectPtr<FontTexture> Font, int x, int y, const NString &str, const Color &color, bool WriteAlphaChannel, int SkipFirstNCharacters, int NumCharacter) 00143 { 00144 return RenderText (Font, x, y, str, color, WriteAlphaChannel, SkipFirstNCharacters, NumCharacter); 00145 } 00146 00147 void FontRenderer::PositionString (ObjectPtr<FontTexture> Font, const NString &str, const PageBBox &pageBBox, StringBBox &strBBox, TextAlignment alignment, int NumCharacter) 00148 { 00149 int x, y; 00150 int xmin, ymin, xmax, ymax; 00151 xmin = pageBBox.xmin + pageBBox.x_margin; 00152 xmax = pageBBox.xmax - pageBBox.x_margin; 00153 ymin = pageBBox.ymin + pageBBox.y_margin; 00154 ymax = pageBBox.ymax - pageBBox.y_margin; 00155 00156 int NumChar = 0; 00157 00158 if (NumCharacter == 0) 00159 NumChar = str.Size(); 00160 else 00161 NumChar = Min ((int) str.Size(), NumCharacter); 00162 00163 strBBox.width = Font->GetStringWidth(str, NumChar); 00164 strBBox.height = Font->GetLineHeight(); 00165 00166 switch (alignment) 00167 { 00168 case eAlignTextCenter: 00169 00170 if (strBBox.width > xmax - xmin) 00171 x = xmin; // the text is larger than the box: default to eAlignTextLeft for x. 00172 else 00173 x = xmin + ( (float) (xmax - xmin) - (float) (strBBox.width) ) / 2.0f; 00174 00175 y = ymin + ( (float) (ymax - ymin) - (float) (strBBox.height) ) / 2.0f; 00176 break; 00177 00178 case eAlignTextRight: 00179 x = xmin + ( (float) (xmax - xmin) - (float) (strBBox.width) ); 00180 y = ymin + ( (float) (ymax - ymin) - (float) (strBBox.height) ) / 2.0f; 00181 break; 00182 00183 case eAlignTextLeft: 00184 default: 00185 x = xmin; 00186 y = ymin + ( (float) (ymax - ymin) - (float) (strBBox.height) ) / 2.0f; 00187 break; 00188 } 00189 00190 strBBox.x = x; 00191 strBBox.y = y; 00192 } 00193 00194 int FontRenderer::RenderColorText (ObjectPtr<FontTexture> Font, int x, int y, const NString &Str, const Color &color, 00195 bool WriteAlphaChannel, int NumCharacter) 00196 { 00197 int off = DrawColorString (Font, x, y, Str, color, WriteAlphaChannel, 0, NumCharacter); 00198 return off; 00199 } 00200 00201 int FontRenderer::RenderColorTextLineStatic (ObjectPtr<FontTexture> Font, const PageBBox &pageSize, const NString &Str, const Color &color, 00202 bool WriteAlphaChannel, TextAlignment alignment) 00203 { 00204 StringBBox stringBBox; 00205 00206 _graphics_engine.PushClippingRectangle (Rect (pageSize.xmin, pageSize.ymin, pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin) ); 00207 PositionString (Font, Str, pageSize, stringBBox, alignment); 00208 int off = DrawColorString (Font, stringBBox.x, stringBBox.y, Str, color, WriteAlphaChannel, 0, Str.Size() ); 00209 00210 _graphics_engine.PopClippingRectangle(); 00211 return off; 00212 } 00213 00214 int FontRenderer::RenderColorTextLineEdit (ObjectPtr<FontTexture> Font, const PageBBox &pageSize, const NString &Str, 00215 const Color &TextColor, 00216 bool WriteAlphaChannel, 00217 const Color &SelectedTextColor, 00218 const Color &SelectedTextBackgroundColor, 00219 const Color &TextBlinkColor, 00220 const Color &CursorColor, 00221 bool ShowCursor, unsigned int CursorPosition, int offset, int selection_start, int selection_end) 00222 { 00223 StringBBox stringBBox; 00224 Color selection_color (0xFF888888); 00225 00226 NString substring = Str.GetSubString (selection_start, selection_end - selection_start); 00227 unsigned int substring_width = Font->GetStringWidth (substring); 00228 int substring_pos = Font->GetStringWidth (Str, selection_start); 00229 00230 _graphics_engine.PushClippingRectangle (Rect (pageSize.xmin, pageSize.ymin, pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin) ); 00231 00232 if (substring_width > 0) 00233 _graphics_engine.QRP_Color (pageSize.xmin + offset + substring_pos, pageSize.ymin, substring_width, pageSize.ymax - pageSize.ymin, SelectedTextBackgroundColor); 00234 00235 _graphics_engine.PopClippingRectangle(); 00236 00237 _graphics_engine.PushClippingRectangle (Rect (pageSize.xmin, pageSize.ymin, pageSize.xmax - pageSize.xmin, pageSize.ymax - pageSize.ymin) ); 00238 00239 PositionString (Font, Str, pageSize, stringBBox, eAlignTextLeft); 00240 //ComputeGlyphString(stringBBox.x + offset, stringBBox.y, Str.c_str()); 00241 00242 // Part before selected text 00243 int off = DrawColorString (Font, stringBBox.x + offset, stringBBox.y, Str, TextColor, WriteAlphaChannel, 0, selection_start); 00244 // Selection part 00245 off = DrawColorString (Font, stringBBox.x + offset, stringBBox.y, Str, SelectedTextColor, WriteAlphaChannel, selection_start, selection_end - selection_start); 00246 // Part after selected text 00247 off = DrawColorString (Font, stringBBox.x + offset, stringBBox.y, Str, TextColor, WriteAlphaChannel, selection_end, Str.Size() - selection_end); 00248 00249 _graphics_engine.PopClippingRectangle(); 00250 00251 // Render Cursor 00252 NString temp = Str.GetSubString (0, CursorPosition); 00253 int w = Font->GetStringWidth (temp.GetTCharPtr() ); 00254 00255 00256 if (ShowCursor) 00257 { 00258 int x = pageSize.xmin + w + offset + CURSOR_OFFSET; 00259 x = (x >= pageSize.xmax) ? pageSize.xmax - 1 : x; 00260 _graphics_engine.PushClippingRectangle (Rect (x, pageSize.ymin, CURSOR_SIZE, pageSize.ymax - pageSize.ymin) ); 00261 00262 _graphics_engine.QRP_Color (x, pageSize.ymin, CURSOR_SIZE, pageSize.ymax - pageSize.ymin, CursorColor); 00263 00264 DrawColorString (Font, stringBBox.x + offset, stringBBox.y, Str, TextBlinkColor, WriteAlphaChannel, CursorPosition, 1); 00265 _graphics_engine.PopClippingRectangle(); 00266 } 00267 00268 return off; 00269 } 00270 00271 int FontRenderer::RenderText (ObjectPtr<FontTexture> Font, int x, int y, const NString &str, const Color &color, bool WriteAlphaChannel, int StartCharacter, int NumCharacter) 00272 { 00273 // !WARNING This call works if all the glyph of the font are in a single texture. 00274 00275 int StrLength = str.Size(); 00276 00277 if (StrLength <= 0) 00278 return 0; 00279 00280 nuxAssertMsg (NumCharacter >= 0, TEXT ("[FontRenderer::RenderText] Incorrect value for NumCharacter.") ); 00281 nuxAssertMsg (StartCharacter >= 0, TEXT ("[FontRenderer::RenderText] Incorrect value for StartCharacter.") ); 00282 nuxAssertMsg (StartCharacter <= StrLength, TEXT ("[FontRenderer::RenderText] Incorrect value for StartCharacter.") ); 00283 00284 // if(NumCharacter == 0) 00285 // NumCharacter = str.Size(); 00286 00287 int NumCharToDraw = Min<int> (StrLength - StartCharacter, NumCharacter); 00288 00289 //nuxAssertMsg(NumCharToDraw > 0, TEXT("[FontRenderer::RenderText] Incorrect value for NumCharToDraw.")); 00290 if (NumCharToDraw <= 0) 00291 return 0; 00292 00293 CHECKGL ( glDisable (GL_CULL_FACE) ); 00294 int CurX = x; 00295 int CurY = y; 00296 _graphics_engine.GetRenderStates().SetBlend (TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00297 _graphics_engine.GetRenderStates().SetColorMask (TRUE, TRUE, TRUE, WriteAlphaChannel); // Do not write the alpha of characters 00298 00299 Vector4 *Position = new Vector4[StrLength*4]; 00300 Vector4 *UV = new Vector4[StrLength*4]; 00301 Vector4 *Offset = new Vector4[StrLength*4]; 00302 Vector4 *Scale = new Vector4[StrLength*4]; 00303 00304 ObjectPtr<CachedBaseTexture> glTexture = _graphics_engine.ResourceCache.GetCachedResource (Font->TextureArray[0]); 00305 00306 float tex_width = (float) glTexture->m_Texture->GetWidth(); 00307 float tex_height = (float) glTexture->m_Texture->GetHeight(); 00308 00309 for (int i = 0; i < StrLength; ++i) 00310 { 00311 unsigned char c = static_cast<unsigned char> (str[i]); 00312 unsigned int CharX = Font->m_Charset.Chars[c /*Str[i]*/].x; 00313 unsigned int CharY = Font->m_Charset.Chars[c /*Str[i]*/].y; 00314 unsigned int Width = Font->m_Charset.Chars[c /*Str[i]*/].Width; 00315 unsigned int Height = Font->m_Charset.Chars[c /*Str[i]*/].Height; 00316 //int OffsetX = Font->m_Charset.Chars[c /*Str[i]*/].XOffset; 00317 //int OffsetY = Font->m_Charset.Chars[c /*Str[i]*/].YOffset; 00318 int abcA = Font->m_Charset.Chars[c /*Str[i]*/].abcA; 00319 int abcB = Font->m_Charset.Chars[c /*Str[i]*/].abcB; 00320 int abcC = Font->m_Charset.Chars[c /*Str[i]*/].abcC; 00321 //int page = Font->m_Charset.Chars[c /*Str[i]*/].page; 00322 00323 if ( (i >= StartCharacter) && (i < StartCharacter + NumCharToDraw) ) 00324 { 00325 int II = i - StartCharacter; 00326 Position[II*4 + 0].x = 0; // x 00327 Position[II*4 + 0].y = 0; // y 00328 Position[II*4 + 0].z = 0; // z 00329 Position[II*4 + 0].w = 1.0f; // w 00330 00331 Position[II*4 + 1].x = 1.0f; // x 00332 Position[II*4 + 1].y = 0; // y 00333 Position[II*4 + 1].z = 0; // z 00334 Position[II*4 + 1].w = 1; // w 00335 00336 Position[II*4 + 2].x = 1.0f; // x 00337 Position[II*4 + 2].y = 1.0f; // y 00338 Position[II*4 + 2].z = 0; // z 00339 Position[II*4 + 2].w = 1; // w 00340 00341 Position[II*4 + 3].x = 0; // x 00342 Position[II*4 + 3].y = 1.0f; // y 00343 Position[II*4 + 3].z = 0; // z 00344 Position[II*4 + 3].w = 1; // w 00345 00346 for (int j = 0; j < 4; j++) 00347 { 00348 Offset[II*4 + j].x = CurX + abcA; 00349 Offset[II*4 + j].y = CurY; 00350 Offset[II*4 + j].z = 0.0f; 00351 Offset[II*4 + j].w = 0.0f; 00352 00353 Scale[II*4 + j].x = Width; 00354 Scale[II*4 + j].y = Height; 00355 Scale[II*4 + j].z = 1.0f; 00356 Scale[II*4 + j].w = 1.0f; 00357 } 00358 00359 if(glTexture->m_Texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) 00360 { 00361 //upper left 00362 UV[II*4 + 0].x = CharX; 00363 UV[II*4 + 0].y = CharY; 00364 UV[II*4 + 0].z = 0.0f; 00365 UV[II*4 + 0].w = 0.0f; 00366 00367 //upper right 00368 UV[II*4 + 1].x = (CharX + Width); 00369 UV[II*4 + 1].y = CharY; 00370 UV[II*4 + 1].z = 0.0f; 00371 UV[II*4 + 1].w = 0.0f; 00372 00373 //lower right 00374 UV[II*4 + 2].x = (CharX + Width); 00375 UV[II*4 + 2].y = (CharY + Height); 00376 UV[II*4 + 2].z = 0.0f; 00377 UV[II*4 + 2].w = 0.0f; 00378 00379 //lower left 00380 UV[II*4 + 3].x = CharX; 00381 UV[II*4 + 3].y = (CharY + Height); 00382 UV[II*4 + 3].z = 0.0f; 00383 UV[II*4 + 3].w = 0.0f; 00384 } 00385 else 00386 { 00387 //upper left 00388 UV[II*4 + 0].x = CharX / tex_width; 00389 UV[II*4 + 0].y = CharY / tex_height; 00390 UV[II*4 + 0].z = 0.0f; 00391 UV[II*4 + 0].w = 0.0f; 00392 00393 //upper right 00394 UV[II*4 + 1].x = (CharX + Width) / tex_width; 00395 UV[II*4 + 1].y = CharY / tex_height; 00396 UV[II*4 + 1].z = 0.0f; 00397 UV[II*4 + 1].w = 0.0f; 00398 00399 //lower right 00400 UV[II*4 + 2].x = (CharX + Width) / tex_width; 00401 UV[II*4 + 2].y = (CharY + Height) / tex_height; 00402 UV[II*4 + 2].z = 0.0f; 00403 UV[II*4 + 2].w = 0.0f; 00404 00405 //lower left 00406 UV[II*4 + 3].x = CharX / tex_width; 00407 UV[II*4 + 3].y = (CharY + Height) / tex_height; 00408 UV[II*4 + 3].z = 0.0f; 00409 UV[II*4 + 3].w = 0.0f; 00410 } 00411 } 00412 00413 CurX += abcA + abcB + abcC; 00414 } 00415 00416 CHECKGL (glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0) ); 00417 CHECKGL (glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0) ); 00418 00419 int in_attrib_position = 0; 00420 int in_attrib_tex_uv = 0; 00421 int in_attrib_scale = 0; 00422 int in_attrib_offset = 0; 00423 00424 ObjectPtr<IOpenGLAsmShaderProgram> shader_program; 00425 if(_graphics_engine.UsingGLSLCodePath()) 00426 { 00427 _shader_prog->Begin(); 00428 int ViewProjectionMatrix = _shader_prog->GetUniformLocationARB ("ViewProjectionMatrix"); 00429 Matrix4 mat = _graphics_engine.GetOpenGLModelViewProjectionMatrix(); 00430 00431 _shader_prog->SetUniformLocMatrix4fv (ViewProjectionMatrix, 1, false, (float *) &mat); 00432 00433 in_attrib_position = _shader_prog->GetAttributeLocation("_Position"); 00434 in_attrib_tex_uv = _shader_prog->GetAttributeLocation("iTexUV"); 00435 in_attrib_scale = _shader_prog->GetAttributeLocation("iScale"); 00436 in_attrib_offset = _shader_prog->GetAttributeLocation("iOffset"); 00437 00438 int FontTexture = _shader_prog->GetUniformLocationARB("FontTexture"); 00439 int TextColor = _shader_prog->GetUniformLocationARB("TextColor"); 00440 00441 _graphics_engine.SetTexture(GL_TEXTURE0, glTexture->m_Texture); 00442 00443 if(FontTexture != -1) 00444 { 00445 CHECKGL(glUniform1iARB(FontTexture, 0)); 00446 } 00447 00448 if(TextColor != -1) 00449 { 00450 CHECKGL(glUniform4fARB(TextColor, color.red, color.green, color.blue, color.alpha)); 00451 } 00452 } 00453 else 00454 { 00455 shader_program = _asm_shader_prog; 00456 if(glTexture->m_Texture->Type().IsDerivedFromType(IOpenGLRectangleTexture::StaticObjectType)) 00457 { 00458 shader_program = _asm_font_texture_rect_prog; 00459 } 00460 shader_program->Begin(); 00461 00462 CHECKGL (glMatrixMode(GL_MODELVIEW)); 00463 CHECKGL (glLoadIdentity()); 00464 Matrix4 model_view_matrix = _graphics_engine.GetModelViewMatrix (); 00465 model_view_matrix.Transpose(); 00466 CHECKGL (glLoadMatrixf((float *) model_view_matrix.m)); 00467 00468 CHECKGL (glMatrixMode(GL_PROJECTION)); 00469 CHECKGL (glLoadIdentity()); 00470 Matrix4 projection_matrix = GetGraphicsDisplay()->GetGraphicsEngine()->GetProjectionMatrix (); 00471 projection_matrix.Transpose (); 00472 CHECKGL (glLoadMatrixf ((float *) projection_matrix.m)); 00473 00474 in_attrib_position = VTXATTRIB_POSITION; 00475 in_attrib_tex_uv = VTXATTRIB_TEXCOORD0; 00476 in_attrib_scale = VTXATTRIB_TEXCOORD1; 00477 in_attrib_offset = VTXATTRIB_TEXCOORD2; 00478 00479 CHECKGL ( glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 0, color.red, color.green, color.blue, color.alpha ) ); 00480 00481 _graphics_engine.SetTexture (GL_TEXTURE0, glTexture->m_Texture); 00482 } 00483 00484 if (in_attrib_offset != -1) 00485 { 00486 CHECKGL ( glEnableVertexAttribArrayARB (in_attrib_offset) ); 00487 CHECKGL ( glVertexAttribPointerARB (in_attrib_offset, 4, GL_FLOAT, GL_FALSE, 16, Offset) ); 00488 } 00489 00490 if (in_attrib_position != -1) 00491 { 00492 CHECKGL ( glEnableVertexAttribArrayARB (in_attrib_position) ); 00493 CHECKGL ( glVertexAttribPointerARB (in_attrib_position, 4, GL_FLOAT, GL_FALSE, 16, Position) ); 00494 } 00495 00496 if (in_attrib_scale != -1) 00497 { 00498 CHECKGL ( glEnableVertexAttribArrayARB (in_attrib_scale) ); 00499 CHECKGL ( glVertexAttribPointerARB (in_attrib_scale, 4, GL_FLOAT, GL_FALSE, 16, Scale) ); 00500 } 00501 00502 if (in_attrib_tex_uv != -1) 00503 { 00504 CHECKGL ( glEnableVertexAttribArrayARB (in_attrib_tex_uv) ); 00505 CHECKGL ( glVertexAttribPointerARB (in_attrib_tex_uv, 4, GL_FLOAT, GL_FALSE, 16, UV) ); 00506 } 00507 00508 if (NumCharToDraw > 0) 00509 CHECKGL ( glDrawArrays ( GL_QUADS, 0, NumCharToDraw * 4 ) ); 00510 00511 if (in_attrib_position != -1) 00512 CHECKGL ( glDisableVertexAttribArrayARB (in_attrib_position) ); 00513 00514 if (in_attrib_offset != -1) 00515 CHECKGL ( glDisableVertexAttribArrayARB (in_attrib_offset) ); 00516 00517 if (in_attrib_scale != -1) 00518 CHECKGL ( glDisableVertexAttribArrayARB (in_attrib_scale) ); 00519 00520 if (in_attrib_tex_uv != -1) 00521 CHECKGL ( glDisableVertexAttribArrayARB (in_attrib_tex_uv) ); 00522 00523 if(_graphics_engine.UsingGLSLCodePath()) 00524 { 00525 _shader_prog->End(); 00526 } 00527 else 00528 { 00529 shader_program->End(); 00530 } 00531 00532 _graphics_engine.GetRenderStates().SetColorMask (TRUE, TRUE, TRUE, TRUE); 00533 _graphics_engine.GetRenderStates().SetBlend (FALSE); 00534 00535 CurX -= x + CURSOR_OFFSET; 00536 00537 delete [] Position; 00538 delete [] UV; 00539 delete [] Scale; 00540 delete [] Offset; 00541 00542 return CurX; // number of pixel to offset before writing the next string. 00543 } 00544 00545 int FontRenderer::RenderTextToBuffer (float *VertexBuffer, int VBSize, 00546 ObjectPtr<FontTexture> Font, Rect geo, const NString &str, const Color &color, TextAlignment alignment, int NumCharacter) 00547 { 00548 nuxAssertMsg (NumCharacter >= 0, TEXT ("[FontRenderer::RenderTextToBuffer] Number of char to draw must be positive.") ); 00549 int NumCharToDraw = 0; 00550 00551 if (NumCharacter == 0) 00552 NumCharToDraw = str.Size(); 00553 else 00554 NumCharToDraw = Min ( (int) str.Size(), NumCharacter); 00555 00556 nuxAssertMsg (3 * NumCharToDraw * 16 <= VBSize, TEXT ("[FontRenderer::RenderTextToBuffer] VertexBuffer not large enough.") ); 00557 00558 if (3 * NumCharToDraw * 16 > VBSize) 00559 return 0; 00560 00561 StringBBox stringBBox; 00562 PageBBox pageBox; 00563 pageBox.xmin = geo.x; 00564 pageBox.xmax = geo.x + geo.GetWidth(); 00565 pageBox.ymin = geo.y; 00566 pageBox.ymax = geo.y + geo.GetHeight(); 00567 pageBox.x_margin = 0; 00568 pageBox.y_margin = 0; 00569 00570 PositionString (Font, str, pageBox, stringBBox, alignment); 00571 00572 int CurX = stringBBox.x; 00573 int CurY = stringBBox.y; 00574 00575 Vector4 *Position = (Vector4 *) VertexBuffer; 00576 00577 for (int i = 0; i < NumCharToDraw; ++i) 00578 { 00579 unsigned char c = static_cast<unsigned char> (str[i]); 00580 unsigned int CharX = Font->m_Charset.Chars[c /*Str[i]*/].x; 00581 unsigned int CharY = Font->m_Charset.Chars[c /*Str[i]*/].y; 00582 unsigned int Width = Font->m_Charset.Chars[c /*Str[i]*/].Width; 00583 unsigned int Height = Font->m_Charset.Chars[c /*Str[i]*/].Height; 00584 //int OffsetX = Font->m_Charset.Chars[c /*Str[i]*/].XOffset; 00585 //int OffsetY = Font->m_Charset.Chars[c /*Str[i]*/].YOffset; 00586 int abcA = Font->m_Charset.Chars[c /*Str[i]*/].abcA; 00587 int abcB = Font->m_Charset.Chars[c /*Str[i]*/].abcB; 00588 int abcC = Font->m_Charset.Chars[c /*Str[i]*/].abcC; 00589 //int page = Font->m_Charset.Chars[c /*Str[i]*/].page; 00590 00591 // Position upper left 00592 // Scale Offset 00593 Position[i*12 + 0].x = 0.0f * Width + (CurX + abcA); // x 00594 Position[i*12 + 0].y = 0.0f * Height + (CurY); // y 00595 Position[i*12 + 0].z = 0.0f * 1.0f + 0.0f; // z 00596 Position[i*12 + 0].w = 1.0f * 1.0f + 0.0f; // w 00597 // texture coord 00598 Position[i*12 + 1].x = CharX; 00599 Position[i*12 + 1].y = CharY; 00600 Position[i*12 + 1].z = 0.0f; 00601 Position[i*12 + 1].w = 1.0f; 00602 // color 00603 Position[i*12 + 2].x = color.red; 00604 Position[i*12 + 2].y = color.green; 00605 Position[i*12 + 2].z = color.blue; 00606 Position[i*12 + 2].w = color.alpha; 00607 00608 // Position lower left 00609 Position[i*12 + 9].x = 0.0f * Width + (CurX + abcA); // x 00610 Position[i*12 + 9].y = 1.0f * Height + (CurY); // y 00611 Position[i*12 + 9].z = 0.0f * 1.0f + 0.0f; // z 00612 Position[i*12 + 9].w = 1.0f * 1.0f + 0.0f; // w 00613 // texture coord 00614 Position[i*12 + 10].x = CharX; 00615 Position[i*12 + 10].y = CharY + Height; 00616 Position[i*12 + 10].z = 0.0f; 00617 Position[i*12 + 10].w = 1.0f; 00618 // color 00619 Position[i*12 + 11].x = color.red; 00620 Position[i*12 + 11].y = color.green; 00621 Position[i*12 + 11].z = color.blue; 00622 Position[i*12 + 11].w = color.alpha; 00623 00624 // Position lower right 00625 Position[i*12 + 6].x = 1.0f * Width + (CurX + abcA); // x 00626 Position[i*12 + 6].y = 1.0f * Height + (CurY); // y 00627 Position[i*12 + 6].z = 0.0f * 1.0f + 0.0f; // z 00628 Position[i*12 + 6].w = 1.0f * 1.0f + 0.0f; // w 00629 // texture coord 00630 Position[i*12 + 7].x = CharX + Width; 00631 Position[i*12 + 7].y = CharY + Height; 00632 Position[i*12 + 7].z = 0.0f; 00633 Position[i*12 + 7].w = 1.0f; 00634 // color 00635 Position[i*12 + 8].x = color.red; 00636 Position[i*12 + 8].y = color.green; 00637 Position[i*12 + 8].z = color.blue; 00638 Position[i*12 + 8].w = color.alpha; 00639 00640 // Position upper right 00641 Position[i*12 + 3].x = 1.0f * Width + (CurX + abcA); // x 00642 Position[i*12 + 3].y = 0.0f * Height + (CurY); // y 00643 Position[i*12 + 3].z = 0.0f * 1.0f + 0.0f; // z 00644 Position[i*12 + 3].w = 1.0f * 1.0f + 0.0f; // w 00645 // texture coord 00646 Position[i*12 + 4].x = CharX + Width; 00647 Position[i*12 + 4].y = CharY; 00648 Position[i*12 + 4].z = 0.0f; 00649 Position[i*12 + 4].w = 1.0f; 00650 // color 00651 Position[i*12 + 5].x = color.red; 00652 Position[i*12 + 5].y = color.green; 00653 Position[i*12 + 5].z = color.blue; 00654 Position[i*12 + 5].w = color.alpha; 00655 00656 CurX += abcA + abcB + abcC; 00657 } 00658 00659 CurX -= stringBBox.x + CURSOR_OFFSET; 00660 return NumCharToDraw; 00661 } 00662 00663 }