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: 27904 $
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     //!
186     //! @param[in] use ボーンで法線マトリクスを使うフラグです。
187     //!
NW_DEPRECATED_FUNCTION(void SetUseBoneNormalMatrix (bool use)const)188     NW_DEPRECATED_FUNCTION(void SetUseBoneNormalMatrix(bool use) const)
189     {
190         NW_UNUSED_VARIABLE(use);
191     }
192 
193     //! @brief ユニバーサルレジスタに値を設定します。
194     //!
195     //! @param[in] index ユニバーサルレジスタでのインデックスです。
196     //! @param[in] vec   設定する値です。
197     //!
SetUniversal(int index,const math::VEC4 & vec)198     void SetUniversal(int index, const math::VEC4& vec) const
199     {
200         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_UNIVREG_INDEX + index, 1, vec);
201     }
202 
203     //! @brief ユニバーサルレジスタに値を設定します。
204     //!
205     //! @param[in] index ユニバーサルレジスタでのインデックスです。
206     //! @param[in] mtx   設定する値です。
207     //!
SetUniversal(int index,const math::MTX34 & mtx)208     void SetUniversal(int index, const math::MTX34& mtx) const
209     {
210         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_UNIVREG_INDEX + index, 3, mtx);
211     }
212 
213     //! @brief ユニバーサルレジスタに値を設定します。
214     //!
215     //! @param[in] index ユニバーサルレジスタでのインデックスです。
216     //! @param[in] mtx   設定する値です。
217     //!
SetUniversal(int index,const math::MTX44 & mtx)218     void SetUniversal(int index, const math::MTX44& mtx) const
219     {
220         internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_UNIVREG_INDEX + index, 4, mtx);
221     }
222 
223 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
224     //! @brief boolの値を設定します。
225     //!
226     //! @param[in] location シェーダーユニフォームのインデックス番号です。
227     //! @param[in] value 設定する値です。
228     //!
SetUniformBool(ShaderUniform location,bool value)229     void SetUniformBool(ShaderUniform location, bool value) const { glUniform1i(m_UniformLocation->GetUniformLocation(location), value ? 1 : 0); }
230 
231     //! @brief f32の値を設定します。
232     //!
233     //! @param[in] location シェーダーユニフォームのインデックス番号です。
234     //! @param[in] value 設定する値です。
235     //!
SetUniformFloat(ShaderUniform location,f32 value)236     void SetUniformFloat(ShaderUniform location, f32 value) const { glUniform1f(m_UniformLocation->GetUniformLocation(location), value); }
237 
238     //! @brief s32の値を設定します。
239     //!
240     //! @param[in] location シェーダーユニフォームのインデックス番号です。
241     //! @param[in] value 設定する値です。
242     //!
SetUniformInt(ShaderUniform location,s32 value)243     void SetUniformInt(ShaderUniform location, s32 value) const { glUniform1i(m_UniformLocation->GetUniformLocation(location), value); }
244 
245     //! @brief s32の値を設定します。
246     //!
247     //! @param[in] location シェーダーユニフォームのインデックス番号です。
248     //! @param[in] x 設定する値です。
249     //! @param[in] y 設定する値です。
250     //!
SetUniformInt(ShaderUniform location,s32 x,s32 y)251     void SetUniformInt(ShaderUniform location, s32 x, s32 y) const { glUniform2i(m_UniformLocation->GetUniformLocation(location), x, y); }
252 
253     //! @brief s32の値を設定します。
254     //!
255     //! @param[in] location シェーダーユニフォームのインデックス番号です。
256     //! @param[in] x 設定する値です。
257     //! @param[in] y 設定する値です。
258     //! @param[in] z 設定する値です。
259     //!
SetUniformInt(ShaderUniform location,s32 x,s32 y,s32 z)260     void SetUniformInt(ShaderUniform location, s32 x, s32 y, s32 z) const { glUniform3i(m_UniformLocation->GetUniformLocation(location), x, y, z); }
261 
262     //! @brief s32の値を設定します。
263     //!
264     //! @param[in] location シェーダーユニフォームのインデックス番号です。
265     //! @param[in] x 設定する値です。
266     //! @param[in] y 設定する値です。
267     //! @param[in] z 設定する値です。
268     //! @param[in] w 設定する値です。
269     //!
SetUniformInt(ShaderUniform location,s32 x,s32 y,s32 z,s32 w)270     void SetUniformInt(ShaderUniform location, s32 x, s32 y, s32 z, s32 w) const { glUniform4i(m_UniformLocation->GetUniformLocation(location), x, y, z, w); }
271 
272     //! @brief 2要素のfloatの配列を設定します。
273     //!
274     //! @param[in] location シェーダーユニフォームのインデックス番号です。
275     //! @param[in] pointer 設定する配列です。
276     //!
SetUniform2(ShaderUniform location,const GLfloat * pointer)277     void SetUniform2(ShaderUniform location, const GLfloat* pointer) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), 1, pointer); }
278 
279     //! @brief 3要素のfloatの配列を設定します。
280     //!
281     //! @param[in] location シェーダーユニフォームのインデックス番号です。
282     //! @param[in] pointer 設定する配列です。
283     //!
SetUniform3(ShaderUniform location,const GLfloat * pointer)284     void SetUniform3(ShaderUniform location, const GLfloat* pointer) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), 1, pointer); }
285 
286     //! @brief 4要素のfloatの配列を設定します。
287     //!
288     //! @param[in] location シェーダーユニフォームのインデックス番号です。
289     //! @param[in] pointer 設定する配列です。
290     //!
SetUniform4(ShaderUniform location,const GLfloat * pointer)291     void SetUniform4(ShaderUniform location, const GLfloat* pointer) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 1, pointer); }
292 
293     //! @brief VectorやMatrixの値を設定します。
294     //!
295     //! @param[in] location シェーダーユニフォームのインデックス番号です。
296     //! @param[in] vec 設定する値です。
297     //!
SetUniform(ShaderUniform location,const math::VEC2 & vec)298     void SetUniform(ShaderUniform location, const math::VEC2& vec) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), 1, vec); }
299 
300     //! @brief VectorやMatrixの値を設定します。
301     //!
302     //! @param[in] location シェーダーユニフォームのインデックス番号です。
303     //! @param[in] vec 設定する値です。
304     //!
SetUniform(ShaderUniform location,const math::VEC3 & vec)305     void SetUniform(ShaderUniform location, const math::VEC3& vec) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), 1, vec); }
306 
307     //! @brief VectorやMatrixの値を設定します。
308     //!
309     //! @param[in] location シェーダーユニフォームのインデックス番号です。
310     //! @param[in] vec 設定する値です。
311     //!
SetUniform(ShaderUniform location,const math::VEC4 & vec)312     void SetUniform(ShaderUniform location, const math::VEC4& vec) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 1, vec); }
313 
314     //! @brief VectorやMatrixの値を設定します。
315     //!
316     //! @param[in] location シェーダーユニフォームのインデックス番号です。
317     //! @param[in] mtx 設定する値です。
318     //!
SetUniform(ShaderUniform location,const math::MTX22 & mtx)319     void SetUniform(ShaderUniform location, const math::MTX22& mtx) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), 2, mtx); }
320 
321     //! @brief VectorやMatrixの値を設定します。
322     //!
323     //! @param[in] location シェーダーユニフォームのインデックス番号です。
324     //! @param[in] mtx 設定する値です。
325     //!
SetUniform(ShaderUniform location,const math::MTX23 & mtx)326     void SetUniform(ShaderUniform location, const math::MTX23& mtx) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), 2, mtx); }
327 
328     //! @brief VectorやMatrixの値を設定します。
329     //!
330     //! @param[in] location シェーダーユニフォームのインデックス番号です。
331     //! @param[in] mtx 設定する値です。
332     //!
SetUniform(ShaderUniform location,const math::MTX34 & mtx)333     void SetUniform(ShaderUniform location, const math::MTX34& mtx) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 3, mtx); }
334 
335     //! @brief VectorやMatrixの値を設定します。
336     //!
337     //! @param[in] location シェーダーユニフォームのインデックス番号です。
338     //! @param[in] mtx 設定する値です。
339     //!
SetUniform(ShaderUniform location,const math::MTX44 & mtx)340     void SetUniform(ShaderUniform location, const math::MTX44& mtx) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), 4, mtx); }
341 
342     //! @brief Vectorの配列を設定します。
343     //!
344     //! @param[in] location シェーダーユニフォームのインデックス番号です。
345     //! @param[in] vec 設定する配列です。
346     //! @param[in] count 設定する配列の数です。
347     //!
SetUniforms(ShaderUniform location,const math::VEC2 * vec,int count)348     void SetUniforms(ShaderUniform location, const math::VEC2* vec, int count) const { glUniform2fv(m_UniformLocation->GetUniformLocation(location), count, *vec); }
349 
350     //! @brief Vectorの配列を設定します。
351     //!
352     //! @param[in] location シェーダーユニフォームのインデックス番号です。
353     //! @param[in] vec 設定する配列です。
354     //! @param[in] count 設定する配列の数です。
355     //!
SetUniforms(ShaderUniform location,const math::VEC3 * vec,int count)356     void SetUniforms(ShaderUniform location, const math::VEC3* vec, int count) const { glUniform3fv(m_UniformLocation->GetUniformLocation(location), count, *vec); }
357 
358     //! @brief Vectorの配列を設定します。
359     //!
360     //! @param[in] location シェーダーユニフォームのインデックス番号です。
361     //! @param[in] vec 設定する配列です。
362     //! @param[in] count 設定する配列の数です。
363     //!
SetUniforms(ShaderUniform location,const math::VEC4 * vec,int count)364     void SetUniforms(ShaderUniform location, const math::VEC4* vec, int count) const { glUniform4fv(m_UniformLocation->GetUniformLocation(location), count, *vec); }
365 
366     //! @brief 配列を設定します。
367     //!
368     //! @param[in] location シェーダーユニフォームのインデックス番号です。
369     //! @param[in] array 設定する配列です。
370     //!
371     template<typename TValue>
SetUniforms(ShaderUniform location,const ut::MoveArray<TValue> * array)372     void SetUniforms(ShaderUniform location, const ut::MoveArray<TValue>* array) const
373     {
374         NW_NULL_ASSERT(array);
375         if (array->empty()) { return; }
376 
377         this->SetUniforms(location, array->Elements(), array->size());
378     }
379 
380     //! @brief サイズを指定して配列を設定します。
381     //!
382     //! @param[in] location シェーダーユニフォームのインデックス番号です。
383     //! @param[in] array 設定する配列です。
384     //! @param[in] size 配列の大きさです。
385     //!
386     template<typename TValue>
SetUniforms(ShaderUniform location,const ut::MoveArray<TValue> * array,s32 size)387     void SetUniforms(ShaderUniform location, const ut::MoveArray<TValue>* array, s32 size) const
388     {
389         NW_NULL_ASSERT(array);
390         NW_ASSERT(size <= array->size());
391 
392         this->SetUniforms(location, array->Elements(), size);
393     }
394 
395     //! @brief ユーザーレジスタにパラメータを設定します。
396     //!
397     //! locationにはglGetUniformLocationで取得したGLintの値を渡してください。
398     //!
399     //! @param[in] location シェーダーユニフォームの場所です。
400     //! @param[in] parameter 設定するシェーダーパラメータです。
401     //!
SetUserUniform(GLint location,ResShaderParameterValue parameter)402     void SetUserUniform(GLint location, ResShaderParameterValue parameter) const
403     {
404         if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_BOOL1)
405         {
406             glUniform1iv(location, 1, reinterpret_cast<GLint*>(parameter.GetValueS32()));
407         }
408         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT1)
409         {
410             glUniform1fv(location, 1, parameter.GetValueF32());
411         }
412         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT2)
413         {
414             glUniform2fv(location, 1, parameter.GetValueF32());
415         }
416         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT3)
417         {
418             glUniform3fv(location, 1, parameter.GetValueF32());
419         }
420         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT4)
421         {
422             glUniform4fv(location, 1, parameter.GetValueF32());
423         }
424     }
425 #endif // defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
426 
427     //! @brief ユーザー頂点レジスタにパラメータを設定します。
428     //!
429     //! @param[in] index 頂点シェーダーのレジスタ番号です。
430     //! @param[in] parameter 設定するシェーダーパラメータです。
431     //!
SetUserVertexUniform(s32 index,ResShaderParameterValue parameter)432     void SetUserVertexUniform(s32 index, ResShaderParameterValue parameter) const
433     {
434         if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_BOOL1)
435         {
436             this->SetVertexUniformBool(index, parameter.GetValueBool());
437         }
438         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT1)
439         {
440             internal::NWSetVertexUniform1fv(index, 1, parameter.GetValueF32());
441         }
442         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT2)
443         {
444             internal::NWSetVertexUniform2fv(index, 1, parameter.GetValueF32());
445         }
446         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT3)
447         {
448             internal::NWSetVertexUniform3fv(index, 1, parameter.GetValueF32());
449         }
450         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT4)
451         {
452             internal::NWSetVertexUniform4fv(index, 1, parameter.GetValueF32());
453         }
454     }
455 
456     //! @brief ユーザージオメトリレジスタにパラメータを設定します。
457     //!
458     //! @param[in] index ジオメトリシェーダーのレジスタ番号です。
459     //! @param[in] parameter 設定するシェーダーパラメータです。
460     //!
SetUserGeometryUniform(s32 index,ResShaderParameterValue parameter)461     void SetUserGeometryUniform(s32 index, ResShaderParameterValue parameter) const
462     {
463         if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_BOOL1)
464         {
465             this->SetGeometryUniformBool(index, parameter.GetValueBool());
466         }
467         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT1)
468         {
469             internal::NWSetGeometryUniform1fv(index, 1, parameter.GetValueF32());
470         }
471         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT2)
472         {
473             internal::NWSetGeometryUniform2fv(index, 1, parameter.GetValueF32());
474         }
475         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT3)
476         {
477             internal::NWSetGeometryUniform3fv(index, 1, parameter.GetValueF32());
478         }
479         else if (parameter.GetUniformType() == ResShaderParameterValue::TYPE_FLOAT4)
480         {
481             internal::NWSetGeometryUniform4fv(index, 1, parameter.GetValueF32());
482         }
483     }
484 
485     //! @brief boolの値を設定します。
486     //!
487     //! @param[in] index シェーダーユニフォームのインデックス番号です。
488     //! @param[in] value 設定する値です。
489     //!
SetVertexUniformBool(int index,bool value)490     void SetVertexUniformBool(int index, bool value) const
491     {
492         NW_ASSERT(0 <= index && index < 16);
493         if (value)
494         {
495             m_VertexIntUniforms[0] |= 0x1 << index;
496         }
497         else
498         {
499             m_VertexIntUniforms[0] &= ~(0x1 << index);
500         }
501     }
502 
503     //! @brief boolの値を設定します。
504     //!
505     //! @param[in] index シェーダーユニフォームのインデックス番号です。
506     //! @param[in] value 設定する値です。
507     //!
SetGeometryUniformBool(int index,bool value)508     void SetGeometryUniformBool(int index, bool value) const
509     {
510         NW_ASSERT(0 <= index && index < 16);
511         if (value)
512         {
513             m_GeometryIntUniforms[0] |= 0x1 << index;
514         }
515         else
516         {
517             m_GeometryIntUniforms[0] &= ~(0x1 << index);
518         }
519     }
520 
521     //! @brief intの値を設定します。
522     //!
523     //! @param[in] index シェーダーユニフォームのインデックス番号です。
524     //! @param[in] value 設定する値です。
525     //!
SetVertexUniformInt(int index,s32 value)526     void SetVertexUniformInt(int index, s32 value) const
527     {
528         NW_ASSERT(0 <= index && index < 4);
529         m_VertexIntUniforms[2 + index] = value & 0xFF;
530     }
531 
532     //! @brief intの値を設定します。
533     //!
534     //! @param[in] index シェーダーユニフォームのインデックス番号です。
535     //! @param[in] value 設定する値です。
536     //!
SetGeometryUniformInt(int index,s32 value)537     void SetGeometryUniformInt(int index, s32 value) const
538     {
539         NW_ASSERT(0 <= index && index < 4);
540         m_GeometryIntUniforms[2 + index] = value & 0xFF;
541     }
542 
543     //! @brief intの値を設定します。
544     //!
545     //! @param[in] index シェーダーユニフォームのインデックス番号です。
546     //! @param[in] x     設定する x 値です。
547     //! @param[in] y     設定する y 値です。
548     //!
SetVertexUniformInt(int index,s32 x,s32 y)549     void SetVertexUniformInt(int index, s32 x, s32 y) const
550     {
551         NW_ASSERT(0 <= index && index < 4);
552         m_VertexIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8);
553     }
554 
555     //! @brief intの値を設定します。
556     //!
557     //! @param[in] index シェーダーユニフォームのインデックス番号です。
558     //! @param[in] x     設定する x 値です。
559     //! @param[in] y     設定する y 値です。
560     //!
SetGeometryUniformInt(int index,s32 x,s32 y)561     void SetGeometryUniformInt(int index, s32 x, s32 y) const
562     {
563         NW_ASSERT(0 <= index && index < 4);
564         m_GeometryIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8);
565     }
566 
567     //! @brief intの値を設定します。
568     //!
569     //! @param[in] index シェーダーユニフォームのインデックス番号です。
570     //! @param[in] x     設定する x 値です。
571     //! @param[in] y     設定する y 値です。
572     //! @param[in] z     設定する z 値です。
573     //!
SetVertexUniformInt(int index,s32 x,s32 y,s32 z)574     void SetVertexUniformInt(int index, s32 x, s32 y, s32 z) const
575     {
576         NW_ASSERT(0 <= index && index < 4);
577         m_VertexIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8) | ((z & 0xFF) << 16);
578     }
579 
580     //! @brief intの値を設定します。
581     //!
582     //! @param[in] index シェーダーユニフォームのインデックス番号です。
583     //! @param[in] x     設定する x 値です。
584     //! @param[in] y     設定する y 値です。
585     //! @param[in] z     設定する z 値です。
586     //!
SetGeometryUniformInt(int index,s32 x,s32 y,s32 z)587     void SetGeometryUniformInt(int index, s32 x, s32 y, s32 z) const
588     {
589         NW_ASSERT(0 <= index && index < 4);
590         m_GeometryIntUniforms[2 + index] = (x & 0xFF) | ((y & 0xFF) << 8) | ((z & 0xFF) << 16);
591     }
592 
593     //! @brief     VertexUniform と GeometryUniform の状態をコマンドへ Flush します。
FlushUniform()594     void FlushUniform() const
595     {
596         internal::NWUseCmdlist<sizeof(m_VertexIntUniforms)>(&m_VertexIntUniforms[0]);
597         if (m_Description.GetGeometryShaderIndex() >= 0)
598         {
599             internal::NWUseCmdlist<sizeof(m_GeometryIntUniforms)>(&m_GeometryIntUniforms[0]);
600         }
601     }
602     //@}
603 
604     //----------------------------------------
605     //! @name シェーダーシンボル
606     //@{
607 
608     //@}
609 
610     //---------------------------------------------------------------------------
611     //! @brief        コンストラクタです。
612     //---------------------------------------------------------------------------
613     ShaderProgram(os::IAllocator* allocator);
614 
615 private:
616     //---------------------------------------------------------------------------
617     //! @brief        デストラクタです。
618     //---------------------------------------------------------------------------
619     virtual ~ShaderProgram();
620 
621     ResShaderProgramDescription m_Description;
622 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
623     ShaderUniformLocation* m_UniformLocation;
624 #endif
625     GLuint m_ProgramObject;
626 
627     GeometryShaderMode m_GeometryShaderMode;
628 
629     mutable u32 m_VertexIntUniforms[6];
630     mutable u32 m_GeometryIntUniforms[6];
631     mutable u32 m_DisableGeometry[2];
632 };
633 
634 NW_INLINE int
GetVertexAttributeIndex(ResVertexAttribute::VertexAttributeUsage usage)635 ShaderProgram::GetVertexAttributeIndex(
636     ResVertexAttribute::VertexAttributeUsage usage
637 ) const
638 {
639     ResShaderProgramDescription description = this->GetActiveDescription();
640     NW_ASSERT(description.IsValid());
641 
642     return description.GetAttributeIndices(usage);
643 }
644 
645 } // namespace gfx
646 } // namespace nw
647 
648 #endif // NW_GFX_SHADERPROGRAM_H_
649