1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     demo_GraphicsDrawing.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  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   $Revision: 28366 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nw/os.h>
17 #include <nw/demo.h>
18 #include <nw/demo/demo_GraphicsDrawing.h>
19 #include <nw/gfx/gfx_Common.h>
20 #include <GLES2/gl2.h>
21 #include <GLES2/gl2ext.h>
22 
23 namespace nw {
24 namespace demo {
25 
26 const f32 GraphicsDrawing::FONT_SIZE = 16.0f;
27 const f32 GraphicsDrawing::FONT_FIXED_WIDTH = 10.5f;
28 
29 //--------------------------------------------------------------------------
30 /* ctor */
GraphicsDrawing()31 GraphicsDrawing::GraphicsDrawing()
32  : m_ScreenSize( f32(DEFAULT_SCREEN_WIDTH), f32(DEFAULT_SCREEN_HEIGHT) ),
33    m_LineWidth( 2.0f ),
34    m_MaxShapeVertexCount( DEFAULT_MAX_SHAPE_VERTEX_COUNT ),
35    m_ShapeVertexCount( 0 ),
36    m_pShapeShaderBinary( NULL ),
37    m_ShapeShader(),
38    m_ShapeBindSymbolProjectionMatrix(),
39    m_ShapeBindSymbolModelViewMatrix(),
40    m_ShapeBindSymbolPos(),
41    m_ShapeBindSymbolColor(),
42    m_ShapeViewport(),
43    m_ShapeRenderState(),
44    m_ShapeCombiner(),
45    m_ShapeVertex(),
46    m_ShapeIndexStream(),
47    m_ShapePositionStreamArray( NULL ),
48    m_ShapeColorStreamArray( NULL ),
49    m_ShapeIndexStreamArray( NULL ),
50    m_ShapeAllocator( NULL ),
51    m_Font(),
52    m_TextWriter(),
53    m_Drawer(),
54    m_MaxTextCount( DEFAULT_MAX_TEXT_COUNT ),
55    m_FontCommandBuffer( NULL ),
56    m_IsFontOwner( true ),
57    m_FontAllocator( NULL )
58 {
59 }
60 
61 //--------------------------------------------------------------------------
~GraphicsDrawing()62 GraphicsDrawing::~GraphicsDrawing()
63 {
64 }
65 
66 //--------------------------------------------------------------------------
67 void
Finalize()68 GraphicsDrawing::Finalize()
69 {
70     this->DestroyShape();
71 
72     this->DestroyFont();
73 
74     m_FontAllocator = NULL;
75     m_ShapeAllocator = NULL;
76 }
77 
78 //--------------------------------------------------------------------------
79 bool
InitializeShape(void * pShaderBinary,size_t binarySize)80 GraphicsDrawing::InitializeShape( void* pShaderBinary, size_t binarySize )
81 {
82     bool result = true;
83 
84     m_pShapeShaderBinary = pShaderBinary;
85 
86     NN_UNUSED_VAR( binarySize );
87 
88     // シェーダーバイナリを指定して初期化
89     // 0番目の実行イメージを頂点シェーダーとして有効化
90     m_ShapeShader.SetupBinary( pShaderBinary, 0, -1 );
91 
92     // 文字列で、Uniform を検索
93     result = m_ShapeShader.SearchBindSymbol( &m_ShapeBindSymbolProjectionMatrix, "uProjection" );
94     NW_ASSERT( result );
95 
96     result = m_ShapeShader.SearchBindSymbol( &m_ShapeBindSymbolModelViewMatrix, "uModelView" );
97     NW_ASSERT( result );
98 
99     // 文字列による location の検索
100     result = m_ShapeShader.SearchBindSymbol( &m_ShapeBindSymbolPos, "aPosition" );
101     NW_ASSERT( result );
102 
103     result = m_ShapeShader.SearchBindSymbol( &m_ShapeBindSymbolColor, "aColor" );
104     NW_ASSERT( result );
105 
106     // 頂点ストリームの設定
107     uptr physicalAddr = nngxGetPhysicalAddr( reinterpret_cast< uptr >( m_ShapePositionStreamArray ) );
108     m_ShapeVertex.EnableAttrAsArray( m_ShapeBindSymbolPos, physicalAddr, PICA_DATA_SIZE_2_FLOAT );
109 
110     physicalAddr = nngxGetPhysicalAddr( reinterpret_cast< uptr >( m_ShapeColorStreamArray ) );
111     m_ShapeVertex.EnableAttrAsArray( m_ShapeBindSymbolColor, physicalAddr, PICA_DATA_SIZE_4_FLOAT );
112 
113     // インデックスストリームの設定
114     physicalAddr = nngxGetPhysicalAddr( reinterpret_cast< uptr >( m_ShapeIndexStreamArray ) );
115     m_ShapeIndexStream.physicalAddr   = physicalAddr;
116     m_ShapeIndexStream.isUnsignedByte = false;
117 
118     return result;
119 }
120 
121 //--------------------------------------------------------------------------
122 bool
InitializeShape(os::IAllocator * allocator,const wchar_t * shaderPath)123 GraphicsDrawing::InitializeShape( os::IAllocator* allocator, const wchar_t* shaderPath )
124 {
125     m_ShapeAllocator = allocator;
126 
127     ut::MoveArray<u8> buffer = nw::demo::Utility::LoadFile( allocator, shaderPath );
128 
129     if ( buffer.empty() )
130     {
131         return false;
132     }
133 
134     s32 size = buffer.size();
135     void* pBuffer = buffer.release();
136 
137     u32 shapePositionStreamArraySize = 2 * 4 * m_MaxShapeVertexCount;
138     u32 shapeColorStreamArraySize    = 4 * 4 * m_MaxShapeVertexCount;
139     u32 shapeIndexStreamArraySize    = 2 * m_MaxShapeVertexCount;
140 
141     m_ShapePositionStreamArray = static_cast<math::VEC2*>( m_ShapeAllocator->Alloc( shapePositionStreamArraySize, 128 ) );
142     m_ShapeColorStreamArray    = static_cast<f32*>( m_ShapeAllocator->Alloc( shapeColorStreamArraySize, 128 ) );
143     m_ShapeIndexStreamArray    = static_cast<u16*>( m_ShapeAllocator->Alloc( shapeIndexStreamArraySize, 128 ) );
144 
145     for ( s32 index = 0; index < m_MaxShapeVertexCount; index++ )
146     {
147         m_ShapePositionStreamArray[ index ] = math::VEC2( 0.0f, 0.0f );
148 
149         u32 colorIndex = 4 * index;
150         m_ShapeColorStreamArray[ colorIndex     ] = 1.0f;
151         m_ShapeColorStreamArray[ colorIndex + 1 ] = 1.0f;
152         m_ShapeColorStreamArray[ colorIndex + 2 ] = 1.0f;
153         m_ShapeColorStreamArray[ colorIndex + 3 ] = 1.0f;
154     }
155 
156     for ( s32 index = 0; index < m_MaxShapeVertexCount; index++ )
157     {
158         m_ShapeIndexStreamArray[ index ] = static_cast<u16>( index );
159     }
160     InitializeShapeGraphicsState();
161 
162     return InitializeShape( pBuffer, size );
163 }
164 
165 //--------------------------------------------------------------------------
166 void
DestroyShape()167 GraphicsDrawing::DestroyShape()
168 {
169     m_ShapeVertex.DisableAll();
170 
171     if ( m_pShapeShaderBinary && m_ShapeAllocator )
172     {
173         os::SafeFree( m_pShapeShaderBinary, m_ShapeAllocator );
174     }
175 
176     if ( m_ShapeAllocator )
177     {
178         os::SafeFree( m_ShapePositionStreamArray, m_ShapeAllocator );
179         os::SafeFree( m_ShapeColorStreamArray, m_ShapeAllocator );
180         os::SafeFree( m_ShapeIndexStreamArray, m_ShapeAllocator );
181     }
182 }
183 
184 
185 //--------------------------------------------------------------------------
186 void
SetupShape()187 GraphicsDrawing::SetupShape()
188 {
189     this->SetupShapeMaterial();
190     this->SetupShapeTexEnv();
191 }
192 
193 //--------------------------------------------------------------------------
194 void
BeginDrawingShape()195 GraphicsDrawing::BeginDrawingShape()
196 {
197     SetupShape();
198 
199     m_ShapeVertexCount = 0;
200 
201     m_ShapeViewport.Set( 0, 0, m_ScreenSize.y, m_ScreenSize.x );
202 
203     bit32* command;
204     nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast<GLint*>( &command ) );
205 
206     bit32* commandStart = command;
207     command      = m_ShapeViewport.MakeCommand( command );
208 
209     nngxMoveCommandbufferPointer( ( command - commandStart ) * sizeof(u32) );
210 
211     this->SendShapeMatrix();
212 }
213 
214 //--------------------------------------------------------------------------
215 void
EndDrawingShape(void)216 GraphicsDrawing::EndDrawingShape( void )
217 {
218     m_ShapeIndexStream.drawVtxNum          = m_ShapeVertexCount;
219 
220     u32 shapePositionStreamArraySize = 2 * 4 * m_ShapeVertexCount;
221     u32 shapeColorStreamArraySize    = 4 * 4 * m_ShapeVertexCount;
222     u32 shapeIndexStreamArraySize    = 2 * m_ShapeVertexCount;
223 
224     nngxUpdateBuffer( m_ShapePositionStreamArray, shapePositionStreamArraySize );
225     nngxUpdateBuffer( m_ShapeColorStreamArray,    shapeColorStreamArraySize );
226     nngxUpdateBuffer( m_ShapeIndexStreamArray, shapeIndexStreamArraySize );
227 
228     bit32* command;
229     nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast<GLint*>( &command ) );
230 
231     bit32* commandStart = command;
232     command      = nn::gr::CTR::Vertex::MakeDisableCommand( command );
233     command      = m_ShapeVertex.MakeEnableAttrCommand( command );
234     command      = m_ShapeVertex.MakeDrawCommand( command, m_ShapeIndexStream );
235     command      = m_ShapeVertex.MakeDisableAttrCommand( command );
236     command      = nn::gr::CTR::Vertex::MakeDisableCommand( command );
237 
238     nngxMoveCommandbufferPointer( ( command - commandStart ) * sizeof(u32) );
239 
240     m_ShapeVertexCount = 0;
241 }
242 
243 
244 //--------------------------------------------------------------------------
245 void
DrawLine(const math::VEC2 & p1,const math::VEC2 & p2,ut::Color8 color)246 GraphicsDrawing::DrawLine( const math::VEC2& p1, const math::VEC2& p2, ut::Color8 color )
247 {
248     NW_ASSERT( ( m_ShapeVertexCount + SHAPE_DRAW_LINE_VERTEX_COUNT ) <= m_MaxShapeVertexCount );
249 
250     s32 count = this->BuildLine( p1, p2, m_LineWidth, &m_ShapePositionStreamArray[ m_ShapeVertexCount ] );
251 
252     u32 index = 4 * m_ShapeVertexCount;
253     BuildColor( count, color, &m_ShapeColorStreamArray[ index ] );
254 
255     m_ShapeVertexCount += count;
256 }
257 
258 //--------------------------------------------------------------------------
259 void
DrawRectangle(const math::VEC2 & pos,const math::VEC2 & size,ut::Color8 color)260 GraphicsDrawing::DrawRectangle( const math::VEC2& pos, const math::VEC2& size, ut::Color8 color )
261 {
262     NW_ASSERT( ( m_ShapeVertexCount + SHAPE_DRAW_RECTANGLE_VERTEX_COUNT ) <= m_MaxShapeVertexCount );
263 
264     s32 count = 0;
265 
266     count += this->BuildLine( pos, math::VEC2( pos.x + size.x, pos.y ),
267         m_LineWidth, &m_ShapePositionStreamArray[ m_ShapeVertexCount + count ] );
268 
269     count += this->BuildLine(
270         math::VEC2( pos.x + size.x, pos.y ), pos + size,
271         m_LineWidth, &m_ShapePositionStreamArray[ m_ShapeVertexCount + count ] );
272 
273     count += this->BuildLine( pos + size, math::VEC2( pos.x, pos.y + size.y ),
274         m_LineWidth, &m_ShapePositionStreamArray[ m_ShapeVertexCount + count ] );
275 
276     count += this->BuildLine(math::VEC2( pos.x, pos.y + size.y ), pos,
277         m_LineWidth, &m_ShapePositionStreamArray[ m_ShapeVertexCount + count ] );
278 
279     u32 index = 4 * m_ShapeVertexCount;
280     BuildColor( count, color, &m_ShapeColorStreamArray[ index ] );
281 
282     m_ShapeVertexCount += count;
283 }
284 
285 //--------------------------------------------------------------------------
286 void
FillRectangle(const math::VEC2 & pos,const math::VEC2 & size,ut::Color8 color)287 GraphicsDrawing::FillRectangle( const math::VEC2& pos, const math::VEC2& size, ut::Color8 color )
288 {
289     NW_ASSERT( ( m_ShapeVertexCount + SHAPE_FILL_RECTANGLE_VERTEX_COUNT ) <= m_MaxShapeVertexCount );
290 
291     s32 count = this->BuildRectangle(pos, size, &m_ShapePositionStreamArray[ m_ShapeVertexCount ]);
292 
293     u32 index = 4 * m_ShapeVertexCount;
294     BuildColor( count, color, &m_ShapeColorStreamArray[ index ] );
295 
296     m_ShapeVertexCount += count;
297 }
298 
299 //--------------------------------------------------------------------------
300 void
FillTriangle(const math::VEC2 & pt1,const math::VEC2 & pt2,const math::VEC2 & pt3,ut::Color8 color)301 GraphicsDrawing::FillTriangle( const math::VEC2& pt1, const math::VEC2& pt2, const math::VEC2& pt3, ut::Color8 color )
302 {
303     NW_ASSERT( ( m_ShapeVertexCount + SHAPE_FILL_TRIANGLE_VERTEX_COUNT ) <= m_MaxShapeVertexCount );
304 
305     s32 count = this->BuildTriangle( pt1, pt2, pt3, &m_ShapePositionStreamArray[ m_ShapeVertexCount ] );
306 
307     u32 index = 4 * m_ShapeVertexCount;
308     BuildColor( count, color, &m_ShapeColorStreamArray[ index ] );
309 
310     m_ShapeVertexCount += count;
311 }
312 
313 //--------------------------------------------------------------------------
314 void
FillTriangles(const math::VEC2 * pPointArray,s32 pointCount,ut::Color8 color)315 GraphicsDrawing::FillTriangles( const math::VEC2* pPointArray, s32 pointCount, ut::Color8 color )
316 {
317     NW_NULL_ASSERT( pPointArray );
318     NW_ASSERT( pointCount > 0 );
319 
320     NW_ASSERT( ( m_ShapeVertexCount + pointCount ) <= m_MaxShapeVertexCount );
321 
322     s32 size = 2 * 4 * pointCount;
323     std::memcpy( &m_ShapePositionStreamArray[ m_ShapeVertexCount ],
324                  pPointArray, size );
325 
326     u32 index = 4 * m_ShapeVertexCount;
327     BuildColor( pointCount, color, &m_ShapeColorStreamArray[ index ] );
328 
329     m_ShapeVertexCount += pointCount;
330 }
331 
332 //--------------------------------------------------------------------------
333 bool
InitializeFont(os::IAllocator * allocator,const wchar_t * fontShaderPath,const wchar_t * fontPath)334 GraphicsDrawing::InitializeFont(
335     os::IAllocator* allocator,
336     const wchar_t* fontShaderPath,
337     const wchar_t* fontPath
338 )
339 {
340     m_FontAllocator = allocator;
341     m_IsFontOwner = true;
342 
343     // フォントリソースをロードします。
344     ut::MoveArray<u8> fontData = nw::demo::Utility::LoadFile( allocator, fontPath, nw::font::GlyphDataAlignment );
345     ut::MoveArray<u8> fontShaderData = nw::demo::Utility::LoadFile( allocator, fontShaderPath );
346 
347     s32 fontSize = fontData.size();
348     void* fontBuffer = fontData.release();
349 
350     s32 shaderSize = fontShaderData.size();
351     void* shaderBuffer = fontShaderData.release();
352 
353     const u32 vtxBufCommandBufferSize =
354         nw::font::RectDrawer::GetVertexBufferCommandBufferSize(shaderBuffer, shaderSize);
355     m_FontCommandBuffer = allocator->Alloc(vtxBufCommandBufferSize);
356     NN_NULL_ASSERT(m_FontCommandBuffer);
357 
358     const u32 drawBufferSize = nw::font::ResFont::GetDrawBufferSize(fontBuffer);
359     void* drawBuffer = allocator->Alloc(drawBufferSize, 4);
360     NW_NULL_ASSERT(drawBuffer);
361 
362     const u32 stringBufferSize = nw::font::CharWriter::GetDispStringBufferSize(m_MaxTextCount);
363     void *const stringBuffer = allocator->Alloc(stringBufferSize);
364     NN_NULL_ASSERT(stringBuffer);
365 
366     bool result = false;
367     if ( fontBuffer != NULL && shaderBuffer != NULL )
368     {
369         result = this->InitializeFontFromBinary( shaderBuffer, shaderSize, fontBuffer, fontSize, drawBuffer, stringBuffer );
370     }
371 
372     os::SafeFree(shaderBuffer, allocator);
373 
374     if ( ! result )
375     {
376         os::SafeFree(fontBuffer, allocator);
377     }
378 
379     return result;
380 }
381 
382 //--------------------------------------------------------------------------
383 bool
InitializeFont(os::IAllocator * allocator,const wchar_t * fontShaderPath,void * fontBinary,size_t fontSize)384 GraphicsDrawing::InitializeFont(
385     os::IAllocator* allocator,
386     const wchar_t* fontShaderPath,
387     void* fontBinary,
388     size_t fontSize
389 )
390 {
391     m_FontAllocator = allocator;
392     m_IsFontOwner = false;
393 
394     ut::MoveArray<u8> fontShaderData = nw::demo::Utility::LoadFile( allocator, fontShaderPath );
395 
396     s32 shaderSize = fontShaderData.size();
397     void* shaderBuffer = fontShaderData.release();
398 
399     const u32 vtxBufCommandBufferSize =
400         nw::font::RectDrawer::GetVertexBufferCommandBufferSize(shaderBuffer, shaderSize);
401     m_FontCommandBuffer = allocator->Alloc(vtxBufCommandBufferSize);
402     NN_NULL_ASSERT(m_FontCommandBuffer);
403 
404     const u32 drawBufferSize = nw::font::ResFont::GetDrawBufferSize(fontBinary);
405     void* drawBuffer = allocator->Alloc(drawBufferSize, 4);
406     NW_NULL_ASSERT(drawBuffer);
407 
408     const u32 stringBufferSize = nw::font::CharWriter::GetDispStringBufferSize(m_MaxTextCount);
409     void *const stringBuffer = allocator->Alloc(stringBufferSize);
410     NN_NULL_ASSERT(stringBuffer);
411 
412     bool result = this->InitializeFontFromBinary( shaderBuffer, shaderSize, fontBinary, fontSize, drawBuffer, stringBuffer );
413 
414     os::SafeFree(shaderBuffer, allocator);
415 
416     return result;
417 }
418 
419 //--------------------------------------------------------------------------
420 void
DestroyFont()421 GraphicsDrawing::DestroyFont()
422 {
423     m_Drawer.Finalize();
424 
425     os::SafeFree(m_FontCommandBuffer, m_FontAllocator);
426 
427     nw::font::DispStringBuffer* stringBuffer = m_TextWriter.GetDispStringBuffer();
428     os::SafeFree(stringBuffer, m_FontAllocator);
429 
430     // フォントの破棄
431     if (!m_Font.IsManaging(NULL))
432     {
433         void* drawBuffer = m_Font.SetDrawBuffer(NULL);
434         void* resource = m_Font.RemoveResource();
435 
436         if (m_IsFontOwner)
437         {
438             os::SafeFree(resource, m_FontAllocator);
439         }
440 
441         os::SafeFree(drawBuffer, m_FontAllocator);
442     }
443 }
444 
445 //--------------------------------------------------------------------------
446 void
BeginDrawingString()447 GraphicsDrawing::BeginDrawingString()
448 {
449     // カラーバッファ情報
450     // LCDの向きに合わせて、幅と高さを入れ替えています。
451     const nw::font::ColorBufferInfo colBufInfo = { m_ScreenSize.y, m_ScreenSize.x, PICA_DATA_DEPTH24_STENCIL8_EXT };
452 
453     const u32 screenSettingCommands[] =
454     {
455         // ビューポートの設定
456         NW_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ),
457 
458         // シザー処理を無効
459         NW_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ),
460 
461         // wバッファの無効化
462         // デプスレンジの設定
463         // ポリゴンオフセットの無効化
464         NW_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(
465             0.0f,           // wScale : 0.0 でWバッファが無効
466             0.0f,           // depth range near
467             1.0f,           // depth range far
468             0,              // polygon offset units : 0.0 で ポリゴンオフセットが無効
469             colBufInfo),
470     };
471 
472     nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true);
473 
474     static const u32 s_InitCommands[] =
475     {
476         // カリングを無効
477         NW_FONT_CMD_SET_CULL_FACE( NW_FONT_CMD_CULL_FACE_DISABLE ),
478 
479         // ステンシルテストを無効
480         NW_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
481 
482         // デプステストを無効
483         // カラーバッファの全ての成分を書き込み可
484         NW_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(
485             false,  // isDepthTestEnabled
486             0,      // depthFunc
487             true,   // depthMask
488             true,   // red
489             true,   // green
490             true,   // blue
491             true),  // alpha
492 
493         // アーリーデプステストを無効
494         NW_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ),
495 
496         // フレームバッファアクセス制御
497         NW_FONT_CMD_SET_FBACCESS(
498             true,   // colorRead
499             true,   // colorWrite
500             false,  // depthRead
501             false,  // depthWrite
502             false,  // stencilRead
503             false), // stencilWrite
504     };
505 
506     nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true);
507 
508     m_Drawer.DrawBegin();
509 
510     this->SendFontMatrix();
511 
512     m_TextWriter.SetCursor( 0, 0 );
513 }
514 
515 //--------------------------------------------------------------------------
516 f32
DrawString(const char * format,...)517 GraphicsDrawing::DrawString( const char* format, ... )
518 {
519     NW_NULL_ASSERT( format );
520 
521     std::va_list vargs;
522     va_start(vargs, format);
523 
524     m_TextWriter.StartPrint();
525         f32 width = m_TextWriter.VPrintf(format, vargs);
526     m_TextWriter.EndPrint();
527 
528     m_Drawer.BuildTextCommand(&m_TextWriter);
529     m_TextWriter.UseCommandBuffer();
530 
531     va_end(vargs);
532 
533     return width;
534 }
535 
536 //--------------------------------------------------------------------------
537 f32
DrawString(s32 posh,s32 posv,const char * format,...)538 GraphicsDrawing::DrawString( s32 posh, s32 posv, const char* format, ... )
539 {
540     NW_NULL_ASSERT( format );
541 
542     m_TextWriter.SetCursor( static_cast<f32>(posh), static_cast<f32>(posv) );
543 
544     std::va_list vargs;
545     va_start(vargs, format);
546 
547     f32 width = this->DrawStringArgs( posh, posv, format, vargs);
548 
549     va_end(vargs);
550 
551     return width;
552 }
553 
554 //--------------------------------------------------------------------------
555 f32
DrawStringArgs(s32 posh,s32 posv,const char * format,std::va_list args)556 GraphicsDrawing::DrawStringArgs( s32 posh, s32 posv, const char* format, std::va_list args )
557 {
558     NW_NULL_ASSERT( format );
559 
560     m_TextWriter.SetCursor( static_cast<f32>(posh), static_cast<f32>(posv) );
561 
562     m_TextWriter.StartPrint();
563         f32 width = m_TextWriter.VPrintf(format, args);
564     m_TextWriter.EndPrint();
565 
566     m_Drawer.BuildTextCommand(&m_TextWriter);
567     m_TextWriter.UseCommandBuffer();
568 
569     return width;
570 }
571 
572 //--------------------------------------------------------------------------
573 void
EndDrawingString()574 GraphicsDrawing::EndDrawingString()
575 {
576     m_Drawer.DrawEnd();
577 }
578 
579 //--------------------------------------------------------------------------
580 void
InitializeShapeGraphicsState()581 GraphicsDrawing::InitializeShapeGraphicsState()
582 {
583     // レンダリングステートの設定
584     m_ShapeRenderState.blend.isEnable          = true;
585     m_ShapeRenderState.blend.eqRgb             = PICA_DATA_BLEND_EQUATION_ADD;
586     m_ShapeRenderState.blend.eqAlpha           = PICA_DATA_BLEND_EQUATION_ADD;
587     m_ShapeRenderState.blend.srcRgb            = PICA_DATA_BLEND_FUNC_SRC_ALPHA;
588     m_ShapeRenderState.blend.srcAlpha          = PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
589     m_ShapeRenderState.blend.dstRgb            = PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
590     m_ShapeRenderState.blend.dstAlpha          = PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
591 
592     m_ShapeRenderState.stencilTest.isEnable    = false;
593 
594     m_ShapeRenderState.depthTest.isEnable      = false;
595     m_ShapeRenderState.depthTest.isEnableWrite = false;
596 
597     m_ShapeRenderState.cullingTest.isEnable    = false;
598 
599     // テクスチャコンバイナの設定
600     for ( u32 stageIndex = 0; stageIndex < nn::gr::CTR::Combiner::COMBINER_STAGE_MAX; stageIndex++ )
601     {
602         m_ShapeCombiner.stage[ stageIndex ].rgb.combine   = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
603         m_ShapeCombiner.stage[ stageIndex ].alpha.combine = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
604 
605         for ( u32 sourceIndex = 0; sourceIndex < 3; sourceIndex++)
606         {
607             if ( ( stageIndex == 0 ) && ( sourceIndex == 0 ) )
608             {
609                 m_ShapeCombiner.stage[ stageIndex ].rgb.source[ sourceIndex ]   = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
610                 m_ShapeCombiner.stage[ stageIndex ].alpha.source[ sourceIndex ] = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
611             }
612             else
613             {
614                 m_ShapeCombiner.stage[ stageIndex ].rgb.source[ sourceIndex ]   = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
615                 m_ShapeCombiner.stage[ stageIndex ].alpha.source[ sourceIndex ] = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
616             }
617 
618             m_ShapeCombiner.stage[ stageIndex ].rgb.operand[ sourceIndex ]      = PICA_DATA_OPE_RGB_SRC_COLOR;
619             m_ShapeCombiner.stage[ stageIndex ].alpha.operand[ sourceIndex ]    = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
620         }
621 
622         m_ShapeCombiner.stage[ stageIndex ].rgb.scale   = PICA_DATA_TEX_ENV_SCALE_1;
623         m_ShapeCombiner.stage[ stageIndex ].alpha.scale = PICA_DATA_TEX_ENV_SCALE_1;
624     }
625 }
626 
627 //--------------------------------------------------------------------------
628 void
SetupShapeMaterial()629 GraphicsDrawing::SetupShapeMaterial()
630 {
631     bit32* command;
632     nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast<GLint*>( &command ) );
633 
634     bit32* commandStart = command;
635     command = m_ShapeShader.MakeFullCommand( command );
636     command = m_ShapeRenderState.MakeCommand( command ) ;
637 
638     nngxMoveCommandbufferPointer( ( command - commandStart ) * sizeof(u32) );
639 }
640 
641 //--------------------------------------------------------------------------
642 void
SetupShapeTexEnv()643 GraphicsDrawing::SetupShapeTexEnv()
644 {
645     bit32* command;
646     nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast<GLint*>( &command ) );
647 
648     bit32* commandStart = command;
649     command      = m_ShapeCombiner.MakeCommand( command );
650 
651     nngxMoveCommandbufferPointer( ( command - commandStart ) * sizeof(u32) );
652 }
653 
654 //--------------------------------------------------------------------------
655 void
SendShapeMatrix()656 GraphicsDrawing::SendShapeMatrix()
657 {
658     nw::math::MTX44 projMtx;
659     nw::math::MTX44 viewMtx;
660 
661     const nw::math::VEC3 camPos( 0.0f, 0.0f, 1.0f );
662     const nw::math::VEC3 aimPos( 0.0f, 0.0f, 0.0f );
663     const nw::math::VEC3 camUp( 0.0f, 1.0f, 0.0f );
664 
665     f32 width        = m_ScreenSize.y;
666     f32 height       = m_ScreenSize.x;
667 
668     const f32 left   = 0.f;
669     f32 right        = m_ScreenSize.x;
670     f32 bottom       = m_ScreenSize.y;
671     const f32 top    = 0.f;
672 
673     const f32 znear = - 100.0f;
674     const f32 zfar  =   100.0f;
675 
676     math::MTX44OrthoPivot( &projMtx, left, right, bottom, top, znear, zfar, math::PIVOT_UPSIDE_TO_TOP );
677 
678     math::MTX44Identity( &viewMtx );
679     math::MTX34LookAt( reinterpret_cast<nw::math::MTX34*>(&viewMtx), &camPos, &camUp, &aimPos );
680 
681     bit32* command;
682     nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast<GLint*>( &command ) );
683 
684     bit32* commandStart = command;
685 
686     // シェーダのUniformを設定
687     {
688         command = m_ShapeBindSymbolProjectionMatrix.MakeUniformCommand( command, projMtx );
689         command = m_ShapeBindSymbolModelViewMatrix.MakeUniformCommand( command, viewMtx );
690     }
691 
692     nngxMoveCommandbufferPointer( ( command - commandStart ) * sizeof(u32) );
693 }
694 
695 //--------------------------------------------------------------------------
696 s32
BuildTriangle(const math::VEC2 & pt1,const math::VEC2 & pt2,const math::VEC2 & pt3,math::VEC2 * pVecArray)697 GraphicsDrawing::BuildTriangle( const math::VEC2& pt1, const math::VEC2& pt2, const math::VEC2& pt3, math::VEC2 *pVecArray )
698 {
699     NW_NULL_ASSERT( pVecArray );
700 
701     pVecArray[ 0 ] = pt1;
702     pVecArray[ 1 ] = pt2;
703     pVecArray[ 2 ] = pt3;
704 
705     return 3;
706 }
707 
708 //--------------------------------------------------------------------------
709 s32
BuildRectangle(const math::VEC2 & pt1,const math::VEC2 & pt2,const math::VEC2 & pt3,const math::VEC2 & pt4,math::VEC2 * pVecArray)710 GraphicsDrawing::BuildRectangle(
711     const math::VEC2& pt1,
712     const math::VEC2& pt2,
713     const math::VEC2& pt3,
714     const math::VEC2& pt4,
715     math::VEC2 *pVecArray )
716 {
717     NW_NULL_ASSERT( pVecArray );
718     s32 count = 0;
719 
720     count += this->BuildTriangle( pt1, pt2, pt3, &pVecArray[count] );
721     count += this->BuildTriangle( pt1, pt3, pt4, &pVecArray[count] );
722 
723     return count;
724 }
725 
726 //--------------------------------------------------------------------------
727 s32
BuildRectangle(const math::VEC2 & pos,const math::VEC2 & size,math::VEC2 * pVecArray)728 GraphicsDrawing::BuildRectangle( const math::VEC2& pos, const math::VEC2& size, math::VEC2 *pVecArray )
729 {
730     NW_NULL_ASSERT( pVecArray );
731 
732     s32 count = 0;
733     count += this->BuildRectangle(
734         pos,
735         math::VEC2(pos.x + size.x, pos.y),
736         pos + size,
737         math::VEC2(pos.x, pos.y + size.y),
738         pVecArray );
739 
740     return count;
741 }
742 
743 //--------------------------------------------------------------------------
744 s32
BuildLine(const math::VEC2 & pt1,const math::VEC2 & pt2,f32 lineWidth,math::VEC2 * pVecArray)745 GraphicsDrawing::BuildLine( const math::VEC2& pt1, const math::VEC2& pt2, f32 lineWidth, math::VEC2 *pVecArray )
746 {
747     NW_ASSERT( lineWidth >= 0.f );
748     NW_NULL_ASSERT( pVecArray );
749 
750     math::VEC2 direction  = pt1 - pt2;
751     math::VEC2 ortho      = math::VEC2( direction.y, - direction.x );
752 
753     VEC2Normalize( &ortho, &ortho );
754     ortho *= lineWidth;
755 
756     s32 count = 0;
757 
758     count += this->BuildRectangle( pt1 - ortho / 2, pt1 + ortho / 2, pt2 + ortho / 2, pt2 - ortho / 2, pVecArray );
759 
760     return count;
761 }
762 
763 //--------------------------------------------------------------------------
764 void
BuildColor(const s32 vertexCount,const ut::Color8 color,f32 * pColorArray)765 GraphicsDrawing::BuildColor( const s32 vertexCount, const ut::Color8 color,
766                              f32* pColorArray )
767 {
768     ut::FloatColor floatColor = color;
769 
770     for ( s32 index = 0; index < vertexCount; index++ )
771     {
772         s32 colorIndex = 4 * index;
773         pColorArray[ colorIndex    ] = floatColor.r;
774         pColorArray[ colorIndex + 1] = floatColor.g;
775         pColorArray[ colorIndex + 2] = floatColor.b;
776         pColorArray[ colorIndex + 3] = floatColor.a;
777     }
778 }
779 
780 //--------------------------------------------------------------------------
781 bool
InitializeFontFromBinary(void * shaderBinary,size_t shaderSize,void * fontBinary,size_t fontSize,void * drawBuffer,void * stringBuffer)782 GraphicsDrawing::InitializeFontFromBinary(
783     void* shaderBinary,
784     size_t shaderSize,
785     void* fontBinary,
786     size_t fontSize,
787     void* drawBuffer,
788     void* stringBuffer
789 )
790 {
791     if ( ! this->InitializeFontResource( fontBinary, fontSize ) )
792     {
793         return false;
794     }
795 
796     if ( ! this->InitializeFontShader( shaderBinary, shaderSize ) )
797     {
798         return false;
799     }
800 
801     // 描画用バッファを設定します。
802     m_Font.SetDrawBuffer(drawBuffer);
803 
804     m_TextWriter.SetFont( &m_Font );
805     m_TextWriter.SetFontSize( FONT_SIZE, FONT_SIZE );
806     m_TextWriter.EnableFixedWidth( true );
807     m_TextWriter.SetFixedWidth( FONT_FIXED_WIDTH );
808     nw::font::DispStringBuffer *const pDrawStringBuf = nw::font::CharWriter::InitDispStringBuffer(stringBuffer, m_MaxTextCount);
809     m_TextWriter.SetDispStringBuffer(pDrawStringBuf);
810 
811     return true;
812 }
813 
814 //--------------------------------------------------------------------------
815 bool
InitializeFontResource(void * fontData,size_t fontSize)816 GraphicsDrawing::InitializeFontResource( void* fontData, size_t fontSize )
817 {
818     NW_UNUSED_VARIABLE( fontSize );
819 
820     // フォントリソースをセットします。
821     return m_Font.SetResource( fontData );
822 }
823 
824 
825 //--------------------------------------------------------------------------
826 bool
InitializeFontShader(void * shaderBinary,size_t shaderSize)827 GraphicsDrawing::InitializeFontShader( void* shaderBinary, size_t shaderSize )
828 {
829     m_Drawer.Initialize(m_FontCommandBuffer, shaderBinary, shaderSize);
830     return true;
831 }
832 
833 //--------------------------------------------------------------------------
834 void
SendFontMatrix()835 GraphicsDrawing::SendFontMatrix()
836 {
837     //---- 射影行列を正射影に設定
838     {
839         // 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。
840         math::MTX44 proj;
841         const f32 znear =   0.0f;
842         const f32 zfar  = - 1.0f;
843         const f32 t     =      0;
844         f32 b           =  static_cast<f32>( m_ScreenSize.y );
845         const f32 l     =      0;
846         f32 r           =  static_cast<f32>( m_ScreenSize.x );
847 
848         math::MTX44OrthoPivot( &proj, l, r, b, t, znear, zfar, math::PIVOT_UPSIDE_TO_TOP );
849 
850         m_Drawer.SetProjectionMtx( proj );
851     }
852 
853     //---- モデルビュー行列を単位行列に設定
854     {
855         nn::math::MTX34 mv;
856         nn::math::MTX34Identity(&mv);
857         m_Drawer.SetViewMtxForText(mv);
858     }
859 }
860 
861 } /* namespace demo */
862 } /* namespace nw   */
863