1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_MaterialState.h
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: 26187 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NW_GFX_MATERIALSTATE_H_
17 #define NW_GFX_MATERIALSTATE_H_
18
19 #include <nw/types.h>
20 #include <nw/gfx/gfx_ActivateCommand.h>
21 #include <nw/gfx/gfx_GraphicsDevice.h>
22
23 // このマクロを定義するとマテリアルの個々の要素の設定に関するプロファイルを行います。
24 // #define NW_MATERIAL_PROFILE
25
26 // このマクロを定義するとマテリアルを設定します。
27 #define MATERIAL_SET_ENABLED
28
29 namespace nw
30 {
31 namespace os
32 {
33 class IAllocator;
34 }
35
36 namespace gfx
37 {
38
39 namespace internal
40 {
41
42 // OpenGL 標準仕様の射影変換行列を生成する
43 nn::math::Matrix34*
44 CreateMatrixForLinearShadowMapTexture(nn::math::Matrix34* pOut, f32 coeff, f32 nearp, f32 farp);
45
46 //---------------------------------------------------------------------------
47 //! @brief マテリアル内容を GL に設定するクラスです。
48 //---------------------------------------------------------------------------
49 class MaterialState
50 {
51 public:
52 //----------------------------------------
53 //! @name マテリアル関連
54 //@{
55
56 //---------------------------------------------------------------------------
57 //! @brief シェーダーパラメータを設定します。
58 //!
59 //! @param[in] shaderProgram シェーダープログラムです。
60 //! @param[in] material マテリアルです。
61 //---------------------------------------------------------------------------
62 static NW_INLINE void ActivateShaderParameter(
63 const ShaderProgram* shaderProgram,
64 const ResMaterial material);
65
66 //---------------------------------------------------------------------------
67 //! @brief フラグメントライトに関するパラメータを設定します。
68 //!
69 //! @param[in] sceneEnvironment シーン環境です。
70 //! @param[in] shaderProgram シェーダープログラムです。
71 //! @param[in] material マテリアルです。
72 //---------------------------------------------------------------------------
73 static NW_INLINE void ActivateFragmentLightParameters(
74 const SceneEnvironment& sceneEnvironment,
75 const ShaderProgram* shaderProgram,
76 const ResMaterial material);
77
78 //---------------------------------------------------------------------------
79 //! @brief シェーディングに関するパラメータを設定します。
80 //!
81 //! @param[in] sceneEnvironment シーン環境です。
82 //! @param[in] shaderProgram シェーダープログラムです。
83 //! @param[in] material マテリアルです。
84 //---------------------------------------------------------------------------
85 static NW_INLINE void ActivateShadingParameters(
86 const SceneEnvironment& sceneEnvironment,
87 const ShaderProgram* shaderProgram,
88 const ResMaterial material);
89
90 //---------------------------------------------------------------------------
91 //! @brief ラスタライゼーションを設定します。
92 //!
93 //! @param[in] rasterization ラスタライゼーションです。
94 //---------------------------------------------------------------------------
95 static NW_INLINE void ActivateRasterization(const ResRasterization rasterization);
96
97 //---------------------------------------------------------------------------
98 //! @brief フラグメントライティングテーブルを設定します。
99 //!
100 //! @param[in] fragmentLighting フラグメントライティングです。
101 //! @param[in] fragmentLightingTable フラグメントライティングテーブルです。
102 //---------------------------------------------------------------------------
103 static void ActivateFragmentLightingTable(
104 const ResFragmentLighting fragmentLighting,
105 const ResFragmentLightingTable fragmentLightingTable);
106
107 //---------------------------------------------------------------------------
108 //! @brief テクスチャ座標の設定をおこないます。
109 //!
110 //! @param[in] renderContext レンダーコンテキストです。
111 //! @param[in] shaderProgram シェーダープログラムです。
112 //! @param[in] texCoordMaterial テクスチャ座標の設定に利用するマテリアルです。
113 //---------------------------------------------------------------------------
114 static void ActivateTextureCoordinators(
115 RenderContext* renderContext,
116 const ShaderProgram* shaderProgram,
117 const ResMaterial texCoordMaterial);
118
119 //---------------------------------------------------------------------------
120 //! @brief パーティクル独自のテクスチャ座標設定をおこないます。
121 //!
122 //! @param[in] renderContext レンダーコンテキストです。
123 //! @param[in] shaderProgram シェーダープログラムです。
124 //! @param[in] texCoordMaterial テクスチャ座標の設定に利用するマテリアルです。
125 //---------------------------------------------------------------------------
126 static void ActivateParticleTextureCoordinators(
127 RenderContext* renderContext,
128 const ShaderProgram* shaderProgram,
129 const ResMaterial texCoordMaterial);
130
131 //---------------------------------------------------------------------------
132 //! @brief マテリアルカラーを設定します。
133 //!
134 //! @param[in] sceneEnvironment シーン環境です。
135 //! @param[in] shaderProgram シェーダープログラムです。
136 //! @param[in] materialColor マテリアルカラーです。
137 //! @param[in] useReflection 反射テーブルが有効どうかを表すフラグです。
138 //---------------------------------------------------------------------------
139 static NW_INLINE void ActivateMaterialColor(
140 const SceneEnvironment& sceneEnvironment,
141 const ShaderProgram* shaderProgram,
142 ResMaterialColor materialColor,
143 bool useReflection);
144
145 //---------------------------------------------------------------------------
146 //! @brief フラグメントライティングを設定します。
147 //!
148 //! @param[in] sceneEnvironment シーン環境です。
149 //! @param[in] fragmentLighting 設定するフラグメントライティングです。
150 //---------------------------------------------------------------------------
151 static NW_INLINE void ActivateFragmentLighting(
152 const SceneEnvironment& sceneEnvironment,
153 const ResFragmentLighting fragmentLighting);
154
155 //---------------------------------------------------------------------------
156 //! @brief テクスチャマッパーの設定をおこないます。
157 //!
158 //! @param[in] texMapperMaterial テクスチャマッパーを利用するマテリアルです。
159 //---------------------------------------------------------------------------
160 static NW_INLINE void ActivateTextureMappers(const ResMaterial texMapperMaterial);
161
162
163 //---------------------------------------------------------------------------
164 //! @brief パーティクル独自のテクスチャマッパー設定をおこないます。
165 //!
166 //! @param[in] texMapperMaterial テクスチャマッパーを利用するマテリアルです。
167 //---------------------------------------------------------------------------
168 static NW_INLINE void ActivateParticleTextureMappers(const ResMaterial texMapperMaterial);
169
170 //---------------------------------------------------------------------------
171 //! @brief プロシージャルテクスチャマッパーの設定をおこないます。
172 //!
173 //! @param[in] renderContext レンダーコンテキストです。
174 //! @param[in] shaderProgram シェーダープログラムです。
175 //! @param[in] material プロシージャルテクスチャマッパを利用するマテリアルです。
176 //---------------------------------------------------------------------------
177 static NW_INLINE void ActivateProceduralTextureMapper(
178 RenderContext* renderContext,
179 const ShaderProgram* shaderProgram,
180 const ResMaterial material);
181
182 //---------------------------------------------------------------------------
183 //! @brief テクスチャコンバイナを設定します。
184 //!
185 //! @param[in] fragmentShader フラグメントシェーダーです。
186 //! @param[in] materialColor マテリアルカラーです。
187 //---------------------------------------------------------------------------
188 static NW_INLINE void ActivateTextureCombiners(
189 const ResFragmentShader fragmentShader,
190 const ResMaterialColor materialColor);
191
192 //---------------------------------------------------------------------------
193 //! @brief アルファテストを設定します。
194 //!
195 //! @param[in] alphaTest アルファテストです。
196 //---------------------------------------------------------------------------
197 static NW_INLINE void ActivateAlphaTest(const ResAlphaTest alphaTest);
198
199 //---------------------------------------------------------------------------
200 //! @brief フラグメントオペレーションを設定します。
201 //!
202 //! @param[in] fragmentOperation フラグメントオペレーションです。
203 //---------------------------------------------------------------------------
204 static NW_INLINE void ActivateFragmentOperation(const ResFragmentOperation fragmentOperation);
205
206 //---------------------------------------------------------------------------
207 //! @brief フォグに関するパラメータを設定します。
208 //!
209 //! @param[in] material マテリアルです。
210 //---------------------------------------------------------------------------
211 static NW_INLINE void ActivateFogParameters(
212 const SceneEnvironment& sceneEnvironment,
213 const ResMaterial material);
214
215 //@}
216
217 private:
218 //! コンスタントカラーを取得します。
219 static NW_INLINE u32 GetConstantColorU32(
220 ResTextureCombiner::Constant constant,
221 const ResMaterialColor materialColor);
222
223 //---------------------------------------------------------------------------
224 //! @brief デプスオペレーションを設定します。
225 //!
226 //! @param[in] depthOperation デプスオペレーションです。
227 //---------------------------------------------------------------------------
228 static NW_INLINE void ActivateDepthOperation(const ResDepthOperation depthOperation);
229
230 //---------------------------------------------------------------------------
231 //! @brief ステンシルオペレーションを設定します。
232 //!
233 //! @param[in] stencilOperation ステンシルオペレーションです。
234 //---------------------------------------------------------------------------
235 static NW_INLINE void ActivateStencilOperation(const ResStencilOperation stencilOperation);
236
237 //---------------------------------------------------------------------------
238 //! @brief ブレンドオペレーションを設定します。
239 //!
240 //! @param[in] blendOperation ブレンドオペレーションです。
241 //---------------------------------------------------------------------------
242 static NW_INLINE void ActivateBlendOperation(const ResBlendOperation blendOperation);
243
244 //---------------------------------------------------------------------------
245 //! @brief 計算方式別にテクスチャマトリクスを設定します。
246 //!
247 //! @param[out] textureMatrix 設定されるマトリクスです。
248 //! @param[in] mode 計算方式の指定です。
249 //! @param[in] scaleS S 軸のスケール値です。
250 //! @param[in] scaleT T 軸のスケール値です。
251 //! @param[in] rotate 回転値です。
252 //! @param[in] translateS S 軸の移動値です。
253 //! @param[in] translateT T 軸の移動値です。
254 //---------------------------------------------------------------------------
255 static math::MTX44* SetupTextureMatrix(
256 math::MTX44* textureMatrix,
257 ResTextureCoordinator::MappingMatrixMode mode,
258 float scaleS, float scaleT,
259 float rotate,
260 float translateS, float translateT);
261 };
262
263 //----------------------------------------
264 NW_INLINE u32
GetConstantColorU32(ResTextureCombiner::Constant constant,const ResMaterialColor materialColor)265 MaterialState::GetConstantColorU32(
266 ResTextureCombiner::Constant constant,
267 const ResMaterialColor materialColor)
268 {
269 switch ( constant )
270 {
271 case ResTextureCombiner::CONSTANT0: return materialColor.GetConstant0U32();
272 case ResTextureCombiner::CONSTANT1: return materialColor.GetConstant1U32();
273 case ResTextureCombiner::CONSTANT2: return materialColor.GetConstant2U32();
274 case ResTextureCombiner::CONSTANT3: return materialColor.GetConstant3U32();
275 case ResTextureCombiner::CONSTANT4: return materialColor.GetConstant4U32();
276 case ResTextureCombiner::CONSTANT5: return materialColor.GetConstant5U32();
277 case ResTextureCombiner::EMISSION: return materialColor.GetEmissionU32();
278 case ResTextureCombiner::AMBIENT: return materialColor.GetAmbientU32();
279 case ResTextureCombiner::DIFFUSE: return materialColor.GetDiffuseU32();
280 case ResTextureCombiner::SPECULAR0: return materialColor.GetSpecular0U32();
281 case ResTextureCombiner::SPECULAR1: return materialColor.GetSpecular1U32();
282 default:
283 NW_FATAL_ERROR("Illegal constant name");
284 return materialColor.GetConstant0U32();
285 }
286 }
287
288 //----------------------------------------
289 NW_INLINE void
ActivateFogParameters(const SceneEnvironment & sceneEnvironment,const ResMaterial material)290 MaterialState::ActivateFogParameters(const SceneEnvironment& sceneEnvironment, const ResMaterial material)
291 {
292 #if defined(NW_MATERIAL_PROFILE)
293 NW_PROFILE("MaterialState::ActivateFogParameters");
294 #endif
295
296 #if defined(MATERIAL_SET_ENABLED)
297 u32 flags = material.GetFlags();
298
299 enum
300 {
301 FOG_MODE_FALSE = 0,
302 FOG_MODE_FOG = 5,
303 FOG_MODE_GAS = 7,
304 REG_FOG_MODE = 0xe0
305 };
306
307 // フォグを設定します。
308 s32 fogMode = FOG_MODE_FALSE;
309 if (ut::CheckFlag(flags, ResMaterialData::FLAG_FOG_ENABLED))
310 {
311 if (sceneEnvironment.GetActiveFog() != NULL)
312 {
313 fogMode = FOG_MODE_FOG;
314 }
315 }
316
317 {
318 const u32 HEADER_FOG_MODE = internal::MakeCommandHeader(REG_FOG_MODE, 1, false, 0x1);
319
320 u32 FOG_COMMAND[] =
321 {
322 fogMode,
323 HEADER_FOG_MODE
324 };
325
326 internal::NWUseCmdlist<sizeof(FOG_COMMAND)>(&FOG_COMMAND[0]);
327 }
328 #endif
329 }
330
331 //----------------------------------------
332 NW_INLINE void
ActivateDepthOperation(const ResDepthOperation depthOperation)333 MaterialState::ActivateDepthOperation(const ResDepthOperation depthOperation)
334 {
335 #if defined(NW_MATERIAL_PROFILE)
336 NW_PROFILE("MaterialState::ActivateDepthOperation");
337 #endif
338
339 GraphicsDevice::SetDepthTestEnabled(
340 ut::CheckFlag(
341 depthOperation.GetFlags(),
342 ResDepthOperationData::FLAG_TEST_ENABLED));
343
344 GraphicsDevice::SetDepthMaskEnabled(
345 ut::CheckFlag(
346 depthOperation.GetFlags(),
347 ResDepthOperationData::FLAG_MASK_ENABLED));
348
349 GraphicsDevice::ActivateMask();
350
351 internal::NWUseCmdlist<sizeof(depthOperation.ref().m_CommandBuffer)>( &depthOperation.ref().m_CommandBuffer[0] );
352 }
353
354 //----------------------------------------
355 NW_INLINE void
ActivateStencilOperation(const ResStencilOperation stencilOperation)356 MaterialState::ActivateStencilOperation(const ResStencilOperation stencilOperation)
357 {
358 #if defined(NW_MATERIAL_PROFILE)
359 NW_PROFILE("MaterialState::ActivateStencilOperation");
360 #endif
361
362 if (!stencilOperation.IsValid())
363 {
364 return;
365 }
366
367 if (stencilOperation.IsTestEnabled())
368 {
369 GraphicsDevice::SetStencilTestEnabled(true);
370 }
371 else
372 {
373 GraphicsDevice::SetStencilTestEnabled(false);
374 }
375 internal::NWUseCmdlist<sizeof(stencilOperation.ref().m_CommandBuffer)>( &stencilOperation.ref().m_CommandBuffer[0] );
376 }
377
378 //----------------------------------------
379 NW_INLINE void
ActivateBlendOperation(const ResBlendOperation blendOperation)380 MaterialState::ActivateBlendOperation(const ResBlendOperation blendOperation)
381 {
382 #if defined(NW_MATERIAL_PROFILE)
383 NW_PROFILE("MaterialState::ActivateBlendOperation");
384 #endif
385
386 ResBlendOperation::Mode mode = blendOperation.GetMode();
387
388 if (mode == ResBlendOperation::MODE_NOT_USE)
389 {
390 GraphicsDevice::SetBlendEnabled(false);
391 }
392 else
393 {
394 GraphicsDevice::SetBlendEnabled(true);
395 }
396
397 internal::NWUseCmdlist<sizeof(blendOperation.ref().m_CommandBuffer)>(blendOperation.ref().m_CommandBuffer);
398 }
399
400 //----------------------------------------
401 NW_INLINE void
ActivateShaderParameter(const ShaderProgram * shaderProgram,const ResMaterial material)402 MaterialState::ActivateShaderParameter(
403 const ShaderProgram* shaderProgram,
404 const ResMaterial material)
405 {
406 #if defined(NW_MATERIAL_PROFILE)
407 NW_PROFILE("MaterialState::ActivateShaderParameter");
408 #endif
409
410 #if defined(MATERIAL_SET_ENABLED)
411 ResShaderProgramDescription description = shaderProgram->GetActiveDescription();
412 ResShaderSymbolArray symbolArray = description.GetSymbols();
413 int symbolCount = description.GetSymbolsCount();
414
415 // マテリアルのシェーダパラメータの値をすべて設定した後に、設定されていないパラメータに
416 // デフォルト値を設定します。
417
418 bool symbolHasBeenSetFlag[64] = { false };
419
420 ResShaderParameterArrayConst::const_iterator end = material.GetShaderParameters().end();
421 for ( ResShaderParameterArrayConst::const_iterator parameter = material.GetShaderParameters().begin();
422 parameter != end; ++parameter )
423 {
424 int symbolIndex = (*parameter).GetSymbolIndex();
425 if ( 0 <= symbolIndex && symbolIndex < symbolCount)
426 {
427 ResShaderSymbol shaderSymbol = symbolArray[symbolIndex];
428 if (shaderSymbol.IsEnabled() && shaderSymbol.GetLocation() >= 0)
429 {
430 NW_ASSERT(shaderSymbol.GetLocation() < 96);
431
432 if (shaderSymbol.IsGeometryUniform())
433 {
434 shaderProgram->SetUserGeometryUniform(shaderSymbol.GetLocation(), (*parameter).GetParameter());
435 }
436 else
437 {
438 shaderProgram->SetUserVertexUniform(shaderSymbol.GetLocation(), (*parameter).GetParameter());
439 }
440 }
441
442 // シェーダシンボル自体が無効な場合にも、デフォルト値の設定は必要ないのでフラグは立てておく。
443 symbolHasBeenSetFlag[symbolIndex] = true;
444 }
445 }
446
447 for (int symbolIndex = 0; symbolIndex < symbolCount; ++symbolIndex)
448 {
449 if ( ! symbolHasBeenSetFlag[symbolIndex] )
450 {
451 ResShaderSymbol shaderSymbol = symbolArray[symbolIndex];
452
453 if (shaderSymbol.IsEnabled() && shaderSymbol.GetLocation() >= 0)
454 {
455 NW_ASSERT(shaderSymbol.GetLocation() < 96);
456
457 if (shaderSymbol.IsGeometryUniform())
458 {
459 shaderProgram->SetUserGeometryUniform(shaderSymbol.GetLocation(), shaderSymbol.GetDefaultValue());
460 }
461 else
462 {
463 shaderProgram->SetUserVertexUniform(shaderSymbol.GetLocation(), shaderSymbol.GetDefaultValue());
464 }
465 }
466 }
467 }
468 #endif
469 }
470
471 //----------------------------------------
472 NW_INLINE void
ActivateFragmentLightParameters(const SceneEnvironment & sceneEnvironment,const ShaderProgram * shaderProgram,const ResMaterial material)473 MaterialState::ActivateFragmentLightParameters(
474 const SceneEnvironment& sceneEnvironment,
475 const ShaderProgram* shaderProgram,
476 const ResMaterial material)
477 {
478 // 各種ライトの ON/OFF を設定します。
479 enum
480 {
481 REG_FRAGMENT_LIGHT_ENABLED = 0x1c6,
482 REG_FRAGMENT_LIGHT_ENABLED2 = 0x8F
483 };
484 const u32 ENABLED_HEADER = internal::MakeCommandHeader(REG_FRAGMENT_LIGHT_ENABLED, 1, false, 0x1);
485 const u32 ENABLED_HEADER2 = internal::MakeCommandHeader(REG_FRAGMENT_LIGHT_ENABLED2, 1, false, 0x1);
486 bool isFragmentLightEnabled =
487 ut::CheckFlag(material.GetFlags(), ResMaterialData::FLAG_FRAGMENTLIGHT_ENABLED) &&
488 (sceneEnvironment.GetFragmentLightCount() != 0);
489
490 u32 LIGHT_COUNT_COMMAND[] =
491 {
492 isFragmentLightEnabled ? 0 : 1,
493 ENABLED_HEADER,
494 isFragmentLightEnabled ? 1 : 0,
495 ENABLED_HEADER2
496 };
497
498 // フラグメントライティングを行わない場合はクォータニオンの計算を省略します。
499 shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISQUATE), isFragmentLightEnabled);
500
501 internal::NWUseCmdlist<sizeof(LIGHT_COUNT_COMMAND)>( &LIGHT_COUNT_COMMAND[0] );
502 }
503
504 //----------------------------------------
505 NW_INLINE void
ActivateShadingParameters(const SceneEnvironment & sceneEnvironment,const ShaderProgram * shaderProgram,const ResMaterial material)506 MaterialState::ActivateShadingParameters(
507 const SceneEnvironment& sceneEnvironment,
508 const ShaderProgram* shaderProgram,
509 const ResMaterial material)
510 {
511 #if defined(NW_MATERIAL_PROFILE)
512 NW_PROFILE("MaterialState::ActivateShadingParameters");
513 #endif
514
515 #if defined(MATERIAL_SET_ENABLED)
516 u32 flags = material.GetFlags();
517
518 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
519 if (shaderProgram->GetActiveDescription().GetMaxVertexLightCount() > 0)
520 {
521 if (sceneEnvironment.GetVertexLightCount() > 0 &&
522 ut::CheckFlag(flags, ResMaterialData::FLAG_VERTEXLIGHT_ENABLED))
523 {
524 shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISVERTL), true);
525 }
526 else
527 {
528 shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISVERTL), false);
529 }
530 }
531 #endif
532
533 if (ut::CheckFlag(
534 shaderProgram->GetActiveDescription().GetFlags(),
535 ResShaderProgramDescription::FLAG_IS_SUPPORTING_HEMISPHERE_LIGHTING))
536 {
537 if (sceneEnvironment.GetHemiSphereLight() != NULL &&
538 ut::CheckFlag(flags, ResMaterialData::FLAG_HEMISPHERELIGHT_ENABLED))
539 {
540 shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISHEMIL), true);
541 shaderProgram->SetVertexUniformBool(
542 NW_GFX_VERTEX_UNIFORM(ISHEMIO),
543 ut::CheckFlag(flags, ResMaterialData::FLAG_HEMISPHERE_OCCLUSION_ENABLED));
544 }
545 else
546 {
547 shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISHEMIL), false);
548 }
549 }
550
551 enum
552 {
553 FOG_MODE_FALSE = 0,
554 FOG_MODE_FOG = 5,
555 FOG_MODE_GAS = 7,
556 REG_FOG_MODE = 0xe0
557 };
558
559 // フォグを設定します。
560 s32 fogMode = FOG_MODE_FALSE;
561 if (ut::CheckFlag(flags, ResMaterialData::FLAG_FOG_ENABLED))
562 {
563 if (sceneEnvironment.GetActiveFog() != NULL)
564 {
565 fogMode = FOG_MODE_FOG;
566 }
567 }
568
569 {
570 const u32 HEADER_FOG_MODE = internal::MakeCommandHeader(REG_FOG_MODE, 1, false, 0x1);
571
572 u32 FOG_COMMAND[] =
573 {
574 fogMode,
575 HEADER_FOG_MODE
576 };
577
578 internal::NWUseCmdlist<sizeof(FOG_COMMAND)>(&FOG_COMMAND[0]);
579 }
580 #endif
581 }
582
583 //----------------------------------------
584 NW_INLINE void
ActivateRasterization(const ResRasterization rasterization)585 MaterialState::ActivateRasterization(const ResRasterization rasterization)
586 {
587 #if defined(NW_MATERIAL_PROFILE)
588 NW_PROFILE("MaterialState::ActivateRasterization");
589 #endif
590
591 #if defined(MATERIAL_SET_ENABLED)
592 NW_ASSERT(rasterization.IsValid());
593
594 GraphicsDevice::SetPolygonOffsetEnabled(ut::CheckFlag(rasterization.GetFlags(), ResRasterizationData::FLAG_POLYGON_OFFSET_ENABLED));
595 GraphicsDevice::SetPolygonOffsetUnit(rasterization.GetPolygonOffsetUnit());
596 GraphicsDevice::ActivatePolygonOffset();
597
598 // CullModeの設定
599 internal::NWUseCmdlist<sizeof(rasterization.ref().m_CommandBuffer)>( rasterization.ref().m_CommandBuffer );
600 #endif
601 }
602
603 //----------------------------------------
604 NW_INLINE void
ActivateMaterialColor(const SceneEnvironment & sceneEnvironment,const ShaderProgram * shaderProgram,ResMaterialColor materialColor,bool useReflection)605 MaterialState::ActivateMaterialColor(
606 const SceneEnvironment& sceneEnvironment,
607 const ShaderProgram* shaderProgram,
608 ResMaterialColor materialColor,
609 bool useReflection)
610 {
611 #if defined(NW_MATERIAL_PROFILE)
612 NW_PROFILE("MaterialState::ActivateMaterialColor");
613 #endif
614
615 #if defined(MATERIAL_SET_ENABLED)
616 NW_ASSERT(materialColor.IsValid());
617
618 ResShaderProgramDescription resShaderProgram = shaderProgram->GetActiveDescription();
619
620 // 頂点シェーダーにマテリアルカラーを設定します。
621 internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_MATDIFF_INDEX, 1, materialColor.GetDiffuse());
622 internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_MATAMBI_INDEX, 1, materialColor.GetAmbient());
623
624 int lightCount = ut::Min(sceneEnvironment.GetFragmentLightCount(), MAX_PER_PIXEL_LIGHTS);
625 internal::ActivateFragmentLightCount( lightCount );
626
627 internal::ActivateFragmentAmbientLight( materialColor, sceneEnvironment.GetAmbientLight() );
628
629 for (int i = 0; i < lightCount; ++i)
630 {
631 const FragmentLight* light = sceneEnvironment.GetFragmentLight(i);
632
633 internal::ActivateFragmentLight(i, materialColor, light, useReflection);
634 }
635 #endif
636 }
637
638 //----------------------------------------
639 NW_INLINE void
ActivateFragmentLighting(const SceneEnvironment & sceneEnvironment,const ResFragmentLighting fragmentLighting)640 MaterialState::ActivateFragmentLighting(
641 const SceneEnvironment& sceneEnvironment,
642 const ResFragmentLighting fragmentLighting)
643 {
644 #if defined(NW_MATERIAL_PROFILE)
645 NW_PROFILE("MaterialState::ActivateFragmentLighting");
646 #endif
647
648 #if defined(MATERIAL_SET_ENABLED)
649 NW_ASSERT(fragmentLighting.IsValid());
650
651 // NOTE: リソース側であらかじめコマンドを持つようにできないかを検討。
652 // fragmentLighting, fragmengShader(LayerConfig) のバッファを
653 // それぞれ持っている部分が問題なので、計測してみて効果があるようなら
654 // FragmentShaderクラス内でのメンバの引越しもあるかもしれない。
655 internal::ActivateFragmentLighting(fragmentLighting);
656
657 bool geomFactor0 = ut::CheckFlag(
658 fragmentLighting.GetFlags(),
659 ResFragmentLightingData::FLAG_GEOMETRIC_FACTOR0_ENABLED);
660
661 bool geomFactor1 = ut::CheckFlag(
662 fragmentLighting.GetFlags(),
663 ResFragmentLightingData::FLAG_GEOMETRIC_FACTOR1_ENABLED);
664
665 int lightCount = sceneEnvironment.GetFragmentLightCount();
666 for (int i = 0; i < lightCount; ++i)
667 {
668 const FragmentLight* light = sceneEnvironment.GetFragmentLight(i);
669 ResFragmentLight resLight = light->GetResFragmentLight();
670 s32 lightKind = resLight.GetLightKind();
671
672 bool twoSideDiffuse = ut::CheckFlag(resLight.GetFlags(), ResFragmentLightData::FLAG_TWO_SIDE_DIFFUSE_ENABLED);
673 bool isDirectional = (lightKind == ResFragmentLight::KIND_DIRECTIONAL) || GraphicsDevice::GetFragmentLightPositionW(i);
674
675 internal::ActivateFragmentLightParameters(i, isDirectional, twoSideDiffuse, geomFactor0, geomFactor1);
676 }
677 #endif
678 }
679
680 //----------------------------------------
681 NW_INLINE void
ActivateTextureMappers(const ResMaterial texMapperMaterial)682 MaterialState::ActivateTextureMappers(const ResMaterial texMapperMaterial)
683 {
684 #if defined(NW_MATERIAL_PROFILE)
685 NW_PROFILE("MaterialState::ActivateTextureMappers");
686 #endif
687
688 #if defined(MATERIAL_SET_ENABLED)
689 // TODO: プロシージャルテクスチャには未対応
690 u32 samplerSetting = 0;
691
692 for ( s32 textureUnit = 0; textureUnit < texMapperMaterial.GetTextureMappersCount(); textureUnit++)
693 {
694 const ResTextureMapper textureMapper = texMapperMaterial.GetTextureMappers(textureUnit);
695 if ( ! textureMapper.IsValid() )
696 {
697 continue;
698 }
699
700 samplerSetting |= 1 << textureUnit;
701
702 // TODO: ShadowTextureMapperには未対応。
703 const ResPixelBasedTextureMapper pixTexMapper = ResStaticCast<const ResPixelBasedTextureMapper>(textureMapper);
704
705 // 0x81-0x8a, 0x8e[3:0] の内容はここに含まれる
706 const u32* command = pixTexMapper.GetCommandCache();
707 u32 commandSize = pixTexMapper.GetCommandSizeToSend();
708
709 internal::NWUseCmdlist(command, commandSize);
710 }
711
712 const u32 HEADER = internal::MakeCommandHeader(PICA_REG_TEXTURE_FUNC, 1, false, 0x5);
713
714 u32 INVALIDATE_TEXTURE_CACHE[] =
715 {
716 samplerSetting | 0x00010000,
717 HEADER
718 };
719
720 internal::NWUseCmdlist<sizeof(INVALIDATE_TEXTURE_CACHE)>(&INVALIDATE_TEXTURE_CACHE[0]);
721 #endif
722 }
723
724
725 //----------------------------------------
726 NW_INLINE void
ActivateParticleTextureMappers(const ResMaterial texMapperMaterial)727 MaterialState::ActivateParticleTextureMappers(const ResMaterial texMapperMaterial)
728 {
729 #if defined(NW_MATERIAL_PROFILE)
730 NW_PROFILE("MaterialState::ActivateParticleTextureMappers");
731 #endif
732
733 #if defined(MATERIAL_SET_ENABLED)
734 // TODO: プロシージャルテクスチャには未対応
735 const ResTextureMapper textureMapper = texMapperMaterial.GetTextureMappers(0);
736 if ( textureMapper.IsValid() )
737 {
738 // TODO: ShadowTextureMapperには未対応。
739 const ResPixelBasedTextureMapper pixTexMapper = ResStaticCast<const ResPixelBasedTextureMapper>(textureMapper);
740
741 // 0x81-0x8a, 0x8e[3:0] の内容はここに含まれる
742 const u32* command = pixTexMapper.GetCommandCache();
743 u32 commandSize = pixTexMapper.GetCommandSizeToSend();
744
745 internal::NWUseCmdlist(command, commandSize);
746 }
747
748 const u32 HEADER = internal::MakeCommandHeader(PICA_REG_TEXTURE_FUNC, 1, false, 0x5);
749
750 const u32 INVALIDATE_TEXTURE_CACHE[] =
751 {
752 0x00010001,
753 HEADER
754 };
755 internal::NWUseCmdlist<sizeof(INVALIDATE_TEXTURE_CACHE)>(&INVALIDATE_TEXTURE_CACHE[0]);
756 #endif
757 }
758
759
760 //----------------------------------------
761 NW_INLINE void
ActivateProceduralTextureMapper(RenderContext * renderContext,const ShaderProgram * shaderProgram,const ResMaterial material)762 MaterialState::ActivateProceduralTextureMapper(
763 RenderContext* renderContext,
764 const ShaderProgram* shaderProgram,
765 const ResMaterial material)
766 {
767
768 #if defined(NW_MATERIAL_PROFILE)
769 NW_PROFILE("MaterialState::ActivateProceduralTextureMapper");
770 #endif
771 NW_UNUSED_VARIABLE(renderContext);
772 NW_UNUSED_VARIABLE(shaderProgram);
773 NW_UNUSED_VARIABLE(material);
774 }
775
776 //----------------------------------------
777 NW_INLINE void
ActivateTextureCombiners(const ResFragmentShader fragmentShader,const ResMaterialColor materialColor)778 MaterialState::ActivateTextureCombiners(
779 const ResFragmentShader fragmentShader,
780 const ResMaterialColor materialColor)
781 {
782 #if defined(NW_MATERIAL_PROFILE)
783 NW_PROFILE("MaterialState::ActivateTextureCombiners");
784 #endif
785
786 #if defined(MATERIAL_SET_ENABLED)
787 #ifdef NW_TARGET_CTR_GL_FINAL
788 internal::NWUseCmdlist<sizeof(fragmentShader.ref().m_BufferCommand)>(&(fragmentShader.ref().m_BufferCommand[0]));
789 #endif
790
791 for (uint stage = 0; stage < COMBINER_AVAILABLE_COUNT; stage++)
792 {
793 ResTextureCombiner textureCombiner = fragmentShader.GetTextureCombiners(stage);
794
795 // 計測してみたところ、現状では処理のオーバーヘッドによる有意な差が見られなかったので、
796 // コンスタントカラーはマテリアルカラーから参照する形にしておく。
797 u32 constantU32 = GetConstantColorU32(
798 textureCombiner.GetConstant(),
799 materialColor);
800
801 textureCombiner.SetConstantCmd( constantU32 );
802
803 internal::NWUseCmdlist<sizeof(textureCombiner.ref().m_CommandBuffer)>( reinterpret_cast<const u32*>(textureCombiner.ref().m_CommandBuffer) );
804 }
805 #endif
806 }
807
808 //----------------------------------------
809 NW_INLINE void
ActivateAlphaTest(const ResAlphaTest alphaTest)810 MaterialState::ActivateAlphaTest(const ResAlphaTest alphaTest)
811 {
812 #if defined(NW_MATERIAL_PROFILE)
813 NW_PROFILE("MaterialState::ActivateAlphaTest");
814 #endif
815
816 #if defined(MATERIAL_SET_ENABLED)
817 NW_ASSERT(alphaTest.IsValid());
818 internal::NWUseCmdlist<sizeof(alphaTest.ref().m_CommandBuffer)>( &alphaTest.ref().m_CommandBuffer[0] );
819 #endif
820 }
821
822 //----------------------------------------
823 NW_INLINE void
ActivateFragmentOperation(const ResFragmentOperation fragmentOperation)824 MaterialState::ActivateFragmentOperation(const ResFragmentOperation fragmentOperation)
825 {
826 #if defined(MATERIAL_SET_ENABLED)
827 ResDepthOperation resDepthOperation = fragmentOperation.GetDepthOperation();
828 ResStencilOperation resStencilOperation = fragmentOperation.GetStencilOperation();
829 ResBlendOperation resBlendOperation = fragmentOperation.GetBlendOperation();
830
831 ActivateDepthOperation(resDepthOperation);
832 ActivateStencilOperation(resStencilOperation);
833 ActivateBlendOperation(resBlendOperation);
834
835 GraphicsDevice::SetFragmentOperationMode(fragmentOperation.GetFragmentOperationMode());
836 GraphicsDevice::ActivateFrameBuffer();
837 #endif
838 }
839
840 } // namespace internal
841 } // namespace gfx
842 } // namespace nw
843
844 #endif // NW_GFX_MATERIALSTATE_H_
845