diff options
Diffstat (limited to 'o3d/core')
-rw-r--r-- | o3d/core/cross/effect.cc | 7 | ||||
-rw-r--r-- | o3d/core/cross/effect_test.cc | 73 | ||||
-rw-r--r-- | o3d/core/cross/gl/effect_gl.cc | 2 | ||||
-rw-r--r-- | o3d/core/cross/gl/param_cache_gl.cc | 272 | ||||
-rw-r--r-- | o3d/core/win/d3d9/effect_d3d9.cc | 442 |
5 files changed, 76 insertions, 720 deletions
diff --git a/o3d/core/cross/effect.cc b/o3d/core/cross/effect.cc index 64b109d..9c271fb 100644 --- a/o3d/core/cross/effect.cc +++ b/o3d/core/cross/effect.cc @@ -125,11 +125,12 @@ void Effect::CreateSpecifiedParameters(ParamObject* param_object, bool sas) { param = param_object->CreateParamByClass( param_info.name(), param_info.sas_class_type() ? param_info.sas_class_type() : - param_info.class_type()); + param_info.class_type()); } else { // Array type - param = - param_object->CreateParam<ParamParamArray>(param_info.name()); + param = param_object->CreateParamByClass( + param_info.name(), + ParamParamArray::GetApparentClass()); } if (!param) { errors += String(errors.empty() ? "" : "\n") + diff --git a/o3d/core/cross/effect_test.cc b/o3d/core/cross/effect_test.cc index b26f632..af028e6 100644 --- a/o3d/core/cross/effect_test.cc +++ b/o3d/core/cross/effect_test.cc @@ -34,7 +34,6 @@ #include "core/cross/effect.h" #include "core/cross/primitive.h" #include "core/cross/standard_param.h" -#include "core/cross/param_array.h" #include "core/cross/stream.h" #include "tests/common/win/testing_common.h" @@ -162,7 +161,7 @@ uint32 kIndexBlock[4] = { 0, 1, 2, 3 }; -bool IsExpectedParamInfo(const EffectParameterInfo& info) { +bool IsExpectedParam(const EffectParameterInfo& info) { for (unsigned ii = 0; ii < arraysize(expected_params); ++ii) { const ParamInfo& expected_info = expected_params[ii]; if (info.name().compare(expected_info.name) == 0) { @@ -334,75 +333,7 @@ TEST_F(EffectTest, GetEffectParameters) { EXPECT_EQ(arraysize(expected_params), info.size()); for (EffectParameterInfoArray::size_type ii = 0; ii < info.size(); ++ii) { - EXPECT_TRUE(IsExpectedParamInfo(info[ii])); - } - - // Clean up. - object_manager()->DestroyPack(pack); -} - -TEST_F(EffectTest, CreateUniformParameters) { - Pack* pack = object_manager()->CreatePack(); - ASSERT_TRUE(pack != NULL); - - // load an effect - Effect *fx = pack->Create<Effect>(); - ASSERT_TRUE(fx != NULL); - EXPECT_TRUE(fx->LoadFromFXString(String(kLambertEffect))); - - ParamObject* param_object = pack->Create<ParamObject>(); - ASSERT_TRUE(param_object != NULL); - - // Check that we get the correct params - fx->CreateUniformParameters(param_object); - - for (unsigned ii = 0; ii < arraysize(expected_params); ++ii) { - const ParamInfo& expected_info = expected_params[ii]; - Param* param = param_object->GetUntypedParam(expected_info.name); - if (expected_info.sas_type) { - ASSERT_TRUE(param == NULL); - } else { - ASSERT_TRUE(param != NULL); - if (expected_info.num_elements > 0) { - ASSERT_TRUE(param->IsA(ParamParamArray::GetApparentClass())); - } else { - EXPECT_TRUE(param->IsA(expected_info.type)); - } - } - } - - // Clean up. - object_manager()->DestroyPack(pack); -} - -TEST_F(EffectTest, CreateSASParameters) { - Pack* pack = object_manager()->CreatePack(); - ASSERT_TRUE(pack != NULL); - - // load an effect - Effect *fx = pack->Create<Effect>(); - ASSERT_TRUE(fx != NULL); - EXPECT_TRUE(fx->LoadFromFXString(String(kLambertEffect))); - - ParamObject* param_object = pack->Create<ParamObject>(); - ASSERT_TRUE(param_object != NULL); - - // Check that we get the correct params - fx->CreateSASParameters(param_object); - - for (unsigned ii = 0; ii < arraysize(expected_params); ++ii) { - const ParamInfo& expected_info = expected_params[ii]; - Param* param = param_object->GetUntypedParam(expected_info.name); - if (expected_info.sas_type) { - ASSERT_TRUE(param != NULL); - if (expected_info.num_elements > 0) { - ASSERT_TRUE(param->IsA(ParamParamArray::GetApparentClass())); - } else { - EXPECT_TRUE(param->IsA(expected_info.sas_type)); - } - } else { - ASSERT_TRUE(param == NULL); - } + EXPECT_TRUE(IsExpectedParam(info[ii])); } // Clean up. diff --git a/o3d/core/cross/gl/effect_gl.cc b/o3d/core/cross/gl/effect_gl.cc index d8c24d4..9fe940e 100644 --- a/o3d/core/cross/gl/effect_gl.cc +++ b/o3d/core/cross/gl/effect_gl.cc @@ -75,7 +75,6 @@ static const ObjectBase::Class* CgTypeToParamType(CGtype cg_type) { case CG_FLOAT2 : return ParamFloat2::GetApparentClass(); case CG_FLOAT3 : return ParamFloat3::GetApparentClass(); case CG_FLOAT4 : return ParamFloat4::GetApparentClass(); - case CG_INT : return ParamInteger::GetApparentClass(); case CG_INT1 : return ParamInteger::GetApparentClass(); case CG_FLOAT4x4 : return ParamMatrix4::GetApparentClass(); case CG_BOOL : @@ -83,7 +82,6 @@ static const ObjectBase::Class* CgTypeToParamType(CGtype cg_type) { case CG_SAMPLER : case CG_SAMPLER1D : case CG_SAMPLER2D : - case CG_SAMPLER3D : case CG_SAMPLERCUBE : return ParamSampler::GetApparentClass(); default : { DLOG(ERROR) << "Cannot convert CGtype " diff --git a/o3d/core/cross/gl/param_cache_gl.cc b/o3d/core/cross/gl/param_cache_gl.cc index 8b46da2..b91245e 100644 --- a/o3d/core/cross/gl/param_cache_gl.cc +++ b/o3d/core/cross/gl/param_cache_gl.cc @@ -179,7 +179,8 @@ class EffectParamHandlerForSamplersGL : public EffectParamHandlerGL { SamplerGL* sampler_gl = down_cast<SamplerGL*>(param_->value()); if (!sampler_gl) { // Use the error sampler. - sampler_gl = down_cast<SamplerGL*>(renderer->error_sampler()); + sampler_gl = down_cast<SamplerGL*>( + renderer->error_sampler()); // If no error texture is set then generate an error. if (!renderer->error_texture()) { O3D_ERROR(param_->service_locator()) @@ -190,220 +191,41 @@ class EffectParamHandlerForSamplersGL : public EffectParamHandlerGL { } virtual void ResetEffectParam(RendererGL* renderer, CGparameter cg_param) { SamplerGL* sampler_gl = down_cast<SamplerGL*>(param_->value()); - if (!sampler_gl) { - sampler_gl = down_cast<SamplerGL*>(renderer->error_sampler()); + if (sampler_gl) { + sampler_gl->ResetTexture(cg_param); } - sampler_gl->ResetTexture(cg_param); } private: ParamSampler* param_; }; -template <typename T> -class EffectParamArrayHandlerGL : public EffectParamHandlerGL { +class EffectParamFloatArrayHandlerGL : public EffectParamHandlerGL { public: - explicit EffectParamArrayHandlerGL(ParamParamArray* param) + explicit EffectParamFloatArrayHandlerGL(ParamParamArray* param) : param_(param) { } - virtual void SetEffectParam(RendererGL* renderer, CGparameter cg_param) { - ParamArray* param = param_->value(); - if (param) { - int size = cgGetArraySize(cg_param, 0); - if (size != static_cast<int>(param->size())) { - O3D_ERROR(param->service_locator()) - << "number of params in ParamArray does not match number of params " - << "needed by shader array"; - } else { - for (int i = 0; i < size; ++i) { - Param* untyped_element = param->GetUntypedParam(i); - // TODO: Make this check happen when building the param cache. - // To do that would require that ParamParamArray mark it's owner - // as changed if a Param in it's ParamArray changes. - if (untyped_element->IsA(T::GetApparentClass())) { - CGparameter cg_element = cgGetArrayParameter(cg_param, i); - SetElement(cg_element, down_cast<T*>(untyped_element)); - } else { - O3D_ERROR(param->service_locator()) - << "Param in ParamArray at index " << i << " is not a " - << T::GetApparentClassName(); - } - } - } - } - } - void SetElement(CGparameter cg_element, T* param); - - private: - ParamParamArray* param_; -}; - -template <bool column_major> -class EffectParamArrayMatrix4HandlerGL : public EffectParamHandlerGL { - public: - explicit EffectParamArrayMatrix4HandlerGL(ParamParamArray* param) - : param_(param) { - } - virtual void SetEffectParam(RendererGL* renderer, CGparameter cg_param) { - ParamArray* param = param_->value(); - if (param) { - int size = cgGetArraySize(cg_param, 0); - if (size != static_cast<int>(param->size())) { - O3D_ERROR(param->service_locator()) - << "number of params in ParamArray does not match number of params " - << "needed by shader array"; - } else { - for (int i = 0; i < size; ++i) { - Param* untyped_element = param->GetUntypedParam(i); - // TODO: Make this check happen when building the param cache. - // To do that would require that ParamParamArray mark it's owner - // as changed if a Param in it's ParamArray changes. - if (untyped_element->IsA(ParamMatrix4::GetApparentClass())) { - CGparameter cg_element = cgGetArrayParameter(cg_param, i); - SetElement(cg_element, down_cast<ParamMatrix4*>(untyped_element)); - } else { - O3D_ERROR(param->service_locator()) - << "Param in ParamArray at index " << i - << " is not a ParamMatrix4"; - } - } - } - } - } - void SetElement(CGparameter cg_element, ParamMatrix4* param); - + virtual void SetEffectParam(RendererGL* renderer, CGparameter cg_param); private: ParamParamArray* param_; }; -class EffectParamArraySamplerHandlerGL : public EffectParamHandlerGL { - public: - explicit EffectParamArraySamplerHandlerGL(ParamParamArray* param) - : param_(param) { - } - virtual void SetEffectParam(RendererGL* renderer, CGparameter cg_param) { - ParamArray* param = param_->value(); - if (param) { - int size = cgGetArraySize(cg_param, 0); - if (size != static_cast<int>(param->size())) { - O3D_ERROR(param->service_locator()) - << "number of params in ParamArray does not match number of params " - << "needed by shader array"; +void EffectParamFloatArrayHandlerGL::SetEffectParam( + RendererGL* renderer, + CGparameter cg_param) { + ParamArray* param = param_->value(); + if (param) { + int cg_size = cgGetArraySize(cg_param, 0); + int size = std::min(static_cast<int>(param->size()), cg_size); + for (int i = 0; i < size; ++i) { + ParamFloat* element = param->GetParam<ParamFloat>(i); + CGparameter cg_element = cgGetArrayParameter(cg_param, i); + if (element) { + cgSetParameter1f(cg_element, element->value()); } else { - for (int i = 0; i < size; ++i) { - Param* untyped_element = param->GetUntypedParam(i); - // TODO: Make this check happen when building the param cache. - // To do that would require that ParamParamArray mark it's owner - // as changed if a Param in it's ParamArray changes. - if (untyped_element->IsA(ParamSampler::GetApparentClass())) { - CGparameter cg_element = cgGetArrayParameter(cg_param, i); - ParamSampler* element = down_cast<ParamSampler*>(untyped_element); - SamplerGL* sampler_gl = down_cast<SamplerGL*>(element->value()); - if (!sampler_gl) { - // Use the error sampler. - sampler_gl = down_cast<SamplerGL*>(renderer->error_sampler()); - // If no error texture is set then generate an error. - if (!renderer->error_texture()) { - O3D_ERROR(param_->service_locator()) - << "Missing Sampler for ParamSampler '" << param_->name() - << "' index " << i; - } - } - sampler_gl->SetTextureAndStates(cg_element); - } else { - O3D_ERROR(param->service_locator()) - << "Param in ParamArray at index " << i - << " is not a ParamSampler"; - } - } - } - } - } - virtual void ResetEffectParam(RendererGL* renderer, CGparameter cg_param) { - ParamArray* param = param_->value(); - if (param) { - int size = cgGetArraySize(cg_param, 0); - if (size == static_cast<int>(param->size())) { - for (int i = 0; i < size; ++i) { - Param* untyped_element = param->GetUntypedParam(i); - if (untyped_element->IsA(ParamSampler::GetApparentClass())) { - CGparameter cg_element = cgGetArrayParameter(cg_param, i); - ParamSampler* element = down_cast<ParamSampler*>(untyped_element); - SamplerGL* sampler_gl = down_cast<SamplerGL*>(element->value()); - if (!sampler_gl) { - sampler_gl = down_cast<SamplerGL*>(renderer->error_sampler()); - } - sampler_gl->ResetTexture(cg_param); - } - } + cgSetParameter1f(cg_element, 0.0f); } } } - - private: - ParamParamArray* param_; -}; - -template<> -void EffectParamArrayHandlerGL<ParamFloat>::SetElement( - CGparameter cg_element, - ParamFloat* param) { - cgSetParameter1f(cg_element, param->value()); -} - -template<> -void EffectParamArrayHandlerGL<ParamFloat2>::SetElement( - CGparameter cg_element, - ParamFloat2* param) { - Float2 f = param->value(); - cgSetParameter2fv(cg_element, f.GetFloatArray()); -} - -template<> -void EffectParamArrayHandlerGL<ParamFloat3>::SetElement( - CGparameter cg_element, - ParamFloat3* param) { - Float3 f = param->value(); - cgSetParameter3fv(cg_element, f.GetFloatArray()); -} - -template<> -void EffectParamArrayHandlerGL<ParamFloat4>::SetElement( - CGparameter cg_element, - ParamFloat4* param) { - Float4 f = param->value(); - cgSetParameter4fv(cg_element, f.GetFloatArray()); -} - -template<> -void EffectParamArrayMatrix4HandlerGL<false>::SetElement( - CGparameter cg_element, - ParamMatrix4* param) { - // set the data as floats in row major order. - Matrix4 mat = param->value(); - cgSetMatrixParameterfr(cg_element, &mat[0][0]); -} - -template<> -void EffectParamArrayMatrix4HandlerGL<true>::SetElement( - CGparameter cg_element, - ParamMatrix4* param) { - // set the data as floats in column major order. - Matrix4 mat = param->value(); - cgSetMatrixParameterfc(cg_element, &mat[0][0]); -} - -template<> -void EffectParamArrayHandlerGL<ParamInteger>::SetElement( - CGparameter cg_element, - ParamInteger* param) { - cgSetParameter1i(cg_element, param->value()); -} - -template<> -void EffectParamArrayHandlerGL<ParamBoolean>::SetElement( - CGparameter cg_element, - ParamBoolean* param) { - cgSetParameter1i(cg_element, param->value()); } static EffectParamHandlerGL::Ref GetHandlerFromParamAndCgType( @@ -412,52 +234,10 @@ static EffectParamHandlerGL::Ref GetHandlerFromParamAndCgType( CGtype cg_type) { EffectParamHandlerGL::Ref handler; if (param->IsA(ParamParamArray::GetApparentClass())) { - ParamParamArray* param_param_array = down_cast<ParamParamArray*>(param); - switch (cg_type) { - case CG_FLOAT: - case CG_FLOAT1: - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayHandlerGL<ParamFloat>(param_param_array)); - break; - case CG_FLOAT2: - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayHandlerGL<ParamFloat2>(param_param_array)); - break; - case CG_FLOAT3: - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayHandlerGL<ParamFloat3>(param_param_array)); - break; - case CG_FLOAT4: - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayHandlerGL<ParamFloat4>(param_param_array)); - break; - case CG_FLOAT4x4: - if (effect_gl->matrix_load_order() == Effect::COLUMN_MAJOR) { - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayMatrix4HandlerGL<true>(param_param_array)); - } else { - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayMatrix4HandlerGL<false>(param_param_array)); - } - break; - case CG_INT: - case CG_INT1: - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayHandlerGL<ParamInteger>(param_param_array)); - break; - case CG_BOOL: - case CG_BOOL1: - handler = EffectParamHandlerGL::Ref( - new EffectParamArrayHandlerGL<ParamBoolean>(param_param_array)); - break; - case CG_SAMPLER: - case CG_SAMPLER1D: - case CG_SAMPLER2D: - case CG_SAMPLER3D: - case CG_SAMPLERCUBE: - handler = EffectParamHandlerGL::Ref( - new EffectParamArraySamplerHandlerGL(param_param_array)); - break; + if (cg_type == CG_FLOAT) { + handler = EffectParamHandlerGL::Ref( + new EffectParamFloatArrayHandlerGL( + down_cast<ParamParamArray*>(param))); } } else if (param->IsA(ParamMatrix4::GetApparentClass())) { if (cg_type == CG_FLOAT4x4) { @@ -499,13 +279,13 @@ static EffectParamHandlerGL::Ref GetHandlerFromParamAndCgType( down_cast<ParamFloat4*>(param))); } } else if (param->IsA(ParamInteger::GetApparentClass())) { - if (cg_type == CG_INT || cg_type == CG_INT1) { + if (cg_type == CG_INT) { handler = EffectParamHandlerGL::Ref( new TypedEffectParamHandlerGL<ParamInteger>( down_cast<ParamInteger*>(param))); } } else if (param->IsA(ParamBoolean::GetApparentClass())) { - if (cg_type == CG_BOOL || cg_type == CG_BOOL1) { + if (cg_type == CG_BOOL) { handler = EffectParamHandlerGL::Ref( new TypedEffectParamHandlerGL<ParamBoolean>( down_cast<ParamBoolean*>(param))); diff --git a/o3d/core/win/d3d9/effect_d3d9.cc b/o3d/core/win/d3d9/effect_d3d9.cc index 566145f..216e6b9 100644 --- a/o3d/core/win/d3d9/effect_d3d9.cc +++ b/o3d/core/win/d3d9/effect_d3d9.cc @@ -32,8 +32,6 @@ // This file contains the definition of EffectD3D9. -// TODO: Most of the D3DXHANDLE lookup could be cached. - #include "core/cross/precompile.h" #include "core/win/d3d9/effect_d3d9.h" @@ -55,18 +53,6 @@ namespace o3d { -namespace { - -inline bool IsSamplerType(D3DXPARAMETER_TYPE type) { - return type == D3DXPT_SAMPLER || - type == D3DXPT_SAMPLER1D || - type == D3DXPT_SAMPLER2D || - type == D3DXPT_SAMPLER3D || - type == D3DXPT_SAMPLERCUBE; -} - -} // anonymous namespace - // A 'mostly' typesafe class to set an effect parameter from an O3D // Param. The phandle must match the type of Param to be typesafe. That is // handled when these are created. @@ -83,329 +69,22 @@ class TypedEffectParamHandlerD3D9 : public EffectParamHandlerD3D9 { D3DXHANDLE phandle_; }; -template <typename T> -class EffectParamArrayHandlerD3D9 : public EffectParamHandlerD3D9 { +class EffectParamFloatArrayHandlerD3D9 : public EffectParamHandlerD3D9 { public: - EffectParamArrayHandlerD3D9(ParamParamArray* param, - D3DXHANDLE phandle, - unsigned num_elements) + EffectParamFloatArrayHandlerD3D9(ParamParamArray* param, D3DXHANDLE phandle) : param_(param), - phandle_(phandle), - num_elements_(num_elements) { - } - virtual void SetEffectParam(RendererD3D9* renderer, ID3DXEffect* d3d_effect) { - ParamArray* param = param_->value(); - if (param) { - int size = param->size(); - if (size != num_elements_) { - O3D_ERROR(param->service_locator()) - << "number of params in ParamArray does not match number of params " - << "needed by shader array"; - } else { - for (int i = 0; i < size; ++i) { - Param* untyped_element = param->GetUntypedParam(i); - // TODO: Make this check happen when building the param cache. - // To do that would require that ParamParamArray mark it's owner - // as changed if a Param in it's ParamArray changes. - if (untyped_element->IsA(T::GetApparentClass())) { - D3DXHANDLE dx_element = - d3d_effect->GetParameterElement(phandle_, i); - SetElement(d3d_effect, dx_element, down_cast<T*>(untyped_element)); - } else { - O3D_ERROR(param->service_locator()) - << "Param in ParamArray at index " << i << " is not a " - << T::GetApparentClassName(); - } - } - } - } + phandle_(phandle) { } - void SetElement(ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - T* element); - + virtual void SetEffectParam(RendererD3D9* renderer, ID3DXEffect* d3d_effect); private: ParamParamArray* param_; D3DXHANDLE phandle_; - unsigned num_elements_; }; // Number of h/w sampler units in the same shader using a single sampler. // Eight should be enough! static const int kMaxUnitsPerSampler = 8; -template <bool column_major> -class EffectParamMatrix4ArrayHandlerD3D9 : public EffectParamHandlerD3D9 { - public: - EffectParamMatrix4ArrayHandlerD3D9(ParamParamArray* param, - D3DXHANDLE phandle, - unsigned num_elements) - : param_(param), - phandle_(phandle), - num_elements_(num_elements) { - } - virtual void SetEffectParam(RendererD3D9* renderer, ID3DXEffect* d3d_effect) { - ParamArray* param = param_->value(); - if (param) { - int size = param->size(); - if (size != num_elements_) { - O3D_ERROR(param->service_locator()) - << "number of params in ParamArray does not match number of params " - << "needed by shader array"; - } else { - for (int i = 0; i < size; ++i) { - Param* untyped_element = param->GetUntypedParam(i); - // TODO: Make this check happen when building the param cache. - // To do that would require that ParamParamArray mark it's owner - // as changed if a Param in it's ParamArray changes. - if (untyped_element->IsA(ParamMatrix4::GetApparentClass())) { - D3DXHANDLE dx_element = - d3d_effect->GetParameterElement(phandle_, i); - SetElement(d3d_effect, - dx_element, - down_cast<ParamMatrix4*>(untyped_element)); - } else { - O3D_ERROR(param->service_locator()) - << "Param in ParamArray at index " << i << " is not a " - << ParamMatrix4::GetApparentClassName(); - } - } - } - } - } - void SetElement(ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamMatrix4* element); - - private: - ParamParamArray* param_; - D3DXHANDLE phandle_; - unsigned num_elements_; -}; - -// A class for setting the the appropriate d3d sampler states from an array of -// o3d Sampler object. -class EffectParamSamplerArrayHandlerD3D9 : public EffectParamHandlerD3D9 { - public: - EffectParamSamplerArrayHandlerD3D9(ParamParamArray* param, - D3DXHANDLE phandle, - const D3DXPARAMETER_DESC& pdesc, - LPD3DXCONSTANTTABLE fs_constant_table, - LPDIRECT3DDEVICE9 d3d_device) - : param_(param), - phandle_(phandle), - sampler_unit_index_arrays_(pdesc.Elements) { - if (!fs_constant_table) { - DLOG(ERROR) << "Fragment shader constant table is NULL"; - return; - } - D3DXHANDLE sampler_array_handle = fs_constant_table->GetConstantByName( - NULL, - pdesc.Name); - if (!sampler_array_handle) { - DLOG(ERROR) << "Sampler " << pdesc.Name << - " not found in fragment shader"; - return; - } - for (unsigned ii = 0; ii < pdesc.Elements; ++ii) { - D3DXHANDLE sampler_handle = fs_constant_table->GetConstantElement( - sampler_array_handle, - ii); - if (!sampler_handle) { - DLOG(ERROR) << "Sampler " << pdesc.Name << " index " << ii - << " not found in fragment shader"; - } else { - D3DXCONSTANT_DESC desc_array[kMaxUnitsPerSampler]; - UINT num_desc = kMaxUnitsPerSampler; - fs_constant_table->GetConstantDesc( - sampler_handle, desc_array, &num_desc); - // We have no good way of querying how many descriptions would really be - // returned as we're capping the number to kMaxUnitsPerSampler (which - // should be more than sufficient). If however we do end up with the - // max number there's a chance that there were actually more so let's - // log it. - if (num_desc == kMaxUnitsPerSampler) { - DLOG(WARNING) << "Number of constant descriptions might have " - << "exceeded the maximum of " << kMaxUnitsPerSampler; - } - SamplerUnitIndexArray& index_array = sampler_unit_index_arrays_[ii]; - - for (UINT desc_index = 0; desc_index < num_desc; desc_index++) { - D3DXCONSTANT_DESC constant_desc = desc_array[desc_index]; - if (constant_desc.Class == D3DXPC_OBJECT && - IsSamplerType(constant_desc.Type)) { - index_array.push_back(constant_desc.RegisterIndex); - } - } - if (index_array.empty()) { - DLOG(ERROR) << "No matching sampler units found for " << - pdesc.Name; - } - } - } - } - - virtual void SetEffectParam(RendererD3D9* renderer, ID3DXEffect* d3d_effect) { - ParamArray* param = param_->value(); - if (param) { - unsigned size = param->size(); - if (size != sampler_unit_index_arrays_.size()) { - O3D_ERROR(param->service_locator()) - << "number of params in ParamArray does not match number of params " - << "needed by shader array"; - } else { - for (int i = 0; i < size; ++i) { - SamplerUnitIndexArray& index_array = sampler_unit_index_arrays_[i]; - Param* untyped_element = param->GetUntypedParam(i); - // TODO: Make this check happen when building the param cache. - // To do that would require that ParamParamArray mark it's owner - // as changed if a Param in it's ParamArray changes. - if (untyped_element->IsA(ParamSampler::GetApparentClass())) { - D3DXHANDLE dx_element = - d3d_effect->GetParameterElement(phandle_, i); - // Find the texture associated with the sampler first. - Sampler* sampler = - down_cast<ParamSampler*>(untyped_element)->value(); - if (!sampler) { - sampler = renderer->error_sampler(); - if (!renderer->error_texture()) { - O3D_ERROR(param->service_locator()) - << "Missing Sampler for ParamSampler " - << param->name(); - } - } - - SamplerD3D9* d3d_sampler = down_cast<SamplerD3D9*>(sampler); - for (unsigned stage = 0; stage < index_array.size(); stage++) { - d3d_sampler->SetTextureAndStates(index_array[stage]); - } - } else { - O3D_ERROR(param->service_locator()) - << "Param in ParamArray at index " << i << " is not a " - << ParamSampler::GetApparentClassName(); - } - } - } - } - } - - // Resets the value of the parameter to default. Currently this is used - // to unbind textures contained in Sampler params. - virtual void ResetEffectParam(RendererD3D9* renderer, - ID3DXEffect* d3d_effect) { - ParamArray* param = param_->value(); - if (param) { - unsigned size = param->size(); - if (size == sampler_unit_index_arrays_.size()) { - for (int i = 0; i < size; ++i) { - SamplerUnitIndexArray& index_array = sampler_unit_index_arrays_[i]; - Param* untyped_element = param->GetUntypedParam(i); - // TODO: Make this check happen when building the param cache. - // To do that would require that ParamParamArray mark it's owner - // as changed if a Param in it's ParamArray changes. - if (untyped_element->IsA(ParamSampler::GetApparentClass())) { - D3DXHANDLE dx_element = - d3d_effect->GetParameterElement(phandle_, i); - // Find the texture associated with the sampler first. - Sampler* sampler = - down_cast<ParamSampler*>(untyped_element)->value(); - if (!sampler) { - sampler = renderer->error_sampler(); - } - - SamplerD3D9* d3d_sampler = down_cast<SamplerD3D9*>(sampler); - for (unsigned stage = 0; stage < index_array.size(); stage++) { - d3d_sampler->ResetTexture(index_array[stage]); - } - } - } - } - } - } - - private: - typedef std::vector<int> SamplerUnitIndexArray; - typedef std::vector<SamplerUnitIndexArray> SamplerIndexArrayArray; - - ParamParamArray* param_; - D3DXHANDLE phandle_; - // An array of arrays of sampler unit indices. - SamplerIndexArrayArray sampler_unit_index_arrays_; -}; - -template<> -void EffectParamArrayHandlerD3D9<ParamFloat>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamFloat* element) { - d3dx_effect->SetFloat(dx_element, element->value()); -} - -template<> -void EffectParamArrayHandlerD3D9<ParamFloat2>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamFloat2* element) { - Float2 float2 = element->value(); - HR(d3dx_effect->SetFloatArray(dx_element, float2.GetFloatArray(), 2)); -} - -template<> -void EffectParamArrayHandlerD3D9<ParamFloat3>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamFloat3* element) { - Float3 float3 = element->value(); - HR(d3dx_effect->SetFloatArray(dx_element, float3.GetFloatArray(), 3)); -} - -template<> -void EffectParamArrayHandlerD3D9<ParamFloat4>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamFloat4* element) { - Float4 float4 = element->value(); - HR(d3dx_effect->SetFloatArray(dx_element, float4.GetFloatArray(), 4)); -} - -template<> -void EffectParamArrayHandlerD3D9<ParamBoolean>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamBoolean* element) { - HR(d3dx_effect->SetBool(dx_element, element->value())); -} - -template<> -void EffectParamArrayHandlerD3D9<ParamInteger>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamInteger* element) { - HR(d3dx_effect->SetInt(dx_element, element->value())); -} - -template<> -void EffectParamMatrix4ArrayHandlerD3D9<false>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamMatrix4* element) { - Matrix4 param_matrix = element->value(); - HR(d3dx_effect->SetMatrix( - dx_element, - reinterpret_cast<D3DXMATRIX*>(¶m_matrix[0][0]))); -} - -template<> -void EffectParamMatrix4ArrayHandlerD3D9<true>::SetElement( - ID3DXEffect* d3dx_effect, - D3DXHANDLE dx_element, - ParamMatrix4* element) { - Matrix4 param_matrix = transpose(element->value()); - HR(d3dx_effect->SetMatrix( - dx_element, - reinterpret_cast<D3DXMATRIX*>(¶m_matrix[0][0]))); -} - // A class for setting the the appropriate d3d sampler states from a // o3d Sampler object. class EffectParamHandlerForSamplersD3D9 : public EffectParamHandlerD3D9 { @@ -471,7 +150,10 @@ static const ObjectBase::Class* D3DXPDescToParamType( pdesc.Class == D3DXPC_OBJECT) { return ParamTexture::GetApparentClass(); // Sampler param - } else if (pdesc.Class == D3DXPC_OBJECT && IsSamplerType(pdesc.Type)) { + } else if (pdesc.Class == D3DXPC_OBJECT && + (pdesc.Type == D3DXPT_SAMPLER || + pdesc.Type == D3DXPT_SAMPLER2D || + pdesc.Type == D3DXPT_SAMPLERCUBE)) { return ParamSampler::GetApparentClass(); } return NULL; @@ -674,69 +356,12 @@ bool EffectD3D9::AddParameterMapping( D3DXHANDLE phandle, EffectParamHandlerCacheD3D9* effect_param_cache) { // Array param - if (param->IsA(ParamParamArray::GetApparentClass()) && pdesc.Elements > 0) { - ParamParamArray* param_param_array = down_cast<ParamParamArray*>(param); - if (pdesc.Class == D3DXPC_SCALAR && - pdesc.Type == D3DXPT_FLOAT) { - effect_param_cache->AddElement( - new EffectParamArrayHandlerD3D9<ParamFloat>( - param_param_array, phandle, pdesc.Elements)); - } else if (pdesc.Class == D3DXPC_VECTOR && - pdesc.Type == D3DXPT_FLOAT && - pdesc.Columns == 2) { - effect_param_cache->AddElement( - new EffectParamArrayHandlerD3D9<ParamFloat2>( - param_param_array, phandle, pdesc.Elements)); - } else if (pdesc.Class == D3DXPC_VECTOR && - pdesc.Type == D3DXPT_FLOAT && - pdesc.Columns == 3) { - effect_param_cache->AddElement( - new EffectParamArrayHandlerD3D9<ParamFloat3>( - param_param_array, phandle, pdesc.Elements)); - } else if (pdesc.Class == D3DXPC_VECTOR && - pdesc.Type == D3DXPT_FLOAT && - pdesc.Columns == 4) { - effect_param_cache->AddElement( - new EffectParamArrayHandlerD3D9<ParamFloat4>( - param_param_array, phandle, pdesc.Elements)); - } else if (pdesc.Class == D3DXPC_SCALAR && - pdesc.Type == D3DXPT_INT && - pdesc.Columns == 1) { + if (param->IsA(ParamParamArray::GetApparentClass()) && + pdesc.Elements > 1) { + if (pdesc.Class == D3DXPC_SCALAR && pdesc.Type == D3DXPT_FLOAT) { effect_param_cache->AddElement( - new EffectParamArrayHandlerD3D9<ParamInteger>( - param_param_array, phandle, pdesc.Elements)); - } else if (pdesc.Class == D3DXPC_SCALAR && - pdesc.Type == D3DXPT_BOOL && - pdesc.Columns == 1) { - effect_param_cache->AddElement( - new EffectParamArrayHandlerD3D9<ParamBoolean>( - param_param_array, phandle, pdesc.Elements)); - } else if (pdesc.Class == D3DXPC_MATRIX_COLUMNS) { - effect_param_cache->AddElement( - new EffectParamMatrix4ArrayHandlerD3D9<true>( - param_param_array, phandle, pdesc.Elements)); - } else if (pdesc.Class == D3DXPC_MATRIX_ROWS) { - if (matrix_load_order() == COLUMN_MAJOR) { - // D3D has already created a uniform of type MATRIX_ROWS, but the - // effect wants column major matrices, so we create a handler - // for MATRIX_COLUMNS. This will cause the matrix to be transposed - // on load. - effect_param_cache->AddElement( - new EffectParamMatrix4ArrayHandlerD3D9<true>( - param_param_array, phandle, pdesc.Elements)); - } else { - effect_param_cache->AddElement( - new EffectParamMatrix4ArrayHandlerD3D9<false>( - param_param_array, phandle, pdesc.Elements)); - } - } else if (pdesc.Class == D3DXPC_OBJECT && IsSamplerType(pdesc.Type)) { - effect_param_cache->AddElement( - new EffectParamSamplerArrayHandlerD3D9( - param_param_array, - phandle, - pdesc, - fs_constant_table_, - d3d_device_)); + new EffectParamFloatArrayHandlerD3D9( + down_cast<ParamParamArray*>(param), phandle)); } // Matrix4 Param } else if (param->IsA(ParamMatrix4::GetApparentClass()) && @@ -750,7 +375,7 @@ bool EffectD3D9::AddParameterMapping( if (matrix_load_order() == COLUMN_MAJOR) { // D3D has already created a uniform of type MATRIX_ROWS, but the // effect wants column major matrices, so we create a handler - // for MATRIX_COLUMNS. This will cause the matrix to be transposed + // for MATRIX_COLUMNS. This will cause the matrix to be tranposed // on load. effect_param_cache->AddElement( new TypedEffectParamHandlerD3D9<ParamMatrix4, @@ -828,7 +453,10 @@ bool EffectD3D9::AddParameterMapping( down_cast<ParamTexture*>(param), phandle)); // Sampler param } else if (param->IsA(ParamSampler::GetApparentClass()) && - pdesc.Class == D3DXPC_OBJECT && IsSamplerType(pdesc.Type)) { + pdesc.Class == D3DXPC_OBJECT && + (pdesc.Type == D3DXPT_SAMPLER || + pdesc.Type == D3DXPT_SAMPLER2D || + pdesc.Type == D3DXPT_SAMPLERCUBE)) { effect_param_cache->AddElement( new EffectParamHandlerForSamplersD3D9(down_cast<ParamSampler*>(param), pdesc, @@ -1065,6 +693,24 @@ void TypedEffectParamHandlerD3D9<ParamTexture, } } +void EffectParamFloatArrayHandlerD3D9::SetEffectParam( + RendererD3D9* renderer, + ID3DXEffect* d3dx_effect) { + ParamArray* param = param_->value(); + if (param) { + int size = param->size(); + for (int i = 0; i < size; ++i) { + ParamFloat* element = param->GetParam<ParamFloat>(i); + D3DXHANDLE dx_element = d3dx_effect->GetParameterElement(phandle_, i); + if (element) { + d3dx_effect->SetFloat(dx_element, element->value()); + } else { + d3dx_effect->SetFloat(dx_element, 0.0); + } + } + } +} + void EffectParamHandlerForSamplersD3D9::SetEffectParam( RendererD3D9* renderer, ID3DXEffect* d3dx_effect) { @@ -1088,13 +734,11 @@ void EffectParamHandlerForSamplersD3D9::ResetEffectParam( RendererD3D9* renderer, ID3DXEffect* d3dx_effect) { Sampler* sampler = sampler_param_->value(); - if (!sampler) { - sampler = renderer->error_sampler(); - } - - SamplerD3D9* d3d_sampler = down_cast<SamplerD3D9*>(sampler); - for (int stage = 0; stage < number_sampler_units_; stage++) { - d3d_sampler->ResetTexture(sampler_unit_index_array_[stage]); + if (sampler) { + SamplerD3D9* d3d_sampler = down_cast<SamplerD3D9*>(sampler); + for (int stage = 0; stage < number_sampler_units_; stage++) { + d3d_sampler->ResetTexture(sampler_unit_index_array_[stage]); + } } } @@ -1137,7 +781,9 @@ EffectParamHandlerForSamplersD3D9::EffectParamHandlerForSamplersD3D9( for (UINT desc_index = 0; desc_index < num_desc; desc_index++) { D3DXCONSTANT_DESC constant_desc = desc_array[desc_index]; if (constant_desc.Class == D3DXPC_OBJECT && - IsSamplerType(constant_desc.Type)) { + (constant_desc.Type == D3DXPT_SAMPLER || + constant_desc.Type == D3DXPT_SAMPLER2D || + constant_desc.Type == D3DXPT_SAMPLERCUBE)) { sampler_unit_index_array_[number_sampler_units_++] = constant_desc.RegisterIndex; } |