
I've made some structures and classes for managing shaders.
I have no where to upload a demo so here is the code in the next posts.
Enjoy

Code: Select all
/***************************************************************************
* Copyright (C) 2007-2008 by Radu Dumitru Bolovan *
* radubolovan@darkstarlinux.ro *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/**
@author Radu Dumitru Bolovan <radubolovan@darkstarlinux.ro>
*/
#ifndef __DSWHEELS_SHADER_H__
#define __DSWHEELS_SHADER_H__
#include "irrlicht.h"
using namespace irr;
typedef enum _eShaderParamType
{
SH_PARAM_TYPE_VERTEX = 0,
SH_PARAM_TYPE_PIXEL
}eShaderParamType;
typedef enum _eTexParamType
{
SH_TEX_TYPE_DIFFUSE = 0,
SH_TEX_TYPE_BUMP,
SH_TEX_TYPE_SPECULAR
}eTexParamType;
typedef struct _tShaderParam
{
inline _tShaderParam()
{
m_type = SH_PARAM_TYPE_VERTEX;
strcpy( m_name, "" );
m_nVanCount = 0;
m_values = NULL;
}
_tShaderParam( char const* name, float const* values, int nValCount, eShaderParamType type );
~_tShaderParam();
eShaderParamType m_type;
char m_name[256];
float* m_values;
int m_nVanCount;
}tShaderParam;
class DSWShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
inline DSWShaderCallBack() : video::IShaderConstantSetCallBack(){}
~DSWShaderCallBack()
{
uint nIndex;
for( nIndex = 0; nIndex < m_params.size(); nIndex++ )
{
tShaderParam* param = m_params[ nIndex ];
delete param;
}
}
inline void addShaderParam( char const* name, float const* values, int nValCount, const eShaderParamType& type )
{
uint nIndex;
for( nIndex = 0; nIndex < m_params.size(); nIndex++ )
{
if( strcmp( m_params[nIndex]->m_name, name ) == 0 )
return;
}
tShaderParam* param = new tShaderParam( name, values, nValCount, type );
m_params.push_back( param );
}
inline void setParamValues( char const* name, float const* values, int nValCount )
{
uint nIndex;
for( nIndex = 0; nIndex < m_params.size(); nIndex++ )
{
if( strcmp( m_params[nIndex]->m_name, name ) == 0 )
{
if( m_params[nIndex]->m_nVanCount < nValCount )
return;
memcpy( m_params[nIndex]->m_values, values, nValCount * sizeof(float) );
return;
}
}
}
inline void OnSetConstants( video::IMaterialRendererServices* s, s32 userData )
{
uint nIndex;
for( nIndex = 0; nIndex < m_params.size(); nIndex++ )
{
if( m_params[nIndex]->m_type, SH_PARAM_TYPE_VERTEX )
s->setVertexShaderConstant( m_params[nIndex]->m_name, m_params[nIndex]->m_values, m_params[nIndex]->m_nVanCount );
else
s->setPixelShaderConstant( m_params[nIndex]->m_name, m_params[nIndex]->m_values, m_params[nIndex]->m_nVanCount );
}
}
protected:
core::array<tShaderParam*> m_params;
};
class ShaderManager;
class Shader
{
public:
inline Shader()
{
m_shCallback = NULL;
strcpy( m_name, "" );
m_nId = -1;
m_manager = NULL;
}
Shader( char const* name, ShaderManager* man );
~Shader();
int load( c8* vsFileName, c8* psFileName, E_MATERIAL_TYPE matType );
inline int id(){ return m_nId; }
inline void addParam( char const* name, float const* values, int nValCount, const eShaderParamType& type )
{
m_shCallback->addShaderParam( name, values, nValCount, type );
}
inline void setParamValues( char const* name, float const* values, int nValCount )
{
m_shCallback->setParamValues( name, values, nValCount );
}
friend class ShaderManager;
protected:
DSWShaderCallBack* m_shCallback;
char m_name[256];
int m_nId;
ShaderManager* m_manager;
};
class ShaderManager
{
public:
ShaderManager();
~ShaderManager();
void init( char const* szAppDir );
s32 loadShader( char const* shaderName, c8* vsFileName, c8* psFileName, E_MATERIAL_TYPE matType );
s32 getShader( char const* shaderName );
Shader* shader( char const* shaderName ) const;
friend class Shader;
protected:
char m_szAppDir[DSW_MAX_PATH];
E_VERTEX_SHADER_TYPE m_vsType;
E_PIXEL_SHADER_TYPE m_psType;
core::array<Shader*> m_shaders;
video::IVideoDriver* m_driver
};
extern DSWheels::ShaderManager* g_pShaderManager;
#endif //__DSWHEELS_SHADER_H__
Code: Select all
/***************************************************************************
* Copyright (C) 2007-2008 by Radu Dumitru Bolovan *
* radubolovan@darkstarlinux.ro *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/**
@author Radu Dumitru Bolovan <radubolovan@darkstarlinux.ro>
*/
#include "dswshader.h"
_tShaderParam::_tShaderParam( char const* name, float const* values, int nValCount, eShaderParamType type )
{
m_type = type;
strcpy( m_name, name );
m_nVanCount = nValCount;
m_values = (float*)malloc( nValCount * sizeof(float) );
memcpy( m_values, values, nValCount * sizeof(float) );
}
_tShaderParam::~_tShaderParam()
{
if( m_nVanCount > 0 )
{
free( m_values );
}
}
DSWheels::ShaderManager* g_pShaderManager = NULL;
/************************************************************************************/
Shader::Shader( char const* name, ShaderManager* man )
{
m_shCallback = new DSWShaderCallBack();
strcpy( m_name, name );
m_nId = -1;
m_manager = man;
}
Shader::~Shader()
{
delete m_shCallback;
}
int Shader::load( c8* vsFileName, c8* psFileName, E_MATERIAL_TYPE matType )
{
m_nId = m_manager->m_driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles( vsFileName, "main", m_manager->m_vsType, psFileName, "main", m_manager->m_psType, m_shCallback, matType );
return m_nId;
}
/************************************************************************************/
/************************************************************************************/
ShaderManager::ShaderManager()
{
strcpy( m_szAppDir, "" );
m_driver = NULL;
m_vsType = EVST_VS_1_1;
m_psType = EPST_PS_1_1;
}
ShaderManager::~ShaderManager()
{
uint nIndex;
for( nIndex = 0; nIndex < m_shaders.size(); nIndex++ )
{
delete m_shaders[nIndex];
}
}
void ShaderManager::init( char const* szAppDir, video::IVideoDriver* driver )
{
strcpy( m_szAppDir, szAppDir );
video::E_DRIVER_TYPE dType = driver->getDriverType();
if( ( dType == video::EDT_DIRECT3D9 ) || ( dType == video::EDT_DIRECT3D8 ) )
{
if( driver->queryFeature( video::EVDF_VERTEX_SHADER_3_0 ) )
m_vsType = video::EVST_VS_3_0;
else if( driver->queryFeature( video::EVDF_VERTEX_SHADER_2_0 ) )
m_vsType = video::EVST_VS_2_0;
else if( driver->queryFeature( video::EVDF_VERTEX_SHADER_1_1 ) )
m_vsType = video::EVST_VS_1_1;
if( driver->queryFeature( video::EVDF_VERTEX_SHADER_3_0 ) )
m_psType = video::EPST_PS_3_0;
else if( driver->queryFeature( video::EVDF_PIXEL_SHADER_2_0 ) )
m_psType = video::EPST_PS_2_0;
else if( driver->queryFeature( video::EVDF_PIXEL_SHADER_1_4 ) )
m_psType = video::EPST_PS_1_4;
else if( driver->queryFeature( video::EVDF_PIXEL_SHADER_1_3 ) )
m_psType = video::EPST_PS_1_3;
else if( driver->queryFeature( video::EVDF_PIXEL_SHADER_1_2 ) )
m_psType = video::EPST_PS_1_2;
else if( driver->queryFeature( video::EVDF_VERTEX_SHADER_1_1 ) )
m_psType = video::EPST_PS_1_1;
}
else if( dType == video::EDT_OPENGL )
{
m_vsType = EVST_VS_3_0;
m_psType = EPST_PS_3_0;
}
m_driver = driver;
}
s32 ShaderManager::loadShader( char const* shaderName, c8* vsFileName, c8* psFileName, E_MATERIAL_TYPE matType )
{
uint nIndex;
for( nIndex = 0; nIndex < m_shaders.size(); nIndex++ )
{
if( strcmp( m_shaders[nIndex]->m_name, shaderName ) == 0 )
{
return m_shaders[nIndex]->id();
}
}
Shader* sh = new Shader( shaderName, this );
int nRet = sh->load( vsFileName, psFileName, matType );
if( nRet > -1 )
m_shaders.push_back( sh );
return nRet;
}
s32 ShaderManager::getShader( char const* shaderName )
{
uint nIndex;
for( nIndex = 0; nIndex < m_shaders.size(); nIndex++ )
{
if( strcmp( m_shaders[nIndex]->m_name, shaderName ) == 0 )
{
return m_shaders[nIndex]->id();
}
}
return -1;
}
Shader* ShaderManager::shader( char const* shaderName ) const
{
uint nIndex;
for( nIndex = 0; nIndex < m_shaders.size(); nIndex++ )
{
Shader* sh = m_shaders[nIndex];
if( strcmp( sh->m_name, shaderName ) == 0 )
{
return sh;
}
}
return NULL;
}
/************************************************************************************/
Code: Select all
g_pShaderManager = new ShaderManager();
g_pShaderManager->init( "data_directory", driver );
Code: Select all
delete g_pShaderManager;
Code: Select all
int nShader = g_pShaderManager->loadShader( "my_shader", "path_to_vertex_shader_inside_data_directory", "path_to_fragment_shader_inside_data_directory", video::EMT_SOLID );
Code: Select all
float fVValue = 1.0f;
g_pShaderManager->shader( "my_shader" )->addParam( "a_Vparameter", &fPValue, 1, SH_PARAM_TYPE_VERTEX );
Code: Select all
float fPValue = 1.0f;
g_pShaderManager->shader( "my_shader" )->addParam( "a_Pparameter", &fPValue, 1, SH_PARAM_TYPE_PIXEL );
Code: Select all
float fNewValue = 5.0f;
g_pShaderManager->shader( "my_shader" )->setParamValues( "a_Vparameter", &fNewValue, 1 );
You're absolutly rightBlindSide wrote:Instead of setting the default to PS 1.1, and VS 1.1, what I like to do is query the maximum supported shader model using driver->queryFeature() and use that instead, it's a good idea to compile for the highest supported shader model even on shaders that fall well below the instruction limit for example PS 3.0, because compiling at a higher model produces much more efficient code and less instructions since the compiler can utilize newly added optimization features.
Cheers
You can export any variables to shader ... any lights variables or ... anything...dlangdev wrote:... no lights are going to be added in this design, though. it's mostly about shaders and its relation to a material.....
Code: Select all
scene::ILightSceneNode* l1 = smgr->addLightSceneNode( ... );
video::SLight ld = l1->getLightData ();
float lightVector[4];
lightVector[0] = ld.AmbientColor.getRed();
lightVector[1] = ld.AmbientColor.getGreen();
lightVector[2] = ld.AmbientColor.getBlue();
lightVector[3] = ld.AmbientColor.getAlpha();
Code: Select all
g_pShaderManager->shader( "my_shader" )->addParam( "light_color", &lightVector[0], 4, SH_PARAM_TYPE_PIXEL );
Code: Select all
uniform float light_color[4];
Code: Select all
varying vec4 a_color;
void main()
{
vec3 normal = normalize( gl_NormalMatrix * gl_Normal );
vec3 position = vec3( gl_ModelViewMatrix * gl_Vertex );
vec3 lightVector = normalize( gl_LightSource[0].position.xyz - position );
vec4 diffuse = gl_FrontLightProduct[0].diffuse * max( 0.0, dot( normal,lightVector ) );
a_color = gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + diffuse;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
Code: Select all
varying vec4 a_color;
uniform sampler2D myTexture;
void main()
{
vec4 col = texture2D( myTexture, vec2( gl_TexCoord[0] ) );
gl_FragColor = col * a_color;
}