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