1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     lyt_Common.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 "precompiled.h"
19 
20 #include <nw/lyt/lyt_Common.h>
21 #include <nw/lyt/lyt_DrawInfo.h>
22 #include <nw/lyt/lyt_GraphicsResource.h>
23 #include <nw/lyt/lyt_Material.h>
24 #include <nw/lyt/lyt_Pane.h>
25 #include <nw/lyt/lyt_Layout.h>
26 #include <nw/lyt/lyt_Stopwatch.h>
27 #include <nw/lyt/lyt_Supplement.h>
28 
29 #define ARRAY_LENGTH(a)   (sizeof(a) / sizeof((a)[0]))
30 
31 namespace nw
32 {
33 namespace lyt
34 {
35 
36 // コンパイル時チェック
37 void
CompileCheck()38 TevStage::CompileCheck()
39 {
40     NW_COMPILER_ASSERT(
41         FIELD0_SIZE ==
42             BITS_SRCRGB * 3 +
43             BITS_OPERANDRGB * 3 +
44             BITS_COMBINERGB +
45             BITS_SCALE +
46             BITS_SAVEPREV);
47 
48     NW_COMPILER_ASSERT(
49         FIELD1_SIZE ==
50             BITS_SRCALPHA * 3 +
51             BITS_OPERANDALPHA * 3 +
52             BITS_COMBINEALPHA +
53             BITS_SCALE +
54             BITS_SAVEPREV);
55 
56     NW_COMPILER_ASSERT(
57         FIELD2_SIZE ==
58             BITS_KONSTSEL * 2);
59 }
60 
61 namespace
62 {
63 
64 #ifdef NW_LYT_DMPGL_ENABLED
65 
66 static const GLushort s_VertexIndex[] =
67 {
68     VERTEX_RT, VERTEX_LT, VERTEX_RB,
69     VERTEX_LT, VERTEX_LB, VERTEX_RB,
70 };
71 
72 static const int s_NumVertex = ARRAY_LENGTH(s_VertexIndex);
73 
74 static const GLshort s_UniformVertexIndex[][VERTEXATTRSIZE_INDEX] =
75 {
76     { 0, 0 }, // LT
77     { 1, 0 }, // RT
78     { 0, 1 }, // LB
79     { 1, 1 }, // RB
80 };
81 
82 NW_COMPILER_ASSERT(ARRAY_LENGTH(s_UniformVertexIndex) == VERTEX_MAX);
83 
84 static const GLfloat s_VertexPosition[][VERTEXATTRSIZE_POS] =
85 {
86     { 0.f,  0.f,  0.f,  1.f }, // LT
87     { 1.f,  0.f,  0.f,  1.f }, // RT
88     { 0.f, -1.f,  0.f,  1.f }, // LB
89     { 1.f, -1.f,  0.f,  1.f }, // RB
90 };
91 
92 NW_COMPILER_ASSERT(ARRAY_LENGTH(s_VertexPosition) == VERTEX_MAX);
93 
94 #endif // NW_LYT_DMPGL_ENABLED
95 
96 }
97 
98 namespace internal
99 {
100 
101 using namespace nw::math;
102 
103 bool
EqualsResName(const char * name1,const char * name2)104 EqualsResName(const char* name1, const char* name2)
105 {
106      return 0 == std::strncmp(name1, name2, ResourceNameStrMax);
107 }
108 
109 bool
EqualsMaterialName(const char * name1,const char * name2)110 EqualsMaterialName(const char* name1, const char* name2)
111 {
112      return 0 == std::strncmp(name1, name2, MaterialNameStrMax);
113 }
114 
TexCoordAry()115 TexCoordAry::TexCoordAry()
116 :   m_Cap(0),
117     m_Num(0),
118     m_pData(NULL)
119 {
120 }
121 
122 void
Free()123 TexCoordAry::Free()
124 {
125     if (m_pData)
126     {
127         const u32 coordNum = m_Cap;
128         Layout::DeleteArray<math::VEC2>(&m_pData[0][0], VERTEX_MAX * coordNum);
129         m_pData = 0;
130 
131         m_Cap = 0;
132         m_Num = 0;
133     }
134 }
135 
136 void
Reserve(u8 num)137 TexCoordAry::Reserve(u8 num)
138 {
139     NW_ASSERT(num <= TexMapMax);
140 
141     if (m_Cap < num)
142     {
143         Free();
144 
145         // テクスチャ座標
146         const u32 coordNum = num;
147         math::VEC2 *const pVecAry = Layout::NewArray<math::VEC2>(VERTEX_MAX * coordNum);
148         m_pData = reinterpret_cast<TexCoordQuad *>(pVecAry);
149         if (m_pData)
150         {
151             m_Cap = num;
152         }
153     }
154 }
155 
156 void
SetSize(u8 num)157 TexCoordAry::SetSize(u8 num)
158 {
159     if (m_pData && num <= m_Cap)
160     {
161         static const VEC2 texCoords[] =
162         {
163             VEC2(0.f, 0.f),
164             VEC2(1.f, 0.f),
165             VEC2(0.f, 1.f),
166             VEC2(1.f, 1.f)
167         };
168         NW_COMPILER_ASSERT(ARRAY_LENGTH(texCoords) == VERTEX_MAX);
169 
170         for (int j = m_Num; j < num; ++j)
171         {
172             for (int i = 0; i < VERTEX_MAX; ++i)
173             {
174                 m_pData[j][i] = texCoords[i];
175             }
176         }
177         m_Num = num;
178     }
179 }
180 
181 void
GetCoord(u32 idx,TexCoordQuad coord) const182 TexCoordAry::GetCoord(
183     u32 idx,
184     TexCoordQuad coord
185 ) const
186 {
187     NW_ASSERT(idx < m_Num);
188 
189     for (int i = 0; i < VERTEX_MAX; ++i)
190     {
191         coord[i] = m_pData[idx][i];
192     }
193 }
194 
195 void
SetCoord(u32 idx,const TexCoordQuad coord)196 TexCoordAry::SetCoord(
197     u32 idx,
198     const TexCoordQuad coord
199 )
200 {
201     NW_ASSERT(idx < m_Num);
202 
203     for (int i = 0; i < VERTEX_MAX; ++i)
204     {
205         m_pData[idx][i] = coord[i];
206     }
207 }
208 
209 void
Copy(const void * pResTexCoord,u8 texCoordNum)210 TexCoordAry::Copy(
211     const void* pResTexCoord,
212     u8 texCoordNum
213 )
214 {
215     NW_ASSERT(texCoordNum <= m_Cap);
216 
217     m_Num = ut::Max(m_Num, texCoordNum);
218     const math::VEC2 (*src)[VERTEX_MAX] = static_cast<const math::VEC2 (*)[VERTEX_MAX]>(pResTexCoord);
219     for (int j = 0; j < texCoordNum; ++j)
220     {
221         for (int i = 0; i < VERTEX_MAX; ++i)
222         {
223             m_pData[j][i] = src[j][i];
224         }
225     }
226 }
227 
228 const ut::Color8
MultipleAlpha(const ut::Color8 col,u8 alpha)229 MultipleAlpha(
230     const ut::Color8   col,
231     u8                  alpha
232 )
233 {
234     ut::Color8 ret = col;
235     if (alpha != ut::Color8::ALPHA_MAX)
236     {
237         ret.a = u8(col.a * alpha / ut::Color8::ALPHA_MAX);
238     }
239     return ret;
240 }
241 
242 static f32
ColorU8ToFloat(u8 value)243 ColorU8ToFloat(u8 value)
244 {
245     return 1.0F / 255 * value;
246 }
247 
248 #ifdef NW_LYT_DMPGL_ENABLED
249 
250 void
DrawQuad(const DrawInfo & drawInfo,const VEC2 & basePt,const Size & size,u8 texCoordNum,const VEC2 (* texCoords)[VERTEX_MAX],const ut::Color8 * vtxColors)251 DrawQuad(
252     const DrawInfo&     drawInfo,
253     const VEC2&         basePt,
254     const Size&         size,
255     u8                  texCoordNum,
256     const VEC2          (*texCoords)[VERTEX_MAX],
257     const ut::Color8*    vtxColors
258 )
259 {
260     NW_LYT_STOPWATCH_MEASURE(-100, "nw::lyt::internal::DrawQuad");
261 
262     GraphicsResource& gres = *drawInfo.GetGraphicsResource();
263 
264     // プログラムが設定されてから一度だけ行う初期化。
265     gres.SetupProgram();
266 
267     // 頂点カラー
268     if (vtxColors != NULL)
269     {
270         GLint loc = gres.GetUniformLocation(gres.UNIFORM_uVertexColor);
271         glUniform4f(loc + 0, vtxColors[0].r, vtxColors[0].g, vtxColors[0].b, vtxColors[0].a);
272         glUniform4f(loc + 1, vtxColors[1].r, vtxColors[1].g, vtxColors[1].b, vtxColors[1].a);
273         glUniform4f(loc + 2, vtxColors[2].r, vtxColors[2].g, vtxColors[2].b, vtxColors[2].a);
274         glUniform4f(loc + 3, vtxColors[3].r, vtxColors[3].g, vtxColors[3].b, vtxColors[3].a);
275         NW_GL_ASSERT();
276     }
277 
278     // テクスチャ座標
279     if (texCoordNum > 0 && texCoords != NULL)
280     {
281         for (int i = 0; i < TexMapMax; ++i)
282         {
283             int src = gres.GetTexCoordSrc(i);
284             if (0 <= src && texCoords != NULL && src < texCoordNum)
285             {
286                 GLint loc = gres.GetUniformLocation(gres.UNIFORM_uVertexTexCoord0 + i);
287                 glUniform4f(loc + 0, texCoords[src][0].x, texCoords[src][0].y, 0.0f, 1.0f);
288                 glUniform4f(loc + 1, texCoords[src][1].x, texCoords[src][1].y, 0.0f, 1.0f);
289                 glUniform4f(loc + 2, texCoords[src][2].x, texCoords[src][2].y, 0.0f, 1.0f);
290                 glUniform4f(loc + 3, texCoords[src][3].x, texCoords[src][3].y, 0.0f, 1.0f);
291                 NW_GL_ASSERT();
292             }
293         }
294     }
295 
296     // ローカル座標変換を設定
297     {
298         GLint loc = gres.GetUniformLocation(gres.UNIFORM_uTransform);
299         glUniform4f(loc, size.width, size.height, basePt.x, basePt.y);
300         NW_GL_ASSERT();
301     }
302 
303     gres.LoadMtxModelView();
304     NW_GL_ASSERT();
305 
306     glDrawElements(GL_TRIANGLES, s_NumVertex, GL_UNSIGNED_SHORT, 0);
307     NW_GL_ASSERT();
308 }
309 
310 // @brief 前回と同じ設定で描画を繰り返す
311 void
DrawQuad_Repeat(const DrawInfo & drawInfo,const VEC2 & basePt,const Size & size)312 DrawQuad_Repeat(
313     const DrawInfo&     drawInfo,
314     const VEC2&         basePt,
315     const Size&         size
316 )
317 {
318     NW_LYT_STOPWATCH_MEASURE(-101, "nw::lyt::internal::DrawQuad_Repeat");
319 
320     GraphicsResource& gres = *drawInfo.GetGraphicsResource();
321 
322     // ローカル座標変換を設定
323     {
324         GLint loc = gres.GetUniformLocation(gres.UNIFORM_uTransform);
325         glUniform4f(loc, size.width, size.height, basePt.x, basePt.y);
326         NW_GL_ASSERT();
327     }
328 
329     glDrawElements(GL_TRIANGLES, s_NumVertex, GL_UNSIGNED_SHORT, 0);
330     NW_GL_ASSERT();
331 }
332 
333 void
DrawLine(const DrawInfo & drawInfo,const math::VEC2 & pos,const Size & size,ut::Color8 color)334 DrawLine(
335     const DrawInfo&     drawInfo,
336     const math::VEC2&   pos,
337     const Size&         size,
338     ut::Color8          color)
339 {
340     GraphicsResource& graphicsResource = *drawInfo.GetGraphicsResource();
341 
342     GLuint program = graphicsResource.GetGlProgramDebug();
343     graphicsResource.UseProgram(program);
344 
345     // バッファオブジェクトは使わない。
346     glBindBuffer(GL_ARRAY_BUFFER, 0);
347     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
348 
349     // 頂点座標
350     glEnableVertexAttribArray(VERTEXATTR_POS);
351     glVertexAttribPointer(VERTEXATTR_POS, VERTEXATTRSIZE_POS, GL_FLOAT, GL_FALSE, 0, s_VertexPosition);
352 
353     glDisableVertexAttribArray(VERTEXATTR_COLOR);
354     glDisableVertexAttribArray(VERTEXATTR_TEXCOORD0);
355     glDisableVertexAttribArray(VERTEXATTR_TEXCOORD1);
356     glDisableVertexAttribArray(VERTEXATTR_TEXCOORD2);
357 
358     glDisable(GL_BLEND);
359     glDisable(GL_COLOR_LOGIC_OP);
360     NW_GL_ASSERT();
361 
362     glUniform4f(glGetUniformLocation(program, "dmp_TexEnv[0].constRgba"),
363         ColorU8ToFloat(color.r),
364         ColorU8ToFloat(color.g),
365         ColorU8ToFloat(color.b),
366         ColorU8ToFloat(color.a));
367     NW_GL_ASSERT();
368 
369     f32 x = pos.x;
370     f32 y = pos.y;
371     f32 w = size.width;
372     f32 h = size.height;
373     f32 u = ((w > 0.f)? 1.f : -1.f) * 2.f;
374     f32 v = ((h > 0.f)? 1.f : -1.f) * 2.f;
375 
376     // LINEが描けないので、4つの矩形で表現する。
377 
378     {
379         nw::math::MTX44 m(
380             w, 0, 0, x,
381             0, v, 0, y,
382             0, 0, 1, 0,
383             0, 0, 0, 1);
384         internal::MTX44Mult(&m, &graphicsResource.GetMtxModelView(), &m);
385         glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_TRUE, m.a);
386         NW_GL_ASSERT();
387 
388         glDrawElements(GL_TRIANGLES, s_NumVertex, GL_UNSIGNED_SHORT, s_VertexIndex);
389         NW_GL_ASSERT();
390     }
391 
392     {
393         nw::math::MTX44 m(
394             w, 0, 0, x,
395             0, v, 0, y - h,
396             0, 0, 1, 0,
397             0, 0, 0, 1);
398         internal::MTX44Mult(&m, &graphicsResource.GetMtxModelView(), &m);
399         glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_TRUE, m.a);
400         NW_GL_ASSERT();
401 
402         glDrawElements(GL_TRIANGLES, s_NumVertex, GL_UNSIGNED_SHORT, s_VertexIndex);
403         NW_GL_ASSERT();
404     }
405 
406     {
407         nw::math::MTX44 m(
408             u, 0, 0, x,
409             0, h, 0, y,
410             0, 0, 1, 0,
411             0, 0, 0, 1);
412         internal::MTX44Mult(&m, &graphicsResource.GetMtxModelView(), &m);
413         glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_TRUE, m.a);
414         NW_GL_ASSERT();
415 
416         glDrawElements(GL_TRIANGLES, s_NumVertex, GL_UNSIGNED_SHORT, s_VertexIndex);
417         NW_GL_ASSERT();
418     }
419 
420     {
421         nw::math::MTX44 m(
422             u, 0, 0, x + w,
423             0, h, 0, y,
424             0, 0, 1, 0,
425             0, 0, 0, 1);
426         internal::MTX44Mult(&m, &graphicsResource.GetMtxModelView(), &m);
427         glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_TRUE, m.a);
428         NW_GL_ASSERT();
429 
430         glDrawElements(GL_TRIANGLES, s_NumVertex, GL_UNSIGNED_SHORT, s_VertexIndex);
431         NW_GL_ASSERT();
432     }
433 
434     NW_GL_ASSERT();
435 }
436 
437 // 外部のシェーダに影響を与えないように後始末。
438 void
FinalizeGraphics()439 FinalizeGraphics()
440 {
441     glDisableVertexAttribArray(VERTEXATTR_POS);
442     glDisableVertexAttribArray(VERTEXATTR_COLOR);
443     glDisableVertexAttribArray(VERTEXATTR_TEXCOORD0);
444     glDisableVertexAttribArray(VERTEXATTR_TEXCOORD1);
445     glDisableVertexAttribArray(VERTEXATTR_TEXCOORD2);
446 
447     glBindBuffer(GL_ARRAY_BUFFER, 0);
448     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
449 }
450 
451 void
SetTextureSamplerType(GraphicsResource & graphicsResource,int index,int value)452 GL::SetTextureSamplerType(GraphicsResource& graphicsResource, int index, int value)
453 {
454     //NW_MINMAX_ASSERT(index, 0, internal::TexUnitMax - 1);
455 
456     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_Texture0_samplerType + index);
457     glUniform1i(loc, value);
458 }
459 
460 static const int tevMode[] =
461 {
462     GL_REPLACE,
463     GL_MODULATE,
464     GL_ADD,
465     GL_ADD_SIGNED,
466     GL_INTERPOLATE,
467     GL_SUBTRACT,
468     GL_ADD_MULT_DMP,
469     GL_MULT_ADD_DMP,
470 };
471 NW_COMPILER_ASSERT(ARRAY_LENGTH(tevMode) == TEVMODE_MAX);
472 
473 void
SetTevCombineRgb(GraphicsResource & graphicsResource,int index,TevMode value)474 GL::SetTevCombineRgb(GraphicsResource& graphicsResource, int index, TevMode value)
475 {
476     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
477 
478     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_combineRgb + index);
479     glUniform1i(loc, tevMode[value]);
480 }
481 
482 void
SetTevCombineAlpha(GraphicsResource & graphicsResource,int index,TevMode value)483 GL::SetTevCombineAlpha(GraphicsResource& graphicsResource, int index, TevMode value)
484 {
485     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
486 
487     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_combineAlpha + index);
488     glUniform1i(loc, tevMode[value]);
489 }
490 
491 static const int tevSrc[] =
492 {
493     GL_TEXTURE0,
494     GL_TEXTURE1,
495     GL_TEXTURE2,
496     GL_TEXTURE3,
497     GL_CONSTANT,
498     GL_PRIMARY_COLOR,
499     GL_PREVIOUS,
500 #ifdef NW_TARGET_CTR_GL_FINAL
501     GL_PREVIOUS_BUFFER_DMP,
502 #else
503     GL_CONSTANT,
504 #endif
505 };
506 NW_COMPILER_ASSERT(ARRAY_LENGTH(tevSrc) == TEVSRC_MAX);
507 
508 void
SetTevSrcRgb(GraphicsResource & graphicsResource,int index,TevSrc value0,TevSrc value1,TevSrc value2)509 GL::SetTevSrcRgb(GraphicsResource& graphicsResource, int index, TevSrc value0, TevSrc value1, TevSrc value2)
510 {
511     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
512 
513     GLint ivec[3] = { tevSrc[value0], tevSrc[value1], tevSrc[value2] };
514     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_srcRgb + index);
515     glUniform3iv(loc, 1, ivec);
516 }
517 
518 void
SetTevSrcAlpha(GraphicsResource & graphicsResource,int index,TevSrc value0,TevSrc value1,TevSrc value2)519 GL::SetTevSrcAlpha(GraphicsResource& graphicsResource, int index, TevSrc value0, TevSrc value1, TevSrc value2)
520 {
521     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
522 
523     GLint ivec[3] = { tevSrc[value0], tevSrc[value1], tevSrc[value2] };
524     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_srcAlpha + index);
525     glUniform3iv(loc, 1, ivec);
526 }
527 
528 void
SetTevOperandRgb(GraphicsResource & graphicsResource,int index,TevOpRgb value0,TevOpRgb value1,TevOpRgb value2)529 GL::SetTevOperandRgb(GraphicsResource& graphicsResource, int index, TevOpRgb value0, TevOpRgb value1, TevOpRgb value2)
530 {
531     static const int tevOpRgb[] =
532     {
533         GL_SRC_COLOR,
534         GL_ONE_MINUS_SRC_COLOR,
535         GL_SRC_ALPHA,
536         GL_ONE_MINUS_SRC_ALPHA,
537 #ifdef NW_TARGET_CTR_GL_FINAL
538         GL_SRC_R_DMP,
539         GL_ONE_MINUS_SRC_R_DMP,
540         GL_SRC_G_DMP,
541         GL_ONE_MINUS_SRC_G_DMP,
542         GL_SRC_B_DMP,
543         GL_ONE_MINUS_SRC_B_DMP,
544 #else
545         GL_SRC_COLOR, // RRR
546         GL_ONE_MINUS_SRC_COLOR, // INV_RRR
547         GL_SRC_COLOR, // GGG
548         GL_ONE_MINUS_SRC_COLOR, // INV_GGG
549         GL_SRC_COLOR, // BBB
550         GL_ONE_MINUS_SRC_COLOR, // INV_BBB
551 #endif
552     };
553     NW_COMPILER_ASSERT(ARRAY_LENGTH(tevOpRgb) == TEVOPRGB_MAX);
554     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
555 
556     GLint ivec[3] = { tevOpRgb[value0], tevOpRgb[value1], tevOpRgb[value2] };
557     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_operandRgb + index);
558     glUniform3iv(loc, 1, ivec);
559 }
560 
561 void
SetTevOperandAlpha(GraphicsResource & graphicsResource,int index,TevOpAlp value0,TevOpAlp value1,TevOpAlp value2)562 GL::SetTevOperandAlpha(GraphicsResource& graphicsResource, int index, TevOpAlp value0, TevOpAlp value1, TevOpAlp value2)
563 {
564     static const int tevOpAlp[] =
565     {
566         GL_SRC_ALPHA,
567         GL_ONE_MINUS_SRC_ALPHA,
568 #ifdef NW_TARGET_CTR_GL_FINAL
569         GL_SRC_R_DMP,
570         GL_ONE_MINUS_SRC_R_DMP,
571         GL_SRC_G_DMP,
572         GL_ONE_MINUS_SRC_G_DMP,
573         GL_SRC_B_DMP,
574         GL_ONE_MINUS_SRC_B_DMP,
575 #else
576         GL_SRC_ALPHA, // R
577         GL_ONE_MINUS_SRC_ALPHA, // INV_R
578         GL_SRC_ALPHA, // G
579         GL_ONE_MINUS_SRC_ALPHA, // INV_G
580         GL_SRC_ALPHA, // B
581         GL_ONE_MINUS_SRC_ALPHA, // INV_B
582 #endif
583     };
584     NW_COMPILER_ASSERT(ARRAY_LENGTH(tevOpAlp) == TEVOPALP_MAX);
585     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
586 
587     GLint ivec[3] = { tevOpAlp[value0], tevOpAlp[value1], tevOpAlp[value2] };
588     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_operandAlpha + index);
589     glUniform3iv(loc, 1, ivec);
590 }
591 
592 static const float scale[] =
593 {
594     1.0F,
595     2.0F,
596     4.0F,
597 };
598 NW_COMPILER_ASSERT(ARRAY_LENGTH(scale) == TEVSCALE_MAX);
599 
600 void
SetTevScaleRgb(GraphicsResource & graphicsResource,int index,TevScale value)601 GL::SetTevScaleRgb(GraphicsResource& graphicsResource, int index, TevScale value)
602 {
603     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
604 
605     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_scaleRgb + index);
606     glUniform1f(loc, scale[value]);
607 }
608 
609 void
SetTevScaleAlpha(GraphicsResource & graphicsResource,int index,TevScale value)610 GL::SetTevScaleAlpha(GraphicsResource& graphicsResource, int index, TevScale value)
611 {
612     //NW_MINMAX_ASSERT(index, 0, internal::TexEnvUnitMax - 1);
613 
614     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_scaleAlpha + index);
615     glUniform1f(loc, scale[value]);
616 }
617 
618 void
SetTevConstRgba(GraphicsResource & graphicsResource,int index,nw::ut::Color8 value)619 GL::SetTevConstRgba(GraphicsResource& graphicsResource, int index, nw::ut::Color8 value)
620 {
621     GLfloat fvec[4] =
622     {
623         ColorU8ToFloat(value.r),
624         ColorU8ToFloat(value.g),
625         ColorU8ToFloat(value.b),
626         ColorU8ToFloat(value.a),
627     };
628 
629     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_constRgba + index);
630     glUniform4fv(loc, 1, fvec);
631 }
632 
633 void
SetTevConstRgba(GraphicsResource & graphicsResource,int index,nw::ut::Color8 value0,nw::ut::Color8 value1)634 GL::SetTevConstRgba(GraphicsResource& graphicsResource, int index, nw::ut::Color8 value0, nw::ut::Color8 value1)
635 {
636     GLfloat fvec[4] =
637     {
638         ColorU8ToFloat(value0.r),
639         ColorU8ToFloat(value0.g),
640         ColorU8ToFloat(value0.b),
641         ColorU8ToFloat(value1.a),
642     };
643 
644     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_constRgba + index);
645     glUniform4fv(loc, 1, fvec);
646 }
647 
648 void
SetTevBufferColor(nw::lyt::GraphicsResource & graphicsResource,ut::Color8 value)649 GL::SetTevBufferColor(nw::lyt::GraphicsResource &graphicsResource, ut::Color8 value)
650 {
651 #ifdef NW_TARGET_CTR_GL_FINAL
652     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv0_bufferColor);
653     glUniform4f(
654         loc,
655         ColorU8ToFloat(value.r),
656         ColorU8ToFloat(value.g),
657         ColorU8ToFloat(value.b),
658         ColorU8ToFloat(value.a));
659 #else
660     NW_UNUSED_VARIABLE(graphicsResource)
661     NW_UNUSED_VARIABLE(value)
662 #endif
663 }
664 
665 void
SetTevBufferInput(nw::lyt::GraphicsResource & graphicsResource,int index,bool valueRgb,bool valueAlpha)666 GL::SetTevBufferInput(nw::lyt::GraphicsResource &graphicsResource, int index, bool valueRgb, bool valueAlpha)
667 {
668 #ifdef NW_TARGET_CTR_GL_FINAL
669     //NW_MINMAX_ASSERT(index, 1, 4);
670 
671     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_TexEnv1_bufferInput + index - 1);
672     glUniform2i(
673         loc,
674         valueRgb? GL_PREVIOUS : GL_PREVIOUS_BUFFER_DMP,
675         valueAlpha? GL_PREVIOUS : GL_PREVIOUS_BUFFER_DMP);
676 
677 #else
678     NW_UNUSED_VARIABLE(graphicsResource)
679     NW_UNUSED_VARIABLE(index)
680     NW_UNUSED_VARIABLE(valueRgb)
681     NW_UNUSED_VARIABLE(valueAlpha)
682 #endif
683 }
684 
685 void
SetEnableAlphaTest(nw::lyt::GraphicsResource & graphicsResource,bool value)686 GL::SetEnableAlphaTest(nw::lyt::GraphicsResource &graphicsResource, bool value)
687 {
688     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_FragOperation_enableAlphaTest);
689     glUniform1i(loc, value? GL_TRUE : GL_FALSE);
690 }
691 
692 void
SetAlphaRefValue(nw::lyt::GraphicsResource & graphicsResource,f32 value)693 GL::SetAlphaRefValue(nw::lyt::GraphicsResource &graphicsResource, f32 value)
694 {
695     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_FragOperation_alphaRefValue);
696     glUniform1f(loc, value);
697 }
698 
699 void
SetAlphaTestFunc(nw::lyt::GraphicsResource & graphicsResource,nw::lyt::AlphaTest value)700 GL::SetAlphaTestFunc(nw::lyt::GraphicsResource &graphicsResource, nw::lyt::AlphaTest value)
701 {
702     static const GLint alphaTest[] =
703     {
704         GL_NEVER,
705         GL_LESS,
706         GL_LEQUAL,
707         GL_EQUAL,
708         GL_NOTEQUAL,
709         GL_GEQUAL,
710         GL_GREATER,
711         GL_ALWAYS,
712     };
713     NW_COMPILER_ASSERT(ARRAY_LENGTH(alphaTest) == ALPHATEST_MAX);
714 
715     GLint loc = graphicsResource.GetUniformLocation(graphicsResource.UNIFORM_dmp_FragOperation_alphaTestFunc);
716     glUniform1i(loc, alphaTest[value]);
717 }
718 
719 static const GLint filterMode[] =
720 {
721     GL_NEAREST,
722     GL_LINEAR,
723 };
724 NW_COMPILER_ASSERT(ARRAY_LENGTH(filterMode)  == TEXFILTER_MAX);
725 
726 void
SetTexMinFilter(nw::lyt::GraphicsResource &,nw::lyt::TexFilter value)727 GL::SetTexMinFilter(nw::lyt::GraphicsResource&, nw::lyt::TexFilter value)
728 {
729     //NW_MINMAX_ASSERT(value, 0, TEXFILTER_MAX - 1);
730     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode[value]);
731 }
732 
733 void
SetTexMagFilter(nw::lyt::GraphicsResource &,nw::lyt::TexFilter value)734 GL::SetTexMagFilter(nw::lyt::GraphicsResource&, nw::lyt::TexFilter value)
735 {
736     //NW_MINMAX_ASSERT(value, 0, TEXFILTER_MAX - 1);
737     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode[value]);
738 }
739 
740 #endif // NW_LYT_DMPGL_ENABLED
741 
742 } // namespace nw::lyt::internal
743 
744 #ifdef NW_LYT_DMPGL_ENABLED
745 void
InitVBO()746 GraphicsResource::InitVBO()
747 {
748     glGenBuffers(this->VBO_MAX, m_GlVertexBufferObject);
749     NW_GL_ASSERT();
750 
751     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->GetVBO(this->VBO_ELEMENT));
752     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(s_VertexIndex), s_VertexIndex, GL_STATIC_DRAW);
753     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
754     NW_GL_ASSERT();
755 
756     glBindBuffer(GL_ARRAY_BUFFER, this->GetVBO(this->VBO_VERTEX_INDEX));
757     glBufferData(GL_ARRAY_BUFFER, sizeof(s_UniformVertexIndex), s_UniformVertexIndex, GL_STATIC_DRAW);
758     glBindBuffer(GL_ARRAY_BUFFER, 0);
759     NW_GL_ASSERT();
760 }
761 #endif
762 
763 } // namespace nw::lyt
764 } // namespace nw
765