summaryrefslogtreecommitdiffstats
path: root/o3d/core
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/core')
-rw-r--r--o3d/core/cross/effect.cc7
-rw-r--r--o3d/core/cross/effect_test.cc73
-rw-r--r--o3d/core/cross/gl/effect_gl.cc2
-rw-r--r--o3d/core/cross/gl/param_cache_gl.cc272
-rw-r--r--o3d/core/win/d3d9/effect_d3d9.cc442
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*>(&param_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*>(&param_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;
}