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