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