1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_MaterialState.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/gfx/gfx_MaterialState.h>
21 
22 namespace nw
23 {
24 namespace gfx
25 {
26 namespace internal
27 {
28 
29 nn::math::Matrix34*
CreateMatrixForLinearShadowMapTexture(nn::math::Matrix34 * pOut,f32 coeff,f32 nearp,f32 farp)30 CreateMatrixForLinearShadowMapTexture(nn::math::Matrix34* pOut, f32 coeff, f32 nearp, f32 farp)
31 {
32     f32 (*const m)[4] = pOut->m;
33     f32 scaleZ = 1.0f / (farp - nearp);
34 
35     m[0][0] = 0.5f * coeff * scaleZ;
36     m[0][1] = 0.0f;
37     m[0][2] = -0.5f * scaleZ;
38     m[0][3] = 0.0f;
39 
40     m[1][0] = 0.0f;
41     m[1][1] = 0.5f * coeff * scaleZ;
42     m[1][2] = -0.5f * scaleZ;
43     m[1][3] = 0.0f;
44 
45     m[2][0] = 0.0f;
46     m[2][1] = 0.0f;
47     m[2][2] = -scaleZ;
48     m[2][3] = 0.0f;
49 
50     return pOut;
51 }
52 
53 /*!--------------------------------------------------------------------------*
54   @brief        計算方式別にテクスチャマトリクスを設定します。
55 
56   @param[out]   textureMatrix  設定されるマトリクスです。
57   @param[in]    mode           計算方式の指定です。
58   @param[in]    scaleS         S 軸のスケール値です。
59   @param[in]    scaleT         T 軸のスケール値です。
60   @param[in]    rotate         回転値です。
61   @param[in]    translateS     S 軸の移動値です。
62   @param[in]    translateT     T 軸の移動値です。
63  *---------------------------------------------------------------------------*/
64 math::MTX44*
SetupTextureMatrix(math::MTX44 * textureMatrix,ResTextureCoordinator::MappingMatrixMode mode,float scaleS,float scaleT,float rotate,float translateS,float translateT)65 MaterialState::SetupTextureMatrix(
66     math::MTX44* textureMatrix,
67     ResTextureCoordinator::MappingMatrixMode mode,
68     float scaleS, float scaleT,
69     float rotate,
70     float translateS, float translateT)
71 {
72     NW_NULL_ASSERT(textureMatrix);
73 
74     switch (mode)
75     {
76     case ResTextureCoordinator::MAPPINGMATRIXMODE_MAYA:
77         math::MTX44TextureMatrixForMaya(
78             textureMatrix, scaleS, scaleT, rotate, translateS, translateT);
79         break;
80     case ResTextureCoordinator::MAPPINGMATRIXMODE_SOFTIMAGE:
81         math::MTX44TextureMatrixForSoftimage(
82             textureMatrix, scaleS, scaleT, rotate, translateS, translateT);
83         break;
84     case ResTextureCoordinator::MAPPINGMATRIXMODE_3DSMAX:
85         math::MTX44TextureMatrixForMax(
86             textureMatrix, scaleS, scaleT, rotate, translateS, translateT);
87         break;
88     default:
89         math::MTX44Identity(textureMatrix);
90         break;
91     }
92 
93     return textureMatrix;
94 }
95 
96 //----------------------------------------
97 void
ActivateFragmentLightingTable(const ResFragmentLighting fragmentLighting,const ResFragmentLightingTable fragmentLightingTable)98 MaterialState::ActivateFragmentLightingTable(
99     const ResFragmentLighting fragmentLighting,
100     const ResFragmentLightingTable fragmentLightingTable)
101 {
102 #if defined(NW_MATERIAL_PROFILE)
103 NW_PROFILE("MaterialState::ActivateFragmentLightingTable");
104 #endif
105     #if defined(MATERIAL_SET_ENABLED)
106 
107     s32 flags = fragmentLighting.GetFlags();
108     bool isDistribution0Enbaled = ut::CheckFlag(flags, ResFragmentLightingData::FLAG_DISTRIBUTION0_ENABLED);
109     bool isDistribution1Enbaled = ut::CheckFlag(flags, ResFragmentLightingData::FLAG_DISTRIBUTION1_ENABLED);
110     bool isReflectionEnabled = ut::CheckFlag(flags, ResFragmentLightingData::FLAG_REFLECTION_ENABLED);
111     bool isFresnelEnabled = (fragmentLighting.GetFresnelConfig() != ResFragmentLighting::CONFIG_NO_FRESNEL);
112 
113     u32 absLutInput = 0;
114     u32 lutInput = 0;
115     u32 lutScale = 0;
116 
117     ResLightingLookupTable lightingLookupTable;
118     ResImageLookupTable lookupTable;
119 
120     //--------------------------------------
121     // Reflection R のテーブル設定。
122     lightingLookupTable = fragmentLightingTable.GetReflectanceRSampler();
123     if (lightingLookupTable.IsValid() && isReflectionEnabled)
124     {
125         NW_NULL_ASSERT(lightingLookupTable.GetSampler().IsValid());
126 
127         lookupTable = lightingLookupTable.GetSampler().Dereference();
128 
129         GraphicsDevice::SetLutIsAbs( GraphicsDevice::LUT_TARGET_RR, lookupTable.IsAbs() );
130         GraphicsDevice::SetLutInput( GraphicsDevice::LUT_TARGET_RR, lightingLookupTable.GetInput() );
131         GraphicsDevice::SetLutScale( GraphicsDevice::LUT_TARGET_RR, lightingLookupTable.GetScale() );
132 
133         GraphicsDevice::ActivateLookupTable(lookupTable, GraphicsDevice::LUT_TARGET_RR);
134     }
135 
136     //--------------------------------------
137     // Reflection G のテーブル設定。
138     lightingLookupTable = fragmentLightingTable.GetReflectanceGSampler();
139     if (lightingLookupTable.IsValid() && isReflectionEnabled)
140     {
141         NW_NULL_ASSERT(lightingLookupTable.GetSampler().IsValid());
142 
143         lookupTable = lightingLookupTable.GetSampler().Dereference();
144 
145         GraphicsDevice::SetLutIsAbs( GraphicsDevice::LUT_TARGET_RG, lookupTable.IsAbs() );
146         GraphicsDevice::SetLutInput( GraphicsDevice::LUT_TARGET_RG, lightingLookupTable.GetInput() );
147         GraphicsDevice::SetLutScale( GraphicsDevice::LUT_TARGET_RG, lightingLookupTable.GetScale() );
148 
149         GraphicsDevice::ActivateLookupTable(lookupTable, GraphicsDevice::LUT_TARGET_RG);
150     }
151 
152     //--------------------------------------
153     // Reflection B のテーブル設定。
154     lightingLookupTable = fragmentLightingTable.GetReflectanceBSampler();
155     if (lightingLookupTable.IsValid() && isReflectionEnabled)
156     {
157         NW_NULL_ASSERT(lightingLookupTable.GetSampler().IsValid());
158 
159         lookupTable = lightingLookupTable.GetSampler().Dereference();
160 
161         GraphicsDevice::SetLutIsAbs( GraphicsDevice::LUT_TARGET_RB, lookupTable.IsAbs() );
162         GraphicsDevice::SetLutInput( GraphicsDevice::LUT_TARGET_RB, lightingLookupTable.GetInput() );
163         GraphicsDevice::SetLutScale( GraphicsDevice::LUT_TARGET_RB, lightingLookupTable.GetScale() );
164 
165         GraphicsDevice::ActivateLookupTable(lookupTable, GraphicsDevice::LUT_TARGET_RB);
166     }
167 
168     //--------------------------------------
169     // D0 のテーブル設定。
170     lightingLookupTable = fragmentLightingTable.GetDistribution0Sampler();
171     if (lightingLookupTable.IsValid() && isDistribution0Enbaled)
172     {
173         NW_NULL_ASSERT(lightingLookupTable.GetSampler().IsValid());
174 
175         lookupTable = lightingLookupTable.GetSampler().Dereference();
176 
177         GraphicsDevice::SetLutIsAbs( GraphicsDevice::LUT_TARGET_D0, lookupTable.IsAbs() );
178         GraphicsDevice::SetLutInput( GraphicsDevice::LUT_TARGET_D0, lightingLookupTable.GetInput() );
179         GraphicsDevice::SetLutScale( GraphicsDevice::LUT_TARGET_D0, lightingLookupTable.GetScale() );
180 
181         GraphicsDevice::ActivateLookupTable(lookupTable, GraphicsDevice::LUT_TARGET_D0);
182     }
183 
184     //--------------------------------------
185     // D1 のテーブル設定。
186     lightingLookupTable = fragmentLightingTable.GetDistribution1Sampler();
187     if (lightingLookupTable.IsValid() && isDistribution1Enbaled)
188     {
189         NW_NULL_ASSERT(lightingLookupTable.GetSampler().IsValid());
190 
191         lookupTable = lightingLookupTable.GetSampler().Dereference();
192 
193         GraphicsDevice::SetLutIsAbs( GraphicsDevice::LUT_TARGET_D1, lookupTable.IsAbs() );
194         GraphicsDevice::SetLutInput( GraphicsDevice::LUT_TARGET_D1, lightingLookupTable.GetInput() );
195         GraphicsDevice::SetLutScale( GraphicsDevice::LUT_TARGET_D1, lightingLookupTable.GetScale() );
196 
197         GraphicsDevice::ActivateLookupTable(lookupTable, GraphicsDevice::LUT_TARGET_D1);
198     }
199 
200     //--------------------------------------
201     // Fresnel のテーブル設定。
202     lightingLookupTable = fragmentLightingTable.GetFresnelSampler();
203     if (lightingLookupTable.IsValid() && isFresnelEnabled)
204     {
205         NW_NULL_ASSERT(lightingLookupTable.GetSampler().IsValid());
206 
207         lookupTable = lightingLookupTable.GetSampler().Dereference();
208 
209         GraphicsDevice::SetLutIsAbs( GraphicsDevice::LUT_TARGET_FR, lookupTable.IsAbs() );
210         GraphicsDevice::SetLutInput( GraphicsDevice::LUT_TARGET_FR, lightingLookupTable.GetInput() );
211         GraphicsDevice::SetLutScale( GraphicsDevice::LUT_TARGET_FR, lightingLookupTable.GetScale() );
212 
213         GraphicsDevice::ActivateLookupTable(lookupTable, GraphicsDevice::LUT_TARGET_FR);
214     }
215 
216     GraphicsDevice::ActivateLutParameters();
217 
218     #endif
219 }
220 
221 //----------------------------------------
222 void
ActivateTextureCoordinators(RenderContext * renderContext,const ShaderProgram * shaderProgram,const ResMaterial texCoordMaterial)223 MaterialState::ActivateTextureCoordinators(
224     RenderContext* renderContext,
225     const ShaderProgram* shaderProgram,
226     const ResMaterial texCoordMaterial)
227 {
228 #if defined(NW_MATERIAL_PROFILE)
229     NW_PROFILE("MaterialState::ActivateTextureCoordinators");
230 #endif
231 
232 #if defined(MATERIAL_SET_ENABLED)
233     enum
234     {
235         TEXCOORD2_SHIFT = 13,
236         TEXCOORD3_SHIFT = 8
237     };
238 
239     const u32 TEXCOORD_SETTING[] =
240     {
241         0,                                               // CONFIG_0120
242         (1 << TEXCOORD2_SHIFT),                          // CONFIG_0110
243         (1 << TEXCOORD2_SHIFT) | (1 << TEXCOORD3_SHIFT), // CONFIG_0111
244         (1 << TEXCOORD2_SHIFT) | (2 << TEXCOORD3_SHIFT), // CONFIG_0112
245         (1 << TEXCOORD3_SHIFT),                          // CONFIG_0121
246         (2 << TEXCOORD3_SHIFT)                           // CONFIG_0122
247     };
248 
249     // texture設定レジスタ PICA_REG_TEXTURE_FUNC(0x80) の値
250     // [0-7] はここでは設定しない
251     // [0] dmp_Texture[0].samplerType 0: GL_FALSE, 1: それ以外
252     // [1] dmp_Texture[1].samplerType 0: GL_FALSE, 1: GL_TEXTURE_2D
253     // [2] dmp_Texture[2].samplerType 0: GL_FALSE, 1: GL_TEXTURE_2D
254     // [10] dmp_Texture[3].samplerType 0: GL_FALSE, 1: GL_PROCEDURAL_DMP
255     // [12] かならず1を設定する。
256     // [13] dmp_Texture[2].texcoord   0: GL_TEXTURE2, 1:GLTEXTURE1
257     // [9:8] dmp_Texture[3].texcoord  0: GL_TEXTURE0, 1: GL_TEXTURE1, 2: GL_TEXTURE2
258     // [16] 1を書き込むとテクスチャキャッシュをクリア
259     // [23:17] テクスチャキャッシュのクリア時は0、それ以外の場合はBEでアクセスしない
260     // [31:24] 0を設定する
261 
262     u32 textureSetting = 0;
263 
264     NW_ASSERT(texCoordMaterial.GetTextureCoordinateConfig() < ResMaterial::CONFIG_NUM);
265     textureSetting = TEXCOORD_SETTING[texCoordMaterial.GetTextureCoordinateConfig()];
266 
267     const u32 HEADER = internal::MakeCommandHeader(PICA_REG_TEXTURE_FUNC, 1, false, 0xa);
268 
269     u32 TEXTYPE_COMMAND[] =
270     {
271         textureSetting | (0x1 << 12),
272         HEADER
273     };
274 
275     internal::NWUseCmdlist<sizeof(TEXTYPE_COMMAND)>( &TEXTYPE_COMMAND[0] );
276 
277     // テクスチャ座標の計算。
278     // TODO: 関数を分割し整理する。
279 
280     const int TEXTURE_UNIT_COUNT = 3;
281     GLfloat textureMappings[TEXTURE_UNIT_COUNT] = {0.0f, 0.0f, 0.0f};
282 
283     int coordinatorsCount = texCoordMaterial.GetActiveTextureCoordinatorsCount();
284 
285     for (int unit = 0; unit < TEXTURE_UNIT_COUNT; ++unit)
286     {
287         shaderProgram->SetVertexUniformBool(
288             NW_GFX_VERTEX_UNIFORM(UVMAP0) + unit, false);
289 
290         if (unit == 1 || unit == 2)
291         {
292             // テクスチャの有効フラグを頂点シェーダーに設定します。
293             if (unit < coordinatorsCount)
294             {
295                 shaderProgram->SetVertexUniformBool(
296                     NW_GFX_VERTEX_UNIFORM(ISTEX1) + unit - 1, true);
297             }
298             else
299             {
300                 shaderProgram->SetVertexUniformBool(
301                     NW_GFX_VERTEX_UNIFORM(ISTEX1) + unit - 1, false);
302             }
303         }
304     }
305 
306     math::VEC4 projectionTranslate;
307     bool isProjectionEnabled = false;
308 
309     for (int i = 0; i < coordinatorsCount; ++i)
310     {
311         ResTextureCoordinator coordinator = texCoordMaterial.GetTextureCoordinators(i);
312         NW_ASSERT(coordinator.IsValid());
313 
314         if (!coordinator.IsEnabled()) { continue; }
315 
316         math::MTX34 texMtx34;
317 
318         // TODO: テクスチャSRTアニメーションでDirtyフラグが設定できるようになれば、coordinator.IsDirty()に変更する。
319         if (coordinator.IsDirty())
320         {
321             math::MTX44 texMtx;
322             SetupTextureMatrix(
323                 &texMtx,
324                 coordinator.GetMatrixMode(),
325                 coordinator.GetScale().x,
326                 coordinator.GetScale().y,
327                 coordinator.GetRotate(),
328                 coordinator.GetTranslate().x,
329                 coordinator.GetTranslate().y);
330 
331             texMtx34.v[0] = texMtx.v[0];
332             texMtx34.v[1] = texMtx.v[1];
333             texMtx34.v[2] = texMtx.v[2];
334 
335             coordinator.GetTextureMatrix().v[0] = texMtx34.v[0];
336             coordinator.GetTextureMatrix().v[1] = texMtx34.v[1];
337             coordinator.GetTextureMatrix().v[2] = texMtx34.v[2];
338             coordinator.SetDirty(false);
339         }
340         else
341         {
342             texMtx34 = coordinator.GetTextureMatrix();
343         }
344 
345         NW_ASSERTMSG(
346             i < 1 ||
347             coordinator.GetMappingMethod() != ResTextureCoordinator::MAPPINGMETHOD_CAMERA_CUBE_ENV,
348             "Cube Map is supported just on Texture Unit 0.");
349 
350         switch (coordinator.GetMappingMethod())
351         {
352         case ResTextureCoordinator::MAPPINGMETHOD_UV_COORDINATE:
353             {
354                 textureMappings[i] = static_cast<GLfloat>(coordinator.GetSourceCoordinate());
355                 shaderProgram->SetVertexUniformBool(
356                     NW_GFX_VERTEX_UNIFORM(UVMAP0) + i, true);
357             }
358             break;
359         case ResTextureCoordinator::MAPPINGMETHOD_PROJECTION:
360             {
361                 // プロジェクションマッピングはコーディネータ0と1でのみ使用可能です。
362                 NW_ASSERTMSG(i == 0 || i == 1, "Projection mapping can use coordinator0 or coordinator1.");
363 
364                 SceneEnvironment& sceneEnvironment = renderContext->GetSceneEnvironment();
365                 int cameraIndex = coordinator.GetReferenceCamera();
366                 const Camera* camera = ((cameraIndex < 0) ? renderContext->GetActiveCamera() :
367                     sceneEnvironment.GetCamera(cameraIndex));
368 
369                 NW_NULL_ASSERT(camera);
370 
371                 const math::MTX34& referenceViewMatrix = camera->ViewMatrix();
372 
373                 if (i == 0)
374                 {
375                     projectionTranslate.x = texMtx34._03;
376                     projectionTranslate.y = texMtx34._13;
377 
378                 }
379                 else
380                 {
381                     projectionTranslate.z = texMtx34._03;
382                     projectionTranslate.w = texMtx34._13;
383                 }
384 
385                 texMtx34._03 = 0.0f;
386                 texMtx34._13 = 0.0f;
387 
388                 math::MTX34Mult(&texMtx34, &texMtx34, &camera->TextureProjectionMatrix());
389                 math::MTX34Mult(&texMtx34, &texMtx34, &referenceViewMatrix);
390 
391                 isProjectionEnabled = true;
392             }
393             break;
394         case ResTextureCoordinator::MAPPINGMETHOD_SHADOW:
395             {
396                 // シャドウマッピングはコーディネータ0でのみ使用可能です。
397                 NW_ASSERTMSG(i == 0, "Projection mapping can use coordinator0.");
398 
399                 SceneEnvironment& sceneEnvironment = renderContext->GetSceneEnvironment();
400                 int cameraIndex = coordinator.GetReferenceCamera();
401                 const Camera* camera = ((cameraIndex < 0) ? renderContext->GetActiveCamera() :
402                     sceneEnvironment.GetCamera(cameraIndex));
403 
404                 NW_NULL_ASSERT(camera);
405 
406                 projectionTranslate.x = texMtx34._03;
407                 projectionTranslate.y = texMtx34._13;
408 
409                 texMtx34._03 = 0.0f;
410                 texMtx34._13 = 0.0f;
411 
412                 f32 near = camera->GetNear();
413                 f32 far = camera->GetFar();
414                 ResCameraProjectionUpdater updater = camera->GetProjectionUpdater()->GetResource();
415 
416                 math::MTX34 projection = camera->TextureProjectionMatrix();
417                 switch(updater.ref().typeInfo)
418                 {
419                 case ResPerspectiveProjectionUpdater::TYPE_INFO:
420                     {
421                         f32 scaleFactor = 1.0f / (far - near);
422                         math::MTX34 scaleMatrix = math::MTX34::Identity();
423                         math::Vector3 scale(scaleFactor, scaleFactor, scaleFactor);
424                         math::MTX34Scale(&scaleMatrix, &scale);
425                         math::MTX34Mult(&texMtx34, &texMtx34, &scaleMatrix);
426                     }
427                     break;
428                 case ResFrustumProjectionUpdater::TYPE_INFO:
429                     {
430                         f32 scaleFactor = 1.0f / (far - near);
431                         math::MTX34 scaleMatrix = math::MTX34::Identity();
432                         math::Vector3 scale(scaleFactor, scaleFactor, scaleFactor);
433                         math::MTX34Scale(&scaleMatrix, &scale);
434                         math::MTX34Mult(&texMtx34, &texMtx34, &scaleMatrix);
435                     }
436                     break;
437                 case ResOrthoProjectionUpdater::TYPE_INFO:
438                     {
439                         f32 scaleFactor = -1.0f / (far - near);
440                         projection._22 = scaleFactor;
441                         projection._23 = near * scaleFactor;
442                     }
443                     break;
444                 default:
445                     NW_FATAL_ERROR("Unsupported camera updater type.\n");
446                     break;
447                 }
448 
449                 math::MTX34Mult(&texMtx34, &texMtx34, &projection);
450 
451                 const math::MTX34& referenceViewMatrix = camera->ViewMatrix();
452                 math::MTX34Mult(&texMtx34, &texMtx34, &referenceViewMatrix);
453 
454                 isProjectionEnabled = true;
455             }
456             break;
457         case ResTextureCoordinator::MAPPINGMETHOD_CAMERA_CUBE_ENV:
458             {
459                 textureMappings[i] =
460                     static_cast<GLfloat>(TEXTURE_COORDINATE_COUNT - 1) +
461                     static_cast<GLfloat>(coordinator.GetMappingMethod());
462 
463                 const Camera* camera = renderContext->GetActiveCamera();
464                 if (camera)
465                 {
466                     texMtx34 = camera->InverseViewMatrix();
467                 }
468             }
469             break;
470         case ResTextureCoordinator::MAPPINGMETHOD_CAMERA_SPHERE_ENV:
471             {
472                 textureMappings[i] =
473                     static_cast<GLfloat>(TEXTURE_COORDINATE_COUNT - 1) +
474                     static_cast<GLfloat>(coordinator.GetMappingMethod());
475             }
476             break;
477         default:
478             NW_FATAL_ERROR("Invalid texture coordinator type.");
479             break;
480         }
481 
482         int matrixCount = 3;
483 
484         // Texture2に関してはTexMtxが2行のみ設定可能。
485         if (i == 2)
486         {
487             matrixCount = 2;
488         }
489 
490         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_TEXMTX0_INDEX + 3 * i, matrixCount, texMtx34);
491     }
492 
493     if (isProjectionEnabled)
494     {
495         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_TEXTRAN_INDEX, 1, projectionTranslate);
496     }
497 
498     internal::NWSetVertexUniform3fv(VERTEX_SHADER_UNIFORM_TEXCMAP_INDEX, 1, textureMappings);
499 #endif
500 }
501 
502 //----------------------------------------
503 void
ActivateParticleTextureCoordinators(RenderContext * renderContext,const ShaderProgram * shaderProgram,const ResMaterial texCoordMaterial)504 MaterialState::ActivateParticleTextureCoordinators(
505     RenderContext* renderContext,
506     const ShaderProgram* shaderProgram,
507     const ResMaterial texCoordMaterial)
508 {
509     NW_UNUSED_VARIABLE(renderContext);
510 
511 #if defined(NW_MATERIAL_PROFILE)
512     NW_PROFILE("MaterialState::ActivateParticleTextureCoordinators");
513 #endif
514 
515 #if defined(MATERIAL_SET_ENABLED)
516     enum
517     {
518         TEXCOORD2_SHIFT = 13,
519         TEXCOORD3_SHIFT = 8
520     };
521 
522     const u32 TEXCOORD_SETTING[] =
523     {
524         0,                                               // CONFIG_0120
525         (1 << TEXCOORD2_SHIFT),                          // CONFIG_0110
526         (1 << TEXCOORD2_SHIFT) | (1 << TEXCOORD3_SHIFT), // CONFIG_0111
527         (1 << TEXCOORD2_SHIFT) | (2 << TEXCOORD3_SHIFT), // CONFIG_0112
528         (1 << TEXCOORD3_SHIFT),                          // CONFIG_0121
529         (2 << TEXCOORD3_SHIFT)                           // CONFIG_0122
530     };
531 
532     // texture設定レジスタ PICA_REG_TEXTURE_FUNC(0x80) の値
533     // [0-7] はここでは設定しない
534     // [0] dmp_Texture[0].samplerType 0: GL_FALSE, 1: それ以外
535     // [1] dmp_Texture[1].samplerType 0: GL_FALSE, 1: GL_TEXTURE_2D
536     // [2] dmp_Texture[2].samplerType 0: GL_FALSE, 1: GL_TEXTURE_2D
537     // [10] dmp_Texture[3].samplerType 0: GL_FALSE, 1: GL_PROCEDURAL_DMP
538     // [12] かならず1を設定する。
539     // [13] dmp_Texture[2].texcoord   0: GL_TEXTURE2, 1:GLTEXTURE1
540     // [9:8] dmp_Texture[3].texcoord  0: GL_TEXTURE0, 1: GL_TEXTURE1, 2: GL_TEXTURE2
541     // [16] 1を書き込むとテクスチャキャッシュをクリア
542     // [23:17] テクスチャキャッシュのクリア時は0、それ以外の場合はBEでアクセスしない
543     // [31:24] 0を設定する
544 
545     u32 textureSetting = 0;
546 
547     NW_ASSERT(texCoordMaterial.GetTextureCoordinateConfig() < ResMaterial::CONFIG_NUM);
548     textureSetting = TEXCOORD_SETTING[texCoordMaterial.GetTextureCoordinateConfig()];
549 
550     const u32 HEADER = internal::MakeCommandHeader(PICA_REG_TEXTURE_FUNC, 1, false, 0xa);
551 
552     u32 TEXTYPE_COMMAND[] =
553     {
554         textureSetting | (0x1 << 12),
555         HEADER
556     };
557 
558     internal::NWUseCmdlist<sizeof(TEXTYPE_COMMAND)>( &TEXTYPE_COMMAND[0] );
559 
560     // テクスチャ座標の計算。
561     // TODO: 関数を分割し整理する。
562 
563 
564     const int TEXTURE_UNIT_COUNT = 3;
565     GLfloat textureMappings[TEXTURE_UNIT_COUNT] = {0.0f, 0.0f, 0.0f};
566 
567     // パーティクルではテクスチャは1枚張まで。
568     shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(UVMAP0), false);
569 
570     int coordinatorsCount = texCoordMaterial.GetActiveTextureCoordinatorsCount();
571 
572     // コーディネイタ設定も1枚目のみ処理。
573     ResTextureCoordinator coordinator = texCoordMaterial.GetTextureCoordinators(0);
574     NW_ASSERT(coordinator.IsValid());
575 
576     if (coordinator.IsEnabled())
577     {
578         math::MTX34 texMtx34;
579 
580         // TODO: テクスチャSRTアニメーションでDirtyフラグが設定できるようになれば、coordinator.IsDirty()に変更する。
581         if (coordinator.IsDirty())
582         {
583             math::MTX44 texMtx;
584             SetupTextureMatrix(
585                 &texMtx,
586                 coordinator.GetMatrixMode(),
587                 coordinator.GetScale().x,
588                 coordinator.GetScale().y,
589                 coordinator.GetRotate(),
590                 coordinator.GetTranslate().x,
591                 coordinator.GetTranslate().y);
592 
593             texMtx34.v[0] = texMtx.v[0];
594             texMtx34.v[1] = texMtx.v[1];
595             texMtx34.v[2] = texMtx.v[2];
596 
597             coordinator.GetTextureMatrix().v[0] = texMtx34.v[0];
598             coordinator.GetTextureMatrix().v[1] = texMtx34.v[1];
599             coordinator.GetTextureMatrix().v[2] = texMtx34.v[2];
600             coordinator.SetDirty(false);
601         }
602         else
603         {
604             texMtx34 = coordinator.GetTextureMatrix();
605         }
606 
607         NW_ASSERT(coordinator.GetMappingMethod() == ResTextureCoordinator::MAPPINGMETHOD_UV_COORDINATE);
608         {
609             textureMappings[0] = static_cast<GLfloat>(coordinator.GetSourceCoordinate());
610             shaderProgram->SetVertexUniformBool( NW_GFX_VERTEX_UNIFORM(UVMAP0), true);
611         }
612 
613         int matrixCount = 3;
614         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_TEXMTX0_INDEX, matrixCount, texMtx34);
615     }
616 
617     internal::NWSetVertexUniform3fv(VERTEX_SHADER_UNIFORM_TEXCMAP_INDEX, 1, textureMappings);
618 #endif
619 }
620 
621 
622 
623 } // namesapce internal
624 } // namespace gfx
625 } // namespace nw
626