// EXTERNAL INCLUDES
#include <dali/integration-api/debug.h>
-#include <dali/public-api/images/resource-image.h>
#include <dali/public-api/common/stage.h>
#include <dali/devel-api/adaptor-framework/bitmap-loader.h>
#include <dali/devel-api/adaptor-framework/file-loader.h>
//INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/renderers/renderer-string-constants.h>
-#include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
-#include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
#include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
namespace Dali
GLOSS_INDEX = 2u
};
-const char * const RENDERER_TYPE_VALUE( "mesh" ); //String label for which type of control renderer this is.
-const char * const LIGHT_POSITION( "uLightPosition" ); //Shader property
-const char * const OBJECT_MATRIX( "uObjectMatrix" ); //Shader property
+//Shader properties
+const char * const OBJECT_MATRIX_UNIFORM_NAME( "uObjectMatrix" );
+const char * const STAGE_OFFSET_UNIFORM_NAME( "uStageOffset" );
+
+const char * const SHADER_TYPE_TEXTURELESS( "TEXTURELESS" );
+const char * const SHADER_TYPE_DIFFUSE_TEXTURE( "DIFFUSE_TEXTURE" );
+const char * const SHADER_TYPE_ALL_TEXTURES( "ALL_TEXTURES" );
//Shaders
//If a shader requires certain textures, they must be listed in order,
uniform mediump vec3 uSize;\n
uniform mediump mat4 uMvpMatrix;\n
uniform mediump mat4 uModelView;\n
+ uniform mediump mat4 uViewMatrix;\n
uniform mediump mat3 uNormalMatrix;
uniform mediump mat4 uObjectMatrix;\n
- uniform mediump vec3 uLightPosition;\n
+ uniform mediump vec3 lightPosition;\n
+ uniform mediump vec2 uStageOffset;\n
void main()\n
{\n
- vec4 vertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
- vertexPosition = uObjectMatrix * vertexPosition;\n
+ vec4 normalisedVertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
+ vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
vertexPosition = uMvpMatrix * vertexPosition;\n
//Illumination in Model-View space - Transform attributes and uniforms\n
- vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n
+ vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n
vec3 normal = uNormalMatrix * mat3( uObjectMatrix ) * aNormal;\n
- vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n
- vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n
- vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
- float lightDiffuse = max( dot( vecToLight, normal ), 0.0 );\n
+ vec4 mvLightPosition = vec4( ( lightPosition.xy - uStageOffset ), lightPosition.z, 1.0 );\n
+ mvLightPosition = uViewMatrix * mvLightPosition;\n
+ vec3 vectorToLight = normalize( mvLightPosition.xyz - mvVertexPosition.xyz );\n
+
+ float lightDiffuse = max( dot( vectorToLight, normal ), 0.0 );\n
vIllumination = vec3( lightDiffuse * 0.5 + 0.5 );\n
gl_Position = vertexPosition;\n
uniform mediump vec3 uSize;\n
uniform mediump mat4 uMvpMatrix;\n
uniform mediump mat4 uModelView;
+ uniform mediump mat4 uViewMatrix;\n
uniform mediump mat3 uNormalMatrix;
uniform mediump mat4 uObjectMatrix;\n
- uniform mediump vec3 uLightPosition;\n
+ uniform mediump vec3 lightPosition;\n
+ uniform mediump vec2 uStageOffset;\n
void main()
{\n
- vec4 vertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
- vertexPosition = uObjectMatrix * vertexPosition;\n
+ vec4 normalisedVertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
+ vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
vertexPosition = uMvpMatrix * vertexPosition;\n
//Illumination in Model-View space - Transform attributes and uniforms\n
- vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n
- vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n
- vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n
+ vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n
vec3 normal = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aNormal );\n
- vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
- vec3 viewDir = normalize( -vertPos.xyz );
+ vec4 mvLightPosition = vec4( ( lightPosition.xy - uStageOffset ), lightPosition.z, 1.0 );\n
+ mvLightPosition = uViewMatrix * mvLightPosition;\n
+ vec3 vectorToLight = normalize( mvLightPosition.xyz - mvVertexPosition.xyz );\n
- vec3 halfVector = normalize( viewDir + vecToLight );
+ vec3 viewDirection = normalize( -mvVertexPosition.xyz );
- float lightDiffuse = dot( vecToLight, normal );\n
+ float lightDiffuse = dot( vectorToLight, normal );\n
lightDiffuse = max( 0.0,lightDiffuse );\n
vIllumination = vec3( lightDiffuse * 0.5 + 0.5 );\n
- vec3 reflectDir = reflect( -vecToLight, normal );
- vSpecular = pow( max( dot( reflectDir, viewDir ), 0.0 ), 4.0 );
+ vec3 reflectDirection = reflect( -vectorToLight, normal );
+ vSpecular = pow( max( dot( reflectDirection, viewDirection ), 0.0 ), 4.0 );
vTexCoord = aTexCoord;\n
gl_Position = vertexPosition;\n
uniform mediump vec3 uSize;\n
uniform mediump mat4 uMvpMatrix;\n
uniform mediump mat4 uModelView;
+ uniform mediump mat4 uViewMatrix;\n
uniform mediump mat3 uNormalMatrix;
uniform mediump mat4 uObjectMatrix;\n
- uniform mediump vec3 uLightPosition;\n
-
+ uniform mediump vec3 lightPosition;\n
+ uniform mediump vec2 uStageOffset;\n
void main()
{\n
- vec4 vertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
- vertexPosition = uObjectMatrix * vertexPosition;\n
+ vec4 normalisedVertexPosition = vec4( aPosition * min( uSize.x, uSize.y ), 1.0 );\n
+ vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n
vertexPosition = uMvpMatrix * vertexPosition;\n
- vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n
- vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n
- vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n
+ vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n
- vec3 tangent = normalize( uNormalMatrix * aTangent );
- vec3 binormal = normalize( uNormalMatrix * aBiNormal );
+ vec3 tangent = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aTangent );
+ vec3 binormal = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aBiNormal );
vec3 normal = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aNormal );
- vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
- vLightDirection.x = dot( vecToLight, tangent );
- vLightDirection.y = dot( vecToLight, binormal );
- vLightDirection.z = dot( vecToLight, normal );
+ vec4 mvLightPosition = vec4( ( lightPosition.xy - uStageOffset ), lightPosition.z, 1.0 );\n
+ mvLightPosition = uViewMatrix * mvLightPosition;\n
+ vec3 vectorToLight = normalize( mvLightPosition.xyz - mvVertexPosition.xyz );\n
+ vLightDirection.x = dot( vectorToLight, tangent );
+ vLightDirection.y = dot( vectorToLight, binormal );
+ vLightDirection.z = dot( vectorToLight, normal );
- vec3 viewDir = normalize( -vertPos.xyz );
- vec3 halfVector = normalize( viewDir + vecToLight );
+ vec3 viewDirection = normalize( -mvVertexPosition.xyz );
+ vec3 halfVector = normalize( viewDirection + vectorToLight );
vHalfVector.x = dot( halfVector, tangent );
vHalfVector.y = dot( halfVector, binormal );
vHalfVector.z = dot( halfVector, normal );
: ControlRenderer( factoryCache ),
mShaderType( ALL_TEXTURES ),
mUseTexture( true ),
- mUseMipmapping( true )
+ mUseMipmapping( true ),
+ mUseSoftNormals( true )
{
}
}
Property::Value* materialUrl = propertyMap.Find( MATERIAL_URL );
-
if( !materialUrl || !materialUrl->Get( mMaterialUrl ) || mMaterialUrl.empty() )
{
mUseTexture = false;
mTexturesPath.clear();
}
+ Property::Value* shaderType = propertyMap.Find( SHADER_TYPE );
+ if( shaderType )
+ {
+ std::string shaderTypeString;
+ if( shaderType->Get( shaderTypeString ) )
+ {
+ if( shaderTypeString == SHADER_TYPE_TEXTURELESS )
+ {
+ mShaderType = TEXTURELESS;
+ }
+ else if( shaderTypeString == SHADER_TYPE_DIFFUSE_TEXTURE )
+ {
+ mShaderType = DIFFUSE_TEXTURE;
+ }
+ else if( shaderTypeString == SHADER_TYPE_ALL_TEXTURES )
+ {
+ mShaderType = ALL_TEXTURES;
+ }
+ else
+ {
+ DALI_LOG_ERROR( "Unknown shader type provided to the MeshRenderer object.\n");
+ }
+ }
+ }
+
Property::Value* useMipmapping = propertyMap.Find( USE_MIPMAPPING );
if( useMipmapping )
{
useMipmapping->Get( mUseMipmapping );
}
- Property::Value* shaderType = propertyMap.Find( SHADER_TYPE );
- if( shaderType && shaderType->Get( mShaderTypeString ) )
+ Property::Value* useSoftNormals = propertyMap.Find( USE_SOFT_NORMALS );
+ if( useSoftNormals )
{
- if( mShaderTypeString == "textureless" )
- {
- mShaderType = TEXTURELESS;
- }
- else if( mShaderTypeString == "diffuseTexture" )
- {
- mShaderType = DIFFUSE_TEXTURE;
- }
- else if( mShaderTypeString == "allTextures" )
- {
- mShaderType = ALL_TEXTURES;
- }
- else
+ useSoftNormals->Get( mUseSoftNormals );
+ }
+
+ Property::Value* lightPosition = propertyMap.Find( LIGHT_POSITION_UNIFORM_NAME );
+ if( lightPosition )
+ {
+ if( !lightPosition->Get( mLightPosition ) )
{
- DALI_LOG_ERROR( "Unknown shader type provided to the MeshRenderer object.\n");
+ DALI_LOG_ERROR( "Invalid value passed for light position in MeshRenderer object.\n" );
+ mLightPosition = Vector3::ZERO;
}
}
+ else
+ {
+ //Default behaviour is to place the light directly in front of the object,
+ // at a reasonable distance to light everything on screen.
+ Stage stage = Stage::GetCurrent();
+
+ mLightPosition = Vector3( stage.GetSize().width / 2, stage.GetSize().height / 2, stage.GetSize().width * 5 );
+ }
}
void MeshRenderer::SetSize( const Vector2& size )
void MeshRenderer::DoCreatePropertyMap( Property::Map& map ) const
{
map.Clear();
- map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
+ map.Insert( RENDERER_TYPE, MESH_RENDERER );
map.Insert( OBJECT_URL, mObjectUrl );
map.Insert( MATERIAL_URL, mMaterialUrl );
map.Insert( TEXTURES_PATH, mTexturesPath );
- map.Insert( SHADER_TYPE, mShaderTypeString );
+
+ std::string shaderTypeString;
+ switch( mShaderType )
+ {
+ case ALL_TEXTURES:
+ {
+ shaderTypeString = SHADER_TYPE_ALL_TEXTURES;
+ break;
+ }
+
+ case DIFFUSE_TEXTURE:
+ {
+ shaderTypeString = SHADER_TYPE_DIFFUSE_TEXTURE;
+ break;
+ }
+
+ case TEXTURELESS:
+ {
+ shaderTypeString = SHADER_TYPE_TEXTURELESS;
+ break;
+ }
+ }
+ map.Insert( SHADER_TYPE, shaderTypeString );
+
+ map.Insert( USE_MIPMAPPING, mUseMipmapping );
+ map.Insert( USE_SOFT_NORMALS, mUseSoftNormals );
+ map.Insert( LIGHT_POSITION_UNIFORM_NAME, mLightPosition );
}
void MeshRenderer::InitializeRenderer()
void MeshRenderer::UpdateShaderUniforms()
{
Stage stage = Stage::GetCurrent();
-
- Vector3 lightPosition( 0, 0, stage.GetSize().width );
- mShader.RegisterProperty( LIGHT_POSITION, lightPosition );
+ float width = stage.GetSize().width;
+ float height = stage.GetSize().height;
Matrix scaleMatrix;
scaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) );
- mShader.RegisterProperty( OBJECT_MATRIX, scaleMatrix );
+
+ mShader.RegisterProperty( STAGE_OFFSET_UNIFORM_NAME, Vector2( width, height ) / 2.0f );
+ mShader.RegisterProperty( LIGHT_POSITION_UNIFORM_NAME, mLightPosition );
+ mShader.RegisterProperty( OBJECT_MATRIX_UNIFORM_NAME, scaleMatrix );
}
void MeshRenderer::CreateShader()
//Determine if we need to use a simpler shader to handle the provided data
if( !mUseTexture || !mObjLoader.IsDiffuseMapPresent() )
{
- mUseTexture = false;
mShaderType = TEXTURELESS;
}
else if( mShaderType == ALL_TEXTURES && (!mObjLoader.IsNormalMapPresent() || !mObjLoader.IsSpecularMapPresent()) )
}
//Create geometry with attributes required by shader.
- mGeometry = mObjLoader.CreateGeometry( objectProperties );
+ mGeometry = mObjLoader.CreateGeometry( objectProperties, mUseSoftNormals );
if( mGeometry )
{
{
mTextureSet = TextureSet::New();
- if( mUseTexture )
+ if( mShaderType != TEXTURELESS )
{
Sampler sampler = Sampler::New();
if( mUseMipmapping )