diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 00cdc0e00..fd96ad048 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -64,7 +64,7 @@ public: bool inUse; NiSourceTexturePtr texture; - int clamp, set, filter; + int clamp, uvSet, filter; short unknown2; void read(NIFStream *nif) @@ -75,7 +75,7 @@ public: texture.read(nif); clamp = nif->getInt(); filter = nif->getInt(); - set = nif->getInt(); + uvSet = nif->getInt(); // I have no idea, but I think these are actually two // PS2-specific shorts (ps2L and ps2K), followed by an unknown diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index c5dc7fbb9..f8eca821f 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -749,6 +749,13 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String instance->setProperty("diffuseMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BaseTexture])); instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture])); + instance->setProperty("emissiveMap", sh::makeProperty(texName[Nif::NiTexturingProperty::GlowTexture])); + if (!texName[Nif::NiTexturingProperty::GlowTexture].empty()) + { + instance->setProperty("use_emissive_map", sh::makeProperty(new sh::BooleanValue(true))); + instance->setProperty("emissiveMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::GlowTexture].uvSet))); + } + for(int i = 1;i < 7;i++) { if(!texName[i].empty()) diff --git a/files/materials/objects.mat b/files/materials/objects.mat index 00b43a9d0..8740c82c3 100644 --- a/files/materials/objects.mat +++ b/files/materials/objects.mat @@ -7,6 +7,9 @@ material openmw_objects_base vertmode 0 diffuseMap black.png normalMap + emissiveMap + use_emissive_map false + emissiveMapUVSet 0 is_transparent false // real transparency, alpha rejection doesn't count here scene_blend default @@ -24,6 +27,8 @@ material openmw_objects_base vertexcolor_mode $vertmode is_transparent $is_transparent normalMap $normalMap + emissiveMapUVSet $emissiveMapUVSet + emissiveMap $emissiveMap } diffuse $diffuse @@ -39,12 +44,21 @@ material openmw_objects_base { direct_texture $diffuseMap create_in_ffp true + tex_coord_set $emissiveMapUVSet } texture_unit normalMap { direct_texture $normalMap } + + texture_unit emissiveMap + { + create_in_ffp $use_emissive_map + colour_op add + direct_texture $emissiveMap + tex_coord_set $emissiveMapUVSet + } texture_unit shadowMap0 { diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 73968a6b3..d0e817373 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -15,6 +15,10 @@ #endif #define NORMAL_MAP @shPropertyHasValue(normalMap) +#define EMISSIVE_MAP @shPropertyHasValue(emissiveMap) + +// right now we support 2 UV sets max. implementing them is tedious, and we're probably not going to need more +#define SECOND_UV_SET @shPropertyString(emissiveMapUVSet) // if normal mapping is enabled, we force pixel lighting #define VERTEX_LIGHTING (!@shPropertyHasValue(normalMap)) @@ -42,7 +46,11 @@ #endif shVertexInput(float2, uv0) - shOutput(float2, UV) +#if SECOND_UV_SET + shVertexInput(float2, uv1) +#endif + shOutput(float4, UV) + shNormalInput(float4) #if NORMAL_MAP @@ -109,7 +117,12 @@ SH_START_PROGRAM { shOutputPosition = shMatrixMult(wvp, shInputPosition); - UV = uv0; + + UV.xy = uv0; +#if SECOND_UV_SET + UV.zw = uv1; +#endif + #if NORMAL_MAP tangentPassthrough = tangent.xyz; #endif @@ -219,7 +232,11 @@ shSampler2D(normalMap) #endif - shInput(float2, UV) +#if EMISSIVE_MAP + shSampler2D(emissiveMap) +#endif + + shInput(float4, UV) #if NORMAL_MAP shInput(float3, tangentPassthrough) @@ -294,7 +311,7 @@ SH_START_PROGRAM { - shOutputColour(0) = shSample(diffuseMap, UV); + shOutputColour(0) = shSample(diffuseMap, UV.xy); #if NORMAL_MAP float3 normal = normalPassthrough; @@ -399,6 +416,14 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); #endif +#endif + +#if EMISSIVE_MAP + #if SECOND_UV_SET + shOutputColour(0).xyz += shSample(emissiveMap, UV.zw).xyz; + #else + shOutputColour(0).xyz += shSample(emissiveMap, UV.xy).xyz; + #endif #endif // prevent negative colour output (for example with negative lights)