//already compare with OGLES1 spot and direct light~~~ both work
//ref.
https://github.com/daw42/glslcookbook/b ... er/spot.fs
//fixed for direct light and spot light --part two for COGLES2FixedPipelineRenderer.cpp
void COGLES2MaterialBaseCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
int MAX_SHADER_LIGHTS;
IVideoDriver* driver = services->getVideoDriver();
if (FirstUpdateBase)
{
WVPMatrixID = services->getVertexShaderConstantID("uWVPMatrix");
WVMatrixID = services->getVertexShaderConstantID("uWVMatrix");
NMatrixID = services->getVertexShaderConstantID("uNMatrix");
MaterialAmbientID = services->getVertexShaderConstantID("uMaterialAmbient");
MaterialDiffuseID = services->getVertexShaderConstantID("uMaterialDiffuse");
MaterialEmissiveID = services->getVertexShaderConstantID("uMaterialEmissive");
MaterialSpecularID = services->getVertexShaderConstantID("uMaterialSpecular");
MaterialShininessID = services->getVertexShaderConstantID("uMaterialShininess");
LightCountID = services->getVertexShaderConstantID("uLightCount");
LightTypeID = services->getVertexShaderConstantID("uLightType");
LightPositionID = services->getVertexShaderConstantID("uLightPosition");
LightDirectionID = services->getVertexShaderConstantID("uLightDirection");
LightAttenuationID = services->getVertexShaderConstantID("uLightAttenuation");
LightAmbientID = services->getVertexShaderConstantID("uLightAmbient");
LightDiffuseID = services->getVertexShaderConstantID("uLightDiffuse");
LightSpecularID = services->getVertexShaderConstantID("uLightSpecular");
FogEnableID = services->getVertexShaderConstantID("uFogEnable");
FogTypeID = services->getVertexShaderConstantID("uFogType");
FogColorID = services->getVertexShaderConstantID("uFogColor");
FogStartID = services->getVertexShaderConstantID("uFogStart");
FogEndID = services->getVertexShaderConstantID("uFogEnd");
FogDensityID = services->getVertexShaderConstantID("uFogDensity");
LightOuterConeID = services->getVertexShaderConstantID("uLightOuterCone");
LightFallOffID = services->getVertexShaderConstantID("uLightFallOff");
FirstUpdateBase = false;
}
const core::matrix4 W = driver->getTransform(ETS_WORLD);
const core::matrix4 V = driver->getTransform(ETS_VIEW);
const core::matrix4 P = driver->getTransform(ETS_PROJECTION);
/*core::matrix4 Matrix = P * V * W;
services->setPixelShaderConstant(WVPMatrixID, Matrix.pointer(), 16);
Matrix = V * W;
services->setPixelShaderConstant(WVMatrixID, Matrix.pointer(), 16);
Matrix.makeInverse();
services->setPixelShaderConstant(NMatrixID, Matrix.getTransposed().pointer(), 16);*/
core::matrix4 Matrix_V;
core::matrix4 Matrix_V_W = V * W;
core::matrix4 Matrix_P_V_W = P * Matrix_V_W;
services->setPixelShaderConstant(WVPMatrixID, Matrix_P_V_W.pointer(), 16);
services->setPixelShaderConstant(WVMatrixID, Matrix_V_W.pointer(), 16);
Matrix_V_W.makeInverse();
services->setPixelShaderConstant(NMatrixID, Matrix_V_W.getTransposed().pointer(), 16);
s32 LightCount = LightEnable ? driver->getDynamicLightCount() : 0;
services->setPixelShaderConstant(LightCountID, &LightCount, 1);
if (LightCount > 0)
{
services->setPixelShaderConstant(MaterialAmbientID, reinterpret_cast<f32*>(&MaterialAmbient), 4);
services->setPixelShaderConstant(MaterialDiffuseID, reinterpret_cast<f32*>(&MaterialDiffuse), 4);
services->setPixelShaderConstant(MaterialEmissiveID, reinterpret_cast<f32*>(&MaterialEmissive), 4);
services->setPixelShaderConstant(MaterialSpecularID, reinterpret_cast<f32*>(&MaterialSpecular), 4);
services->setPixelShaderConstant(MaterialShininessID, &MaterialShininess, 1);
//Matrix = V;
Matrix_V = V;
for (s32 i = 0; i < LightCount; ++i)
{
SLight CurrentLight = driver->getDynamicLight(i);
//Matrix.transformVect(CurrentLight.Position);
Matrix_V.transformVect(CurrentLight.Position);
switch (CurrentLight.Type)
{
case ELT_DIRECTIONAL:
LightType
= 2;
//for same as opengl and oges1 use, void COpenGLDriver::assignHardwareLight(u32 lightIndex)
//CurrentLight.Direction = LightDirInView(Matrix_V, CurrentLight.Direction)
CurrentLight.Position = -LightDirInView(Matrix_V, CurrentLight.Direction);
break;
case ELT_SPOT:
LightType = 1;
CurrentLight.Direction = LightDirInView(Matrix_V, CurrentLight.Direction);
break;
default: // ELT_POINT
LightType = 0;
break;
}
LightPosition = CurrentLight.Position;
LightDirection = CurrentLight.Direction;
LightAttenuation = CurrentLight.Attenuation;
LightAmbient = CurrentLight.AmbientColor;
LightDiffuse = CurrentLight.DiffuseColor;
LightSpecular = CurrentLight.SpecularColor;
LightOuterCone = CurrentLight.OuterCone;
LightFallOff[i] = CurrentLight.Falloff;
}
MAX_SHADER_LIGHTS = 8;
services->setPixelShaderConstant(LightTypeID, reinterpret_cast<s32*>(LightType), MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightPositionID, reinterpret_cast<f32*>(LightPosition), 3*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightDirectionID, reinterpret_cast<f32*>(LightDirection), 3*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightAttenuationID,reinterpret_cast<f32*>(LightAttenuation), 3*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightAmbientID, reinterpret_cast<f32*>(LightAmbient), 4*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightDiffuseID, reinterpret_cast<f32*>(LightDiffuse), 4*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightSpecularID, reinterpret_cast<f32*>(LightSpecular), 4*MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightOuterConeID, reinterpret_cast<f32*>(LightOuterCone), MAX_SHADER_LIGHTS);
services->setPixelShaderConstant(LightFallOffID, reinterpret_cast<f32*>(LightFallOff), MAX_SHADER_LIGHTS);
}
services->setPixelShaderConstant(FogEnableID, &FogEnable, 1);
if (FogEnable)
{
SColor TempColor(0);
E_FOG_TYPE TempType = EFT_FOG_LINEAR;
bool TempPerFragment = false;
bool TempRange = false;
driver->getFog(TempColor, TempType, FogStart, FogEnd, FogDensity, TempPerFragment, TempRange);
FogType = (s32)TempType;
FogColor = SColorf(TempColor);
services->setPixelShaderConstant(FogTypeID, &FogType, 1);
services->setPixelShaderConstant(FogColorID, reinterpret_cast<f32*>(&FogColor), 4);
services->setPixelShaderConstant(FogStartID, &FogStart, 1);
services->setPixelShaderConstant(FogEndID, &FogEnd, 1);
services->setPixelShaderConstant(FogDensityID, &FogDensity, 1);
}
}
core::vector3df COGLES2MaterialBaseCB::LightDirInView(core::matrix4 matrix, core::vector3df vec3_dir)
{
struct _Vec4_T
{
f32 x,y,z,w;
};
struct _Vec4_T vec4_dir;
vec4_dir.x = vec3_dir.X;
vec4_dir.y = vec3_dir.Y;
vec4_dir.z = vec3_dir.Z;
vec4_dir.w = 0.0;
vec4_dir.x = matrix[0*4+0]*vec4_dir.x + matrix[1*4+0]*vec4_dir.y + matrix[2*4+0]*vec4_dir.z; // + matrix[3*4+0]*vec4_dir.w;
vec4_dir.y = matrix[0*4+1]*vec4_dir.x + matrix[1*4+1]*vec4_dir.y + matrix[2*4+1]*vec4_dir.z; // + matrix[3*4+1]*vec4_dir.w;
vec4_dir.z = matrix[0*4+2]*vec4_dir.x + matrix[1*4+2]*vec4_dir.y + matrix[2*4+2]*vec4_dir.z; // + matrix[3*4+2]*vec4_dir.w;
//vec4_dir.w = matrix[0*4+3]*vec4_dir.x + matrix[1*4+3]*vec4_dir.y + matrix[2*4+3]*vec4_dir.z + matrix[3*4+3]*vec4_dir.w; //no need return
return core::vector3df(vec4_dir.x, vec4_dir.y, vec4_dir.z);
}