1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: demo_GraphicsDrawing.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_GraphicsDrawing.h" 17 18 namespace demo 19 { 20 21 /* ------------------------------------------------------------------------ 22 GraphicsDrawing class member function 23 ------------------------------------------------------------------------ */ 24 GraphicsDrawing(void)25 GraphicsDrawing::GraphicsDrawing(void) : 26 m_Depth(1.0f), m_AutoDepth(true), 27 m_ShaderManager(), 28 m_InitializeTriangles(false), m_InitializeSquares(false), 29 m_InitializeTexts(false), 30 m_MaxTrianglesNum(demo::MAX_TRIANGLES_NUM), m_TotalTrianglesNum(0), 31 m_MaxSquaresNum(demo::MAX_SQUARES_NUM), m_TotalSquaresNum(0), 32 m_MaxTextLength(demo::MAX_TEXT_LENGTH), m_TotalTextLength(0), 33 m_UseColorFillProgram(false), m_UseFontProgram(false), 34 m_PointSize(1.0f), m_LineWidth(1.0f), 35 m_FontSize(1.0f) 36 { 37 SetWindowSize(NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT); 38 } 39 ~GraphicsDrawing(void)40 GraphicsDrawing::~GraphicsDrawing(void) 41 { 42 Finalize(); 43 } 44 Initialize(void)45 void GraphicsDrawing::Initialize(void) 46 { 47 m_InitializeTriangles = false; 48 m_InitializeSquares = false; 49 m_InitializeTexts = false; 50 51 m_UseColorFillProgram = false; 52 m_UseFontProgram = false; 53 54 m_Color[0] = 1.0f; 55 m_Color[1] = 0.0f; 56 m_Color[2] = 0.0f; 57 m_Color[3] = 1.0f; 58 59 m_Depth = 1.0f; 60 m_AutoDepth = true; 61 m_DepthValue = 0.0001f; 62 63 DecrementDepth(); 64 65 m_PointSize = 1.0f; 66 m_LineWidth = 1.0f; 67 m_FontSize = 8.0f; 68 69 bool flag = m_ShaderManager.Initialize(); 70 if (! flag ) 71 { 72 NN_TPANIC_("GraphicsDrawing::Initialize() : ShaderManager.Initialize() failed.\n"); 73 } 74 } 75 Finalize(void)76 void GraphicsDrawing::Finalize(void) 77 { 78 DEMO_ASSERT_GL_ERROR(); 79 80 m_ShaderManager.Finalize(); 81 82 m_TrianglesRenderData.Finalize(); 83 m_SquaresRenderData.Finalize(); 84 m_TextsRenderData.Finalize(); 85 86 m_InitializeTriangles = false; 87 m_InitializeSquares = false; 88 m_InitializeTexts = false; 89 90 DEMO_ASSERT_GL_ERROR(); 91 } 92 InitializeTriangles(const u32 maxTrianglesNum)93 void GraphicsDrawing::InitializeTriangles(const u32 maxTrianglesNum) 94 { 95 if ( m_InitializeTriangles ) 96 { 97 return; 98 } 99 100 DEMO_ASSERT_GL_ERROR(); 101 102 m_TrianglesRenderData.Initialize(); 103 104 u32 vertexAttributes = m_ShaderManager.GetVertexAttributes(demo::COLOR_FILL_SHADER); 105 106 m_MaxTrianglesNum = maxTrianglesNum; 107 u32 maxVerticesNum = 3 * maxTrianglesNum; 108 m_TrianglesRenderData.InitializeVertexBuffers(vertexAttributes, 109 GL_TRIANGLES, maxVerticesNum, m_MaxTrianglesNum); 110 m_TotalTrianglesNum = 0; 111 112 m_InitializeTriangles = true; 113 114 DEMO_ASSERT_GL_ERROR(); 115 } 116 InitializeSquares(const u32 maxSquaresNum)117 void GraphicsDrawing::InitializeSquares(const u32 maxSquaresNum) 118 { 119 if ( m_InitializeSquares ) 120 { 121 return; 122 } 123 124 DEMO_ASSERT_GL_ERROR(); 125 126 m_SquaresRenderData.Initialize(); 127 128 u32 vertexAttributes = m_ShaderManager.GetVertexAttributes(demo::COLOR_FILL_SHADER); 129 130 m_MaxSquaresNum = maxSquaresNum; 131 u32 maxVerticesNum = m_MaxSquaresNum * 4; 132 u32 maxTrianglesNum = m_MaxSquaresNum * 6; 133 m_SquaresRenderData.InitializeVertexBuffers(vertexAttributes, 134 GL_TRIANGLE_STRIP, maxVerticesNum, maxTrianglesNum); 135 m_TotalSquaresNum = 0; 136 137 m_InitializeSquares = true; 138 139 DEMO_ASSERT_GL_ERROR(); 140 } 141 InitializeTexts(const u32 maxLength)142 void GraphicsDrawing::InitializeTexts(const u32 maxLength) 143 { 144 if ( m_InitializeTexts ) 145 { 146 return; 147 } 148 149 DEMO_ASSERT_GL_ERROR(); 150 151 m_TextsRenderData.Initialize(); 152 153 u32 vertexAttributes = m_ShaderManager.GetVertexAttributes(demo::FONT_SHADER); 154 155 m_MaxTextLength = maxLength; 156 m_TextsRenderData.InitializeVertexBuffers(vertexAttributes, GL_TRIANGLES, m_MaxTextLength); 157 m_TotalTextLength = 0; 158 159 m_InitializeTexts = true; 160 161 DEMO_ASSERT_GL_ERROR(); 162 } 163 SetWindowSize(const f32 windowWidth,const f32 windowHeight)164 void GraphicsDrawing::SetWindowSize(const f32 windowWidth, const f32 windowHeight) 165 { 166 m_WindowWidth = windowWidth; 167 m_WindowHeight = windowHeight; 168 169 m_TrianglesRenderData.SetWindowSize(m_WindowWidth, m_WindowHeight); 170 m_SquaresRenderData.SetWindowSize(m_WindowWidth, m_WindowHeight); 171 m_TextsRenderData.SetWindowSize(m_WindowWidth, m_WindowHeight); 172 } 173 GetWindowSize(f32 & windowWidth,f32 & windowHeight)174 void GraphicsDrawing::GetWindowSize(f32& windowWidth, f32& windowHeight) 175 { 176 windowWidth = m_WindowWidth; 177 windowHeight = m_WindowHeight; 178 } 179 SetColor(const f32 red,const f32 green,const f32 blue)180 void GraphicsDrawing::SetColor(const f32 red, const f32 green, const f32 blue) 181 { 182 m_Color[0] = red; 183 m_Color[1] = green; 184 m_Color[2] = blue; 185 m_Color[3] = 1.0f; 186 } 187 SetColor(const f32 red,const f32 green,const f32 blue,const f32 alpha)188 void GraphicsDrawing::SetColor(const f32 red, const f32 green, const f32 blue, const f32 alpha) 189 { 190 m_Color[0] = red; 191 m_Color[1] = green; 192 m_Color[2] = blue; 193 m_Color[3] = alpha; 194 } 195 SetDepth(const f32 depth)196 void GraphicsDrawing::SetDepth(const f32 depth) 197 { 198 m_Depth = depth; 199 } 200 SetAutoDepth(const bool enableAutoDepth)201 void GraphicsDrawing::SetAutoDepth(const bool enableAutoDepth) 202 { 203 m_AutoDepth = enableAutoDepth; 204 } 205 DecrementDepth(void)206 void GraphicsDrawing::DecrementDepth(void) 207 { 208 if ( m_AutoDepth ) 209 { 210 m_Depth -= m_DepthValue; 211 } 212 213 if ( m_Depth <= 0.0f ) 214 { 215 m_Depth = 0.0f; 216 } 217 } 218 SetPointSize(const f32 pointSize)219 void GraphicsDrawing::SetPointSize(const f32 pointSize) 220 { 221 m_PointSize = pointSize; 222 } 223 DrawPoint(const f32 windowCoordinateX,const f32 windowCoordinateY)224 void GraphicsDrawing::DrawPoint(const f32 windowCoordinateX, const f32 windowCoordinateY) 225 { 226 f32 pointHalfSize = 0.5f * m_PointSize; 227 228 f32 windowCoordinateX0 = windowCoordinateX - pointHalfSize; 229 f32 windowCoordinateX1 = windowCoordinateX + pointHalfSize; 230 f32 windowCoordinateY0 = windowCoordinateY - pointHalfSize; 231 f32 windowCoordinateY1 = windowCoordinateY + pointHalfSize; 232 233 FillSquare(windowCoordinateX0, windowCoordinateY0, 234 windowCoordinateX0, windowCoordinateY1, 235 windowCoordinateX1, windowCoordinateY1, 236 windowCoordinateX1, windowCoordinateY0); 237 } 238 SetLineWidth(const f32 lineWidth)239 void GraphicsDrawing::SetLineWidth(const f32 lineWidth) 240 { 241 m_LineWidth = lineWidth; 242 } 243 DrawLine(const f32 windowCoordinateX0,const f32 windowCoordinateY0,const f32 windowCoordinateX1,const f32 windowCoordinateY1)244 void GraphicsDrawing::DrawLine(const f32 windowCoordinateX0, const f32 windowCoordinateY0, 245 const f32 windowCoordinateX1, const f32 windowCoordinateY1) 246 { 247 static const f32 DEMO_MATH_ERROR = 0.00001f; 248 249 f32 s_LineHalfWidth = 0.5f * m_LineWidth; 250 251 f32 x01 = windowCoordinateX1 - windowCoordinateX0; 252 f32 y01 = windowCoordinateY1 - windowCoordinateY0; 253 254 f32 gradientX = 0.0f; 255 f32 gradientY = 0.0f; 256 257 if ( nn::math::FAbs(x01) < DEMO_MATH_ERROR ) 258 { 259 gradientX = 1.0f; 260 } 261 else if ( nn::math::FAbs(y01) < DEMO_MATH_ERROR ) 262 { 263 gradientY = 1.0f; 264 } 265 else 266 { 267 gradientX = y01; 268 gradientY = (- x01); 269 270 f32 gradient = gradientX * gradientX + gradientY * gradientY; 271 gradient = nn::math::FSqrt(gradient); 272 273 gradientX /= gradient; 274 gradientY /= gradient; 275 } 276 277 gradientX *= s_LineHalfWidth; 278 gradientY *= s_LineHalfWidth; 279 280 FillSquare(windowCoordinateX0 + gradientX, windowCoordinateY0 + gradientY, 281 windowCoordinateX0 - gradientX, windowCoordinateY0 - gradientY, 282 windowCoordinateX1 - gradientX, windowCoordinateY1 - gradientY, 283 windowCoordinateX1 + gradientX, windowCoordinateY1 + gradientY); 284 285 DEMO_ASSERT_GL_ERROR(); 286 } 287 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)288 void GraphicsDrawing::FillSquare(const f32 windowCoordinateX0, const f32 windowCoordinateY0, 289 const f32 windowCoordinateX1, const f32 windowCoordinateY1, 290 const f32 windowCoordinateX2, const f32 windowCoordinateY2, 291 const f32 windowCoordinateX3, const f32 windowCoordinateY3) 292 { 293 if (! m_InitializeSquares ) 294 { 295 InitializeSquares(); 296 } 297 298 if ( m_TotalSquaresNum >= m_MaxSquaresNum ) 299 { 300 NN_TLOG_("GraphicsDrawing::FillSquare() maxSquares limit\n"); 301 NN_TLOG_(" squaresIndex = %d, maxSquaresNum = %d\n", m_TotalSquaresNum, m_MaxSquaresNum); 302 return; 303 } 304 305 m_UseColorFillProgram = true; 306 307 demo::TrianglesRenderData& renderData = m_SquaresRenderData; 308 u32 vertexIndex = renderData.GetPackedVerticesNum(); 309 u32 squareIndex = renderData.GetPackedTrianglesNum() / 4; 310 311 // POSITION 0 312 f32 normalizedDeviceCoordinateX = 0.0f; 313 f32 normalizedDeviceCoordinateY = 0.0f; 314 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX0, windowCoordinateY0, 315 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 316 renderData.SetPosition(vertexIndex, 317 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, m_Depth, 1.0f); 318 319 // POSITION 1 320 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX1, windowCoordinateY1, 321 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 322 renderData.SetPosition(vertexIndex + 2, 323 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, m_Depth, 1.0f); 324 325 // POSITION 2 326 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX2, windowCoordinateY2, 327 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 328 renderData.SetPosition(vertexIndex + 3, 329 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, m_Depth, 1.0f); 330 331 // POSITION 3 332 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX3, windowCoordinateY3, 333 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 334 renderData.SetPosition(vertexIndex + 1, 335 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, m_Depth, 1.0f); 336 337 DecrementDepth(); 338 339 // COLOR 340 for (u32 i = 0; i < 4; i++) 341 { 342 renderData.SetColor(vertexIndex + i, 343 m_Color[0], m_Color[1], m_Color[2]); 344 } 345 346 // INDEX 347 renderData.SetSquareIndex(squareIndex, 348 vertexIndex, vertexIndex + 1, vertexIndex + 2, vertexIndex + 3); 349 350 renderData.AddPackedVerticesNum(4); 351 renderData.AddPackedTrianglesNum(4); 352 353 m_TotalSquaresNum += 1; 354 355 DEMO_ASSERT_GL_ERROR(); 356 } 357 FillRectangle(const f32 windowCoordinateX,const f32 windowCoordinateY,const f32 width,const f32 height)358 void GraphicsDrawing::FillRectangle(const f32 windowCoordinateX, 359 const f32 windowCoordinateY, 360 const f32 width, const f32 height) 361 { 362 f32 windowCoordinateX1 = windowCoordinateX + width; 363 f32 windowCoordinateY1 = windowCoordinateY + height; 364 365 FillTriangle(windowCoordinateX, windowCoordinateY, 366 windowCoordinateX, windowCoordinateY1, 367 windowCoordinateX1, windowCoordinateY); 368 369 FillTriangle(windowCoordinateX, windowCoordinateY1, 370 windowCoordinateX1, windowCoordinateY1, 371 windowCoordinateX1, windowCoordinateY); 372 373 DEMO_ASSERT_GL_ERROR(); 374 } 375 FillTriangle(const f32 windowCoordinateX0,const f32 windowCoordinateY0,const f32 windowCoordinateX1,const f32 windowCoordinateY1,const f32 windowCoordinateX2,const f32 windowCoordinateY2)376 void GraphicsDrawing::FillTriangle(const f32 windowCoordinateX0, const f32 windowCoordinateY0, 377 const f32 windowCoordinateX1, const f32 windowCoordinateY1, 378 const f32 windowCoordinateX2, const f32 windowCoordinateY2) 379 { 380 if (! m_InitializeTriangles ) 381 { 382 InitializeTriangles(); 383 } 384 385 if ( m_TotalTrianglesNum >= m_MaxTrianglesNum ) 386 { 387 NN_TLOG_("GraphicsDrawing::FillTriangle() maxSquares limit\n"); 388 NN_TLOG_(" trianglesIndex = %d, maxTrianglesNum = %d\n", m_TotalTrianglesNum, m_MaxTrianglesNum); 389 return; 390 } 391 392 m_UseColorFillProgram = true; 393 demo::TrianglesRenderData& renderData = m_TrianglesRenderData; 394 u32 triangleIndex = renderData.GetPackedTrianglesNum(); 395 396 // POSITION 0 397 f32 normalizedDeviceCoordinateX = 0.0f; 398 f32 normalizedDeviceCoordinateY = 0.0f; 399 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX0, windowCoordinateY0, 400 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 401 renderData.SetPosition(3 * triangleIndex, 402 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, m_Depth, 1.0f); 403 404 // POSITION 1 405 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX1, windowCoordinateY1, 406 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 407 renderData.SetPosition(3 * triangleIndex + 1, 408 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, m_Depth, 1.0f); 409 410 // POSITION 2 411 renderData.GetNormalizedDeviceCoordinateXY(windowCoordinateX2, windowCoordinateY2, 412 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY); 413 renderData.SetPosition(3 * triangleIndex + 2, 414 normalizedDeviceCoordinateX, normalizedDeviceCoordinateY, m_Depth, 1.0f); 415 416 DecrementDepth(); 417 418 // COLOR 419 for (u32 i = 0; i < 3; i++) 420 { 421 renderData.SetColor(3 * triangleIndex + i, 422 m_Color[0], m_Color[1], m_Color[2]); 423 } 424 425 // INDEX 426 renderData.SetIndex(triangleIndex, 427 3 * triangleIndex, 3 * triangleIndex + 1, 3 * triangleIndex + 2); 428 429 renderData.AddPackedVerticesNum(3); 430 renderData.AddPackedTrianglesNum(1); 431 432 m_TotalTrianglesNum += 1; 433 434 DEMO_ASSERT_GL_ERROR(); 435 } 436 SetFontSize(const f32 fontSize)437 void GraphicsDrawing::SetFontSize(const f32 fontSize) 438 { 439 m_FontSize = fontSize; 440 m_TextsRenderData.SetFontSize(m_FontSize); 441 } 442 DrawText(const f32 windowCoordinateX,const f32 windowCoordinateY,const char * format,...)443 void GraphicsDrawing::DrawText(const f32 windowCoordinateX, const f32 windowCoordinateY, 444 const char* format, ...) 445 { 446 static const u32 tmpBufferSize = 1024; 447 static char textBuffer[tmpBufferSize]; 448 449 if (! m_InitializeTexts ) 450 { 451 InitializeTexts(); 452 } 453 454 va_list va; 455 va_start(va, format); 456 vsnprintf(textBuffer, tmpBufferSize, format, va); 457 va_end(va); 458 459 DrawTextBuffer(windowCoordinateX, windowCoordinateY, textBuffer); 460 461 DEMO_ASSERT_GL_ERROR(); 462 } 463 DrawTextBuffer(const f32 windowCoordinateX,const f32 windowCoordinateY,const char * textBuffer)464 void GraphicsDrawing::DrawTextBuffer(const f32 windowCoordinateX, const f32 windowCoordinateY, 465 const char* textBuffer) 466 { 467 if (! m_InitializeTexts ) 468 { 469 InitializeTexts(); 470 } 471 472 char* ch_ptr = const_cast<char*>(textBuffer); 473 u32 textLength = 0; 474 for (u32 i = 0; i < demo::MAX_CHAR_LENGTH_PER_LINE; i++) 475 { 476 char c = (*ch_ptr); 477 if ( c == '\0') 478 { 479 break; 480 } 481 482 if ( (0x20 <= c) && (c <= 0x7f) ) 483 { 484 textLength += 1; 485 ch_ptr++; 486 } 487 else 488 { 489 break; 490 } 491 } 492 493 demo::TextsRenderData& renderData = m_TextsRenderData; 494 if ( (m_TotalTextLength + textLength) >= m_MaxTextLength ) 495 { 496 NN_TLOG_("GraphicsDrawing::DrawText() maxText limit\n"); 497 NN_TLOG_(" textLength = %d, maxTextLength = %d, totalTextLength = %d\n", 498 textLength, m_MaxTextLength, m_TotalTextLength); 499 return; 500 } 501 502 m_UseFontProgram = true; 503 504 m_TextsRenderData.SetFontColor(m_Color[0], m_Color[1], m_Color[2], m_Color[3]); 505 renderData.AddText(windowCoordinateX, windowCoordinateY, 506 textBuffer, textLength, m_Depth); 507 508 m_TotalTextLength += textLength; 509 510 DecrementDepth(); 511 512 DEMO_ASSERT_GL_ERROR(); 513 } 514 Flush(void)515 void GraphicsDrawing::Flush(void) 516 { 517 FlushColorFillPrimitives(); 518 FlushTexts(); 519 520 m_Depth = 1.0f; 521 DecrementDepth(); 522 } 523 FlushColorFillPrimitives(void)524 void GraphicsDrawing::FlushColorFillPrimitives(void) 525 { 526 if (! m_UseColorFillProgram ) 527 { 528 return; 529 } 530 531 demo::ProgramObject* shaderProgramPtr = m_ShaderManager.GetShaderProgram(demo::COLOR_FILL_SHADER); 532 shaderProgramPtr->SetUse3d(false); 533 shaderProgramPtr->Begin(); 534 shaderProgramPtr->Use(); 535 536 m_TrianglesRenderData.DrawPackedTriangles(); 537 m_SquaresRenderData.DrawPackedTriangles(); 538 539 m_TotalTrianglesNum = 0; 540 m_TotalSquaresNum = 0; 541 542 shaderProgramPtr->End(); 543 544 m_UseColorFillProgram = false; 545 546 DEMO_ASSERT_GL_ERROR(); 547 } 548 FlushTexts(void)549 void GraphicsDrawing::FlushTexts(void) 550 { 551 if (! m_UseFontProgram ) 552 { 553 return; 554 } 555 556 demo::ProgramObject* shaderProgramPtr = m_ShaderManager.GetShaderProgram(demo::FONT_SHADER); 557 shaderProgramPtr->SetUse3d(false); 558 shaderProgramPtr->Begin(); 559 shaderProgramPtr->Use(); 560 561 m_TextsRenderData.DrawPackedTriangles(); 562 m_TextsRenderData.ClearPackedTextLength(); 563 m_TotalTextLength = 0; 564 565 shaderProgramPtr->End(); 566 567 m_UseFontProgram = false; 568 569 DEMO_ASSERT_GL_ERROR(); 570 } 571 572 } 573