1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ShaderProgram.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: 26189 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NW_GFX_SHADERPROGRAM_H_
17 #define NW_GFX_SHADERPROGRAM_H_
18 
19 #include <nw/gfx/gfx_GfxObject.h>
20 #include <nw/gfx/gfx_ShaderUniforms.h>
21 #include <nw/gfx/res/gfx_ResShader.h>
22 #include <nw/gfx/res/gfx_ResVertex.h>
23 
24 #include <nw/ut/ut_MoveArray.h>
25 
26 #include <nw/types.h>
27 #include <nw/gfx/gfx_CommandUtil.h>
28 #include <nw/gfx/gfx_ActivateCommand.h>
29 #include <nw/gfx/gfx_Config.h>
30 
31 namespace nw
32 {
33 namespace gfx
34 {
35 
36 class RenderContext;
37 
38 //! ジオメトリシェーダのモードを表す定義です。
39 enum GeometryShaderMode
40 {
41     //! ジオメトリシェーダが未初期化の状態です。
42     GEOMETRY_SHADER_MODE_UNINITIALIZED,
43     //! ジオメトリシェーダを利用しません。
44     GEOMETRY_SHADER_MODE_NONE,
45     //! ジオメトリシェーダを利用します。
46     GEOMETRY_SHADER_MODE_USED,
47     //! ジオメトリシェーダのモードの定義の数です。
48     GEOMETRY_SHADER_MODE_COUNT
49 };
50 
51 //---------------------------------------------------------------------------
52 //! @brief        各種シェーダを組み合わせてリンクした実行可能なシェーダです。
53 //---------------------------------------------------------------------------
54 class ShaderProgram : public GfxObject
55 {
56 public:
57     //----------------------------------------
58     //! @name 取得/設定
59     //@{
60 
61     //! @brief 詳細設定を有効化します。
62     //!
63     //! @param[in] shaderProgramDescription シェーダプログラムの詳細設定です。
64     //!
65     void ActivateDescription(ResShaderProgramDescription shaderProgramDescription);
66 
67     //! @brief ジオメトリシェーダのモードの設定をします。
68     //!
69     //! @param[in] useGeometry ジオメトリシェーダの有無です。
70     //!
71     void ActivateShaderProgramMode(bool useGeometry);
72 
73     //! @brief 詳細設定を無効化します。
DeactivateDescription()74     void DeactivateDescription()
75     {
76         // ジオメトリシェーダのモード設定をリセットします。
77         m_GeometryShaderMode = GEOMETRY_SHADER_MODE_UNINITIALIZED;
78 
79 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
80         m_UniformLocation = NULL;
81 #endif
82         m_ProgramObject = 0;
83         m_Description = ResShaderProgramDescription( 0 );
84     }
85 
86     //! @brief リソースを取得します。
87     //!
88     //! @return シェーダプログラムの詳細設定です。
89     //!
GetActiveDescription()90     const ResShaderProgramDescription GetActiveDescription() const { return m_Description; }
91 
92 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
93     //! @brief プログラムオブジェクトを取得します。
94     //!
95     //! @return プログラムオブジェクトです。
96     //!
GetProgramObject()97     GLuint GetProgramObject() const { return m_ProgramObject; }
98 #endif
99 
100     //! @brief パーティクル用のシェーダか調べます。
101     //!
102     //! @return パーティクル用のシェーダの場合はtrueを返します。
103     //!
IsParticleShader()104     bool IsParticleShader() const
105     {
106         return m_Description.GetGeometryShaderIndex() > 0;
107     }
108 
109     //@}
110 
111     //----------------------------------------
112     //! @name 頂点属性
113     //@{
114 
115 
116     //---------------------------------------------------------------------------
117     //! @brief        頂点属性のインデックスを取得します。
118     //!
119     //! 無効な頂点属性の場合は-1を返します。
120     //!
121     //! @param[in]    usage 頂点属性のUsageです。
122     //!
123     //! @return       頂点属性のインデックスです。
124     //---------------------------------------------------------------------------
125     NW_INLINE int GetVertexAttributeIndex(
126         ResVertexAttribute::VertexAttributeUsage usage) const;
127 
128     //---------------------------------------------------------------------------
129     //! @brief        頂点属性のインデックスを取得します。
130     //!
131     //! @param[in]    usage 頂点属性のUsageです。
132     //!
133     //! @return       頂点属性のインデックスです。
134     //---------------------------------------------------------------------------
GetVertexAttributeIndex(u32 usage)135     int GetVertexAttributeIndex(u32 usage) const
136     {
137         return GetVertexAttributeIndex(
138             static_cast<ResVertexAttribute::VertexAttributeUsage>(usage));
139     }
140 
141     //@}
142 
143     //----------------------------------------
144     //! @name シェーダー定数
145     //@{
146 
147     //! @brief プロジェクションマトリクスを設定します。
148     //!
149     //! @param[in] projection プロジェクションマトリクスです。
150     //!
SetProjection(const math::MTX44 & projection)151     void SetProjection(const math::MTX44& projection) const
152     {
153         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_PROJMTX_INDEX, 4, projection);
154     }
155 
156     //! @brief ビューマトリクスを設定します。
157     //!
158     //! @param[in] view ビューマトリクスです。
159     //!
SetViewMatrix(const math::MTX34 & view)160     void SetViewMatrix(const math::MTX34& view) const
161     {
162         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_VIEWMTX_INDEX, 3, view);
163     }
164 
165     //! @brief ワールドマトリクスを設定します。
166     //!
167     //! @param[in] world ワールドマトリクスです。
168     //!
SetWorldMatrix(const math::MTX34 & world)169     void SetWorldMatrix(const math::MTX34& world) const
170     {
171         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_WRLDMTX_INDEX, 3, world);
172     }
173 
174     //! @brief モデル法線マトリクスを設定します。
175     //!
176     //! @param[in] normalMatrix モデル法線マトリクスです。
177     //!
SetModelNormalMatrix(const math::MTX34 & normalMatrix)178     void SetModelNormalMatrix(const math::MTX34& normalMatrix) const
179     {
180         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_NORMMTX_INDEX, 3, normalMatrix);
181     }
182 
183     //! @brief ボーンで法線マトリクスを使うフラグを設定します。
184     //!
185     //! @param[in] use ボーンで法線マトリクスを使うフラグです。
186     //!
SetUseBoneNormalMatrix(bool use)187     void SetUseBoneNormalMatrix(bool use) const
188     {
189         SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(USENORM), use);
190     }
191 
192     //! @brief ユニバーサルレジスタに値を設定します。
193     //!
194     //! @param[in] index ユニバーサルレジスタでのインデックスです。
195     //! @param[in] vec   設定する値です。
196     //!
SetUniversal(int index,const math::VEC4 & vec)197     void SetUniversal(int index, const math::VEC4& vec) const
198     {
199         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_UNIVREG_INDEX + index, 1, vec);
200     }
201 
202     //! @brief ユニバーサルレジスタに値を設定します。
203     //!
204     //! @param[in] index ユニバーサルレジスタでのインデックスです。
205     //! @param[in] mtx   設定する値です。
206     //!
SetUniversal(int index,const math::MTX34 & mtx)207     void SetUniversal(int index, const math::MTX34& mtx) const
208     {
209         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_UNIVREG_INDEX + index, 3, mtx);
210     }
211 
212     //! @brief ユニバーサルレジスタに値を設定します。
213     //!
214     //! @param[in] index ユニバーサルレジスタでのインデックスです。
215     //! @param[in] mtx   設定する値です。
216     //!
SetUniversal(int index,const math::MTX44 & mtx)217     void SetUniversal(int index, const math::MTX44& mtx) const
218     {
219         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_UNIVREG_INDEX + index, 4, mtx);
220     }
221 
222 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
223     //! @brief boolの値を設定します。
224     //!
225     //! @param[in] location シェーダーユニフォームのインデックス番号です。
226     //! @param[in] value 設定する値です。
227     //!
SetUniformBool(ShaderUniform location,bool value)228     void SetUniformBool(ShaderUniform location, bool value) const { glUniform1i(m_UniformLocation->GetUniformLocation(location), value ? 1 : 0); }
229 
230     //! @brief f32の値を設定します。
231     //!
232     //! @param[in] location シェーダーユニフォームのインデックス番号です。
233     //! @param[in] value 設定する値です。
234     //!
SetUniformFloat(ShaderUniform location,f32 value)235     void SetUniformFloat(ShaderUniform location, f32 value) const { glUniform1f(m_UniformLocation->GetUniformLocation(location), value); }
236 
237     //! @brief s32の値を設定します。
238     //!
239     //! @param[in] location シェーダーユニフォームのインデックス番号です。
240     //! @param[in] value 設定する値です。
241     //!
SetUniformInt(ShaderUniform location,s32 value)242     void SetUniformInt(ShaderUniform location, s32 value) const { glUniform1i(m_UniformLocation->GetUniformLocation(location), value); }
243 
244     //! @brief s32の値を設定します。
245     //!
246     //! @param[in] location シェーダーユニフォームのインデックス番号です。
247     //! @param[in] x 設定する値です。
248     //! @param[in] y 設定する値です。
249     //!
SetUniformInt(ShaderUniform location,s32 x,s32 y)250     void SetUniformInt(ShaderUniform location, s32 x, s32 y) const { glUniform2i(m_UniformLocation->GetUniformLocation(location), x, y); }
251 
252     //! @brief s32の値を設定します。
253     //!
254     //! @param[in] location シェーダーユニフォームのインデックス番号です。
255     //! @param[in] x 設定する値です。
256     //! @param[in] y 設定する値です。
257     //! @param[in] z 設定する値です。
258     //!
SetUniformInt(ShaderUniform location,s32 x,s32 y,s32 z)259     void SetUniformInt(ShaderUniform location, s32 x, s32 y, s32 z) const { glUniform3i(m_UniformLocation->GetUniformLocation(location), x, y, z); }
260 
261     //! @brief s32の値を設定します。
262     //!
263     //! @param[in] location シェーダーユニフォームのインデックス番号です。
264     //! @param[in] x 設定する値です。
265     //! @param[in] y 設定する値です。
266     //! @param[in] z 設定する値です。
267     //! @param[in] w 設定する値です。
268     //!
SetUniformInt(ShaderUniform location,s32 x,s32 y,s32 z,s32 w)269     void SetUniformInt(ShaderUniform location, s32 x, s32 y, s32 z, s32 w) const { glUniform4i(m_UniformLocation->GetUniformLocation(location), x, y, z, w); }
270 
271     //! @brief 2要素のfloatの配列を設定します。
272     //!
273     //! @param[in] location シェーダーユニフォームのインデックス番号です。
274     //! @param[in] pointer 設定する配列です。
275     //!
SetUniform2(ShaderUniform location,const GLfloat * pointer)276     void SetUniform2(ShaderUniform location, const GLfloat* pointer) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), 1, pointer); }
277 
278     //! @brief 3要素のfloatの配列を設定します。
279     //!
280     //! @param[in] location シェーダーユニフォームのインデックス番号です。
281     //! @param[in] pointer 設定する配列です。
282     //!
SetUniform3(ShaderUniform location,const GLfloat * pointer)283     void SetUniform3(ShaderUniform location, const GLfloat* pointer) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), 1, pointer); }
284 
285     //! @brief 4要素のfloatの配列を設定します。
286     //!
287     //! @param[in] location シェーダーユニフォームのインデックス番号です。
288     //! @param[in] pointer 設定する配列です。
289     //!
SetUniform4(ShaderUniform location,const GLfloat * pointer)290     void SetUniform4(ShaderUniform location, const GLfloat* pointer) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 1, pointer); }
291 
292     //! @brief VectorやMatrixの値を設定します。
293     //!
294     //! @param[in] location シェーダーユニフォームのインデックス番号です。
295     //! @param[in] vec 設定する値です。
296     //!
SetUniform(ShaderUniform location,const math::VEC2 & vec)297     void SetUniform(ShaderUniform location, const math::VEC2& vec) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), 1, vec); }
298 
299     //! @brief VectorやMatrixの値を設定します。
300     //!
301     //! @param[in] location シェーダーユニフォームのインデックス番号です。
302     //! @param[in] vec 設定する値です。
303     //!
SetUniform(ShaderUniform location,const math::VEC3 & vec)304     void SetUniform(ShaderUniform location, const math::VEC3& vec) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), 1, vec); }
305 
306     //! @brief VectorやMatrixの値を設定します。
307     //!
308     //! @param[in] location シェーダーユニフォームのインデックス番号です。
309     //! @param[in] vec 設定する値です。
310     //!
SetUniform(ShaderUniform location,const math::VEC4 & vec)311     void SetUniform(ShaderUniform location, const math::VEC4& vec) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 1, vec); }
312 
313     //! @brief VectorやMatrixの値を設定します。
314     //!
315     //! @param[in] location シェーダーユニフォームのインデックス番号です。
316     //! @param[in] mtx 設定する値です。
317     //!
SetUniform(ShaderUniform location,const math::MTX22 & mtx)318     void SetUniform(ShaderUniform location, const math::MTX22& mtx) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), 2, mtx); }
319 
320     //! @brief VectorやMatrixの値を設定します。
321     //!
322     //! @param[in] location シェーダーユニフォームのインデックス番号です。
323     //! @param[in] mtx 設定する値です。
324     //!
SetUniform(ShaderUniform location,const math::MTX23 & mtx)325     void SetUniform(ShaderUniform location, const math::MTX23& mtx) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), 2, mtx); }
326 
327     //! @brief VectorやMatrixの値を設定します。
328     //!
329     //! @param[in] location シェーダーユニフォームのインデックス番号です。
330     //! @param[in] mtx 設定する値です。
331     //!
SetUniform(ShaderUniform location,const math::MTX34 & mtx)332     void SetUniform(ShaderUniform location, const math::MTX34& mtx) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 3, mtx); }
333 
334     //! @brief VectorやMatrixの値を設定します。
335     //!
336     //! @param[in] location シェーダーユニフォームのインデックス番号です。
337     //! @param[in] mtx 設定する値です。
338     //!
SetUniform(ShaderUniform location,const math::MTX44 & mtx)339     void SetUniform(ShaderUniform location, const math::MTX44& mtx) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 4, mtx); }
340 
341     //! @brief Vectorの配列を設定します。
342     //!
343     //! @param[in] location シェーダーユニフォームのインデックス番号です。
344     //! @param[in] vec 設定する配列です。
345     //! @param[in] count 設定する配列の数です。
346     //!
SetUniforms(ShaderUniform location,const math::VEC2 * vec,int count)347     void SetUniforms(ShaderUniform location, const math::VEC2* vec, int count) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), count, *vec); }
348 
349     //! @brief Vectorの配列を設定します。
350     //!
351     //! @param[in] location シェーダーユニフォームのインデックス番号です。
352     //! @param[in] vec 設定する配列です。
353     //! @param[in] count 設定する配列の数です。
354     //!
SetUniforms(ShaderUniform location,const math::VEC3 * vec,int count)355     void SetUniforms(ShaderUniform location, const math::VEC3* vec, int count) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), count, *vec); }
356 
357     //! @brief Vectorの配列を設定します。
358     //!
359     //! @param[in] location シェーダーユニフォームのインデックス番号です。
360     //! @param[in] vec 設定する配列です。
361     //! @param[in] count 設定する配列の数です。
362     //!
SetUniforms(ShaderUniform location,const math::VEC4 * vec,int count)363     void SetUniforms(ShaderUniform location, const math::VEC4* vec, int count) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), count, *vec); }
364 
365     //! @brief 配列を設定します。
366     //!
367     //! @param[in] location シェーダーユニフォームのインデックス番号です。
368     //! @param[in] array 設定する配列です。
369     //!
370     template<typename TValue>
SetUniforms(ShaderUniform location,const ut::MoveArray<TValue> * array)371     void SetUniforms(ShaderUniform location, const ut::MoveArray<TValue>* array) const
372     {
373         NW_NULL_ASSERT(array);
374         if (array->empty()) { return; }
375 
376         this->SetUniforms(location, array->Elements(), array->size());
377     }
378 
379     //! @brief サイズを指定して配列を設定します。
380     //!
381     //! @param[in] location シェーダーユニフォームのインデックス番号です。
382     //! @param[in] array 設定する配列です。
383     //! @param[in] size 配列の大きさです。
384     //!
385     template<typename TValue>
SetUniforms(ShaderUniform location,const ut::MoveArray<TValue> * array,s32 size)386     void SetUniforms(ShaderUniform location, const ut::MoveArray<TValue>* array, s32 size) const
387     {
388         NW_NULL_ASSERT(array);
389         NW_ASSERT(size <= array->size());
390 
391         this->SetUniforms(location, array->Elements(), size);
392     }
393 
394     //! @brief ユーザーレジスタにパラメータを設定します。
395     //!
396     //! locationにはglGetUniformLocationで取得したGLintの値を渡してください。
397     //!
398     //! @param[in] location シェーダーユニフォームの場所です。
399     //! @param[in] parameter 設定するシェーダーパラメータです。
400     //!
SetUserUniform(GLint location,ResShaderParameterValue parameter)401     void SetUserUniform(GLint location, ResShaderParameterValue parameter) const
402     {
403         if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_BOOL1)
404         {
405             glUniform1iv(location, 1, reinterpret_cast<GLint*>(parameter.GetValueS32()));
406         }
407         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT1)
408         {
409             glUniform1fv(location, 1, parameter.GetValueF32());
410         }
411         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT2)
412         {
413             glUniform2fv(location, 1, parameter.GetValueF32());
414         }
415         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT3)
416         {
417             glUniform3fv(location, 1, parameter.GetValueF32());
418         }
419         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT4)
420         {
421             glUniform4fv(location, 1, parameter.GetValueF32());
422         }
423     }
424 #endif // defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
425 
426     //! @brief ユーザー頂点レジスタにパラメータを設定します。
427     //!
428     //! @param[in] index 頂点シェーダーのレジスタ番号です。
429     //! @param[in] parameter 設定するシェーダーパラメータです。
430     //!
SetUserVertexUniform(s32 index,ResShaderParameterValue parameter)431     void SetUserVertexUniform(s32 index, ResShaderParameterValue parameter) const
432     {
433         if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_BOOL1)
434         {
435             this->SetVertexUniformBool(index, parameter.GetValueBool());
436         }
437         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT1)
438         {
439             internal::NWSetVertexUniform1fv(index, 1, parameter.GetValueF32());
440         }
441         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT2)
442         {
443             internal::NWSetVertexUniform2fv(index, 1, parameter.GetValueF32());
444         }
445         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT3)
446         {
447             internal::NWSetVertexUniform3fv(index, 1, parameter.GetValueF32());
448         }
449         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT4)
450         {
451             internal::NWSetVertexUniform4fv(index, 1, parameter.GetValueF32());
452         }
453     }
454 
455     //! @brief ユーザージオメトリレジスタにパラメータを設定します。
456     //!
457     //! @param[in] index ジオメトリシェーダーのレジスタ番号です。
458     //! @param[in] parameter 設定するシェーダーパラメータです。
459     //!
SetUserGeometryUniform(s32 index,ResShaderParameterValue parameter)460     void SetUserGeometryUniform(s32 index, ResShaderParameterValue parameter) const
461     {
462         if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_BOOL1)
463         {
464             this->SetGeometryUniformBool(index, parameter.GetValueBool());
465         }
466         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT1)
467         {
468             internal::NWSetGeometryUniform1fv(index, 1, parameter.GetValueF32());
469         }
470         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT2)
471         {
472             internal::NWSetGeometryUniform2fv(index, 1, parameter.GetValueF32());
473         }
474         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT3)
475         {
476             internal::NWSetGeometryUniform3fv(index, 1, parameter.GetValueF32());
477         }
478         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT4)
479         {
480             internal::NWSetGeometryUniform4fv(index, 1, parameter.GetValueF32());
481         }
482     }
483 
484     //! @brief boolの値を設定します。
485     //!
486     //! @param[in] index シェーダーユニフォームのインデックス番号です。
487     //! @param[in] value 設定する値です。
488     //!
SetVertexUniformBool(int index,bool value)489     void SetVertexUniformBool(int index, bool value) const
490     {
491         NW_ASSERT(0 <= index && index < 16);
492         if (value)
493         {
494             m_VertexIntUniforms[0] |= 0x1 << index;
495         }
496         else
497         {
498             m_VertexIntUniforms[0] &= ~(0x1 << index);
499         }
500     }
501 
502     //! @brief boolの値を設定します。
503     //!
504     //! @param[in] index シェーダーユニフォームのインデックス番号です。
505     //! @param[in] value 設定する値です。
506     //!
SetGeometryUniformBool(int index,bool value)507     void SetGeometryUniformBool(int index, bool value) const
508     {
509         NW_ASSERT(0 <= index && index < 16);
510         if (value)
511         {
512             m_GeometryIntUniforms[0] |= 0x1 << index;
513         }
514         else
515         {
516             m_GeometryIntUniforms[0] &= ~(0x1 << index);
517         }
518     }
519 
520     //! @brief intの値を設定します。
521     //!
522     //! @param[in] index シェーダーユニフォームのインデックス番号です。
523     //! @param[in] value 設定する値です。
524     //!
SetVertexUniformInt(int index,s32 value)525     void SetVertexUniformInt(int index, s32 value) const
526     {
527         NW_ASSERT(0 <= index && index < 4);
528         m_VertexIntUniforms[2 + index] = value & 0xFF;
529     }
530 
531     //! @brief intの値を設定します。
532     //!
533     //! @param[in] index シェーダーユニフォームのインデックス番号です。
534     //! @param[in] value 設定する値です。
535     //!
SetGeometryUniformInt(int index,s32 value)536     void SetGeometryUniformInt(int index, s32 value) const
537     {
538         NW_ASSERT(0 <= index && index < 4);
539         m_GeometryIntUniforms[2 + index] = value & 0xFF;
540     }
541 
542     //! @brief intの値を設定します。
543     //!
544     //! @param[in] index シェーダーユニフォームのインデックス番号です。
545     //! @param[in] x     設定する x 値です。
546     //! @param[in] y     設定する y 値です。
547     //!
SetVertexUniformInt(int index,s32 x,s32 y)548     void SetVertexUniformInt(int index, s32 x, s32 y) const
549     {
550         NW_ASSERT(0 <= index && index < 4);
551         m_VertexIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8);
552     }
553 
554     //! @brief intの値を設定します。
555     //!
556     //! @param[in] index シェーダーユニフォームのインデックス番号です。
557     //! @param[in] x     設定する x 値です。
558     //! @param[in] y     設定する y 値です。
559     //!
SetGeometryUniformInt(int index,s32 x,s32 y)560     void SetGeometryUniformInt(int index, s32 x, s32 y) const
561     {
562         NW_ASSERT(0 <= index && index < 4);
563         m_GeometryIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8);
564     }
565 
566     //! @brief intの値を設定します。
567     //!
568     //! @param[in] index シェーダーユニフォームのインデックス番号です。
569     //! @param[in] x     設定する x 値です。
570     //! @param[in] y     設定する y 値です。
571     //! @param[in] z     設定する z 値です。
572     //!
SetVertexUniformInt(int index,s32 x,s32 y,s32 z)573     void SetVertexUniformInt(int index, s32 x, s32 y, s32 z) const
574     {
575         NW_ASSERT(0 <= index && index < 4);
576         m_VertexIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8) | ((z & 0xFF) << 16);
577     }
578 
579     //! @brief intの値を設定します。
580     //!
581     //! @param[in] index シェーダーユニフォームのインデックス番号です。
582     //! @param[in] x     設定する x 値です。
583     //! @param[in] y     設定する y 値です。
584     //! @param[in] z     設定する z 値です。
585     //!
SetGeometryUniformInt(int index,s32 x,s32 y,s32 z)586     void SetGeometryUniformInt(int index, s32 x, s32 y, s32 z) const
587     {
588         NW_ASSERT(0 <= index && index < 4);
589         m_GeometryIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8) | ((z & 0xFF) << 16);
590     }
591 
592     //! @brief     VertexUniform と GeometryUniform の状態をコマンドへ Flush します。
FlushUniform()593     void FlushUniform() const
594     {
595         internal::NWUseCmdlist<sizeof(m_VertexIntUniforms)>(&m_VertexIntUniforms[0]);
596         if (m_Description.GetGeometryShaderIndex() >= 0)
597         {
598             internal::NWUseCmdlist<sizeof(m_GeometryIntUniforms)>(&m_GeometryIntUniforms[0]);
599         }
600     }
601     //@}
602 
603     //----------------------------------------
604     //! @name シェーダーシンボル
605     //@{
606 
607     //@}
608 
609     //---------------------------------------------------------------------------
610     //! @brief        コンストラクタです。
611     //---------------------------------------------------------------------------
612     ShaderProgram(os::IAllocator* allocator);
613 
614 private:
615     //---------------------------------------------------------------------------
616     //! @brief        デストラクタです。
617     //---------------------------------------------------------------------------
618     virtual ~ShaderProgram();
619 
620     ResShaderProgramDescription m_Description;
621 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
622     ShaderUniformLocation* m_UniformLocation;
623 #endif
624     GLuint m_ProgramObject;
625 
626     GeometryShaderMode m_GeometryShaderMode;
627 
628     mutable u32 m_VertexIntUniforms[6];
629     mutable u32 m_GeometryIntUniforms[6];
630     mutable u32 m_DisableGeometry[2];
631 };
632 
633 NW_INLINE int
GetVertexAttributeIndex(ResVertexAttribute::VertexAttributeUsage usage)634 ShaderProgram::GetVertexAttributeIndex(
635     ResVertexAttribute::VertexAttributeUsage usage
636 ) const
637 {
638     ResShaderProgramDescription description = this->GetActiveDescription();
639     NW_ASSERT(description.IsValid());
640 
641     return description.GetAttributeIndices(usage);
642 }
643 
644 } // namespace gfx
645 } // namespace nw
646 
647 #endif // NW_GFX_SHADERPROGRAM_H_
648