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