irrlicht/source/Irrlicht/CCgMaterialRenderer.cpp

346 lines
8.1 KiB
C++

// Copyright (C) 2012 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_CG_
#include "CCgMaterialRenderer.h"
namespace irr
{
namespace video
{
CCgUniform::CCgUniform(const CGparameter& parameter, bool global) : Parameter(parameter), Type(CG_UNKNOWN_TYPE)
{
Name = cgGetParameterName(Parameter);
if(global)
Space = CG_GLOBAL;
else
Space = CG_PROGRAM;
}
CCgUniform::~CCgUniform()
{
}
const core::stringc& CCgUniform::getName() const
{
return Name;
}
const CGparameter& CCgUniform::getParameter() const
{
return Parameter;
}
CGenum CCgUniform::getSpace() const
{
return Space;
}
CGtype CCgUniform::getType() const
{
return Type;
}
CCgUniform1f::CCgUniform1f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_FLOAT;
}
void CCgUniform1f::update(const void* data, const SMaterial& material) const
{
f32* Data = (f32*)data;
cgSetParameter1f(Parameter, *Data);
}
CCgUniform2f::CCgUniform2f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_FLOAT2;
}
void CCgUniform2f::update(const void* data, const SMaterial& material) const
{
f32* Data = (f32*)data;
cgSetParameter2f(Parameter, *Data, *(Data+1));
}
CCgUniform3f::CCgUniform3f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_FLOAT3;
}
void CCgUniform3f::update(const void* data, const SMaterial& material) const
{
f32* Data = (f32*)data;
cgSetParameter3f(Parameter, *Data, *(Data+1), *(Data+2));
}
CCgUniform4f::CCgUniform4f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_FLOAT4;
}
void CCgUniform4f::update(const void* data, const SMaterial& material) const
{
f32* Data = (f32*)data;
cgSetParameter4f(Parameter, *Data, *(Data+1), *(Data+2), *(Data+3));
}
CCgUniform1i::CCgUniform1i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_INT;
}
void CCgUniform1i::update(const void* data, const SMaterial& material) const
{
s32* Data = (s32*)data;
cgSetParameter1i(Parameter, *Data);
}
CCgUniform2i::CCgUniform2i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_INT2;
}
void CCgUniform2i::update(const void* data, const SMaterial& material) const
{
s32* Data = (s32*)data;
cgSetParameter2i(Parameter, *Data, *(Data+1));
}
CCgUniform3i::CCgUniform3i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_INT3;
}
void CCgUniform3i::update(const void* data, const SMaterial& material) const
{
s32* Data = (s32*)data;
cgSetParameter3i(Parameter, *Data, *(Data+1), *(Data+2));
}
CCgUniform4i::CCgUniform4i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_INT4;
}
void CCgUniform4i::update(const void* data, const SMaterial& material) const
{
s32* Data = (s32*)data;
cgSetParameter4i(Parameter, *Data, *(Data+1), *(Data+2), *(Data+3));
}
CCgUniform4x4f::CCgUniform4x4f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_FLOAT4x4;
}
void CCgUniform4x4f::update(const void* data, const SMaterial& material) const
{
f32* Data = (f32*)data;
cgSetMatrixParameterfr(Parameter, Data);
}
CCgUniformSampler2D::CCgUniformSampler2D(const CGparameter& parameter, bool global) : CCgUniform(parameter, global)
{
Type = CG_SAMPLER2D;
}
void CCgUniformSampler2D::update(const void* data, const SMaterial& material) const
{
}
CCgMaterialRenderer::CCgMaterialRenderer(IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) :
CallBack(callback), BaseMaterial(baseMaterial), UserData(userData),
VertexProgram(0), FragmentProgram(0), GeometryProgram(0), VertexProfile(CG_PROFILE_UNKNOWN), FragmentProfile(CG_PROFILE_UNKNOWN), GeometryProfile(CG_PROFILE_UNKNOWN),
Material(IdentityMaterial), Error(CG_NO_ERROR)
{
#ifdef _DEBUG
setDebugName("CCgMaterialRenderer");
#endif
if(BaseMaterial)
BaseMaterial->grab();
if(CallBack)
CallBack->grab();
}
CCgMaterialRenderer::~CCgMaterialRenderer()
{
if(CallBack)
CallBack->drop();
if(BaseMaterial)
BaseMaterial->drop();
for(unsigned int i = 0; i < UniformInfo.size(); ++i)
delete UniformInfo[i];
UniformInfo.clear();
}
bool CCgMaterialRenderer::isTransparent() const
{
return BaseMaterial ? BaseMaterial->isTransparent() : false;
}
s32 CCgMaterialRenderer::getVertexShaderConstantID(const c8* name)
{
return getPixelShaderConstantID(name);
}
s32 CCgMaterialRenderer::getPixelShaderConstantID(const c8* name)
{
for(u32 i = 0; i < UniformInfo.size(); ++i)
{
if(UniformInfo[i]->getName() == name)
return i;
}
return -1;
}
void CCgMaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
}
void CCgMaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
}
bool CCgMaterialRenderer::setVertexShaderConstant(s32 index, const f32* floats, int count)
{
return setPixelShaderConstant(index, floats, count);
}
bool CCgMaterialRenderer::setVertexShaderConstant(s32 index, const s32* ints, int count)
{
return setPixelShaderConstant(index, ints, count);
}
bool CCgMaterialRenderer::setPixelShaderConstant(s32 index, const f32* floats, int count)
{
if(index < 0)
return false;
UniformInfo[index]->update(floats, Material);
return true;
}
bool CCgMaterialRenderer::setPixelShaderConstant(s32 index, const s32* ints, int count)
{
if(index < 0)
return false;
UniformInfo[index]->update(ints, Material);
return true;
}
void CCgMaterialRenderer::getUniformList()
{
for(unsigned int i = 0; i < UniformInfo.size(); ++i)
delete UniformInfo[i];
UniformInfo.clear();
for(unsigned int i = 0; i < 2; ++i)
{
CGenum Space = CG_GLOBAL;
bool IsGlobal = 1;
if(i == 1)
{
Space = CG_PROGRAM;
IsGlobal = 0;
}
for(unsigned int j = 0; j < 3; ++j)
{
CGprogram* Program = 0;
switch(j)
{
case 0:
Program = &VertexProgram;
break;
case 1:
Program = &FragmentProgram;
break;
case 2:
Program = &GeometryProgram;
break;
}
if(*Program)
{
CGparameter Parameter = cgGetFirstParameter(*Program, Space);
while(Parameter)
{
if(cgGetParameterVariability(Parameter) == CG_UNIFORM && cgGetParameterDirection(Parameter) == CG_IN)
{
CCgUniform* Uniform = 0;
CGtype Type = cgGetParameterType(Parameter);
switch(Type)
{
case CG_FLOAT:
case CG_FLOAT1:
Uniform = new CCgUniform1f(Parameter, IsGlobal);
break;
case CG_FLOAT2:
Uniform = new CCgUniform2f(Parameter, IsGlobal);
break;
case CG_FLOAT3:
Uniform = new CCgUniform3f(Parameter, IsGlobal);
break;
case CG_FLOAT4:
Uniform = new CCgUniform4f(Parameter, IsGlobal);
break;
case CG_INT:
case CG_INT1:
Uniform = new CCgUniform1i(Parameter, IsGlobal);
break;
case CG_INT2:
Uniform = new CCgUniform2i(Parameter, IsGlobal);
break;
case CG_INT3:
Uniform = new CCgUniform3i(Parameter, IsGlobal);
break;
case CG_INT4:
Uniform = new CCgUniform4i(Parameter, IsGlobal);
break;
case CG_FLOAT4x4:
Uniform = new CCgUniform4x4f(Parameter, IsGlobal);
break;
case CG_SAMPLER2D:
Uniform = new CCgUniformSampler2D(Parameter, IsGlobal);
break;
}
if(Uniform)
UniformInfo.push_back(Uniform);
}
Parameter = cgGetNextParameter(Parameter);
}
}
}
}
}
}
}
#endif