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