commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
674
include/engine/gpu/gpu_shader.cpp
Normal file
674
include/engine/gpu/gpu_shader.cpp
Normal file
@ -0,0 +1,674 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __PLATFORM_IOS__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "gpu/gpu_renderer.h"
|
||||
#include "core/renderer_environment_interface.h"
|
||||
#include "core/light.h"
|
||||
#include "core/camera.h"
|
||||
#include "core/object.h"
|
||||
#include "core/shader.h"
|
||||
#include "container/narray.h"
|
||||
#include "platform_config.h"
|
||||
#include "platform.h"
|
||||
#include "log/file_log.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
using namespace GS::GPU;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Shader::SetVertexStreamInputs(DisplayList &dls)
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryVertexStream].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryVertexStream][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::Position:
|
||||
Set(*input->location, 3, Types::ValueHalfFloat, false, dls.stride, (const void *)dls.vertex_offset);
|
||||
break;
|
||||
case Core::ShaderInput::Normal:
|
||||
Set(*input->location, 3, Types::ValueByte, true, dls.stride, (const void *)dls.normal_offset);
|
||||
break;
|
||||
case Core::ShaderInput::VertexColor:
|
||||
Set(*input->location, 4, Types::ValueUByte, true, dls.stride, (const void *)dls.rgb_offset);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::Tangent:
|
||||
Set(*input->location, 3, Types::ValueByte, true, dls.stride, (const void *)dls.tangent_offset);
|
||||
break;
|
||||
case Core::ShaderInput::Bitangent:
|
||||
Set(*input->location, 3, Types::ValueByte, true, dls.stride, (const void *)(dls.tangent_offset + 4 * sizeof(char)));
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::BoneIndex:
|
||||
Set(*input->location, 4, Types::ValueUByte, false, dls.stride, (const void *)dls.skinning_offset);
|
||||
break;
|
||||
case Core::ShaderInput::BoneWeight:
|
||||
Set(*input->location, 4, Types::ValueUByte, true, dls.stride, (const void *)(dls.skinning_offset + 4 * sizeof(char)));
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::UV0:
|
||||
case Core::ShaderInput::UV1:
|
||||
case Core::ShaderInput::UV2:
|
||||
{
|
||||
int uv_index = (int)input->semantic - (int)Core::ShaderInput::UV0;
|
||||
Set(*input->location, 2, Types::ValueHalfFloat, false, dls.stride, (const void *)dls.uv_offset[uv_index]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetSkinInputs(DisplayList &dls, Core::Skin &skin)
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategorySkin].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategorySkin][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::BoneMatrix:
|
||||
if (float *m = (float *)alloca(4 * 4 * sizeof(float) * dls.bone.GetCount()))
|
||||
{
|
||||
float *p_m = m;
|
||||
for (uint n = 0; n < dls.bone.GetCount(); ++n)
|
||||
{
|
||||
Memory::Copy(p_m, skin.bones_mtx[dls.bone[n]].m, 4 * 4 * sizeof(float));
|
||||
p_m += 4 * 4;
|
||||
}
|
||||
|
||||
Set(*input->location, (Matrix4 *)m, dls.bone.GetCount());
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::PreviousBoneMatrix:
|
||||
if (float *m = (float *)alloca(4 * 4 * sizeof(float) * dls.bone.GetCount()))
|
||||
{
|
||||
float *p_m = m;
|
||||
for (uint n = 0; n < dls.bone.GetCount(); ++n)
|
||||
{
|
||||
Memory::Copy(p_m, skin.previous_bones_mtx[dls.bone[n]].m, 4 * 4 * sizeof(float));
|
||||
p_m += 4 * 4;
|
||||
}
|
||||
|
||||
Set(*input->location, (Matrix4 *)m, dls.bone.GetCount());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetConstantInputs()
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryConstant].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryConstant][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::Constant:
|
||||
switch (input->data_type)
|
||||
{
|
||||
default:
|
||||
case Core::ShaderInput::Matrix3:
|
||||
case Core::ShaderInput::Matrix4:
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::DataTexture2D:
|
||||
case Core::ShaderInput::DataTexture3D:
|
||||
case Core::ShaderInput::DataTextureCube:
|
||||
Set(*input->location, *input->parm_t, input->index);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::Int:
|
||||
Set(*input->location, (int *)&input->parm_v.x);
|
||||
break;
|
||||
case Core::ShaderInput::Float:
|
||||
Set(*input->location, &input->parm_v.x);
|
||||
break;
|
||||
case Core::ShaderInput::Vector2:
|
||||
Set(*input->location, &input->parm_v.x, 2);
|
||||
break;
|
||||
case Core::ShaderInput::Vector3:
|
||||
Set(*input->location, &input->parm_v.x, 3);
|
||||
break;
|
||||
case Core::ShaderInput::Vector4:
|
||||
Set(*input->location, &input->parm_v.x, 4);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetTextureInputs()
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryTexture].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryTexture][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::Texture2D:
|
||||
case Core::ShaderInput::Texture3D:
|
||||
case Core::ShaderInput::TextureCube:
|
||||
if (input->parm_t)
|
||||
Set(*input->location, *input->parm_t, input->index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetRendererInputs(Renderer &r, Material *m)
|
||||
{
|
||||
Color fog_color;
|
||||
float fog_near = 0, fog_far = 0;
|
||||
|
||||
bool fog_enabled = r.environment_interface ? r.environment_interface->GetFogConfiguration(fog_color, fog_near, fog_far) : false;
|
||||
|
||||
if (r.performance_tools.disable_fog)
|
||||
fog_enabled = false;
|
||||
if (m && (m->blendop == Core::Material::Blend_Add))
|
||||
fog_enabled = false;
|
||||
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryRenderer].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryRenderer][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::Clock:
|
||||
Set(*input->location, r.frame_clock);
|
||||
break;
|
||||
case Core::ShaderInput::TimeOfDay:
|
||||
Set(*input->location, r.environment_interface->GetTimeOfDay());
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::ViewVector:
|
||||
{
|
||||
Vector4 tmp = r.GetCamera()->GetMatrix().GetRow(2);
|
||||
Set(*input->location, &tmp.x, 3);
|
||||
}
|
||||
break;
|
||||
case Core::ShaderInput::ViewPosition:
|
||||
{
|
||||
Vector4 tmp = r.GetCamera()->GetMatrix().GetRow(3);
|
||||
Set(*input->location, &tmp.x, 4);
|
||||
}
|
||||
break;
|
||||
case Core::ShaderInput::Viewport:
|
||||
{
|
||||
const fRect viewport = r.GetViewport();
|
||||
float v[4] = { viewport.sx, viewport.sy, viewport.GetWidth(), viewport.GetHeight() };
|
||||
Set(*input->location, v, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::ZNear:
|
||||
Set(*input->location, r.GetCamera()->GetNearClippingPlane());
|
||||
break;
|
||||
case Core::ShaderInput::ZFar:
|
||||
Set(*input->location, r.GetCamera()->GetFarClippingPlane());
|
||||
break;
|
||||
case Core::ShaderInput::ZoomFactor:
|
||||
Set(*input->location, r.GetCamera()->zoom_factor);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::DisplayBufferRatio:
|
||||
{
|
||||
float v[] = { r.GetOutputAspectRatio(), 1.f };
|
||||
Set(*input->location, v, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::ViewportRatio:
|
||||
{
|
||||
float v[] = { r.GetViewport().GetHeight() / r.GetViewport().GetWidth(), 1.f };
|
||||
Set(*input->location, v, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::FxScale:
|
||||
Set(*input->location, float(r.fx_scale));
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::InverseBufferSize:
|
||||
{
|
||||
tVector2 <uint> d = r.GetOutputDimensions();
|
||||
float v[] = { 1.f / d.x, 1.f / d.y };
|
||||
Set(*input->location, v, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::InverseViewportSize:
|
||||
{
|
||||
float v[] = { 1.f / r.GetViewport().GetWidth(), 1.f / r.GetViewport().GetHeight() };
|
||||
Set(*input->location, v, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::ViewDepthOffset:
|
||||
{
|
||||
float k = 0.f;
|
||||
Set(*input->location, &k);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::AmbientColor:
|
||||
{
|
||||
Color ambient = r.environment_interface->GetAmbientColor();
|
||||
Set(*input->location, &ambient.x, 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::FogColor:
|
||||
Set(*input->location, &fog_color.x, 3);
|
||||
break;
|
||||
case Core::ShaderInput::FogNear:
|
||||
Set(*input->location, fog_near);
|
||||
break;
|
||||
case Core::ShaderInput::FogFar:
|
||||
Set(*input->location, fog_far);
|
||||
break;
|
||||
case Core::ShaderInput::FogInverseRange:
|
||||
{
|
||||
bool use_fog = fog_enabled && (fog_far > 0.0);
|
||||
if (m && (m->renderword & Core::Material::Render_NoFog))
|
||||
use_fog = false;
|
||||
|
||||
Set(*input->location, use_fog ? 1.f / (fog_far - fog_near) : -1.f);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::DepthBuffer:
|
||||
if (r.render_technique == Renderer::TechniqueDeferred)
|
||||
Set(*input->location, *r.t_gbuffer[0], input->index);
|
||||
else Set(*input->location, *r.t_depth, input->index);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::FrameBuffer:
|
||||
if (r.t_fx[0].IsValid())
|
||||
Set(*input->location, *r.t_fx[0], input->index);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::GBuffer0:
|
||||
case Core::ShaderInput::GBuffer1:
|
||||
case Core::ShaderInput::GBuffer2:
|
||||
case Core::ShaderInput::GBuffer3:
|
||||
Set(*input->location, *r.t_gbuffer[input->semantic - Core::ShaderInput::GBuffer0], input->index);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::NoiseMap:
|
||||
if (r.t_noise.IsValid())
|
||||
Set(*input->location, *r.t_noise, input->index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetTransformInputs(const Matrix4 &v_pm, const Matrix4 &v_m, const Matrix4 &v_im, const Matrix4 *i_m, const Matrix4 *i_im, uint count)
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryTransform].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryTransform][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::NormalMatrix:
|
||||
if (Matrix3 *n_m = (Matrix3 *)alloca(sizeof(Matrix3) * count))
|
||||
{
|
||||
for (uint n = 0; n < count; ++n)
|
||||
n_m[n] = Matrix3::FromMatrix4(i_m[n]).Normalized();
|
||||
Set(*input->location, n_m, count);
|
||||
}
|
||||
break;
|
||||
case Core::ShaderInput::NormalViewMatrix:
|
||||
if (Matrix3 *nv_m = (Matrix3 *)alloca(sizeof(Matrix3) * count))
|
||||
{
|
||||
Matrix3 vn_m = Matrix3::FromMatrix4(v_m).Normalized().Transposed();
|
||||
for (uint n = 0; n < count; ++n)
|
||||
nv_m[n] = vn_m * Matrix3::FromMatrix4(i_m[n]).Normalized();
|
||||
Set(*input->location, nv_m, count);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::ModelMatrix:
|
||||
Set(*input->location, i_m, count);
|
||||
break;
|
||||
case Core::ShaderInput::ViewMatrix:
|
||||
Set(*input->location, v_im);
|
||||
break;
|
||||
case Core::ShaderInput::ProjectionMatrix:
|
||||
Set(*input->location, v_pm);
|
||||
break;
|
||||
case Core::ShaderInput::ModelViewMatrix:
|
||||
if (Matrix4 *mv_m = (Matrix4 *)alloca(sizeof(Matrix4) * count))
|
||||
{
|
||||
for (uint n = 0; n < count; ++n)
|
||||
mv_m[n] = v_im * i_m[n];
|
||||
Set(*input->location, mv_m, count);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::ModelViewProjectionMatrix:
|
||||
if (Matrix4 *mvp_m = (Matrix4 *)alloca(sizeof(Matrix4) * count))
|
||||
{
|
||||
for (uint n = 0; n < count; ++n)
|
||||
mvp_m[n] = v_pm * (v_im * i_m[n]);
|
||||
Set(*input->location, mvp_m, count);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::InverseViewProjectionMatrix:
|
||||
{
|
||||
Matrix4 vpm = v_pm * v_im, ivpm;
|
||||
vpm.Inverse(ivpm);
|
||||
Set(*input->location, ivpm);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::InverseViewProjectionMatrixAtOrigin:
|
||||
{
|
||||
Matrix4 v_im_o = v_im;
|
||||
v_im_o.SetRow(3, Vector4(0, 0, 0, 1));
|
||||
|
||||
Matrix4 vpm = v_pm * v_im_o, ivpm;
|
||||
vpm.Inverse(ivpm);
|
||||
Set(*input->location, ivpm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetPreviousTransformInputs(const Matrix4 &v_pm, const Matrix4 &v_im, const Matrix4 *i_m, uint count)
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryPreviousTransform].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryPreviousTransform][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::PreviousModelViewMatrix:
|
||||
if (Matrix4 *mv_m = (Matrix4 *)alloca(sizeof(Matrix4) * count))
|
||||
{
|
||||
for (uint n = 0; n < count; ++n)
|
||||
mv_m[n] = v_im * i_m[n];
|
||||
Set(*input->location, mv_m, count);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::PreviousModelViewProjectionMatrix:
|
||||
if (Matrix4 *mvp_m = (Matrix4 *)alloca(sizeof(Matrix4) * count))
|
||||
{
|
||||
for (uint n = 0; n < count; ++n)
|
||||
mvp_m[n] = v_pm * (v_im * i_m[n]);
|
||||
Set(*input->location, mvp_m, count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetMaterialOpacityInputs(Material &m, float opacity)
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryMaterialOpacity].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryMaterialOpacity][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::MaterialOpacity:
|
||||
Set(*input->location, m.opacity * opacity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetMaterialInputs(Material &m)
|
||||
{
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryMaterial].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryMaterial][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::MaterialDiffuse:
|
||||
Set(*input->location, &m.diffuse.x, 4);
|
||||
break;
|
||||
case Core::ShaderInput::MaterialSpecular:
|
||||
Set(*input->location, &m.specular.x, 4);
|
||||
break;
|
||||
case Core::ShaderInput::MaterialAmbient:
|
||||
Set(*input->location, &m.ambient.x, 4);
|
||||
break;
|
||||
case Core::ShaderInput::MaterialSelf:
|
||||
Set(*input->location, &m.self.x, 4);
|
||||
break;
|
||||
case Core::ShaderInput::MaterialGlossiness:
|
||||
Set(*input->location, m.glossiness);
|
||||
break;
|
||||
case Core::ShaderInput::MaterialReflection:
|
||||
Set(*input->location, m.reflection);
|
||||
break;
|
||||
case Core::ShaderInput::MaterialAlphaThreshold:
|
||||
Set(*input->location, m.athreshold);
|
||||
break;
|
||||
case Core::ShaderInput::MaterialDepthBias:
|
||||
Set(*input->location, m.depth_bias);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::MaterialTexture0:
|
||||
case Core::ShaderInput::MaterialTexture1:
|
||||
case Core::ShaderInput::MaterialTexture2:
|
||||
case Core::ShaderInput::MaterialTexture3:
|
||||
case Core::ShaderInput::MaterialTexture4:
|
||||
case Core::ShaderInput::MaterialTexture5:
|
||||
case Core::ShaderInput::MaterialTexture6:
|
||||
case Core::ShaderInput::MaterialTexture7:
|
||||
if (Render::Texture *t = m.texture_table[input->semantic - Core::ShaderInput::MaterialTexture0])
|
||||
Set(*input->location, *t, input->index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Shader::SetLightInputs(Renderer &r, Core::Camera &view_item, Core::Light &l)
|
||||
{
|
||||
float k_clip_fade = 1.f;
|
||||
|
||||
if (l.range > 0.f) // [EJ] fade on last 10% of clip range
|
||||
{
|
||||
float c = l.clip_distance + l.range;
|
||||
float d = Vector4::Dist(view_item.GetMatrix().GetRow(3), l.GetMatrix().GetRow(3));
|
||||
|
||||
k_clip_fade = 1.f - GS::Types::Clamp((d - c * 0.9f) / (c * 0.1f));
|
||||
}
|
||||
|
||||
if (Core::Light::RenderData *light_render_data = (Core::Light::RenderData *)l.render_data.c_ptr())
|
||||
for (uint n = 0; n < input_list[Core::ShaderInput::CategoryLight].GetCount(); ++n)
|
||||
{
|
||||
ShaderInput *input = &input_list[Core::ShaderInput::CategoryLight][n];
|
||||
|
||||
switch (input->semantic)
|
||||
{
|
||||
case Core::ShaderInput::LightRange:
|
||||
Set(*input->location, l.range);
|
||||
break;
|
||||
case Core::ShaderInput::LightSpotEdge:
|
||||
Set(*input->location, Math::Cos(l.edge_angle + l.cone_angle));
|
||||
break;
|
||||
case Core::ShaderInput::LightSpotCone:
|
||||
Set(*input->location, Math::Cos(l.cone_angle));
|
||||
break;
|
||||
case Core::ShaderInput::LightShadowBias:
|
||||
Set(*input->location, l.shadow_bias);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightDiffuseColor:
|
||||
{
|
||||
Color c = l.diffuse_color * l.diffuse_intensity * k_clip_fade;
|
||||
Set(*input->location, &c.x, 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightSpecularColor:
|
||||
{
|
||||
Color c = l.specular_color * l.specular_intensity * k_clip_fade;
|
||||
Set(*input->location, &c.x, 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightShadowColor:
|
||||
Set(*input->location, &l.shadow_color.x, 3);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightViewPosition:
|
||||
{
|
||||
Vector4 p = l.GetMatrix().GetRow(3) * view_item.GetInverseMatrix();
|
||||
Set(*input->location, &p.x, 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightViewDirection:
|
||||
{
|
||||
Vector4 d = l.GetMatrix().GetRow(2) * Matrix3::FromMatrix4(view_item.GetMatrix()).Normalized().Transposed();
|
||||
Set(*input->location, &d.x, 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightShadowMatrix0:
|
||||
case Core::ShaderInput::LightShadowMatrix1:
|
||||
case Core::ShaderInput::LightShadowMatrix2:
|
||||
case Core::ShaderInput::LightShadowMatrix3:
|
||||
case Core::ShaderInput::LightShadowMatrix4:
|
||||
case Core::ShaderInput::LightShadowMatrix5:
|
||||
{
|
||||
uint n = input->semantic - Core::ShaderInput::LightShadowMatrix0;
|
||||
if (n < light_render_data->shadow_data.GetCount())
|
||||
Set(*input->location, light_render_data->shadow_data[n].pmatrix * (light_render_data->shadow_data[n].imatrix * view_item.GetMatrix()));
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::InverseShadowMapSize:
|
||||
{
|
||||
float k = r.pcf_radius / r.gpu_config.shadow_size;
|
||||
Set(*input->location, k);
|
||||
}
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightShadowMap0:
|
||||
case Core::ShaderInput::LightShadowMap1:
|
||||
case Core::ShaderInput::LightShadowMap2:
|
||||
case Core::ShaderInput::LightShadowMap3:
|
||||
case Core::ShaderInput::LightShadowMap4:
|
||||
case Core::ShaderInput::LightShadowMap5:
|
||||
Set(*input->location, *r.shadow_map, input->index);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightPSSMSliceDistance0:
|
||||
case Core::ShaderInput::LightPSSMSliceDistance1:
|
||||
case Core::ShaderInput::LightPSSMSliceDistance2:
|
||||
case Core::ShaderInput::LightPSSMSliceDistance3:
|
||||
if (light_render_data->shadow_data)
|
||||
Set(*input->location, light_render_data->shadow_data[input->semantic - Core::ShaderInput::LightPSSMSliceDistance0].slice_distance);
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::ViewToLightMatrix:
|
||||
Set(*input->location, l.GetInverseMatrix() * view_item.GetMatrix());
|
||||
break;
|
||||
|
||||
case Core::ShaderInput::LightProjectionMap:
|
||||
if (light_render_data->projection_texture.IsValid())
|
||||
Set(*input->location, *light_render_data->projection_texture, input->index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint Shader::GetSemanticInputList(Core::ShaderInput::Semantic semantic)
|
||||
{
|
||||
return Core::ShaderInput::semantic_desc[semantic].category;
|
||||
}
|
||||
ShaderInput *Shader::GetInput(Core::ShaderInput::Semantic semantic) const
|
||||
{
|
||||
uint cat = GetSemanticInputList(semantic);
|
||||
for (uint n = 0; n < input_list[cat].GetCount(); ++n)
|
||||
if (input_list[cat][n].semantic == semantic)
|
||||
return &input_list[cat][n];
|
||||
return NULL;
|
||||
}
|
||||
ShaderInput *Shader::GetInput(const char *n) const
|
||||
{
|
||||
String name(n);
|
||||
for (uint l = 0; l < Core::ShaderInput::CategoryLast; ++l) // need to check all categories here
|
||||
for (uint n = 0; n < input_list[l].GetCount(); ++n)
|
||||
if (!input_list[l][n].name.IsEmpty() && (input_list[l][n].name == name))
|
||||
return &input_list[l][n];
|
||||
return NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Shader::Create(Render::ResourceFactory &rf, const Core::Shader &shader)
|
||||
{
|
||||
Free();
|
||||
|
||||
__RASSERT_MSG__(renderer.shader_compiler != NULL, String::Format("No shader compiler available for this renderer ('%s').", renderer.GetName()));
|
||||
|
||||
if (!renderer.shader_compiler->Compile(shader, *this))
|
||||
return false;
|
||||
|
||||
// Solve uniforms and attributes.
|
||||
Array <AutoPtr <ShaderInputLocation> > locations(shader.input_list.GetCount());
|
||||
|
||||
uint solved_count[Core::ShaderInput::CategoryLast], n = 0;
|
||||
Memory::Set(solved_count, 0, sizeof(uint) * Core::ShaderInput::CategoryLast);
|
||||
ListForeachPtr(Core::ShaderInput *, input, shader.input_list)
|
||||
{
|
||||
uint input_index = GetSemanticInputList(input->semantic);
|
||||
|
||||
locations[n] = NewGPUShaderLocation();
|
||||
if (GetLocation(input->name, *locations[n], input->type))
|
||||
solved_count[input_index]++;
|
||||
else
|
||||
locations[n] = NULL;
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
uint texture_count = 0;
|
||||
for (uint l = 0; l < Core::ShaderInput::CategoryLast; ++l)
|
||||
{
|
||||
uint n = 0, i = 0;
|
||||
|
||||
if (input_list[l].Allocate(solved_count[l]))
|
||||
ListForeachPtr(Core::ShaderInput *, input, shader.input_list)
|
||||
{
|
||||
if ((l != GetSemanticInputList(input->semantic)) || locations[i].IsNull())
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
ShaderInput *gpu_input = &input_list[l][n];
|
||||
gpu_input->location = locations[i].Detach();
|
||||
gpu_input->Set(input);
|
||||
|
||||
// Allocate texture unit index and load render resource.
|
||||
if (input->type == Core::ShaderInput::Uniform)
|
||||
if (input->ConsumesTextureUnit())
|
||||
{
|
||||
if (!input->parm_t.IsEmpty())
|
||||
gpu_input->parm_t = rf.LoadTexture(input->parm_t);
|
||||
gpu_input->index = texture_count++;
|
||||
}
|
||||
|
||||
++i; ++n;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user