Commit 92d1b406 authored by hybrid's avatar hybrid

Add Nadro's initial Cg support. Example 10 is enhanced to allow also Cg shaders.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4060 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 40480a78
/** Example 010 Shaders
This tutorial shows how to use shaders for D3D8, D3D9, and OpenGL with the
This tutorial shows how to use shaders for D3D8, D3D9, OpenGL, and Cg with the
engine and how to create new material types with them. It also shows how to
disable the generation of mipmaps at texture loading, and how to use text scene
nodes.
This tutorial does not explain how shaders work. I would recommend to read the
D3D or OpenGL documentation, to search a tutorial, or to read a book about
D3D, OpenGL, or Cg documentation, to search a tutorial, or to read a book about
this.
At first, we need to include all headers and do the stuff we always do, like in
......@@ -42,6 +42,7 @@ the variable name as parameter instead of the register index.
IrrlichtDevice* device = 0;
bool UseHighLevelShaders = false;
bool UseCgShaders = false;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
......@@ -102,7 +103,14 @@ public:
world = world.getTransposed();
if (UseHighLevelShaders)
{
services->setVertexShaderConstant("mTransWorld", world.pointer(), 16);
// set texture
f32 TextureLayerID = 0.0f;
if (UseHighLevelShaders)
services->setVertexShaderConstant("myTexture",
reinterpret_cast<f32*>(&TextureLayerID), 1);
}
else
services->setVertexShaderConstant(world.pointer(), 10, 4);
}
......@@ -128,7 +136,13 @@ int main()
printf("Please press 'y' if you want to use high level shaders.\n");
std::cin >> i;
if (i == 'y')
{
UseHighLevelShaders = true;
printf("Please press 'y' if you want to use Cg shaders.\n");
std::cin >> i;
if (i == 'y')
UseCgShaders = true;
}
}
// create device
......@@ -167,6 +181,7 @@ int main()
case video::EDT_DIRECT3D9:
if (UseHighLevelShaders)
{
// Cg can also handle this syntax
psFileName = "../../media/d3d9.hlsl";
vsFileName = psFileName; // both shaders are in the same file
}
......@@ -179,11 +194,20 @@ int main()
case video::EDT_OPENGL:
if (UseHighLevelShaders)
{
if (!UseCgShaders)
{
psFileName = "../../media/opengl.frag";
vsFileName = "../../media/opengl.vert";
}
else
{
// Use HLSL syntax for Cg
psFileName = "../../media/d3d9.hlsl";
vsFileName = psFileName; // both shaders are in the same file
}
}
else
{
psFileName = "../../media/opengl.psh";
vsFileName = "../../media/opengl.vsh";
......@@ -258,17 +282,23 @@ int main()
if (UseHighLevelShaders)
{
// create material from high level shaders (hlsl or glsl)
// Choose the desired shader type. Default is the native
// shader type for the driver, for Cg pass the special
// enum value EGSL_CG
const video::E_GPU_SHADING_LANGUAGE shadingLanguage =
UseCgShaders ? video::EGSL_CG:video::EGSL_DEFAULT;
// create material from high level shaders (hlsl, glsl or cg)
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_SOLID);
mc, video::EMT_SOLID, 0, shadingLanguage);
newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_TRANSPARENT_ADD_COLOR);
mc, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage);
}
else
{
......
......@@ -24,6 +24,16 @@ namespace video
class IVideoDriver;
class IShaderConstantSetCallBack;
//! Enumeration for different types of shading languages
enum E_GPU_SHADING_LANGUAGE
{
//! The default language, so HLSL for Direct3D and GLSL for OpenGL.
EGSL_DEFAULT = 0,
//! Cg shading language.*/
EGSL_CG
};
//! Interface making it possible to create and use programs running on the GPU.
class IGPUProgrammingServices
{
......@@ -68,6 +78,7 @@ public:
OnSetConstants(). In this way it is easily possible to use the same
callback method for multiple materials and distinguish between them
during the call.
\param shaderLang a type of shading language used in current shader.
\return Number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an error
occured, e.g. if a shader program could not be compiled or a compile
......@@ -88,7 +99,8 @@ public:
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0 ) = 0;
s32 userData = 0,
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterial(
......@@ -99,8 +111,9 @@ public:
const c8* pixelShaderEntryPointName="main",
E_PIXEL_SHADER_TYPE psCompileTarget=EPST_PS_1_1,
IShaderConstantSetCallBack* callback=0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0)
E_MATERIAL_TYPE baseMaterial=video::EMT_SOLID,
s32 userData=0,
E_GPU_SHADING_LANGUAGE shadingLang=EGSL_DEFAULT)
{
return addHighLevelShaderMaterial(
vertexShaderProgram, vertexShaderEntryPointName,
......@@ -108,7 +121,7 @@ public:
pixelShaderEntryPointName, psCompileTarget,
0, "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
callback, baseMaterial, userData, shadingLang);
}
//! convenience function for use with many defaults, without geometry shader
......@@ -192,6 +205,7 @@ public:
OnSetConstants(). In this way it is easily possible to use the same
callback method for multiple materials and distinguish between them
during the call.
\param shaderLang a type of shading language used in current shader.
\return Number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an error
occured, e.g. if a shader program could not be compiled or a compile
......@@ -212,7 +226,8 @@ public:
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) = 0;
s32 userData = 0,
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterialFromFiles(
......@@ -224,7 +239,8 @@ public:
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
s32 userData = 0,
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgramFileName, vertexShaderEntryPointName,
......@@ -232,7 +248,7 @@ public:
pixelShaderEntryPointName, psCompileTarget,
"", "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
callback, baseMaterial, userData, shadingLang);
}
//! convenience function for use with many defaults, without geometry shader
......@@ -314,6 +330,7 @@ public:
OnSetConstants(). In this way it is easily possible to use the same
callback method for multiple materials and distinguish between them
during the call.
\param shaderLang a type of shading language used in current shader.
\return Number of the material type which can be set in
SMaterial::MaterialType to use the renderer. -1 is returned if an
error occured, e.g. if a shader program could not be compiled or a
......@@ -334,7 +351,8 @@ public:
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) = 0;
s32 userData = 0,
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT) = 0;
//! convenience function for use without geometry shaders
s32 addHighLevelShaderMaterialFromFiles(
......@@ -346,7 +364,8 @@ public:
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0)
s32 userData = 0,
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT)
{
return addHighLevelShaderMaterialFromFiles(
vertexShaderProgram, vertexShaderEntryPointName,
......@@ -354,7 +373,7 @@ public:
pixelShaderEntryPointName, psCompileTarget,
0, "main", EGST_GS_4_0,
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
callback, baseMaterial, userData, shadingLang);
}
//! Adds a new ASM shader material renderer to the VideoDriver
......
......@@ -290,6 +290,15 @@ to provide the user with the proper DLL. That's why it's disabled by default. */
#undef _IRR_D3D_USE_LEGACY_HLSL_COMPILER
#endif
//! Define _IRR_COMPILE_WITH_CG_ to enable Cg Shading Language support
//#define _IRR_COMPILE_WITH_CG_
#ifdef NO_IRR_COMPILE_WITH_CG_
#undef _IRR_COMPILE_WITH_CG_
#endif
#if !defined(_IRR_COMPILE_WITH_OPENGL_) && !defined(_IRR_COMPILE_WITH_DIRECT3D_9_)
#undef _IRR_COMPILE_WITH_CG_
#endif
//! Define _IRR_USE_NVIDIA_PERFHUD_ to opt-in to using the nVidia PerHUD tool
/** Enable, by opting-in, to use the nVidia PerfHUD performance analysis driver
tool <http://developer.nvidia.com/object/nvperfhud_home.html>. */
......
// Copyright (C) 2011 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& pParameter, bool pIsGlobal) : Parameter(pParameter), Type(CG_UNKNOWN_TYPE)
{
Name = cgGetParameterName(Parameter);
if(pIsGlobal)
Space = CG_GLOBAL;
else
Space = CG_PROGRAM;
}
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& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_FLOAT;
}
void CCgUniform1f::update(const float* pData, const SMaterial& pMaterial) const
{
cgSetParameter1f(Parameter, *pData);
}
CCgUniform2f::CCgUniform2f(const CGparameter& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_FLOAT2;
}
void CCgUniform2f::update(const float* pData, const SMaterial& pMaterial) const
{
cgSetParameter2f(Parameter, *pData, *(pData+1));
}
CCgUniform3f::CCgUniform3f(const CGparameter& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_FLOAT3;
}
void CCgUniform3f::update(const float* pData, const SMaterial& pMaterial) const
{
cgSetParameter3f(Parameter, *pData, *(pData+1), *(pData+2));
}
CCgUniform4f::CCgUniform4f(const CGparameter& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_FLOAT4;
}
void CCgUniform4f::update(const float* pData, const SMaterial& pMaterial) const
{
cgSetParameter4f(Parameter, *pData, *(pData+1), *(pData+2), *(pData+3));
}
CCgUniform4x4f::CCgUniform4x4f(const CGparameter& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_FLOAT4x4;
}
void CCgUniform4x4f::update(const float* pData, const SMaterial& pMaterial) const
{
cgSetMatrixParameterfr(Parameter, pData);
}
CCgUniformSampler2D::CCgUniformSampler2D(const CGparameter& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_SAMPLER2D;
}
void CCgUniformSampler2D::update(const float* pData, const SMaterial& pMaterial) const
{
}
CCgMaterialRenderer::CCgMaterialRenderer(IShaderConstantSetCallBack* pCallBack, IMaterialRenderer* pBaseMaterial, s32 pUserData) :
CallBack(pCallBack), BaseMaterial(pBaseMaterial), UserData(pUserData),
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;
}
void CCgMaterialRenderer::setVertexShaderConstant(const f32* pData, s32 pStartRegister, s32 pConstantAmount)
{
os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
}
bool CCgMaterialRenderer::setVertexShaderConstant(const c8* pName, const f32* pData, int pCount)
{
return setPixelShaderConstant(pName, pData, pCount);
}
void CCgMaterialRenderer::setPixelShaderConstant(const f32* pData, s32 pStartRegister, s32 pConstantAmount)
{
os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
}
bool CCgMaterialRenderer::setPixelShaderConstant(const c8* pName, const f32* pData, int pCount)
{
bool Status = false;
for(unsigned int i = 0; i < UniformInfo.size(); ++i)
{
if(UniformInfo[i]->getName() == pName)
{
UniformInfo[i]->update(pData, Material);
Status = true;
}
}
return Status;
}
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);
// TODO: add more uniform types
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_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
// Copyright (C) 2011 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_CG_MATERIAL_RENDERER_H_INCLUDED__
#define __C_CG_MATERIAL_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_CG_
#include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h"
#include "IShaderConstantSetCallBack.h"
#include "IGPUProgrammingServices.h"
#include "irrArray.h"
#include "irrString.h"
#include "IVideoDriver.h"
#include "os.h"
#include "Cg/cg.h"
#ifdef _MSC_VER
#pragma comment(lib, "cg.lib")
#endif
namespace irr
{
namespace video
{
class CCgUniform
{
public:
CCgUniform(const CGparameter& pParameter, bool pIsGlobal);
const core::stringc& getName() const;
const CGparameter& getParameter() const;
CGenum getSpace() const;
CGtype getType() const;
virtual void update(const f32* pData, const SMaterial& pMaterial) const = 0;
protected:
core::stringc Name;
CGparameter Parameter;
CGenum Space;
CGtype Type;
};
class CCgUniform1f : public CCgUniform
{
public:
CCgUniform1f(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class CCgUniform2f : public CCgUniform
{
public:
CCgUniform2f(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class CCgUniform3f : public CCgUniform
{
public:
CCgUniform3f(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class CCgUniform4f : public CCgUniform
{
public:
CCgUniform4f(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class CCgUniform4x4f : public CCgUniform
{
public:
CCgUniform4x4f(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class CCgUniformSampler2D : public CCgUniform
{
public:
CCgUniformSampler2D(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class CCgMaterialRenderer : public IMaterialRenderer, public IMaterialRendererServices
{
public:
CCgMaterialRenderer(IShaderConstantSetCallBack* pCallBack = 0, IMaterialRenderer* pBaseMaterial = 0, s32 pUserData = 0);
virtual ~CCgMaterialRenderer();
virtual void OnSetMaterial(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS, IMaterialRendererServices* pService) = 0;
virtual bool OnRender(IMaterialRendererServices* pService, E_VERTEX_TYPE pVertexType) = 0;
virtual void OnUnsetMaterial() = 0;
virtual bool isTransparent() const;
virtual void setBasicRenderStates(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS) = 0;
virtual bool setVertexShaderConstant(const c8* pName, const f32* pData, int pCount);
virtual void setVertexShaderConstant(const f32* pData, s32 pStartRegister, s32 pConstantAmount = 1);
virtual bool setPixelShaderConstant(const c8* pName, const f32* pData, int pCount);
virtual void setPixelShaderConstant(const f32* pData, s32 pStartRegister, s32 pConstantAmount = 1);
virtual IVideoDriver* getVideoDriver() = 0;
protected:
void getUniformList();
IShaderConstantSetCallBack* CallBack;
IMaterialRenderer* BaseMaterial;
s32 UserData;
core::array<CCgUniform*> UniformInfo;
CGprogram VertexProgram;
CGprogram FragmentProgram;
CGprogram GeometryProgram;
CGprofile VertexProfile;
CGprofile FragmentProfile;
CGprofile GeometryProfile;
SMaterial Material;
CGerror Error;
};
}
}
#endif
#endif
// Copyright (C) 2011-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"
#if defined(_IRR_COMPILE_WITH_DIRECT3D_9_) && defined(_IRR_COMPILE_WITH_CG_)
#include "CD3D9CgMaterialRenderer.h"
#include "CD3D9Driver.h"
#include "CD3D9Texture.h"
namespace irr
{
namespace video
{
CD3D9CgUniformSampler2D::CD3D9CgUniformSampler2D(const CGparameter& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_SAMPLER2D;
}
void CD3D9CgUniformSampler2D::update(const float* pData, const SMaterial& pMaterial) const
{
int LayerID = (int)*pData;
if (pMaterial.TextureLayer[LayerID].Texture)
{
IDirect3DBaseTexture9* Texture = reinterpret_cast<irr::video::CD3D9Texture*>(pMaterial.TextureLayer[LayerID].Texture)->getDX9Texture();
cgD3D9SetTextureParameter(Parameter, Texture);
}
}
CD3D9CgMaterialRenderer::CD3D9CgMaterialRenderer(CD3D9Driver* pDriver, s32& pMaterialType,
const c8* pVertexProgram, const c8* pVertexEntry, E_VERTEX_SHADER_TYPE pVertexProfile,
const c8* pFragmentProgram, const c8* pFragmentEntry, E_PIXEL_SHADER_TYPE pFragmentProfile,
const c8* pGeometryProgram, const c8* pGeometryEntry, E_GEOMETRY_SHADER_TYPE pGeometryProfile,
scene::E_PRIMITIVE_TYPE pInType, scene::E_PRIMITIVE_TYPE pOutType, u32 pVertices,
IShaderConstantSetCallBack* pCallBack, IMaterialRenderer* pBaseMaterial, s32 pUserData) :
Driver(pDriver), CCgMaterialRenderer(pCallBack, pBaseMaterial, pUserData)
{
#ifdef _DEBUG
setDebugName("CD3D9CgMaterialRenderer");
#endif
init(pMaterialType, pVertexProgram, pVertexEntry, pVertexProfile, pFragmentProgram, pFragmentEntry, pFragmentProfile,
pGeometryProgram, pGeometryEntry, pGeometryProfile, pInType, pOutType, pVertices);
}
CD3D9CgMaterialRenderer::~CD3D9CgMaterialRenderer()
{
if (VertexProgram)
{
cgD3D9UnloadProgram(VertexProgram);
cgDestroyProgram(VertexProgram);
}
if (FragmentProgram)
{
cgD3D9UnloadProgram(FragmentProgram);
cgDestroyProgram(FragmentProgram);
}
/*if (GeometryProgram)
{
cgD3D9UnloadProgram(GeometryProgram);
cgDestroyProgram(GeometryProgram);
}*/
}
void CD3D9CgMaterialRenderer::OnSetMaterial(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS, IMaterialRendererServices* pService)
{
Material = pMaterial;
if (pMaterial.MaterialType != pLastMaterial.MaterialType || pResetRS)
{
if (VertexProgram)
cgD3D9BindProgram(VertexProgram);
if (FragmentProgram)
cgD3D9BindProgram(FragmentProgram);
/*if (GeometryProgram)
cgD3D9BindProgram(GeometryProgram);*/
if (BaseMaterial)
BaseMaterial->OnSetMaterial(pMaterial, pMaterial, true, this);
}
if (CallBack)
CallBack->OnSetMaterial(pMaterial);
Driver->setBasicRenderStates(pMaterial, pLastMaterial, pResetRS);
}
bool CD3D9CgMaterialRenderer::OnRender(IMaterialRendererServices* pService, E_VERTEX_TYPE pVertexType)
{
if (CallBack && (VertexProgram || FragmentProgram || GeometryProgram))
CallBack->OnSetConstants(this, UserData);
return true;
}
void CD3D9CgMaterialRenderer::OnUnsetMaterial()
{
if (VertexProgram)
cgD3D9UnbindProgram(VertexProgram);
if (FragmentProgram)
cgD3D9UnbindProgram(FragmentProgram);
/*if (GeometryProgram)
cgD3D9UnbindProgram(GeometryProgram);*/
if (BaseMaterial)
BaseMaterial->OnUnsetMaterial();
Material = IdentityMaterial;;
}
void CD3D9CgMaterialRenderer::setBasicRenderStates(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS)
{
Driver->setBasicRenderStates(pMaterial, pLastMaterial, pResetRS);
}
IVideoDriver* CD3D9CgMaterialRenderer::getVideoDriver()
{
return Driver;
}
void CD3D9CgMaterialRenderer::init(s32& pMaterialType,
const c8* pVertexProgram, const c8* pVertexEntry, E_VERTEX_SHADER_TYPE pVertexProfile,
const c8* pFragmentProgram, const c8* pFragmentEntry, E_PIXEL_SHADER_TYPE pFragmentProfile,
const c8* pGeometryProgram, const c8* pGeometryEntry, E_GEOMETRY_SHADER_TYPE pGeometryProfile,
scene::E_PRIMITIVE_TYPE pInType, scene::E_PRIMITIVE_TYPE pOutType, u32 pVertices)
{
bool Status = true;
CGerror Error = CG_NO_ERROR;
pMaterialType = -1;
// TODO: add profile selection
if (pVertexProgram)
{
VertexProfile = cgD3D9GetLatestVertexProfile();
if (VertexProfile)
VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pVertexProgram, VertexProfile, pVertexEntry, 0);
if (!VertexProgram)
{
Error = cgGetError();
os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR);
os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);
Status = false;
}
else
cgD3D9LoadProgram(VertexProgram, 0, 0);
}
if (pFragmentProgram)
{
FragmentProfile = cgD3D9GetLatestPixelProfile();
if (FragmentProfile)
FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pFragmentProgram, FragmentProfile, pFragmentEntry, 0);
if (!FragmentProgram)
{
Error = cgGetError();
os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR);
os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);
Status = false;
}
else
cgD3D9LoadProgram(FragmentProgram, 0, 0);
}
/*if (pGeometryProgram)
{
GeometryProfile = cgD3D9GetLatestGeometryProfile();
if (GeometryProfile)
GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pGeometryProgram, GeometryProfile, pGeometryEntry, 0);
if (!GeometryProgram)
{
Error = cgGetError();
os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR);
os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);
Status = false;
}
else
cgD3D9LoadProgram(GeometryProgram, 0, 0);
}*/
getUniformList();
// create D3D9 specifics sampler uniforms.
for(unsigned int i = 0; i < UniformInfo.size(); ++i)
{
if (UniformInfo[i]->getType() == CG_SAMPLER2D)
{
bool IsGlobal = true;
if (UniformInfo[i]->getSpace() == CG_PROGRAM)
IsGlobal = false;
CCgUniform* Uniform = new CD3D9CgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal);
delete UniformInfo[i];
UniformInfo[i] = Uniform;
}
}
if (Status)
pMaterialType = Driver->addMaterialRenderer(this);
}
}
}
#endif
// Copyright (C) 2011-2012 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_DIRECT3D_9_CG_MATERIAL_RENDERER_H_INCLUDED__
#define __C_DIRECT3D_9_CG_MATERIAL_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#if defined(_IRR_COMPILE_WITH_DIRECT3D_9_) && defined(_IRR_COMPILE_WITH_CG_)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include "CCgMaterialRenderer.h"
#include "Cg/cgD3D9.h"
#ifdef _MSC_VER
#pragma comment(lib, "cgD3D9.lib")
#endif
namespace irr
{
namespace video
{
class CD3D9Driver;
class IShaderConstantSetCallBack;
class CD3D9CgUniformSampler2D : public CCgUniform
{
public:
CD3D9CgUniformSampler2D(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class CD3D9CgMaterialRenderer : public CCgMaterialRenderer
{
public:
CD3D9CgMaterialRenderer(CD3D9Driver* pDriver, s32& pMaterialType,
const c8* pVertexProgram = 0, const c8* pVertexEntry = "main",
E_VERTEX_SHADER_TYPE pVertexProfile = video::EVST_VS_1_1,
const c8* pFragmentProgram = 0, const c8* pFragmentEntry = "main",
E_PIXEL_SHADER_TYPE pFragmentProfile = video::EPST_PS_1_1,
const c8* pGeometryProgram = 0, const c8* pGeometryEntry = "main",
E_GEOMETRY_SHADER_TYPE pGeometryProfile = video::EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE pInType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE pOutType = scene::EPT_TRIANGLE_STRIP,
u32 pVertices = 0, IShaderConstantSetCallBack* pCallBack = 0,
IMaterialRenderer* pBaseMaterial = 0, s32 pUserData = 0);
virtual ~CD3D9CgMaterialRenderer();
virtual void OnSetMaterial(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS, IMaterialRendererServices* pService);
virtual bool OnRender(IMaterialRendererServices* pService, E_VERTEX_TYPE pVertexType);
virtual void OnUnsetMaterial();
virtual void setBasicRenderStates(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS);
virtual IVideoDriver* getVideoDriver();
protected:
void init(s32& pMaterialType,
const c8* pVertexProgram = 0, const c8* pVertexEntry = "main",
E_VERTEX_SHADER_TYPE pVertexProfile = video::EVST_VS_1_1,
const c8* pFragmentProgram = 0, const c8* pFragmentEntry = "main",
E_PIXEL_SHADER_TYPE pFragmentProfile = video::EPST_PS_1_1,
const c8* pGeometryProgram = 0, const c8* pGeometryEntry = "main",
E_GEOMETRY_SHADER_TYPE pGeometryProfile = video::EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE pInType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE pOutType = scene::EPT_TRIANGLE_STRIP,
u32 pVertices = 0);
CD3D9Driver* Driver;
};
}
}
#endif
#endif
......@@ -15,6 +15,7 @@
#include "CD3D9NormalMapRenderer.h"
#include "CD3D9ParallaxMapRenderer.h"
#include "CD3D9HLSLMaterialRenderer.h"
#include "CD3D9CgMaterialRenderer.h"
#include "SIrrCreationParameters.h"
namespace irr
......@@ -66,6 +67,10 @@ CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSys
core::matrix4 mat;
UnitMatrixD3D9 = *(D3DMATRIX*)((void*)mat.pointer());
#ifdef _IRR_COMPILE_WITH_CG_
CgContext = 0;
#endif
// init direct 3d is done in the factory function
}
......@@ -90,6 +95,15 @@ CD3D9Driver::~CD3D9Driver()
if (pID3D)
pID3D->Release();
#ifdef _IRR_COMPILE_WITH_CG_
cgD3D9SetDevice(0);
if(CgContext)
{
cgDestroyContext(CgContext);
}
#endif
}
......@@ -483,6 +497,11 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
}
ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat);
#ifdef _IRR_COMPILE_WITH_CG_
CgContext = cgCreateContext();
cgD3D9SetDevice(pID3DDevice);
#endif
// so far so good.
return true;
}
......@@ -3109,11 +3128,27 @@ s32 CD3D9Driver::addHighLevelShaderMaterial(
scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,
u32 verticesOut,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial, s32 userData)
E_MATERIAL_TYPE baseMaterial, s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
{
s32 nr = -1;
CD3D9HLSLMaterialRenderer* hlsl = new CD3D9HLSLMaterialRenderer(
#ifdef _IRR_COMPILE_WITH_CG_
if(shadingLang == EGSL_CG)
{
CD3D9CgMaterialRenderer* r = new CD3D9CgMaterialRenderer(
this, nr,
vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
inType, outType, verticesOut,
callback,getMaterialRenderer(baseMaterial), userData);
r->drop();
}
else
#endif
{
CD3D9HLSLMaterialRenderer* r = new CD3D9HLSLMaterialRenderer(
pID3DDevice, this, nr,
vertexShaderProgram,
vertexShaderEntryPointName,
......@@ -3125,7 +3160,9 @@ s32 CD3D9Driver::addHighLevelShaderMaterial(
getMaterialRenderer(baseMaterial),
userData);
hlsl->drop();
r->drop();
}
return nr;
}
......@@ -3481,6 +3518,13 @@ core::dimension2du CD3D9Driver::getMaxTextureSize() const
return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight);
}
#ifdef _IRR_COMPILE_WITH_CG_
const CGcontext& CD3D9Driver::getCgContext()
{
return CgContext;
}
#endif
} // end namespace video
} // end namespace irr
......
......@@ -22,6 +22,11 @@
#endif
#include <d3d9.h>
#ifdef _IRR_COMPILE_WITH_CG_
#include "Cg/cg.h"
#include "Cg/cgD3D9.h"
#endif
namespace irr
{
namespace video
......@@ -315,6 +320,11 @@ namespace video
//! Get Irrlicht color format from D3D color format.
ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format) const;
//! Get Cg context
#ifdef _IRR_COMPILE_WITH_CG_
const CGcontext& getCgContext();
#endif
private:
//! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates.
......@@ -382,7 +392,8 @@ namespace video
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
s32 userData = 0,
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT);
void createMaterialRenderers();
......@@ -457,6 +468,10 @@ namespace video
bool DriverWasReset;
bool OcclusionQuerySupport;
bool AlphaToCoverageSupport;
#ifdef _IRR_COMPILE_WITH_CG_
CGcontext CgContext;
#endif
};
......
......@@ -2052,7 +2052,7 @@ s32 CNullDriver::addHighLevelShaderMaterial(
u32 verticesOut,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
{
os::Printer::log("High level shader materials not available (yet) in this driver, sorry");
return -1;
......@@ -2075,7 +2075,7 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
u32 verticesOut,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
{
io::IReadFile* vsfile = 0;
io::IReadFile* psfile = 0;
......@@ -2116,7 +2116,7 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
psfile, pixelShaderEntryPointName, psCompileTarget,
gsfile, geometryShaderEntryPointName, gsCompileTarget,
inType, outType, verticesOut,
callback, baseMaterial, userData);
callback, baseMaterial, userData, shadingLang);
if (psfile)
psfile->drop();
......@@ -2147,7 +2147,7 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
u32 verticesOut,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
{
c8* vs = 0;
c8* ps = 0;
......@@ -2198,7 +2198,7 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
ps, pixelShaderEntryPointName, psCompileTarget,
gs, geometryShaderEntryPointName, gsCompileTarget,
inType, outType, verticesOut,
callback, baseMaterial, userData);
callback, baseMaterial, userData, shadingLang);
delete [] vs;
delete [] ps;
......
......@@ -536,7 +536,7 @@ namespace video
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
s32 userData = 0, E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT);
//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
//! but tries to load the programs from files.
......@@ -555,7 +555,7 @@ namespace video
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
s32 userData = 0, E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT);
//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
//! but tries to load the programs from files.
......@@ -574,7 +574,7 @@ namespace video
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
s32 userData = 0, E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT);
//! Returns a pointer to the mesh manipulator.
virtual scene::IMeshManipulator* getMeshManipulator();
......
// Copyright (C) 2011-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"
#if defined(_IRR_COMPILE_WITH_OPENGL_) && defined(_IRR_COMPILE_WITH_CG_)
#include "COpenGLCgMaterialRenderer.h"
#include "COpenGLDriver.h"
#include "COpenGLTexture.h"
namespace irr
{
namespace video
{
COpenGLCgUniformSampler2D::COpenGLCgUniformSampler2D(const CGparameter& pParameter, bool pIsGlobal) : CCgUniform(pParameter, pIsGlobal)
{
Type = CG_SAMPLER2D;
}
void COpenGLCgUniformSampler2D::update(const float* pData, const SMaterial& pMaterial) const
{
int LayerID = (int)*pData;
if (pMaterial.TextureLayer[LayerID].Texture)
{
int TextureID = reinterpret_cast<COpenGLTexture*>(pMaterial.TextureLayer[LayerID].Texture)->getOpenGLTextureName();
cgGLSetTextureParameter(Parameter, TextureID);
cgGLEnableTextureParameter(Parameter);
}
}
COpenGLCgMaterialRenderer::COpenGLCgMaterialRenderer(COpenGLDriver* pDriver, s32& pMaterialType,
const c8* pVertexProgram, const c8* pVertexEntry, E_VERTEX_SHADER_TYPE pVertexProfile,
const c8* pFragmentProgram, const c8* pFragmentEntry, E_PIXEL_SHADER_TYPE pFragmentProfile,
const c8* pGeometryProgram, const c8* pGeometryEntry, E_GEOMETRY_SHADER_TYPE pGeometryProfile,
scene::E_PRIMITIVE_TYPE pInType, scene::E_PRIMITIVE_TYPE pOutType, u32 pVertices,
IShaderConstantSetCallBack* pCallBack, IMaterialRenderer* pBaseMaterial, s32 pUserData) :
Driver(pDriver), CCgMaterialRenderer(pCallBack, pBaseMaterial, pUserData)
{
#ifdef _DEBUG
setDebugName("COpenGLCgMaterialRenderer");
#endif
init(pMaterialType, pVertexProgram, pVertexEntry, pVertexProfile, pFragmentProgram, pFragmentEntry, pFragmentProfile,
pGeometryProgram, pGeometryEntry, pGeometryProfile, pInType, pOutType, pVertices);
}
COpenGLCgMaterialRenderer::~COpenGLCgMaterialRenderer()
{
if (VertexProgram)
{
cgGLUnloadProgram(VertexProgram);
cgDestroyProgram(VertexProgram);
}
if (FragmentProgram)
{
cgGLUnloadProgram(FragmentProgram);
cgDestroyProgram(FragmentProgram);
}
if (GeometryProgram)
{
cgGLUnloadProgram(GeometryProgram);
cgDestroyProgram(GeometryProgram);
}
}
void COpenGLCgMaterialRenderer::OnSetMaterial(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS, IMaterialRendererServices* pService)
{
Material = pMaterial;
if (pMaterial.MaterialType != pLastMaterial.MaterialType || pResetRS)
{
if (VertexProgram)
{
cgGLEnableProfile(VertexProfile);
cgGLBindProgram(VertexProgram);
}
if (FragmentProgram)
{
cgGLEnableProfile(FragmentProfile);
cgGLBindProgram(FragmentProgram);
}
if (GeometryProgram)
{
cgGLEnableProfile(GeometryProfile);
cgGLBindProgram(GeometryProgram);
}
if (BaseMaterial)
BaseMaterial->OnSetMaterial(pMaterial, pMaterial, true, this);
}
if (CallBack)
CallBack->OnSetMaterial(pMaterial);
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
Driver->setActiveTexture(i, pMaterial.getTexture(i));
Driver->setBasicRenderStates(pMaterial, pLastMaterial, pResetRS);
}
bool COpenGLCgMaterialRenderer::OnRender(IMaterialRendererServices* pService, E_VERTEX_TYPE pVertexType)
{
if (CallBack && (VertexProgram || FragmentProgram || GeometryProgram))
CallBack->OnSetConstants(this, UserData);
return true;
}
void COpenGLCgMaterialRenderer::OnUnsetMaterial()
{
if (VertexProgram)
{
cgGLUnbindProgram(VertexProfile);
cgGLDisableProfile(VertexProfile);
}
if (FragmentProgram)
{
cgGLUnbindProgram(FragmentProfile);
cgGLDisableProfile(FragmentProfile);
}
if (GeometryProgram)
{
cgGLUnbindProgram(GeometryProfile);
cgGLDisableProfile(GeometryProfile);
}
if (BaseMaterial)
BaseMaterial->OnUnsetMaterial();
Material = IdentityMaterial;;
}
void COpenGLCgMaterialRenderer::setBasicRenderStates(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS)
{
Driver->setBasicRenderStates(pMaterial, pLastMaterial, pResetRS);
}
IVideoDriver* COpenGLCgMaterialRenderer::getVideoDriver()
{
return Driver;
}
void COpenGLCgMaterialRenderer::init(s32& pMaterialType,
const c8* pVertexProgram, const c8* pVertexEntry, E_VERTEX_SHADER_TYPE pVertexProfile,
const c8* pFragmentProgram, const c8* pFragmentEntry, E_PIXEL_SHADER_TYPE pFragmentProfile,
const c8* pGeometryProgram, const c8* pGeometryEntry, E_GEOMETRY_SHADER_TYPE pGeometryProfile,
scene::E_PRIMITIVE_TYPE pInType, scene::E_PRIMITIVE_TYPE pOutType, u32 pVertices)
{
bool Status = true;
CGerror Error = CG_NO_ERROR;
pMaterialType = -1;
// TODO: add profile selection
if (pVertexProgram)
{
VertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
if (VertexProfile)
VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pVertexProgram, VertexProfile, pVertexEntry, 0);
if (!VertexProgram)
{
Error = cgGetError();
os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR);
os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);
Status = false;
}
else
cgGLLoadProgram(VertexProgram);
}
if (pFragmentProgram)
{
FragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
if (FragmentProfile)
FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pFragmentProgram, FragmentProfile, pFragmentEntry, 0);
if (!FragmentProgram)
{
Error = cgGetError();
os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR);
os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);
Status = false;
}
else
cgGLLoadProgram(FragmentProgram);
}
if (pGeometryProgram)
{
GeometryProfile = cgGLGetLatestProfile(CG_GL_GEOMETRY);
if (GeometryProfile)
GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pGeometryProgram, GeometryProfile, pGeometryEntry, 0);
if (!GeometryProgram)
{
Error = cgGetError();
os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR);
os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);
Status = false;
}
else
cgGLLoadProgram(GeometryProgram);
}
getUniformList();
// create OpenGL specifics sampler uniforms.
for (unsigned int i = 0; i < UniformInfo.size(); ++i)
{
if (UniformInfo[i]->getType() == CG_SAMPLER2D)
{
bool IsGlobal = true;
if (UniformInfo[i]->getSpace() == CG_PROGRAM)
IsGlobal = false;
CCgUniform* Uniform = new COpenGLCgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal);
delete UniformInfo[i];
UniformInfo[i] = Uniform;
}
}
if (Status)
pMaterialType = Driver->addMaterialRenderer(this);
}
}
}
#endif
// Copyright (C) 2011-2012 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_OPENGL_CG_MATERIAL_RENDERER_H_INCLUDED__
#define __C_OPENGL_CG_MATERIAL_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#if defined(_IRR_COMPILE_WITH_OPENGL_) && defined(_IRR_COMPILE_WITH_CG_)
#ifdef _IRR_WINDOWS_API_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <GL/gl.h>
#include "glext.h"
#else
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#endif
#if defined(_IRR_OSX_PLATFORM_)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include "glext.h"
#endif
#endif
#include "CCgMaterialRenderer.h"
#include "Cg/cgGL.h"
#ifdef _MSC_VER
#pragma comment(lib, "cgGL.lib")
#endif
namespace irr
{
namespace video
{
class COpenGLDriver;
class IShaderConstantSetCallBack;
class COpenGLCgUniformSampler2D : public CCgUniform
{
public:
COpenGLCgUniformSampler2D(const CGparameter& pParameter, bool pIsGlobal);
void update(const f32* pData, const SMaterial& pMaterial) const;
};
class COpenGLCgMaterialRenderer : public CCgMaterialRenderer
{
public:
COpenGLCgMaterialRenderer(COpenGLDriver* pDriver, s32& pMaterialType,
const c8* pVertexProgram = 0, const c8* pVertexEntry = "main",
E_VERTEX_SHADER_TYPE pVertexProfile = video::EVST_VS_1_1,
const c8* pFragmentProgram = 0, const c8* pFragmentEntry = "main",
E_PIXEL_SHADER_TYPE pFragmentProfile = video::EPST_PS_1_1,
const c8* pGeometryProgram = 0, const c8* pGeometryEntry = "main",
E_GEOMETRY_SHADER_TYPE pGeometryProfile = video::EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE pInType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE pOutType = scene::EPT_TRIANGLE_STRIP,
u32 pVertices = 0, IShaderConstantSetCallBack* pCallBack = 0,
IMaterialRenderer* pBaseMaterial = 0, s32 pUserData = 0);
virtual ~COpenGLCgMaterialRenderer();
virtual void OnSetMaterial(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS, IMaterialRendererServices* pService);
virtual bool OnRender(IMaterialRendererServices* pService, E_VERTEX_TYPE pVertexType);
virtual void OnUnsetMaterial();
virtual void setBasicRenderStates(const SMaterial& pMaterial, const SMaterial& pLastMaterial, bool pResetRS);
virtual IVideoDriver* getVideoDriver();
protected:
void init(s32& pMaterialType,
const c8* pVertexProgram = 0, const c8* pVertexEntry = "main",
E_VERTEX_SHADER_TYPE pVertexProfile = video::EVST_VS_1_1,
const c8* pFragmentProgram = 0, const c8* pFragmentEntry = "main",
E_PIXEL_SHADER_TYPE pFragmentProfile = video::EPST_PS_1_1,
const c8* pGeometryProgram = 0, const c8* pGeometryEntry = "main",
E_GEOMETRY_SHADER_TYPE pGeometryProfile = video::EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE pInType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE pOutType = scene::EPT_TRIANGLE_STRIP,
u32 pVertices = 0);
COpenGLDriver* Driver;
};
}
}
#endif
#endif
......@@ -12,6 +12,7 @@
#include "COpenGLMaterialRenderer.h"
#include "COpenGLShaderMaterialRenderer.h"
#include "COpenGLSLMaterialRenderer.h"
#include "COpenGLCgMaterialRenderer.h"
#include "COpenGLNormalMapRenderer.h"
#include "COpenGLParallaxMapRenderer.h"
#include "os.h"
......@@ -43,6 +44,10 @@ COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
#ifdef _DEBUG
setDebugName("COpenGLDriver");
#endif
#ifdef _IRR_COMPILE_WITH_CG_
CgContext = 0;
#endif
}
......@@ -475,6 +480,11 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
#ifdef _DEBUG
setDebugName("COpenGLDriver");
#endif
#ifdef _IRR_COMPILE_WITH_CG_
CgContext = 0;
#endif
genericDriverInit();
}
......@@ -497,6 +507,10 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
#ifdef _DEBUG
setDebugName("COpenGLDriver");
#endif
#ifdef _IRR_COMPILE_WITH_CG_
CgContext = 0;
#endif
}
......@@ -570,6 +584,10 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
setDebugName("COpenGLDriver");
#endif
#ifdef _IRR_COMPILE_WITH_CG_
CgContext = 0;
#endif
genericDriverInit();
}
......@@ -579,6 +597,11 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
//! destructor
COpenGLDriver::~COpenGLDriver()
{
#ifdef _IRR_COMPILE_WITH_CG_
if (CgContext)
cgDestroyContext(CgContext);
#endif
RequestedLights.clear();
deleteMaterialRenders();
......@@ -722,6 +745,10 @@ bool COpenGLDriver::genericDriverInit()
// This fixes problems with intermediate changes to the material during texture load.
ResetRenderStates = true;
#ifdef _IRR_COMPILE_WITH_CG_
CgContext = cgCreateContext();
#endif
return true;
}
......@@ -3848,10 +3875,26 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
u32 verticesOut,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
{
s32 nr = -1;
#ifdef _IRR_COMPILE_WITH_CG_
if (shadingLang == EGSL_CG)
{
COpenGLCgMaterialRenderer* r = new COpenGLCgMaterialRenderer(
this, nr,
vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
inType, outType, verticesOut,
callback,getMaterialRenderer(baseMaterial), userData);
r->drop();
}
else
#endif
{
COpenGLSLMaterialRenderer* r = new COpenGLSLMaterialRenderer(
this, nr,
vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
......@@ -3859,7 +3902,10 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
inType, outType, verticesOut,
callback,getMaterialRenderer(baseMaterial), userData);
r->drop();
}
return nr;
}
......@@ -4588,6 +4634,13 @@ GLenum COpenGLDriver::getGLBlend(E_BLEND_FACTOR factor) const
return r;
}
#ifdef _IRR_COMPILE_WITH_CG_
const CGcontext& COpenGLDriver::getCgContext()
{
return CgContext;
}
#endif
} // end namespace
} // end namespace
......
......@@ -24,6 +24,10 @@ namespace irr
// also includes the OpenGL stuff
#include "COpenGLExtensionHandler.h"
#ifdef _IRR_COMPILE_WITH_CG_
#include "Cg/cg.h"
#endif
namespace irr
{
......@@ -315,7 +319,8 @@ namespace video
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0);
s32 userData = 0,
E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT);
//! Returns a pointer to the IVideoDriver interface. (Implementation for
//! IMaterialRendererServices)
......@@ -382,6 +387,11 @@ namespace video
//! Convert E_BLEND_FACTOR to OpenGL equivalent
GLenum getGLBlend(E_BLEND_FACTOR factor) const;
//! Get Cg context
#ifdef _IRR_COMPILE_WITH_CG_
const CGcontext& getCgContext();
#endif
private:
//! clears the zbuffer and color buffer
......@@ -506,6 +516,9 @@ namespace video
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
CIrrDeviceSDL *SDLDevice;
#endif
#ifdef _IRR_COMPILE_WITH_CG_
CGcontext CgContext;
#endif
E_DEVICE_TYPE DeviceType;
};
......
......@@ -629,6 +629,8 @@
<Unit filename="CCSMLoader.h" />
<Unit filename="CCameraSceneNode.cpp" />
<Unit filename="CCameraSceneNode.h" />
<Unit filename="CCgMaterialRenderer.cpp" />
<Unit filename="CCgMaterialRenderer.h" />
<Unit filename="CColladaFileLoader.cpp" />
<Unit filename="CColladaFileLoader.h" />
<Unit filename="CColladaMeshWriter.cpp" />
......@@ -648,6 +650,8 @@
<Unit filename="CD3D8ShaderMaterialRenderer.h" />
<Unit filename="CD3D8Texture.cpp" />
<Unit filename="CD3D8Texture.h" />
<Unit filename="CD3D9CgMaterialRenderer.cpp" />
<Unit filename="CD3D9CgMaterialRenderer.h" />
<Unit filename="CD3D9Driver.cpp" />
<Unit filename="CD3D9Driver.h" />
<Unit filename="CD3D9HLSLMaterialRenderer.cpp" />
......@@ -838,6 +842,8 @@
<Unit filename="COctreeTriangleSelector.h" />
<Unit filename="COgreMeshFileLoader.cpp" />
<Unit filename="COgreMeshFileLoader.h" />
<Unit filename="COpenGLCgMaterialRenderer.cpp" />
<Unit filename="COpenGLCgMaterialRenderer.h" />
<Unit filename="COpenGLDriver.cpp" />
<Unit filename="COpenGLDriver.h" />
<Unit filename="COpenGLExtensionHandler.cpp" />
......
......@@ -271,7 +271,7 @@
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Static lib - Release|x64'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Static lib - Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Static lib - Release|x64'" />
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(DXSDK_DIR)include;$(IncludePath)</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(DXSDK_DIR)include;$(CG_INC_PATH);$(IncludePath)</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(DXSDK_DIR)include;$(IncludePath)</IncludePath>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">obj\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">obj\$(Configuration)64\</IntDir>
......@@ -289,7 +289,7 @@
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Static lib - Release - Fast FPU|x64'">$(DXSDK_DIR)include;$(IncludePath)</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Static lib - Release|Win32'">$(DXSDK_DIR)include;$(IncludePath)</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Static lib - Release|x64'">$(DXSDK_DIR)include;$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath)</LibraryPath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release - Fast FPU|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='SDL-Debug|Win32'">$(DXSDK_DIR)Lib\x86;$(LibraryPath)</LibraryPath>
......@@ -821,6 +821,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\include\EDriverFeatures.h" />
<ClInclude Include="..\..\include\EMaterialFlags.h" />
<ClInclude Include="..\..\include\IAnimatedMeshMD3.h" />
<ClInclude Include="..\..\include\IEventReceiver.h" />
<ClInclude Include="..\..\include\ILogger.h" />
......@@ -976,11 +977,14 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
<ClInclude Include="CCgMaterialRenderer.h" />
<ClInclude Include="CD3D9CgMaterialRenderer.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
<ClInclude Include="CDefaultSceneNodeFactory.h" />
<ClInclude Include="CGeometryCreator.h" />
<ClInclude Include="CMeshCache.h" />
<ClInclude Include="CMeshManipulator.h" />
<ClInclude Include="COpenGLCgMaterialRenderer.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
<ClInclude Include="CSMFMeshFileLoader.h" />
......@@ -1223,11 +1227,14 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CCgMaterialRenderer.cpp" />
<ClCompile Include="CD3D9CgMaterialRenderer.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
<ClCompile Include="CDefaultSceneNodeFactory.cpp" />
<ClCompile Include="CGeometryCreator.cpp" />
<ClCompile Include="CMeshCache.cpp" />
<ClCompile Include="CMeshManipulator.cpp" />
<ClCompile Include="COpenGLCgMaterialRenderer.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />
......
......@@ -1294,6 +1294,18 @@
<ClInclude Include="..\..\include\IRandomizer.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\EMaterialFlags.h">
<Filter>include\video</Filter>
</ClInclude>
<ClInclude Include="CD3D9CgMaterialRenderer.h">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClInclude>
<ClInclude Include="COpenGLCgMaterialRenderer.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="CCgMaterialRenderer.h">
<Filter>Irrlicht\video</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
......@@ -2219,6 +2231,15 @@
<ClCompile Include="CSMFMeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CD3D9CgMaterialRenderer.cpp">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClCompile>
<ClCompile Include="COpenGLCgMaterialRenderer.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
<ClCompile Include="CCgMaterialRenderer.cpp">
<Filter>Irrlicht\video</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />
......
......@@ -1014,6 +1014,12 @@
</Filter>
<Filter
Name="video impl">
<File
RelativePath="CCgMaterialRenderer.cpp">
</File>
<File
RelativePath="CCgMaterialRenderer.h">
</File>
<File
RelativePath="CVideoModeList.cpp">
</File>
......@@ -1085,6 +1091,12 @@
</Filter>
<Filter
Name="OpenGL">
<File
RelativePath=".\COpenGLCgMaterialRenderer.cpp">
</File>
<File
RelativePath=".\COpenGLCgMaterialRenderer.h">
</File>
<File
RelativePath="COpenGLDriver.cpp">
</File>
......@@ -1301,6 +1313,12 @@
</Filter>
<Filter
Name="Direct3D9">
<File
RelativePath="CD3D9CgMaterialRenderer.cpp">
</File>
<File
RelativePath="CD3D9CgMaterialRenderer.h">
</File>
<File
RelativePath="CD3D9Driver.cpp">
</File>
......
......@@ -1463,6 +1463,14 @@
<Filter
Name="video impl"
>
<File
RelativePath="CCgMaterialRenderer.cpp"
>
</File>
<File
RelativePath="CCgMaterialRenderer.h"
>
</File>
<File
RelativePath="CVideoModeList.cpp"
>
......@@ -1558,6 +1566,14 @@
<Filter
Name="OpenGL"
>
<File
RelativePath=".\COpenGLCgMaterialRenderer.cpp"
>
</File>
<File
RelativePath=".\COpenGLCgMaterialRenderer.h"
>
</File>
<File
RelativePath=".\COpenGLDriver.cpp"
>
......@@ -1858,6 +1874,14 @@
<Filter
Name="Direct3D9"
>
<File
RelativePath="CD3D9CgMaterialRenderer.cpp"
>
</File>
<File
RelativePath="CD3D9CgMaterialRenderer.h"
>
</File>
<File
RelativePath=".\CD3D9Driver.cpp"
>
......
......@@ -2052,6 +2052,14 @@
<Filter
Name="video"
>
<File
RelativePath="CCgMaterialRenderer.cpp"
>
</File>
<File
RelativePath="CCgMaterialRenderer.h"
>
</File>
<File
RelativePath="CVideoModeList.cpp"
>
......@@ -2147,6 +2155,14 @@
<Filter
Name="OpenGL"
>
<File
RelativePath=".\COpenGLCgMaterialRenderer.cpp"
>
</File>
<File
RelativePath=".\COpenGLCgMaterialRenderer.h"
>
</File>
<File
RelativePath="COpenGLDriver.cpp"
>
......@@ -2455,6 +2471,14 @@
<Filter
Name="Direct3D9"
>
<File
RelativePath="CD3D9CgMaterialRenderer.cpp"
>
</File>
<File
RelativePath="CD3D9CgMaterialRenderer.h"
>
</File>
<File
RelativePath="CD3D9Driver.cpp"
>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment