1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: demo_RenderSystemDrawing.cpp 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 46365 $ 14 *---------------------------------------------------------------------------*/ 15 16 #include "demo/Render/demo_RenderSystemDrawing.h" 17 18 namespace demo 19 { 20 RenderSystemDrawing(void)21 RenderSystemDrawing::RenderSystemDrawing(void) : 22 RenderSystem(), 23 m_InitializeTexturedTriangles(false), m_UseDecalTextureProgram(false), 24 m_MaxTexturedTrianglesNum(demo::MAX_TEXTURED_TRIANGLES_NUM) 25 { 26 for (u32 textureArrayIndex = 0; textureArrayIndex < demo::MAX_TEXTURES_NUM; 27 textureArrayIndex++) 28 { 29 m_TextureIdArray[textureArrayIndex] = 0; 30 m_TotalTexturedTrianglesNumArray[textureArrayIndex] = 0; 31 } 32 33 for (u32 displayIndex = 0; displayIndex < 3; displayIndex++) 34 { 35 for (u32 index = 0; index < 4; index++) 36 { 37 m_ClearColorArray[displayIndex][index] = 0.0f; 38 } 39 } 40 } 41 ~RenderSystemDrawing(void)42 RenderSystemDrawing::~RenderSystemDrawing(void) 43 { 44 Finalize(); 45 } 46 Initialize(const uptr fcramAddress,const size_t memorySize,const u32 commandBufferSize,const u32 requestNum,const bool serialRunMode,const DisplayBuffersDescription & displayBuffers0Desc,const DisplayBuffersDescription & displayBuffers1Desc,const FrameBufferDescription & frameBuffer0Desc,const DisplayBuffersDescription & displayBuffers0ExtDesc,const bool isFillBlackLCD)47 void RenderSystemDrawing::Initialize(const uptr fcramAddress, const size_t memorySize, 48 const u32 commandBufferSize, const u32 requestNum, 49 const bool serialRunMode, 50 const DisplayBuffersDescription& displayBuffers0Desc, 51 const DisplayBuffersDescription& displayBuffers1Desc, 52 const FrameBufferDescription& frameBuffer0Desc, 53 const DisplayBuffersDescription& displayBuffers0ExtDesc, 54 const bool isFillBlackLCD) 55 { 56 57 RenderSystem::Initialize(fcramAddress, memorySize, 58 commandBufferSize, requestNum, serialRunMode, 59 displayBuffers0Desc, displayBuffers1Desc, 60 frameBuffer0Desc, displayBuffers0ExtDesc, isFillBlackLCD); 61 62 m_InitializeTexturedTriangles = false; 63 m_UseDecalTextureProgram = false; 64 65 // Note: nngxInitialize() must be called in advance. It is called from within RenderSystem::Initialize(). 66 m_GraphicsDrawing.Initialize(); 67 } 68 InitializeTexturedTriangles(const u32 maxTrianglesNum)69 void RenderSystemDrawing::InitializeTexturedTriangles(const u32 maxTrianglesNum) 70 { 71 if ( m_InitializeTexturedTriangles ) 72 { 73 return; 74 } 75 76 u32 vertexAttributes = m_GraphicsDrawing.m_ShaderManager.GetVertexAttributes(demo::DECAL_TEXTURE_SHADER); 77 u32 maxVerticesNum = 3 * maxTrianglesNum; 78 m_MaxTexturedTrianglesNum = maxTrianglesNum; 79 80 for (u32 textureArrayIndex = 0; textureArrayIndex < demo::MAX_TEXTURES_NUM; textureArrayIndex++) 81 { 82 m_TotalTexturedTrianglesNumArray[textureArrayIndex] = 0; 83 84 m_TexturedTrianglesRenderDataArray[textureArrayIndex].Initialize(); 85 m_TexturedTrianglesRenderDataArray[textureArrayIndex].InitializeVertexBuffers(vertexAttributes, 86 GL_TRIANGLES, maxVerticesNum, m_MaxTexturedTrianglesNum); 87 } 88 89 for (u32 textureArrayIndex = 0; textureArrayIndex < demo::MAX_TEXTURES_NUM; textureArrayIndex++) 90 { 91 m_TextureIdArray[textureArrayIndex] = 0; 92 } 93 94 m_InitializeTexturedTriangles = true; 95 96 DEMO_ASSERT_GL_ERROR(); 97 } 98 InitializeTriangles(const u32 maxTrianglesNum)99 void RenderSystemDrawing::InitializeTriangles(const u32 maxTrianglesNum) 100 { 101 m_GraphicsDrawing.InitializeTriangles(maxTrianglesNum); 102 } 103 InitializeSquares(const u32 maxSquaresNum)104 void RenderSystemDrawing::InitializeSquares(const u32 maxSquaresNum) 105 { 106 m_GraphicsDrawing.InitializeSquares(maxSquaresNum); 107 } 108 InitializeTexts(const u32 maxLength)109 void RenderSystemDrawing::InitializeTexts(const u32 maxLength) 110 { 111 m_GraphicsDrawing.InitializeTexts(maxLength); 112 } 113 Finalize(void)114 void RenderSystemDrawing::Finalize(void) 115 { 116 for (u32 textureArrayIndex = 0; textureArrayIndex < MAX_TEXTURES_NUM; textureArrayIndex++) 117 { 118 m_TotalTexturedTrianglesNumArray[textureArrayIndex] = 0; 119 m_TexturedTrianglesRenderDataArray[textureArrayIndex].Finalize(); 120 } 121 m_InitializeTexturedTriangles = false; 122 123 for (u32 textureArrayIndex = 0; textureArrayIndex < MAX_TEXTURES_NUM; textureArrayIndex++) 124 { 125 GLuint textureId = m_TextureIdArray[textureArrayIndex]; 126 if ( textureId != 0 ) 127 { 128 glDeleteTextures(1, &textureId); 129 m_TextureIdArray[textureArrayIndex] = 0; 130 } 131 } 132 133 m_GraphicsDrawing.Finalize(); 134 RenderSystem::Finalize(); 135 136 DEMO_ASSERT_GL_ERROR(); 137 } 138 SetViewport(const GLint x,const GLint y,const GLsizei width,const GLsizei height)139 void RenderSystemDrawing::SetViewport(const GLint x, const GLint y, const GLsizei width, const GLsizei height) 140 { 141 NN_UNUSED_VAR(x); 142 NN_UNUSED_VAR(y); 143 144 m_GraphicsDrawing.SetWindowSize(width, height); 145 146 for (u32 textureArrayIndex = 0; textureArrayIndex < MAX_TEXTURES_NUM; textureArrayIndex++) 147 { 148 m_TexturedTrianglesRenderDataArray[textureArrayIndex].SetWindowSize(width, height); 149 } 150 151 RenderSystem::SetViewport(x, y, width, height); 152 } 153 SetClearColor(const s32 display,const f32 red,const f32 green,const f32 blue,const f32 alpha)154 void RenderSystemDrawing::SetClearColor(const s32 display, 155 const f32 red, const f32 green, const f32 blue, const f32 alpha) 156 { 157 if (display == NN_GX_DISPLAY0 || display == NN_GX_DISPLAY_BOTH) 158 { 159 m_ClearColorArray[0][0] = red; 160 m_ClearColorArray[0][1] = green; 161 m_ClearColorArray[0][2] = blue; 162 m_ClearColorArray[0][3] = alpha; 163 } 164 165 if (display == NN_GX_DISPLAY1 || display == NN_GX_DISPLAY_BOTH) 166 { 167 m_ClearColorArray[1][0] = red; 168 m_ClearColorArray[1][1] = green; 169 m_ClearColorArray[1][2] = blue; 170 m_ClearColorArray[1][3] = alpha; 171 } 172 } 173 Clear(const GLbitfield mask)174 void RenderSystemDrawing::Clear(const GLbitfield mask) 175 { 176 u32 displayIndex = 0; 177 if ( m_TargetDisplay == NN_GX_DISPLAY0 ) 178 { 179 displayIndex = 0; 180 } 181 else if ( m_TargetDisplay == NN_GX_DISPLAY1 ) 182 { 183 displayIndex = 1; 184 } 185 glClearColor(m_ClearColorArray[displayIndex][0], m_ClearColorArray[displayIndex][1], 186 m_ClearColorArray[displayIndex][2], m_ClearColorArray[displayIndex][3]); 187 188 RenderSystem::Clear(mask); 189 } 190 SetColor(const f32 red,const f32 green,const f32 blue,const f32 alpha)191 void RenderSystemDrawing::SetColor(const f32 red, const f32 green, const f32 blue, const f32 alpha) 192 { 193 m_GraphicsDrawing.SetColor(red, green, blue, alpha); 194 } 195 SetColor(const f32 red,const f32 green,const f32 blue)196 void RenderSystemDrawing::SetColor(const f32 red, const f32 green, const f32 blue) 197 { 198 m_GraphicsDrawing.SetColor(red, green, blue); 199 } 200 SetDepth(const f32 depth)201 void RenderSystemDrawing::SetDepth(const f32 depth) 202 { 203 m_GraphicsDrawing.SetDepth(depth); 204 } 205 SetAutoDepth(const bool enableAutoDepth)206 void RenderSystemDrawing::SetAutoDepth(const bool enableAutoDepth) 207 { 208 m_GraphicsDrawing.SetAutoDepth(enableAutoDepth); 209 } 210 SetPointSize(const f32 pointSize)211 void RenderSystemDrawing::SetPointSize(const f32 pointSize) 212 { 213 m_GraphicsDrawing.SetPointSize(pointSize); 214 } 215 DrawPoint(const f32 windowCoordinateX,const f32 windowCoordinateY)216 void RenderSystemDrawing::DrawPoint(const f32 windowCoordinateX, const f32 windowCoordinateY) 217 { 218 m_GraphicsDrawing.DrawPoint(windowCoordinateX, windowCoordinateY); 219 } 220 SetLineWidth(const f32 lineWidth)221 void RenderSystemDrawing::SetLineWidth(const f32 lineWidth) 222 { 223 m_GraphicsDrawing.SetLineWidth(lineWidth); 224 } 225 DrawLine(const f32 windowCoordinateX0,const f32 windowCoordinateY0,const f32 windowCoordinateX1,const f32 windowCoordinateY1)226 void RenderSystemDrawing::DrawLine(const f32 windowCoordinateX0, const f32 windowCoordinateY0, 227 const f32 windowCoordinateX1, const f32 windowCoordinateY1) 228 { 229 CheckRenderTarget(); 230 m_GraphicsDrawing.DrawLine(windowCoordinateX0, windowCoordinateY0, 231 windowCoordinateX1, windowCoordinateY1); 232 } 233 FillSquare(const f32 windowCoordinateX0,const f32 windowCoordinateY0,const f32 windowCoordinateX1,const f32 windowCoordinateY1,const f32 windowCoordinateX2,const f32 windowCoordinateY2,const f32 windowCoordinateX3,const f32 windowCoordinateY3)234 void RenderSystemDrawing::FillSquare(const f32 windowCoordinateX0, const f32 windowCoordinateY0, 235 const f32 windowCoordinateX1, const f32 windowCoordinateY1, 236 const f32 windowCoordinateX2, const f32 windowCoordinateY2, 237 const f32 windowCoordinateX3, const f32 windowCoordinateY3) 238 { 239 CheckRenderTarget(); 240 m_GraphicsDrawing.FillSquare(windowCoordinateX0, windowCoordinateY0, 241 windowCoordinateX1, windowCoordinateY1, 242 windowCoordinateX2, windowCoordinateY2, 243 windowCoordinateX3, windowCoordinateY3); 244 } 245 FillRectangle(const f32 windowCoordinateX,const f32 windowCoordinateY,const f32 width,const f32 height)246 void RenderSystemDrawing::FillRectangle(const f32 windowCoordinateX, 247 const f32 windowCoordinateY, const f32 width, const f32 height) 248 { 249 CheckRenderTarget(); 250 m_GraphicsDrawing.FillRectangle(windowCoordinateX, windowCoordinateY, 251 width, height); 252 } 253 FillTriangle(const f32 windowCoordinateX0,const f32 windowCoordinateY0,const f32 windowCoordinateX1,const f32 windowCoordinateY1,const f32 windowCoordinateX2,const f32 windowCoordinateY2)254 void RenderSystemDrawing::FillTriangle(const f32 windowCoordinateX0, const f32 windowCoordinateY0, 255 const f32 windowCoordinateX1, const f32 windowCoordinateY1, 256 const f32 windowCoordinateX2, const f32 windowCoordinateY2) 257 { 258 CheckRenderTarget(); 259 m_GraphicsDrawing.FillTriangle(windowCoordinateX0, windowCoordinateY0, 260 windowCoordinateX1, windowCoordinateY1, 261 windowCoordinateX2, windowCoordinateY2); 262 } 263 SetFontSize(const f32 fontSize)264 void RenderSystemDrawing::SetFontSize(const f32 fontSize) 265 { 266 m_GraphicsDrawing.SetFontSize(fontSize); 267 } 268 DrawText(const f32 windowCoordinateX,const f32 windowCoordinateY,const char * format,...)269 void RenderSystemDrawing::DrawText(const f32 windowCoordinateX, const f32 windowCoordinateY, const char* format, ...) 270 { 271 CheckRenderTarget(); 272 273 static const u32 tmpBufferSize = 1024; 274 static char textBuffer[tmpBufferSize]; 275 276 va_list va; 277 va_start(va, format); 278 vsnprintf(textBuffer, tmpBufferSize, format, va); 279 va_end(va); 280 281 m_GraphicsDrawing.DrawTextBuffer(windowCoordinateX, windowCoordinateY, textBuffer); 282 } 283 HasTexture(const GLuint textureId)284 bool RenderSystemDrawing::HasTexture(const GLuint textureId) 285 { 286 if (! m_InitializeFlag ) 287 { 288 NN_TPANIC_("Initialize() is not called.\n"); 289 } 290 291 if (! m_InitializeTexturedTriangles ) 292 { 293 InitializeTexturedTriangles(); 294 } 295 296 u32 arrayIndex = 0; 297 return FindTextureArrayIndex(textureId, arrayIndex); 298 } 299 GenerateTexture(const GLenum target,const GLenum internalFormat,const GLsizei width,const GLsizei height,const GLenum format,const GLenum type,void * pixels,GLuint & textureId)300 bool RenderSystemDrawing::GenerateTexture(const GLenum target, 301 const GLenum internalFormat, 302 const GLsizei width, const GLsizei height, 303 const GLenum format, const GLenum type, void* pixels, 304 GLuint& textureId) 305 { 306 if (! m_InitializeFlag ) 307 { 308 NN_TPANIC_("Initialize() is not called.\n"); 309 } 310 311 if (! m_InitializeTexturedTriangles ) 312 { 313 InitializeTexturedTriangles(); 314 } 315 316 u32 emptyTextureId = 0; 317 u32 textureArrayIndex = 0; 318 319 if (! FindTextureArrayIndex(emptyTextureId, textureArrayIndex) ) 320 { 321 NN_TPANIC_("Max loadable textures numbers is %d.\n", demo::MAX_TEXTURES_NUM); 322 323 return false; 324 } 325 326 glActiveTexture(GL_TEXTURE0); 327 glGenTextures(1, &textureId); 328 DEMO_ASSERT_GL_ERROR(); 329 330 glBindTexture(GL_TEXTURE_2D, textureId); 331 glTexImage2D(target, 0, internalFormat, 332 width, height, 0, 333 format, type, pixels); 334 DEMO_ASSERT_GL_ERROR(); 335 336 m_TextureIdArray[textureArrayIndex] = textureId; 337 338 return true; 339 } 340 DeleteTexture(const GLuint textureId)341 bool RenderSystemDrawing::DeleteTexture(const GLuint textureId) 342 { 343 if (! m_InitializeFlag ) 344 { 345 NN_TPANIC_("Initialize() is not called.\n"); 346 } 347 348 if (! m_InitializeTexturedTriangles ) 349 { 350 InitializeTexturedTriangles(); 351 } 352 353 if ( textureId == 0 ) 354 { 355 return false; 356 } 357 358 u32 textureArrayIndex = 0; 359 if ( FindTextureArrayIndex(textureId, textureArrayIndex) ) 360 { 361 glDeleteTextures(1, &textureId); 362 DEMO_ASSERT_GL_ERROR(); 363 364 m_TextureIdArray[textureArrayIndex] = 0; 365 366 return true; 367 } 368 else 369 { 370 return false; 371 } 372 } 373 FindTextureArrayIndex(const GLuint textureId,u32 & arrayIndex)374 bool RenderSystemDrawing::FindTextureArrayIndex(const GLuint textureId, u32& arrayIndex) 375 { 376 if (! m_InitializeFlag ) 377 { 378 NN_TPANIC_("Initialize() is not called.\n"); 379 } 380 381 for (u32 textureArrayIndex = 0; textureArrayIndex < demo::MAX_TEXTURES_NUM; 382 textureArrayIndex++) 383 { 384 if ( textureId == m_TextureIdArray[textureArrayIndex] ) 385 { 386 arrayIndex = textureArrayIndex; 387 388 return true; 389 } 390 } 391 392 return false; 393 } 394 FillTexturedRectangle(const GLuint textureId,const f32 windowCoordinateX,const f32 windowCoordinateY,const f32 rectangleWidth,const f32 rectangleHeight,const f32 imageWidth,const f32 imageHeight,const f32 textureWidth,const f32 textureHeight)395 void RenderSystemDrawing::FillTexturedRectangle(const GLuint textureId, 396 const f32 windowCoordinateX, const f32 windowCoordinateY, 397 const f32 rectangleWidth, const f32 rectangleHeight, 398 const f32 imageWidth, const f32 imageHeight, 399 const f32 textureWidth, const f32 textureHeight) 400 { 401 CheckRenderTarget(); 402 403 if ( (textureId == 0 ) || (! HasTexture(textureId) ) ) 404 { 405 NN_TPANIC_("Invalid textureId %d.\n", textureId); 406 return; 407 } 408 409 f32 windowCoordinateX1 = windowCoordinateX + rectangleWidth; 410 f32 windowCoordinateY1 = windowCoordinateY + rectangleHeight; 411 412 f32 texcoordS0 = 0.0f; 413 f32 texcoordT0 = 0.0f; 414 f32 texcoordS1 = static_cast<f32>(imageWidth) / static_cast<f32>(textureWidth); 415 f32 texcoordT1 = static_cast<f32>(imageHeight) / static_cast<f32>(textureHeight); 416 417 FillTexturedTriangle(textureId, 418 windowCoordinateX, windowCoordinateY, 419 texcoordS0, texcoordT1, 420 windowCoordinateX, windowCoordinateY1, 421 texcoordS0, texcoordT0, 422 windowCoordinateX1, windowCoordinateY1, 423 texcoordS1, texcoordT0); 424 425 FillTexturedTriangle(textureId, 426 windowCoordinateX, windowCoordinateY, 427 texcoordS0, texcoordT1, 428 windowCoordinateX1, windowCoordinateY1, 429 texcoordS1, texcoordT0, 430 windowCoordinateX1, windowCoordinateY, 431 texcoordS1, texcoordT1); 432 } 433 FillTexturedTriangle(const GLuint textureId,const f32 windowCoordinateX0,const f32 windowCoordinateY0,const f32 texcoordS0,const f32 texcoordT0,const f32 windowCoordinateX1,const f32 windowCoordinateY1,const f32 texcoordS1,const f32 texcoordT1,const f32 windowCoordinateX2,const f32 windowCoordinateY2,const f32 texcoordS2,const f32 texcoordT2)434 void RenderSystemDrawing::FillTexturedTriangle(const GLuint textureId, 435 const f32 windowCoordinateX0, const f32 windowCoordinateY0, 436 const f32 texcoordS0, const f32 texcoordT0, 437 const f32 windowCoordinateX1, const f32 windowCoordinateY1, 438 const f32 texcoordS1, const f32 texcoordT1, 439 const f32 windowCoordinateX2, const f32 windowCoordinateY2, 440 const f32 texcoordS2, const f32 texcoordT2) 441 { 442 CheckRenderTarget(); 443 444 if (! m_InitializeTexturedTriangles ) 445 { 446 InitializeTexturedTriangles(); 447 } 448 449 u32 textureArrayIndex = 0; 450 if ( ( textureId == 0 ) || (! FindTextureArrayIndex(textureId, textureArrayIndex) ) ) 451 { 452 NN_TPANIC_("Invalid textureId %d.\n", textureId); 453 return; 454 } 455 456 if ( m_TotalTexturedTrianglesNumArray[textureArrayIndex] >= m_MaxTexturedTrianglesNum ) 457 { 458 NN_TLOG_("RenderSystemDrawing::FillTexturedTriangle() maxTriangles limit\n"); 459 NN_TLOG_(" trianglesIndex = %d, maxTrianglesNum = %d\n", 460 m_TotalTexturedTrianglesNumArray[textureArrayIndex], m_MaxTexturedTrianglesNum); 461 return; 462 } 463 464 m_UseDecalTextureProgram = true; 465 466 demo::TrianglesRenderData& renderData = m_TexturedTrianglesRenderDataArray[textureArrayIndex]; 467 u32 triangleIndex = renderData.GetPackedTrianglesNum(); 468 469 f32 s_Depth = m_GraphicsDrawing.m_Depth; 470 471 // POSITION0 472 f32 normalizedDeviceCoordinateX = 0.0f; 473 f32 normalizedDeviceCoordinateY = 0.0f; 474 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX0, windowCoordinateY0, 475 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 476 renderData.SetPosition(3 * triangleIndex, 477 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, s_Depth, 1.0f); 478 479 // POSITION1 480 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX1, windowCoordinateY1, 481 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 482 renderData.SetPosition(3 * triangleIndex + 1, 483 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, s_Depth, 1.0f); 484 485 // POSITION2 486 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX2, windowCoordinateY2, 487 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 488 renderData.SetPosition(3 * triangleIndex + 2, 489 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, s_Depth, 1.0f); 490 491 m_GraphicsDrawing.DecrementDepth(); 492 493 // TEXCOORD0-2 494 renderData.SetTexcoord(3 * triangleIndex, texcoordS0, texcoordT0); 495 renderData.SetTexcoord(3 * triangleIndex + 1, texcoordS1, texcoordT1); 496 renderData.SetTexcoord(3 * triangleIndex + 2, texcoordS2, texcoordT2); 497 498 // INDEX 499 renderData.SetIndex(triangleIndex, 500 3 * triangleIndex, 3 * triangleIndex + 1, 3 * triangleIndex + 2); 501 502 renderData.AddPackedVerticesNum(3); 503 renderData.AddPackedTrianglesNum(1); 504 505 m_TotalTexturedTrianglesNumArray[textureArrayIndex] += 1; 506 } 507 SwapBuffers(void)508 void RenderSystemDrawing::SwapBuffers(void) 509 { 510 CheckRenderTarget(); 511 512 RenderSystemDrawing::Flush(); 513 RenderSystem::SwapBuffers(); 514 } 515 Flush(void)516 void RenderSystemDrawing::Flush(void) 517 { 518 FlushTexturedPrimitives(); 519 m_GraphicsDrawing.Flush(); 520 } 521 FlushTexturedPrimitives(void)522 void RenderSystemDrawing::FlushTexturedPrimitives(void) 523 { 524 if (! m_UseDecalTextureProgram ) 525 { 526 return; 527 } 528 529 demo::ProgramObject* shaderProgramPtr = m_GraphicsDrawing.m_ShaderManager.GetShaderProgram(demo::DECAL_TEXTURE_SHADER); 530 shaderProgramPtr->SetUse3d(false); 531 shaderProgramPtr->Begin(); 532 shaderProgramPtr->Use(); 533 534 for (u32 textureArrayIndex = 0; textureArrayIndex < demo::MAX_TEXTURES_NUM; textureArrayIndex++) 535 { 536 if ( m_TextureIdArray[textureArrayIndex] != 0 ) 537 { 538 demo::TrianglesRenderData& renderData = m_TexturedTrianglesRenderDataArray[textureArrayIndex]; 539 u32 packedTrianglesNum = renderData.GetPackedTrianglesNum(); 540 if ( packedTrianglesNum != 0 ) 541 { 542 GLuint textureId = m_TextureIdArray[textureArrayIndex]; 543 if ( textureId != 0 ) 544 { 545 shaderProgramPtr->SetTextureId(textureId); 546 shaderProgramPtr->Update(); 547 renderData.DrawPackedTriangles(); 548 } 549 } 550 551 m_TotalTexturedTrianglesNumArray[textureArrayIndex] = 0; 552 } 553 } 554 555 shaderProgramPtr->End(); 556 557 m_UseDecalTextureProgram = false; 558 } 559 560 } 561