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