@ -25,6 +25,7 @@
# include "ogre_nif_loader.hpp"
# include <components/settings/settings.hpp>
typedef unsigned char ubyte ;
@ -299,138 +300,136 @@ void NIFLoader::createMaterial(const String &name,
material - > setSelfIllumination ( emissive . array [ 0 ] , emissive . array [ 1 ] , emissive . array [ 2 ] ) ;
material - > setShininess ( glossiness ) ;
// Create shader for the material
// vertex
HighLevelGpuProgramManager & mgr = HighLevelGpuProgramManager : : getSingleton ( ) ;
HighLevelGpuProgramPtr vertex ;
if ( mgr . getByName ( " main_vp " ) . isNull ( ) )
if ( Settings : : Manager : : getBool ( " shaders " , " Objects " ) )
{
vertex = mgr . createProgram ( " main_vp " , ResourceGroupManager : : DEFAULT_RESOURCE_GROUP_NAME ,
" cg " , GPT_VERTEX_PROGRAM ) ;
vertex - > setParameter ( " profiles " , " vs_4_0 vs_2_x vp40 arbvp1 " ) ;
vertex - > setParameter ( " entry_point " , " main_vp " ) ;
StringUtil : : StrStreamType outStream ;
outStream < <
" void main_vp( \n "
" float4 position : POSITION, \n "
" float4 normal : NORMAL, \n "
" float4 colour : COLOR, \n "
" in float2 uv : TEXCOORD0, \n "
" out float2 oUV : TEXCOORD0, \n "
" out float4 oPosition : POSITION, \n "
" out float4 oPositionObjSpace : TEXCOORD1, \n "
" out float4 oNormal : TEXCOORD2, \n "
" out float oFogValue : TEXCOORD3, \n "
" out float4 oVertexColour : TEXCOORD4, \n "
" uniform float4 fogParams, \n "
" uniform float4x4 worldViewProj \n "
" ) \n "
" { \n "
" oVertexColour = colour; \n "
" oUV = uv; \n "
" oNormal = normal; \n "
" oPosition = mul( worldViewProj, position ); \n "
" oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n "
" oPositionObjSpace = position; \n "
" } " ;
vertex - > setSource ( outStream . str ( ) ) ;
vertex - > load ( ) ;
vertex - > getDefaultParameters ( ) - > setNamedAutoConstant ( " worldViewProj " , GpuProgramParameters : : ACT_WORLDVIEWPROJ_MATRIX ) ;
vertex - > getDefaultParameters ( ) - > setNamedAutoConstant ( " fogParams " , GpuProgramParameters : : ACT_FOG_PARAMS ) ;
}
else
vertex = mgr . getByName ( " main_vp " ) ;
material - > getTechnique ( 0 ) - > getPass ( 0 ) - > setVertexProgram ( vertex - > getName ( ) ) ;
// the number of lights to support.
// when rendering an object, OGRE automatically picks the lights that are
// closest to the object being rendered. unfortunately this mechanism does
// not work perfectly for objects batched together (they will all use the same
// lights). to work around this, we are simply pushing the maximum number
// of lights here in order to minimize disappearing lights.
float num_lights ;
if ( GpuProgramManager : : getSingleton ( ) . isSyntaxSupported ( " fp40 " ) | |
GpuProgramManager : : getSingleton ( ) . isSyntaxSupported ( " ps_4_0 " ) )
num_lights = 8 /* 32 */ ;
else
num_lights = 8 ;
// Create shader for the material
// vertex
HighLevelGpuProgramManager & mgr = HighLevelGpuProgramManager : : getSingleton ( ) ;
// fragment
HighLevelGpuProgramPtr fragment ;
if ( mgr . getByName ( " main_fp " ) . isNull ( ) )
{
fragment = mgr . createProgram ( " main_fp " , ResourceGroupManager : : DEFAULT_RESOURCE_GROUP_NAME ,
" cg " , GPT_FRAGMENT_PROGRAM ) ;
fragment - > setParameter ( " profiles " , " ps_4_0 ps_2_x fp40 arbfp1 " ) ;
fragment - > setParameter ( " entry_point " , " main_fp " ) ;
StringUtil : : StrStreamType outStream ;
outStream < <
" void main_fp( \n "
" in float2 uv : TEXCOORD0, \n "
" out float4 oColor : COLOR, \n "
" uniform sampler2D texture : TEXUNIT0, \n "
" float4 positionObjSpace : TEXCOORD1, \n "
" float4 normal : TEXCOORD2, \n "
" float fogValue : TEXCOORD3, \n "
" float4 vertexColour : TEXCOORD4, \n "
" uniform float4 fogColour, \n " ;
for ( int i = 0 ; i < num_lights ; + + i )
HighLevelGpuProgramPtr vertex ;
if ( mgr . getByName ( " main_vp " ) . isNull ( ) )
{
vertex = mgr . createProgram ( " main_vp " , ResourceGroupManager : : DEFAULT_RESOURCE_GROUP_NAME ,
" cg " , GPT_VERTEX_PROGRAM ) ;
vertex - > setParameter ( " profiles " , " vs_4_0 vs_2_x vp40 arbvp1 " ) ;
vertex - > setParameter ( " entry_point " , " main_vp " ) ;
StringUtil : : StrStreamType outStream ;
outStream < <
" uniform float4 lightDiffuse " < < i < < " , \n "
" uniform float4 lightPositionObjSpace " < < i < < " , \n "
" uniform float4 lightAttenuation " < < i < < " , \n " ;
" void main_vp( \n "
" float4 position : POSITION, \n "
" float4 normal : NORMAL, \n "
" float4 colour : COLOR, \n "
" in float2 uv : TEXCOORD0, \n "
" out float2 oUV : TEXCOORD0, \n "
" out float4 oPosition : POSITION, \n "
" out float4 oPositionObjSpace : TEXCOORD1, \n "
" out float4 oNormal : TEXCOORD2, \n "
" out float oFogValue : TEXCOORD3, \n "
" out float4 oVertexColour : TEXCOORD4, \n "
" uniform float4 fogParams, \n "
" uniform float4x4 worldViewProj \n "
" ) \n "
" { \n "
" oVertexColour = colour; \n "
" oUV = uv; \n "
" oNormal = normal; \n "
" oPosition = mul( worldViewProj, position ); \n "
" oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n "
" oPositionObjSpace = position; \n "
" } " ;
vertex - > setSource ( outStream . str ( ) ) ;
vertex - > load ( ) ;
vertex - > getDefaultParameters ( ) - > setNamedAutoConstant ( " worldViewProj " , GpuProgramParameters : : ACT_WORLDVIEWPROJ_MATRIX ) ;
vertex - > getDefaultParameters ( ) - > setNamedAutoConstant ( " fogParams " , GpuProgramParameters : : ACT_FOG_PARAMS ) ;
}
outStream < <
" uniform float4 lightAmbient, \n "
" uniform float4 ambient, \n "
" uniform float4 diffuse, \n "
" uniform float4 emissive \n "
" ) \n "
" { \n "
" float4 tex = tex2D(texture, uv); \n "
" float d; \n "
" float attn; \n "
" float3 lightColour = float3(0, 0, 0); \n " ;
for ( int i = 0 ; i < num_lights ; + + i )
else
vertex = mgr . getByName ( " main_vp " ) ;
material - > getTechnique ( 0 ) - > getPass ( 0 ) - > setVertexProgram ( vertex - > getName ( ) ) ;
// the number of lights to support.
// when rendering an object, OGRE automatically picks the lights that are
// closest to the object being rendered. unfortunately this mechanism does
// not work perfectly for objects batched together (they will all use the same
// lights). to work around this, we are simply pushing the maximum number
// of lights here in order to minimize disappearing lights.
int num_lights = Settings : : Manager : : getInt ( " num lights " , " Objects " ) ;
// fragment
HighLevelGpuProgramPtr fragment ;
if ( mgr . getByName ( " main_fp " ) . isNull ( ) )
{
fragment = mgr . createProgram ( " main_fp " , ResourceGroupManager : : DEFAULT_RESOURCE_GROUP_NAME ,
" cg " , GPT_FRAGMENT_PROGRAM ) ;
fragment - > setParameter ( " profiles " , " ps_4_0 ps_2_x fp40 arbfp1 " ) ;
fragment - > setParameter ( " entry_point " , " main_fp " ) ;
StringUtil : : StrStreamType outStream ;
outStream < <
" void main_fp( \n "
" in float2 uv : TEXCOORD0, \n "
" out float4 oColor : COLOR, \n "
" uniform sampler2D texture : TEXUNIT0, \n "
" float4 positionObjSpace : TEXCOORD1, \n "
" float4 normal : TEXCOORD2, \n "
" float fogValue : TEXCOORD3, \n "
" float4 vertexColour : TEXCOORD4, \n "
" uniform float4 fogColour, \n " ;
for ( int i = 0 ; i < num_lights ; + + i )
{
outStream < <
" uniform float4 lightDiffuse " < < i < < " , \n "
" uniform float4 lightPositionObjSpace " < < i < < " , \n "
" uniform float4 lightAttenuation " < < i < < " , \n " ;
}
outStream < <
" float3 lightDir " < < i < < " = lightPositionObjSpace " < < i < < " .xyz - (positionObjSpace.xyz * lightPositionObjSpace " < < i < < " .w); \n "
" uniform float4 lightAmbient, \n "
" uniform float4 ambient, \n "
" uniform float4 diffuse, \n "
" uniform float4 emissive \n "
" ) \n "
" { \n "
" float4 tex = tex2D(texture, uv); \n "
" float d; \n "
" float attn; \n "
" float3 lightColour = float3(0, 0, 0); \n " ;
for ( int i = 0 ; i < num_lights ; + + i )
{
outStream < <
" float3 lightDir " < < i < < " = lightPositionObjSpace " < < i < < " .xyz - (positionObjSpace.xyz * lightPositionObjSpace " < < i < < " .w); \n "
// pre-multiply light color with attenuation factor
" d = length( lightDir " < < i < < " ); \n "
" attn = ( 1.0 / (( lightAttenuation " < < i < < " .y ) + ( lightAttenuation " < < i < < " .z * d ) + ( lightAttenuation " < < i < < " .w * d * d ))); \n "
" lightDiffuse " < < i < < " *= attn; \n "
// pre-multiply light color with attenuation factor
" d = length( lightDir " < < i < < " ); \n "
" attn = ( 1.0 / (( lightAttenuation " < < i < < " .y ) + ( lightAttenuation " < < i < < " .z * d ) + ( lightAttenuation " < < i < < " .w * d * d ))); \n "
" lightDiffuse " < < i < < " *= attn; \n "
" lightColour.xyz += lit(dot(normalize(lightDir " < < i < < " ), normalize(normal)), 0, 0).y * lightDiffuse " < < i < < " .xyz; \n " ;
}
outStream < <
" float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n "
" oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n "
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n "
" } " ;
fragment - > setSource ( outStream . str ( ) ) ;
fragment - > load ( ) ;
for ( int i = 0 ; i < num_lights ; + + i )
{
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightPositionObjSpace " + StringConverter : : toString ( i ) , GpuProgramParameters : : ACT_LIGHT_POSITION_OBJECT_SPACE , i ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightDiffuse " + StringConverter : : toString ( i ) , GpuProgramParameters : : ACT_LIGHT_DIFFUSE_COLOUR , i ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightAttenuation " + StringConverter : : toString ( i ) , GpuProgramParameters : : ACT_LIGHT_ATTENUATION , i ) ;
" lightColour.xyz += lit(dot(normalize(lightDir " < < i < < " ), normalize(normal)), 0, 0).y * lightDiffuse " < < i < < " .xyz; \n " ;
}
outStream < <
" float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n "
" oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n "
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n "
" } " ;
fragment - > setSource ( outStream . str ( ) ) ;
fragment - > load ( ) ;
for ( int i = 0 ; i < num_lights ; + + i )
{
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightPositionObjSpace " + StringConverter : : toString ( i ) , GpuProgramParameters : : ACT_LIGHT_POSITION_OBJECT_SPACE , i ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightDiffuse " + StringConverter : : toString ( i ) , GpuProgramParameters : : ACT_LIGHT_DIFFUSE_COLOUR , i ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightAttenuation " + StringConverter : : toString ( i ) , GpuProgramParameters : : ACT_LIGHT_ATTENUATION , i ) ;
}
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " emissive " , GpuProgramParameters : : ACT_SURFACE_EMISSIVE_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " diffuse " , GpuProgramParameters : : ACT_SURFACE_DIFFUSE_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " ambient " , GpuProgramParameters : : ACT_SURFACE_AMBIENT_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightAmbient " , GpuProgramParameters : : ACT_AMBIENT_LIGHT_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " fogColour " , GpuProgramParameters : : ACT_FOG_COLOUR ) ;
}
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " emissive " , GpuProgramParameters : : ACT_SURFACE_EMISSIVE_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " diffuse " , GpuProgramParameters : : ACT_SURFACE_DIFFUSE_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " ambient " , GpuProgramParameters : : ACT_SURFACE_AMBIENT_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " lightAmbient " , GpuProgramParameters : : ACT_AMBIENT_LIGHT_COLOUR ) ;
fragment - > getDefaultParameters ( ) - > setNamedAutoConstant ( " fogColour " , GpuProgramParameters : : ACT_FOG_COLOUR ) ;
else
fragment = mgr . getByName ( " main_fp " ) ;
material - > getTechnique ( 0 ) - > getPass ( 0 ) - > setFragmentProgram ( fragment - > getName ( ) ) ;
}
else
fragment = mgr . getByName ( " main_fp " ) ;
material - > getTechnique ( 0 ) - > getPass ( 0 ) - > setFragmentProgram ( fragment - > getName ( ) ) ;
}
// Takes a name and adds a unique part to it. This is just used to