|
|
@@ -43,6 +43,7 @@
|
|
|
#include "../../Resource/ResourceCache.h"
|
|
|
#include "../../Graphics/Shader.h"
|
|
|
#include "../../Graphics/ShaderPrecache.h"
|
|
|
+#include "../../Graphics/ShaderProgram.h"
|
|
|
#include "../../Graphics/ShaderVariation.h"
|
|
|
#include "../../Graphics/Skybox.h"
|
|
|
#include "../../Graphics/StaticModelGroup.h"
|
|
|
@@ -272,7 +273,7 @@ Graphics::Graphics(Context* context) :
|
|
|
numBatches_(0),
|
|
|
maxScratchBufferRequest_(0),
|
|
|
defaultTextureFilterMode_(FILTER_TRILINEAR),
|
|
|
- currentShaderParameters_(0),
|
|
|
+ shaderProgram_(0),
|
|
|
shaderPath_("Shaders/HLSL/"),
|
|
|
shaderExtension_(".hlsl"),
|
|
|
orientations_("LandscapeLeft LandscapeRight"),
|
|
|
@@ -1167,29 +1168,17 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
|
|
|
if (vertexShader_ && pixelShader_)
|
|
|
{
|
|
|
Pair<ShaderVariation*, ShaderVariation*> key = MakePair(vertexShader_, pixelShader_);
|
|
|
- HashMap<Pair<ShaderVariation*, ShaderVariation*>, HashMap<StringHash, Pair<ShaderType, unsigned> > >::Iterator i =
|
|
|
- shaderParameters_.Find(key);
|
|
|
- if (i != shaderParameters_.End())
|
|
|
- currentShaderParameters_ = &i->second_;
|
|
|
+ ShaderProgramMap::Iterator i = shaderPrograms_.Find(key);
|
|
|
+ if (i != shaderPrograms_.End())
|
|
|
+ shaderProgram_ = i->second_.Get();
|
|
|
else
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >& parameters = shaderParameters_[key];
|
|
|
-
|
|
|
- const HashMap<StringHash, ShaderParameter>& vsParams = vertexShader_->GetParameters();
|
|
|
- for (HashMap<StringHash, ShaderParameter>::ConstIterator i = vsParams.Begin(); i != vsParams.End(); ++i)
|
|
|
- parameters[i->first_] = MakePair(i->second_.type_, i->second_.register_);
|
|
|
-
|
|
|
- const HashMap<StringHash, ShaderParameter>& psParams = pixelShader_->GetParameters();
|
|
|
- for (HashMap<StringHash, ShaderParameter>::ConstIterator i = psParams.Begin(); i != psParams.End(); ++i)
|
|
|
- parameters[i->first_] = MakePair(i->second_.type_, i->second_.register_);
|
|
|
-
|
|
|
- // Optimize shader parameter lookup by rehashing to next power of two
|
|
|
- parameters.Rehash(NextPowerOfTwo(parameters.Size()));
|
|
|
- currentShaderParameters_ = ¶meters;
|
|
|
+ ShaderProgram* newProgram = shaderPrograms_[key] = new ShaderProgram(vertexShader_, pixelShader_);
|
|
|
+ shaderProgram_ = newProgram;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
- currentShaderParameters_ = 0;
|
|
|
+ shaderProgram_ = 0;
|
|
|
|
|
|
// Store shader combination if shader dumping in progress
|
|
|
if (shaderPrecache_)
|
|
|
@@ -1198,161 +1187,148 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const float* data, unsigned count)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, data, count / 4);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, data, count / 4);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, data, count / 4);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, data, count / 4);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, float value)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- float data[4];
|
|
|
-
|
|
|
- data[0] = value;
|
|
|
- data[1] = 0.0f;
|
|
|
- data[2] = 0.0f;
|
|
|
- data[3] = 0.0f;
|
|
|
+ static Vector4 data(Vector4::ZERO);
|
|
|
+ data.x_ = value;
|
|
|
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, &data[0], 1);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, &data.x_, 1);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, &data[0], 1);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, &data.x_, 1);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, bool value)
|
|
|
{
|
|
|
/// \todo Bool constants possibly have no effect on Direct3D9
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
BOOL data = value;
|
|
|
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantB(i->second_.second_, &data, 1);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantB(i->second_.register_, &data, 1);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantB(i->second_.second_, &data, 1);
|
|
|
+ impl_->device_->SetPixelShaderConstantB(i->second_.register_, &data, 1);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Color& color)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, color.Data(), 1);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, color.Data(), 1);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, color.Data(), 1);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, color.Data(), 1);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- float data[4];
|
|
|
+ static Vector4 data(Vector4::ZERO);
|
|
|
+ data.x_ = vector.x_;
|
|
|
+ data.y_ = vector.y_;
|
|
|
|
|
|
- data[0] = vector.x_;
|
|
|
- data[1] = vector.y_;
|
|
|
- data[2] = 0.0f;
|
|
|
- data[3] = 0.0f;
|
|
|
-
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, &data[0], 1);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, &data.x_, 1);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, &data[0], 1);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, &data.x_, 1);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- float data[12];
|
|
|
-
|
|
|
- data[0] = matrix.m00_;
|
|
|
- data[1] = matrix.m01_;
|
|
|
- data[2] = matrix.m02_;
|
|
|
- data[3] = 0.0f;
|
|
|
- data[4] = matrix.m10_;
|
|
|
- data[5] = matrix.m11_;
|
|
|
- data[6] = matrix.m12_;
|
|
|
- data[7] = 0.0f;
|
|
|
- data[8] = matrix.m20_;
|
|
|
- data[9] = matrix.m21_;
|
|
|
- data[10] = matrix.m22_;
|
|
|
- data[11] = 0.0f;
|
|
|
-
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, &data[0], 3);
|
|
|
+ static Matrix3x4 data(Matrix3x4::ZERO);
|
|
|
+ data.m00_ = matrix.m00_;
|
|
|
+ data.m01_ = matrix.m01_;
|
|
|
+ data.m02_ = matrix.m02_;
|
|
|
+ data.m10_ = matrix.m10_;
|
|
|
+ data.m11_ = matrix.m11_;
|
|
|
+ data.m12_ = matrix.m12_;
|
|
|
+ data.m20_ = matrix.m20_;
|
|
|
+ data.m21_ = matrix.m21_;
|
|
|
+ data.m22_ = matrix.m22_;
|
|
|
+
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, &data.m00_, 3);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, &data[0], 3);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, &data.m00_, 3);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- float data[4];
|
|
|
-
|
|
|
- data[0] = vector.x_;
|
|
|
- data[1] = vector.y_;
|
|
|
- data[2] = vector.z_;
|
|
|
- data[3] = 0.0f;
|
|
|
-
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, &data[0], 1);
|
|
|
+ static Vector4 data(Vector4::ZERO);
|
|
|
+ data.x_ = vector.x_;
|
|
|
+ data.y_ = vector.y_;
|
|
|
+ data.z_ = vector.z_;
|
|
|
+
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, &data.x_, 1);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, &data[0], 1);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, &data.x_, 1);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, matrix.Data(), 4);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, matrix.Data(), 4);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, matrix.Data(), 4);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, matrix.Data(), 4);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, vector.Data(), 1);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, vector.Data(), 1);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, vector.Data(), 1);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, vector.Data(), 1);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Matrix3x4& matrix)
|
|
|
{
|
|
|
- HashMap<StringHash, Pair<ShaderType, unsigned> >::Iterator i;
|
|
|
- if (!currentShaderParameters_ || (i = currentShaderParameters_->Find(param)) == currentShaderParameters_->End())
|
|
|
+ HashMap<StringHash, ShaderParameter>::Iterator i;
|
|
|
+ if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
|
|
|
return;
|
|
|
|
|
|
- if (i->second_.first_ == VS)
|
|
|
- impl_->device_->SetVertexShaderConstantF(i->second_.second_, matrix.Data(), 3);
|
|
|
+ if (i->second_.type_ == VS)
|
|
|
+ impl_->device_->SetVertexShaderConstantF(i->second_.register_, matrix.Data(), 3);
|
|
|
else
|
|
|
- impl_->device_->SetPixelShaderConstantF(i->second_.second_, matrix.Data(), 3);
|
|
|
+ impl_->device_->SetPixelShaderConstantF(i->second_.register_, matrix.Data(), 3);
|
|
|
}
|
|
|
|
|
|
void Graphics::SetShaderParameter(StringHash param, const Variant& value)
|
|
|
@@ -1414,7 +1390,7 @@ bool Graphics::NeedParameterUpdate(ShaderParameterGroup group, const void* sourc
|
|
|
|
|
|
bool Graphics::HasShaderParameter(StringHash param)
|
|
|
{
|
|
|
- return currentShaderParameters_ && currentShaderParameters_->Find(param) != currentShaderParameters_->End();
|
|
|
+ return shaderProgram_ && shaderProgram_->parameters_.Find(param) != shaderProgram_->parameters_.End();
|
|
|
}
|
|
|
|
|
|
bool Graphics::HasTextureUnit(TextureUnit unit)
|
|
|
@@ -2294,19 +2270,19 @@ void Graphics::CleanupScratchBuffers()
|
|
|
maxScratchBufferRequest_ = 0;
|
|
|
}
|
|
|
|
|
|
-void Graphics::CleanupShaderParameters(ShaderVariation* variation)
|
|
|
+void Graphics::CleanupShaderPrograms(ShaderVariation* variation)
|
|
|
{
|
|
|
- for (HashMap<Pair<ShaderVariation*, ShaderVariation*>, HashMap<StringHash, Pair<ShaderType, unsigned> > >::Iterator i =
|
|
|
- shaderParameters_.Begin(); i != shaderParameters_.End();)
|
|
|
+ for (ShaderProgramMap::Iterator i =
|
|
|
+ shaderPrograms_.Begin(); i != shaderPrograms_.End();)
|
|
|
{
|
|
|
if (i->first_.first_ == variation || i->first_.second_ == variation)
|
|
|
- i = shaderParameters_.Erase(i);
|
|
|
+ i = shaderPrograms_.Erase(i);
|
|
|
else
|
|
|
++i;
|
|
|
}
|
|
|
|
|
|
if (vertexShader_ == variation || pixelShader_ == variation)
|
|
|
- currentShaderParameters_ = 0;
|
|
|
+ shaderProgram_ = 0;
|
|
|
}
|
|
|
|
|
|
unsigned Graphics::GetAlphaFormat()
|