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