Texture image filtering
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-material.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/render/renderers/render-material.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/internal-constants.h>
23 #include <dali/internal/render/gl-resources/texture.h>
24 #include <dali/internal/render/gl-resources/texture-cache.h>
25 #include <dali/internal/render/shaders/program.h>
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31 namespace SceneGraph
32 {
33
34 void RenderMaterialUniforms::ResetCustomUniforms()
35 {
36   for( unsigned int subType = SHADER_DEFAULT; subType < SHADER_SUBTYPE_LAST; ++subType )
37   {
38     for( unsigned int i = 0; i < mNumberOfCustomUniforms; ++i )
39     {
40       mCustomUniform[ subType ][ i ].Reset();
41     }
42   }
43 }
44
45 void RenderMaterialUniforms::SetUniforms( const RenderMaterial& material, Program& program, ShaderSubTypes shaderType )
46 {
47   GLint location = Program::UNIFORM_UNKNOWN;
48
49   location = mCustomUniform[ shaderType ][ 0 ].GetUniformLocation( program, "uMaterial.mOpacity" );
50   if( Program::UNIFORM_UNKNOWN != location )
51   {
52     program.SetUniform1f( location, material.mOpacity );
53   }
54
55   location = mCustomUniform[ shaderType ][ 1 ].GetUniformLocation( program, "uMaterial.mShininess" );
56   if( Program::UNIFORM_UNKNOWN != location )
57   {
58     program.SetUniform1f( location, material.mShininess );
59   }
60
61   location = mCustomUniform[ shaderType ][ 2 ].GetUniformLocation( program, "uMaterial.mAmbient" );
62   if( Program::UNIFORM_UNKNOWN != location )
63   {
64     const Vector4& color = material.mAmbientColor;
65     program.SetUniform4f( location,  color.r, color.g, color.b, color.a );
66   }
67
68   location = mCustomUniform[ shaderType ][ 3 ].GetUniformLocation( program, "uMaterial.mDiffuse" );
69   if( Program::UNIFORM_UNKNOWN != location )
70   {
71     const Vector4& color = material.mDiffuseColor;
72     program.SetUniform4f( location,  color.r, color.g, color.b, color.a );
73   }
74
75   location = mCustomUniform[ shaderType ][ 4 ].GetUniformLocation( program, "uMaterial.mSpecular" );
76   if( Program::UNIFORM_UNKNOWN != location )
77   {
78     const Vector4& color = material.mSpecularColor;
79     program.SetUniform4f( location, color.r, color.g, color.b, color.a );
80   }
81
82   location = mCustomUniform[ shaderType ][ 5 ].GetUniformLocation( program, "uMaterial.mEmissive" );
83   if( Program::UNIFORM_UNKNOWN != location )
84   {
85     const Vector4& color = material.mEmissiveColor;
86     program.SetUniform4f( location, color.r, color.g, color.b, color.a );
87   }
88 }
89
90
91
92 RenderMaterial::RenderMaterial()
93 : mTextureCache(NULL),
94
95   mDiffuseTextureId(0),
96   mOpacityTextureId(0),
97   mNormalMapTextureId(0),
98
99   mDiffuseTexture(NULL),
100   mOpacityTexture(NULL),
101   mNormalMapTexture(NULL),
102
103   mOpacity(1.0f),
104   mShininess(0.5f),
105
106   mAmbientColor(Vector4(0.2f, 0.2f, 0.2f, 1.0f)),
107   mDiffuseColor(Vector4(0.8f, 0.8f, 0.8f, 1.0f)),
108   mSpecularColor(Vector4(0.0f, 0.0f, 0.0f, 1.0f)),
109   mEmissiveColor(Vector4(0.0f, 0.0f, 0.0f, 1.0f))
110 {
111 }
112
113 RenderMaterial::~RenderMaterial()
114 {
115   if(mDiffuseTextureId > 0)
116   {
117     mTextureCache->RemoveObserver( mDiffuseTextureId, this );
118   }
119
120   if(mOpacityTextureId > 0)
121   {
122     mTextureCache->RemoveObserver( mOpacityTextureId, this );
123   }
124
125   if(mNormalMapTextureId > 0)
126   {
127     mTextureCache->RemoveObserver( mNormalMapTextureId, this );
128   }
129 }
130
131 void RenderMaterial::Initialize(TextureCache& textureCache)
132 {
133   mTextureCache = &textureCache;
134 }
135
136 void RenderMaterial::SetDiffuseTextureId( unsigned int textureId )
137 {
138   DALI_ASSERT_DEBUG( NULL != mTextureCache );
139
140   if(mDiffuseTextureId > 0)
141   {
142     mTextureCache->RemoveObserver( mDiffuseTextureId, this );
143   }
144
145   mDiffuseTextureId = textureId;
146   mDiffuseTexture = NULL;
147
148   if(mDiffuseTextureId > 0)
149   {
150     mTextureCache->AddObserver( textureId, this );
151   }
152 }
153
154 void RenderMaterial::SetOpacityTextureId( unsigned int textureId )
155 {
156   DALI_ASSERT_DEBUG( NULL != mTextureCache );
157
158   if(mOpacityTextureId > 0)
159   {
160     mTextureCache->RemoveObserver( mOpacityTextureId, this );
161   }
162
163   mOpacityTextureId = textureId;
164   mOpacityTexture = NULL;
165
166   if(mOpacityTextureId > 0)
167   {
168     mTextureCache->AddObserver( textureId, this );
169   }
170 }
171
172 void RenderMaterial::SetNormalMapTextureId( unsigned int textureId )
173 {
174   DALI_ASSERT_DEBUG( NULL != mTextureCache );
175
176   if(mNormalMapTextureId > 0)
177   {
178     mTextureCache->RemoveObserver( mNormalMapTextureId, this );
179   }
180
181   mNormalMapTextureId = textureId;
182   mNormalMapTexture = NULL;
183
184   if(mNormalMapTextureId > 0)
185   {
186     mTextureCache->AddObserver( textureId, this );
187   }
188 }
189
190 void RenderMaterial::SetOpacity(float opacity)
191 {
192   mOpacity = opacity;
193 }
194
195 void RenderMaterial::SetShininess(float shininess)
196 {
197   mShininess = shininess;
198 }
199
200 void RenderMaterial::SetAmbientColor( const Vector4& color )
201 {
202   mAmbientColor = color;
203 }
204
205 void RenderMaterial::SetDiffuseColor( const Vector4& color )
206 {
207   mDiffuseColor = color;
208 }
209
210 void RenderMaterial::SetSpecularColor( const Vector4& color )
211 {
212   mSpecularColor = color;
213 }
214
215 void RenderMaterial::SetEmissiveColor( const Vector4& color )
216 {
217   mEmissiveColor = color;
218 }
219
220 bool RenderMaterial::HasTexture() const
221 {
222   return( mDiffuseTextureId != 0 );
223 }
224
225 void RenderMaterial::SetUniforms( RenderMaterialUniforms& uniforms, Program& program, ShaderSubTypes shaderType ) const
226 {
227   uniforms.SetUniforms( *this, program, shaderType );
228 }
229
230 void RenderMaterial::BindTexture( Program& program, ResourceId id, Texture* texture, unsigned int textureUnit, Program::UniformType samplerIndex ) const
231 {
232   DALI_ASSERT_DEBUG( NULL != mTextureCache );
233
234   if( texture != NULL )
235   {
236     mTextureCache->BindTexture( texture, id, GL_TEXTURE_2D, GL_TEXTURE0 + textureUnit );
237     // Set sampler uniforms for textures
238     GLint samplerLoc = program.GetUniformLocation( samplerIndex );
239     if( -1 != samplerLoc )
240     {
241       program.SetUniform1i( samplerLoc, textureUnit );
242     }
243
244     GLint location = program.GetUniformLocation(Program::UNIFORM_CUSTOM_TEXTURE_COORDS);
245     if( Program::UNIFORM_UNKNOWN != location )
246     {
247       UvRect uvs;
248       texture->GetTextureCoordinates(uvs);
249
250       // Account for UV mapping on non power of 2 textures
251       program.SetUniform4f(location, uvs.u0, uvs.v0, uvs.u2-uvs.u0, uvs.v2-uvs.v0);
252     }
253   }
254 }
255
256 void RenderMaterial::BindTextures( Program& program, unsigned int textureSampler )
257 {
258   DALI_ASSERT_DEBUG( NULL != mTextureCache );
259
260   if( mDiffuseTexture == NULL )
261   {
262     if( mDiffuseTextureId > 0 )
263     {
264       mDiffuseTexture = mTextureCache->GetTexture( mDiffuseTextureId );
265     }
266   }
267
268   if( mOpacityTexture == NULL )
269   {
270     if( mOpacityTextureId > 0 )
271     {
272       mOpacityTexture = mTextureCache->GetTexture( mOpacityTextureId );
273     }
274   }
275
276   if( mNormalMapTexture == NULL )
277   {
278     if( mNormalMapTextureId > 0 )
279     {
280       mNormalMapTexture = mTextureCache->GetTexture( mNormalMapTextureId );
281     }
282   }
283
284   BindTexture( program, mDiffuseTextureId, mDiffuseTexture, 0, Program::UNIFORM_SAMPLER );
285
286   if( mDiffuseTexture )
287   {
288     mDiffuseTexture->ApplySampler( textureSampler );
289   }
290
291   // GL_TEXTURE1 is used by shader effect texture
292   BindTexture( program, mOpacityTextureId, mOpacityTexture, 2, Program::UNIFORM_SAMPLER_OPACITY );
293
294   if( mOpacityTexture )
295   {
296     mOpacityTexture->ApplySampler( textureSampler );
297   }
298
299   BindTexture( program, mNormalMapTextureId, mNormalMapTexture, 3, Program::UNIFORM_SAMPLER_NORMAL_MAP );
300
301   if( mNormalMapTexture )
302   {
303     mNormalMapTexture->ApplySampler( textureSampler );
304   }
305 }
306
307 void RenderMaterial::TextureDiscarded( unsigned int textureId )
308 {
309   if( mDiffuseTextureId == textureId )
310   {
311     mDiffuseTextureId = 0;
312     mDiffuseTexture = NULL;
313   }
314
315   if( mOpacityTextureId == textureId )
316   {
317     mOpacityTextureId = 0;
318     mOpacityTexture = NULL;
319   }
320
321   if( mNormalMapTextureId == textureId )
322   {
323     mNormalMapTextureId = 0;
324     mNormalMapTexture = NULL;
325   }
326 }
327
328
329
330 } // SceneGraph
331 } // Internal
332 } // Dali