1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ResShader.h
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: $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_GFX_RESSHADER_H_
19 #define NW_GFX_RESSHADER_H_
20 
21 #include <nw/ut/ut_ResUtil.h>
22 #include <nw/ut/ut_ResDictionary.h>
23 #include <nw/gfx/res/gfx_ResSceneObject.h>
24 #include <nw/gfx/res/gfx_ResRevision.h>
25 #include <nw/gfx/res/gfx_ResTypeInfo.h>
26 #include <nw/gfx/gfx_Config.h>
27 #include <nw/gfx/gfx_ShaderBinaryInfo.h>
28 
29 namespace nw {
30 
31 namespace os {
32 class IAllocator;
33 }
34 
35 namespace gfx {
36 
37 namespace res {
38 
39 class ResGraphicsFile;
40 class ResShaderSymbol;
41 class ResBinaryShader;
42 
43 typedef ut::ResArrayClass<ResShaderSymbol>::type::iterator ResShaderSymbolArrayIterator;
44 typedef ut::ResArrayClass<const ResShaderSymbol>::type::const_iterator ResShaderSymbolArrayConstIterator;
45 typedef ut::ResArrayClass<ResShaderSymbol>::type ResShaderSymbolArray;
46 typedef ut::ResArrayClass<const ResShaderSymbol>::type ResShaderSymbolArrayConst;
47 
48 //! @details :private
49 struct ResShaderParameterValueData
50 {
51     nw::ut::ResS32 m_UniformType;
52     nw::ut::ResF32 m_Value[1]; // UniformType によってこの後に可変長のデータが続きます。
53 };
54 
55 //! @details :private
56 struct ResShaderSymbolData
57 {
58     nw::ut::BinString toName;
59     nw::ut::ResBool m_IsEnabled;
60     nw::ut::ResBool m_IsGeometryUniform;
61     u8 _padding_0[2];
62     nw::ut::ResS32 m_Location;
63     ResShaderParameterValueData m_DefaultValue; // 可変長となりますので、この後ろにデータを入れてはならない。
64 };
65 
66 //! @details :private
67 struct ResShaderParameterData
68 {
69     nw::ut::BinString toName;
70     nw::ut::ResS32 m_SymbolIndex;
71     ResShaderParameterValueData m_Parameter;
72 };
73 
74 //! @details :private
75 struct ResShaderProgramDescriptionData
76 {
77     enum { VERTEX_ATTRIBUTE_USAGE_COUNT = 22 };
78 
79     nw::ut::ResU32 m_Flags;
80     nw::ut::ResU32 m_VertexShaderObject;
81     nw::ut::ResU32 m_GeometryShaderObject;
82     nw::ut::ResS32 m_VertexShaderIndex;
83     nw::ut::ResS32 m_GeometryShaderIndex;
84     nw::ut::ResS32 m_SymbolsTableCount;
85     nw::ut::Offset toSymbolsTable;
86     nw::ut::BinString toAttributeSymbols[VERTEX_ATTRIBUTE_COUNT];
87     nw::ut::ResS8 m_AttributeIndices[VERTEX_ATTRIBUTE_USAGE_COUNT];
88     u8 _padding_0[2];
89     nw::ut::ResS32 m_MaxBoneCount;
90     nw::ut::ResS32 m_MaxVertexLightCount;
91     nw::ut::ResS32 m_VertexLightEndUniform;
92     nw::ut::ResS32 m_GeometryShaderMode;
93     nw::ut::ResU32 m_ProgramObject;
94     void* m_UniformLocation;
95 
96     void* m_CommandCache;
97     u32   m_CommandCacheSize;
98 
99     nw::ut::Offset toOwnerShader;
100 };
101 
102 //! @details :private
103 struct ResShaderData : public ResSceneObjectData
104 {
105 };
106 
107 //! @details :private
108 struct ResBinaryShaderData : public ResShaderData
109 {
110     nw::ut::ResS32 m_BinaryDataTableCount;
111     nw::ut::Offset toBinaryDataTable;
112     nw::ut::ResS32 m_ShaderKindsTableCount;
113     nw::ut::Offset toShaderKindsTable;
114     nw::ut::ResS32 m_DescriptionsTableCount;
115     nw::ut::Offset toDescriptionsTable;
116     nw::ut::ResS32 m_ShaderObjectsTableCount;
117     nw::ut::Offset toShaderObjectsTable;
118     void*          m_CommandCache;
119     s32            m_CommandCacheSize;
120     void*          m_ShaderBinaryInfo;
121     nw::os::IAllocator* m_CommandAllocator;
122 };
123 
124 //! @details :private
125 struct ResReferenceShaderData : public ResShaderData
126 {
127     nw::ut::BinString toPath;
128     nw::ut::Offset toTargetShader;
129 };
130 
131 //--------------------------------------------------------------------------
132 //! @brief  シェーダパラメータの値を表すバイナリリソースクラスです。
133 //---------------------------------------------------------------------------
134 class ResShaderParameterValue : public nw::ut::ResCommon< ResShaderParameterValueData >
135 {
136 public:
137     //! @brief シェーダパラメータの型です。
138     enum UniformType
139     {
140         TYPE_BOOL1,     //!< ブール値です。
141         TYPE_FLOAT1,    //!< 1 次元のベクトルです。
142         TYPE_FLOAT2,    //!< 2 次元のベクトルです。
143         TYPE_FLOAT3,    //!< 3 次元のベクトルです。
144         TYPE_FLOAT4     //!< 4 次元のベクトルです。
145     };
146 
147     NW_RES_CTOR( ResShaderParameterValue )
148 
149     //---------------------------------------------------------------------------
150     //! @fn           void SetUniformType(UniformType value)
151     //! @brief        ユニフォームの種類を設定します。
152     //---------------------------------------------------------------------------
153     //---------------------------------------------------------------------------
154     //! @fn           UniformType GetUniformType() const
155     //! @brief        ユニフォームの種類を取得します。
156     //---------------------------------------------------------------------------
NW_RES_FIELD_PRIMITIVE_DECL(UniformType,UniformType)157     NW_RES_FIELD_PRIMITIVE_DECL( UniformType, UniformType ) // GetUniformType(), SetUniformType()
158 
159     //---------------------------------------------------------------------------
160     //! @brief          パラメータの値を指し示す float 型のポインタを取得します。
161     //!
162     //!                 パラメータの 1 次元目の値を指し示す float 型のポインタを返します。
163     //!                 2 次元目以降は戻り値をインクリメントすることで取得できます。
164     //!
165     //! @return         パラメータの値を指し示す float 型のポインタを返します。
166     //---------------------------------------------------------------------------
167     const f32* GetValueF32() const { return &ref().m_Value[0]; }
168 
169     //---------------------------------------------------------------------------
170     //! @brief          パラメータの値を指し示す float 型のポインタを取得します。
171     //!
172     //!                 パラメータの 1 次元目の値を指し示す float 型のポインタを返します。
173     //!                 2 次元目以降は戻り値をインクリメントすることで取得できます。
174     //!
175     //! @return         パラメータの値を指し示す float 型のポインタを返します。
176     //---------------------------------------------------------------------------
GetValueF32()177     f32*       GetValueF32()       { return &ref().m_Value[0]; }
178 
179     //---------------------------------------------------------------------------
180     //! @brief          パラメータの値を指し示す int 型のポインタを取得します。
181     //!
182     //!                 パラメータの 1 次元目の値を指し示す int 型のポインタを返します。
183     //!                 2 次元目以降は戻り値をインクリメントすることで取得できます。
184     //!
185     //! @return         パラメータの値を指し示す int 型のポインタを返します。
186     //---------------------------------------------------------------------------
GetValueS32()187     const s32* GetValueS32() const { return reinterpret_cast<const s32*>( &ref().m_Value[0] ); }
188 
189     //---------------------------------------------------------------------------
190     //! @brief          パラメータの値を指し示す int 型のポインタを取得します。
191     //!
192     //!                 パラメータの 1 次元目の値を指し示す int 型のポインタを返します。
193     //!                 2 次元目以降は戻り値をインクリメントすることで取得できます。
194     //!
195     //! @return         パラメータの値を指し示す int 型のポインタを返します。
196     //---------------------------------------------------------------------------
GetValueS32()197     s32*       GetValueS32()       { return reinterpret_cast<s32*>( &ref().m_Value[0] ); }
198 
199     //---------------------------------------------------------------------------
200     //! @brief          パラメータの値を bool 型で取得します。
201     //!
202     //! @return         パラメータの値を bool 型で返します。
203     //---------------------------------------------------------------------------
GetValueBool()204     bool       GetValueBool() const { return *reinterpret_cast<const s32*>( &ref().m_Value[0]) != 0; }
205 
206     //---------------------------------------------------------------------------
207     //! @brief        種別が TYPE_BOOL1 の場合に値を設定します。
208     //!
209     //! @param[in]    value   設定する値です。
210     //---------------------------------------------------------------------------
SetValue(bool value)211     void       SetValue(bool value)
212     {
213         NW_ASSERT( this->GetUniformType() == TYPE_BOOL1 );
214         s32* pValue = this->GetValueS32();
215         *pValue = value ? 1 : 0;
216     }
217 
218     //---------------------------------------------------------------------------
219     //! @brief        種別が TYPE_FLOAT1 の場合に値を設定します。
220     //!
221     //! @param[in]    x   設定する値です。
222     //---------------------------------------------------------------------------
SetValue(f32 x)223     void       SetValue(f32 x)
224     {
225         NW_ASSERT( this->GetUniformType() == TYPE_FLOAT1 );
226         f32* pValue = this->GetValueF32();
227         *pValue = x;
228     }
229 
230     //---------------------------------------------------------------------------
231     //! @brief        種別が TYPE_FLOAT2 の場合に値を設定します。
232     //!
233     //! @param[in]    x   設定する値の x 座標です。
234     //! @param[in]    y   設定する値の x 座標です。
235     //---------------------------------------------------------------------------
SetValue(f32 x,f32 y)236     void       SetValue(f32 x, f32 y)
237     {
238         NW_ASSERT( this->GetUniformType() == TYPE_FLOAT2 );
239         f32* pValue = this->GetValueF32();
240         *pValue++ = x;
241         *pValue   = y;
242     }
243 
244     //---------------------------------------------------------------------------
245     //! @brief        種別が TYPE_FLOAT2 の場合に値を設定します。
246     //!
247     //! @param[in]    value   設定する VEC2 の値です。
248     //---------------------------------------------------------------------------
SetValue(const math::VEC2 & value)249     void       SetValue(const math::VEC2& value)
250     {
251         NW_ASSERT( this->GetUniformType() == TYPE_FLOAT2 );
252         f32* pDstValue = this->GetValueF32();
253         const f32* pSrcValue = value;
254 
255         *pDstValue++ = *pSrcValue++;
256         *pDstValue   = *pSrcValue;
257     }
258 
259     //---------------------------------------------------------------------------
260     //! @brief        種別が TYPE_FLOAT2 の場合に値を設定します。
261     //!
262     //! @param[in]    x   設定する値の x 座標です。
263     //! @param[in]    y   設定する値の x 座標です。
264     //! @param[in]    z   設定する値の z 座標です。
265     //---------------------------------------------------------------------------
SetValue(f32 x,f32 y,f32 z)266     void       SetValue(f32 x, f32 y, f32 z)
267     {
268         NW_ASSERT( this->GetUniformType() == TYPE_FLOAT3 );
269         f32* pValue = this->GetValueF32();
270         *pValue = x; ++pValue;
271         *pValue = y; ++pValue;
272         *pValue = z;
273     }
274 
275     //---------------------------------------------------------------------------
276     //! @brief        種別が TYPE_FLOAT3 の場合に値を設定します。
277     //!
278     //! @param[in]    value   設定する VEC3 の値です。
279     //---------------------------------------------------------------------------
SetValue(const math::VEC3 & value)280     void       SetValue(const math::VEC3& value)
281     {
282         NW_ASSERT( this->GetUniformType() == TYPE_FLOAT3 );
283         f32* pDstValue = this->GetValueF32();
284         const f32* pSrcValue = value;
285 
286         *pDstValue++ = *pSrcValue++;
287         *pDstValue++ = *pSrcValue++;
288         *pDstValue   = *pSrcValue;
289     }
290 
291     //---------------------------------------------------------------------------
292     //! @brief        種別が TYPE_FLOAT2 の場合に値を設定します。
293     //!
294     //! @param[in]    x   設定する値の x 座標です。
295     //! @param[in]    y   設定する値の x 座標です。
296     //! @param[in]    z   設定する値の z 座標です。
297     //! @param[in]    w   設定する値の w 座標です。
298     //---------------------------------------------------------------------------
SetValue(f32 x,f32 y,f32 z,f32 w)299     void       SetValue(f32 x, f32 y, f32 z, f32 w)
300     {
301         NW_ASSERT( this->GetUniformType() == TYPE_FLOAT4 );
302         f32* pValue = this->GetValueF32();
303         *pValue = x; ++pValue;
304         *pValue = y; ++pValue;
305         *pValue = z; ++pValue;
306         *pValue = w;
307     }
308 
309     //---------------------------------------------------------------------------
310     //! @brief        種別が TYPE_FLOAT4 の場合に値を設定します。
311     //!
312     //! @param[in]    value   設定する VEC4 の値です。
313     //---------------------------------------------------------------------------
SetValue(const math::VEC4 & value)314     void       SetValue(const math::VEC4& value)
315     {
316         NW_ASSERT( this->GetUniformType() == TYPE_FLOAT4 );
317         f32* pDstValue = this->GetValueF32();
318         const f32* pSrcValue = value;
319 
320         *pDstValue++ = *pSrcValue++;
321         *pDstValue++ = *pSrcValue++;
322         *pDstValue++ = *pSrcValue++;
323         *pDstValue   = *pSrcValue;
324     }
325 };
326 
327 //--------------------------------------------------------------------------
328 //! @brief  シェーダパラメータを表すバイナリリソースクラスです。
329 //---------------------------------------------------------------------------
330 class ResShaderParameter : public nw::ut::ResCommon< ResShaderParameterData >
331 {
332 public:
NW_RES_CTOR(ResShaderParameter)333     NW_RES_CTOR( ResShaderParameter )
334 
335     //---------------------------------------------------------------------------
336     //! @fn           void SetSymbolIndex(s32 value)
337     //! @brief        シンボルのインデクスを設定します。
338     //---------------------------------------------------------------------------
339     //---------------------------------------------------------------------------
340     //! @fn           s32 GetSymbolIndex() const
341     //! @brief        シンボルのインデクスを取得します。
342     //---------------------------------------------------------------------------
343     //---------------------------------------------------------------------------
344     //! @fn           ResShaderParameterValueData & GetParameterData()
345     //! @brief        パラメータを取得します。
346     //---------------------------------------------------------------------------
347     //---------------------------------------------------------------------------
348     //! @fn           ResShaderParameterValue GetParameter()
349     //! @brief        パラメータを取得します。
350     //---------------------------------------------------------------------------
351     //---------------------------------------------------------------------------
352     //! @fn           const char * GetName() const
353     //! @brief        シェーダパラメータの名前を取得します。
354     //---------------------------------------------------------------------------
355     NW_RES_FIELD_STRING_DECL( Name )                // GetName()
356     NW_RES_FIELD_PRIMITIVE_DECL( s32, SymbolIndex ) // GetSymbolIndex(), SetSymbolIndex()
357     NW_RES_FIELD_RESSTRUCT_DECL( ResShaderParameterValue, Parameter ) // GetParamter()
358 
359     //---------------------------------------------------------------------------
360     //! @brief        パラメータの要素数を取得します。
361     //---------------------------------------------------------------------------
362     s32 GetParameterLength()
363     {
364         switch (GetParameter().GetUniformType())
365         {
366         case ResShaderParameterValue::TYPE_BOOL1:
367             return 1;
368 
369         case ResShaderParameterValue::TYPE_FLOAT1:
370             return 1;
371 
372         case ResShaderParameterValue::TYPE_FLOAT2:
373             return 2;
374 
375         case ResShaderParameterValue::TYPE_FLOAT3:
376             return 3;
377 
378         case ResShaderParameterValue::TYPE_FLOAT4:
379             return 4;
380 
381         default:
382             NW_FATAL_ERROR("Unsupported ShaderParameterValue type.");
383             return 0;
384         }
385     }
386 };
387 
388 typedef nw::ut::ResArrayClass<ResShaderParameter>::type  ResShaderParameterArray;
389 typedef nw::ut::ResArrayClass<const ResShaderParameter>::type  ResShaderParameterArrayConst;
390 
391 
392 //--------------------------------------------------------------------------
393 //! @brief  シェーダシンボルを表すバイナリリソースクラスです。
394 //---------------------------------------------------------------------------
395 class ResShaderSymbol : public nw::ut::ResCommon< ResShaderSymbolData >
396 {
397 public:
398     NW_RES_CTOR( ResShaderSymbol )
399 
400     //---------------------------------------------------------------------------
401     //! @fn           void SetLocation(s32 value)
402     //! @brief        シェーダユニフォームのロケーションを設定します。
403     //---------------------------------------------------------------------------
404     //---------------------------------------------------------------------------
405     //! @fn           void SetGeometryUniform(bool value)
406     //! @brief        ジオメトリシェーダのパラメータかどうかのフラグを設定します。
407     //---------------------------------------------------------------------------
408     //---------------------------------------------------------------------------
409     //! @fn           void SetEnabled(bool value)
410     //! @brief        シェーダシンボルの有効フラグを設定します。
411     //---------------------------------------------------------------------------
412     //---------------------------------------------------------------------------
413     //! @fn           bool IsGeometryUniform() const
414     //! @brief        ジオメトリシェーダのパラメータかどうかのフラグを取得します。
415     //---------------------------------------------------------------------------
416     //---------------------------------------------------------------------------
417     //! @fn           bool IsEnabled() const
418     //! @brief        シェーダシンボルの有効フラグを取得します。
419     //---------------------------------------------------------------------------
420     //---------------------------------------------------------------------------
421     //! @fn           const char * GetName() const
422     //! @brief        シェーダシンボルの名前を取得します。
423     //---------------------------------------------------------------------------
424     //---------------------------------------------------------------------------
425     //! @fn           s32 GetLocation() const
426     //! @brief        シェーダユニフォームのロケーションを取得します。
427     //---------------------------------------------------------------------------
428     //---------------------------------------------------------------------------
429     //! @fn           ResShaderParameterValueData & GetDefaultValueData()
430     //! @brief        初期値を取得します。
431     //---------------------------------------------------------------------------
432     //---------------------------------------------------------------------------
433     //! @fn           ResShaderParameterValue GetDefaultValue()
434     //! @brief        初期値を取得します。
435     //---------------------------------------------------------------------------
436     NW_RES_FIELD_STRING_DECL( Name )             // GetName()
437     NW_RES_FIELD_BOOL_PRIMITIVE_DECL( Enabled )  // IsEnabled(), SetEnabled()
438     NW_RES_FIELD_RESSTRUCT_DECL( ResShaderParameterValue, DefaultValue ) // GetDefaultValue()
439     NW_RES_FIELD_BOOL_PRIMITIVE_DECL( GeometryUniform ) // IsGeometryUniform(), SetGeometryUniform()
440     NW_RES_FIELD_PRIMITIVE_DECL( s32, Location) // GetLocation(), SetLocation()
441 };
442 
443 //--------------------------------------------------------------------------
444 //! @brief  シェーダープログラムの詳細設定を表すバイナリリソースクラスです。
445 //---------------------------------------------------------------------------
446 class ResShaderProgramDescription : public nw::ut::ResCommon< ResShaderProgramDescriptionData >
447 {
448 public:
449 
450     //! @brief   シェーダプログラムリソースのフラグ定義です。
451     enum Flag
452     {
453         FLAG_IS_SUPPORTING_RIGID_SKINNING      = 0x1 << 0,      //!< リジッドスキニングがサポートされているかのフラグです。
454         FLAG_IS_SUPPORTING_SMOOTH_SKINNING     = 0x1 << 1,      //!< スムーススキニングがサポートされているかのフラグです。
455         FLAG_IS_SUPPORTING_HEMISPHERE_LIGHTING = 0x1 << 2,      //!< 半球ライティングをサポートしているかのフラグです。
456         FLAG_IS_SUPPORTING_VERTEX_MORPH_SHADER = 0x1 << 3       //!< 頂点モーフィングをサポートしているかのフラグです。
457     };
458 
459     NW_RES_CTOR( ResShaderProgramDescription )
460 
461     //---------------------------------------------------------------------------
462     //! @fn           u32 GetFlags() const
463     //! @brief        フラグの値を取得します。
464     //---------------------------------------------------------------------------
465     //---------------------------------------------------------------------------
466     //! @fn           void SetFlags(u32 value)
467     //! @brief        フラグの値を設定します。
468     //!               設定されなかったフラグは無効になります。
469     //---------------------------------------------------------------------------
470     //---------------------------------------------------------------------------
471     //! @fn           void EnableFlags(u32 value)
472     //! @brief        指定された Flag の値を有効にします。
473     //!               設定されなかったフラグは変更されません。
474     //---------------------------------------------------------------------------
475     //---------------------------------------------------------------------------
476     //! @fn           void DisableFlags(u32 value)
477     //! @brief        指定された Flag の値を無効にします。
478     //!               設定されなかったフラグは変更されません。
479     //---------------------------------------------------------------------------
NW_RES_FIELD_FLAGS_DECL(u32,Flags)480     NW_RES_FIELD_FLAGS_DECL( u32, Flags )               // GetFlags(), SetFlags(), EnableFlags(), DisableFlags()
481 
482     //---------------------------------------------------------------------------
483     //! @fn           u32 GetVertexShaderObject() const
484     //! @brief        頂点シェーダオブジェクトを取得します。
485     //---------------------------------------------------------------------------
486     //---------------------------------------------------------------------------
487     //! @fn           void SetVertexShaderObject(u32 value)
488     //! @brief        頂点シェーダオブジェクトを設定します。
489     //---------------------------------------------------------------------------
490     NW_RES_FIELD_PRIMITIVE_DECL( u32, VertexShaderObject )          // GetVertexShaderObject(), SetVertexShaderObject()
491 
492     //---------------------------------------------------------------------------
493     //! @fn           u32 GetGeometryShaderObject() const
494     //! @brief        ジオメトリシェーダオブジェクトを取得します。
495     //---------------------------------------------------------------------------
496     //---------------------------------------------------------------------------
497     //! @fn           void SetGeometryShaderObject(u32 value)
498     //! @brief        ジオメトリシェーダオブジェクトを設定します。
499     //---------------------------------------------------------------------------
500     NW_RES_FIELD_PRIMITIVE_DECL( u32, GeometryShaderObject )        // GetGeometryShaderObject(), SetGeometryShaderObject()
501 
502     //---------------------------------------------------------------------------
503     //! @fn           s32 GetVertexShaderIndex() const
504     //! @brief        シェーダバイナリ中の頂点シェーダのインデクスを取得します。
505     //---------------------------------------------------------------------------
506     //---------------------------------------------------------------------------
507     //! @fn           void SetVertexShaderIndex(s32 value)
508     //! @brief        シェーダバイナリ中の頂点シェーダのインデクスを設定します。
509     //---------------------------------------------------------------------------
510     NW_RES_FIELD_PRIMITIVE_DECL( s32, VertexShaderIndex )           // GetVertexShaderIndex(), SetVertexShaderIndex()
511 
512     //---------------------------------------------------------------------------
513     //! @fn           s32 GetGeometryShaderIndex() const
514     //! @brief        シェーダバイナリ中のジオメトリシェーダのインデクスを取得します。
515     //---------------------------------------------------------------------------
516     //---------------------------------------------------------------------------
517     //! @fn           void SetGeometryShaderIndex(s32 value)
518     //! @brief        シェーダバイナリ中のジオメトリシェーダのインデクスを設定します。
519     //---------------------------------------------------------------------------
520     NW_RES_FIELD_PRIMITIVE_DECL( s32, GeometryShaderIndex )         // GetGeometryShaderIndex(), SetGeometryShaderIndex()
521 
522     //---------------------------------------------------------------------------
523     //! @fn           s32 GetSymbolsCount() const
524     //! @brief        シンボルの要素数を取得します。
525     //---------------------------------------------------------------------------
526     //---------------------------------------------------------------------------
527     //! @fn           ResShaderSymbol GetSymbols(int idx)
528     //! @brief        シンボルを取得します。
529     //---------------------------------------------------------------------------
530     NW_RES_FIELD_CLASS_LIST_DECL( ResShaderSymbol, Symbols )        // GetSymbols(int idx), GetSymbolsCount()
531 
532     //---------------------------------------------------------------------------
533     //! @fn           s32 GetAttributeSymbolsCount() const
534     //! @brief        頂点属性のシンボル名の要素数を取得します。
535     //---------------------------------------------------------------------------
536     //---------------------------------------------------------------------------
537     //! @fn           const char * GetAttributeSymbols(int idx) const
538     //! @brief        頂点属性のシンボル名を取得します。
539     //---------------------------------------------------------------------------
540     NW_RES_FIELD_STRING_FIXED_LIST_DECL( AttributeSymbols )         // GetAttributeSymbols(int idx), GetAttributeSymbolsCount()
541 
542     //---------------------------------------------------------------------------
543     //! @fn           s32 GetAttributeIndicesCount() const
544     //! @brief        頂点属性のインデックスの要素数を取得します。
545     //---------------------------------------------------------------------------
546     //---------------------------------------------------------------------------
547     //! @fn           s8 GetAttributeIndices(int idx) const
548     //! @brief        頂点属性のインデックスを取得します。
549     //---------------------------------------------------------------------------
550     //---------------------------------------------------------------------------
551     //! @fn           void SetAttributeIndices(int idx, s8 value)
552     //! @brief        頂点属性のインデックスのリストに要素を設定します。
553     //---------------------------------------------------------------------------
554     NW_RES_FIELD_PRIMITIVE_FIXED_LIST_DECL( s8, AttributeIndices )  // GetAttributeIndices(int idx), GetAttributeIndices(), GetAttributeIndicesCount(), SetAttributeIndices(int,s8)
555 
556     //---------------------------------------------------------------------------
557     //! @fn           s32 GetMaxBoneCount() const
558     //! @brief        一度に設定できるマトリックスパレットの最大値を取得します。
559     //---------------------------------------------------------------------------
560     //---------------------------------------------------------------------------
561     //! @fn           void SetMaxBoneCount(s32 value)
562     //! @brief        一度に設定できるマトリックスパレットの最大値を設定します。
563     //---------------------------------------------------------------------------
564     NW_RES_FIELD_PRIMITIVE_DECL( s32, MaxBoneCount )                // GetMaxBoneCount(), SetMaxBoneCount()
565 
566     //---------------------------------------------------------------------------
567     //! @fn           s32 GetMaxVertexLightCount() const
568     //! @brief        処理可能な頂点ライト数の最大値を取得します。
569     //---------------------------------------------------------------------------
570     //---------------------------------------------------------------------------
571     //! @fn           void SetMaxVertexLightCount(s32 value)
572     //! @brief        処理可能な頂点ライト数の最大値を設定します。
573     //---------------------------------------------------------------------------
574     NW_RES_FIELD_PRIMITIVE_DECL( s32, MaxVertexLightCount )         // GetMaxVertexLightCount(), SetMaxVertexLightCount()
575 
576     //---------------------------------------------------------------------------
577     //! @fn           s32 GetVertexLightEndUniform() const
578     //! @brief        頂点ライトの終了ユニフォームを取得します。
579     //---------------------------------------------------------------------------
580     //---------------------------------------------------------------------------
581     //! @fn           void SetVertexLightEndUniform(s32 value)
582     //! @brief        頂点ライトの終了ユニフォームを設定します。
583     //---------------------------------------------------------------------------
584     NW_RES_FIELD_PRIMITIVE_DECL( s32, VertexLightEndUniform )       // GetVertexLightEndUniform(), SetVertexLightEndUniform()
585 
586     //---------------------------------------------------------------------------
587     //! @fn           s32 GetGeometryShaderMode() const
588     //! @brief        ジオメトリシェーダのモードを取得します。
589     //---------------------------------------------------------------------------
590     //---------------------------------------------------------------------------
591     //! @fn           void SetGeometryShaderMode(s32 value)
592     //! @brief        ジオメトリシェーダのモードを設定します。
593     //---------------------------------------------------------------------------
594     NW_RES_FIELD_PRIMITIVE_DECL( s32, GeometryShaderMode )          // GetGeometryShaderMode(), SetGeometryShaderMode()
595 
596     //---------------------------------------------------------------------------
597     //! @fn           u32 GetProgramObject() const
598     //! @brief        プログラムオブジェクトを取得します。
599     //---------------------------------------------------------------------------
600     //---------------------------------------------------------------------------
601     //! @fn           void SetProgramObject(u32 value)
602     //! @brief        プログラムオブジェクトを設定します。
603     //---------------------------------------------------------------------------
604     NW_RES_FIELD_PRIMITIVE_DECL( u32, ProgramObject )               // GetProgramObject(), SetProgramObject()
605 
606 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
607     //---------------------------------------------------------------------------
608     //! @fn           void * GetUniformLocation()
609     //! @brief        ユニフォームのロケーションを取得します。
610     //---------------------------------------------------------------------------
611     //---------------------------------------------------------------------------
612     //! @fn           void SetUniformLocation(void * uniformLocation)
613     //! @brief        ユニフォームのロケーションを設定します。
614     //---------------------------------------------------------------------------
615     void*       GetUniformLocation() { return ref().m_UniformLocation; }
GetUniformLocation()616     const void* GetUniformLocation() const { return ref().m_UniformLocation; }
SetUniformLocation(void * uniformLocation)617     void        SetUniformLocation(void* uniformLocation) { ref().m_UniformLocation = uniformLocation; }
618 #endif
619 
620     //---------------------------------------------------------------------------
621     //! @brief        このシェーダプログラムを所有するシェーダバイナリを取得します。
622     //!
623     //! @return       シェーダバイナリへのポインタです。
624     //---------------------------------------------------------------------------
GetOwnerShaderData()625     ResBinaryShaderData* GetOwnerShaderData()
626     {
627         return static_cast<ResBinaryShaderData*>( ref().toOwnerShader.to_ptr() );
628     }
629 
630     //---------------------------------------------------------------------------
631     //! @brief        このシェーダプログラムを所有するシェーダバイナリを取得します。
632     //!
633     //! @return       シェーダバイナリへのポインタです。
634     //---------------------------------------------------------------------------
GetOwnerShaderData()635     const ResBinaryShaderData* GetOwnerShaderData() const
636     {
637         return static_cast<const ResBinaryShaderData*>( ref().toOwnerShader.to_ptr() );
638     }
639 
640     //---------------------------------------------------------------------------
641     //! @brief        シェーダバイナリ解析情報クラスを取得します。
642     //!
643     //! @return       シェーダバイナリ解析情報クラスへのポインタです。
644     //---------------------------------------------------------------------------
GetShaderBinaryInfo()645     const ShaderBinaryInfo* GetShaderBinaryInfo() const
646     {
647         return static_cast<const ShaderBinaryInfo*>( this->GetOwnerShaderData()->m_ShaderBinaryInfo );
648     }
649 
650     //---------------------------------------------------------------------------
651     //! @brief        頂点シェーダのユニフォームインデックスを取得します。
652     //!
653     //! @param[in]    name          ユニフォーム名です。
654     //! @param[out]   pSymbolType   ユニフォームのタイプ取得用の領域です。
655     //!
656     //! @return       シェーダユニフォームレジスタのインデックスを返します。
657     //!               見つからなかった場合には -1 を返します。
658     //---------------------------------------------------------------------------
659     s32 GetVertexUniformIndex( const char* name, ShaderBinaryInfo::SymbolType* pSymbolType ) const;
660 
661     //---------------------------------------------------------------------------
662     //! @brief        ジオメトリシェーダのユニフォームインデックスを取得します。
663     //!
664     //! @param[in]    name          ユニフォーム名です。
665     //! @param[out]   pSymbolType   ユニフォームのタイプ取得用の領域です。
666     //!
667     //! @return       シェーダユニフォームレジスタのインデックスを返します。
668     //!               見つからなかった場合には -1 を返します。
669     //---------------------------------------------------------------------------
670     s32 GetGeometryUniformIndex( const char* name, ShaderBinaryInfo::SymbolType* pSymbolType ) const;
671 
672     //---------------------------------------------------------------------------
673     //! @brief        リソースの初期化処理をおこないます。
674     //!
675     //! @param[in]    allocator アロケータです。
676     //---------------------------------------------------------------------------
677     Result Setup(os::IAllocator* allocator);
678 
679     //---------------------------------------------------------------------------
680     //! @brief        リソースの後始末をおこないます。
681     //---------------------------------------------------------------------------
682     void Cleanup();
683 
684 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
685 private:
686     GLuint CreateProgramObject();
687     void AttachProgram(GLuint programObject);
688     void LinkProgram(GLuint programObject);
689 #endif
690 };
691 
692 //--------------------------------------------------------------------------
693 //! @brief  シェーダを表すバイナリリソースの基底クラスです。
694 //---------------------------------------------------------------------------
695 class ResShader : public ResSceneObject
696 {
697 public:
698     enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResShader) };
699     enum { SIGNATURE = NW_RES_SIGNATURE32('SHDR') };
700     enum { BINARY_REVISION = REVISION_RES_SHADER };
701 
NW_RES_CTOR_INHERIT(ResShader,ResSceneObject)702     NW_RES_CTOR_INHERIT( ResShader, ResSceneObject )
703 
704     //---------------------------------------------------------------------------
705     //! @brief        リビジョンを取得します。
706     //!
707     //! @return       リソースのリビジョン情報です。
708     //---------------------------------------------------------------------------
709     u32 GetRevision() const { return this->GetHeader().revision; }
710 
711     //---------------------------------------------------------------------------
712     //! @brief        リソースの初期化処理をおこないます。
713     //!
714     //! @param[in]    allocator アロケータです。
715     //! @param[in]    graphicsFile グラフィックスリソースです。
716     //---------------------------------------------------------------------------
717     Result Setup(os::IAllocator* allocator, ResGraphicsFile graphicsFile);
718     Result Setup(os::IAllocator* allocator);
719 
720     //---------------------------------------------------------------------------
721     //! @brief        リソースの後始末をおこないます。
722     //---------------------------------------------------------------------------
723     void Cleanup();
724 
725     //---------------------------------------------------------------------------
726     //! @brief        参照を解決し、ResBinaryShader を取得します。
727     //---------------------------------------------------------------------------
728     ResBinaryShader        Dereference();
729 
730     //---------------------------------------------------------------------------
731     //! @brief        参照を解決し、const ResBinaryShader を取得します。
732     //---------------------------------------------------------------------------
733     const ResBinaryShader  Dereference() const;
734 };
735 
736 
737 //--------------------------------------------------------------------------
738 //! @brief シェーダバイナリを表すバイナリリソースクラスです。
739 //---------------------------------------------------------------------------
740 class ResBinaryShader : public ResShader
741 {
742 public:
743     enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResBinaryShader) };
744     enum { SIGNATURE = NW_RES_SIGNATURE32('BSHD') };
745 
NW_RES_CTOR_INHERIT(ResBinaryShader,ResShader)746     NW_RES_CTOR_INHERIT( ResBinaryShader, ResShader )
747 
748     //---------------------------------------------------------------------------
749     //! @fn           s32 GetBinaryDataCount() const
750     //! @brief        シェーダバイナリデータの要素数を取得します。
751     //---------------------------------------------------------------------------
752     //---------------------------------------------------------------------------
753     //! @fn           u8 GetBinaryData(int idx) const
754     //! @brief        シェーダバイナリデータを取得します。
755     //---------------------------------------------------------------------------
756     //---------------------------------------------------------------------------
757     //! @fn           void SetBinaryData(int idx, u8 value)
758     //! @brief        シェーダバイナリデータのリストに要素を設定します。
759     //---------------------------------------------------------------------------
760     NW_RES_FIELD_PRIMITIVE_LIST_DECL( u8, BinaryData )         // GetBinaryData(), GetBinaryData(int idx), GetBinaryDataCount()
761 
762     //---------------------------------------------------------------------------
763     //! @fn           s32 GetShaderKindsCount() const
764     //! @brief        格納されているシェーダーの種類の要素数を取得します。
765     //---------------------------------------------------------------------------
766     //---------------------------------------------------------------------------
767     //! @fn           u32 GetShaderKinds(int idx) const
768     //! @brief        格納されているシェーダーの種類を取得します。
769     //---------------------------------------------------------------------------
770     //---------------------------------------------------------------------------
771     //! @fn           void SetShaderKinds(int idx, u32 value)
772     //! @brief        格納されているシェーダーの種類のリストに要素を設定します。
773     //---------------------------------------------------------------------------
774     NW_RES_FIELD_PRIMITIVE_LIST_DECL( u32, ShaderKinds )       // GetShaderKinds(), GetShaderKinds(int idx), GetShaderKindsCount()
775 
776     //---------------------------------------------------------------------------
777     //! @fn           s32 GetDescriptionsCount() const
778     //! @brief        シェーダープログラムの設定の要素数を取得します。
779     //---------------------------------------------------------------------------
780     //---------------------------------------------------------------------------
781     //! @fn           ResShaderProgramDescription GetDescriptions(int idx)
782     //! @brief        シェーダープログラムの設定を取得します。
783     //---------------------------------------------------------------------------
784     NW_RES_FIELD_CLASS_LIST_DECL( ResShaderProgramDescription, Descriptions ) // GetDescriptions(int idx), GetDescriptionsCount()
785 
786     //---------------------------------------------------------------------------
787     //! @fn           void SetShaderObjects(int idx, u32 value)
788     //! @brief        シェーダオブジェクトのリストに要素を設定します。
789     //---------------------------------------------------------------------------
790     //---------------------------------------------------------------------------
791     //! @fn           s32 GetShaderObjectsCount() const
792     //! @brief        シェーダオブジェクトの要素数を取得します。
793     //---------------------------------------------------------------------------
794     //---------------------------------------------------------------------------
795     //! @fn           u32 GetShaderObjects(int idx) const
796     //! @brief        シェーダオブジェクトを取得します。
797     //---------------------------------------------------------------------------
798     NW_RES_FIELD_PRIMITIVE_LIST_DECL( u32, ShaderObjects )     // GetShaderObjects(), GetShaderObjects(int idx), GetShaderObjectsCount()
799 
800     //---------------------------------------------------------------------------
801     //! @brief        シェーダバイナリ設定用の GPU コマンドです。
802     //!
803     //! @return       GPU コマンドへのポインタです。
804     //---------------------------------------------------------------------------
805     const void* GetCommandCache() const { return ref().m_CommandCache; }
806 
807     //---------------------------------------------------------------------------
808     //! @brief        シェーダバイナリ設定用の GPU コマンドのサイズです。
809     //!
810     //! @return       GPU コマンドのサイズを返します。
811     //---------------------------------------------------------------------------
GetCommandCacheSize()812     int GetCommandCacheSize() const { return ref().m_CommandCacheSize; }
813 
814     //---------------------------------------------------------------------------
815     //! @brief        シェーダバイナリ解析情報クラスを取得します。
816     //!
817     //! @return       シェーダバイナリ解析情報クラスへのポインタです。
818     //---------------------------------------------------------------------------
GetShaderBinaryInfo()819     ShaderBinaryInfo* GetShaderBinaryInfo()
820     {
821         return static_cast<ShaderBinaryInfo*>( ref().m_ShaderBinaryInfo );
822     }
823 
824     //---------------------------------------------------------------------------
825     //! @brief        シェーダバイナリ情報へのアクセサを取得します。
826     //!
827     //! @return       シェーダバイナリへのアクセサクラスへのポインタです。
828     //---------------------------------------------------------------------------
GetShaderBinaryInfo()829     const ShaderBinaryInfo* GetShaderBinaryInfo() const
830     {
831         return static_cast<const ShaderBinaryInfo*>( ref().m_ShaderBinaryInfo );
832     }
833 };
834 
835 //--------------------------------------------------------------------------
836 //! @brief シェーダの外部参照を表すバイナリリソースクラスです。
837 //---------------------------------------------------------------------------
838 class ResReferenceShader : public ResShader
839 {
840 public:
841     enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResReferenceShader) };
842     enum { SIGNATURE = NW_RES_SIGNATURE32('SDRF') };
843 
844     NW_RES_CTOR_INHERIT( ResReferenceShader, ResShader )
845 
846     //---------------------------------------------------------------------------
847     //! @fn           ResShader GetTargetShader()
848     //! @brief        参照解決後のシェーダデータを取得します。
849     //---------------------------------------------------------------------------
850     //---------------------------------------------------------------------------
851     //! @fn           const char * GetPath() const
852     //! @brief        参照するシェーダのパスを取得します。
853     //---------------------------------------------------------------------------
854     NW_RES_FIELD_STRING_DECL( Path )                     // GetPath()
855     NW_RES_FIELD_CLASS_DECL( ResShader, TargetShader )   // GetTargetShader()
856 };
857 
858 } // namespace res
859 } // namespace gfx
860 } // namespace nw
861 
862 #endif // NW_GFX_RESSHADER_H_
863