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