


#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
//***********************************************************************
class CCamSpaceLightAnim : public ISceneNodeAnimator
{
public:
CCamSpaceLightAnim(ICameraSceneNode* cam, float offset, bool left)
: camera(cam), csoffset(0.5f * sin(PI/6.0f), 0.5f * cos(PI/6.0f),-cos(PI/6.0f)), doffset(offset)
{
if(left)
csoffset.X *= -1.0f;
}
virtual void animateNode(ISceneNode* node, u32 timeMs)
{
matrix4 camTM, lightTM;
vector3df wsoffset;
camera->getViewMatrix().getInverse(camTM);
camTM.zeroTranslation();
camTM.transformVect(wsoffset,csoffset);
TransformFromDirVector(-wsoffset, lightTM);
node->setRotation(lightTM.getRotationDegrees());
node->setPosition(wsoffset * doffset);
}
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const {}
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) {}
virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_UNKNOWN; }
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0)
{
return new CCamSpaceLightAnim(camera,doffset,false);
}
private:
void TransformFromDirVector(const vector3df& dir, matrix4& mat)
{
vector3df up(0.0f,1.0f,0.0f), zaxis, xaxis, yaxis;
zaxis = dir;
zaxis.normalize();
xaxis = up.crossProduct(zaxis);
xaxis.normalize();
yaxis = zaxis.crossProduct(xaxis);
mat[0] = xaxis.X; mat[1] = xaxis.Y; mat[2] = xaxis.Z; mat[3] = 0;
mat[4] = yaxis.X; mat[5] = yaxis.Y; mat[6] = yaxis.Z; mat[7] = 0;
mat[8] = zaxis.X; mat[9] = zaxis.Y; mat[10] = zaxis.Z; mat[11] = 0;
mat[12] = 0; mat[13] = 0; mat[14] = 0; mat[15] = 1;
}
vector3df csoffset;
float doffset;
ICameraSceneNode* camera;
};
//***********************************************************************
#define LIGHT_INDEX "glight"
#define AMBIENTCOLOUR "gAmbient"
#define DIFFUSECOLOUR "gDiffuse"
#define DIFFUSEMAP "diffuseMapTexture"
#define BLENDTOMAP "blendtoMapTexture"
class Terrain_Shader : public IShaderConstantSetCallBack
{
u32 light;
SColorf ambient;
SColorf diffuse;
int diffuse_sampler;
public:
Terrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f), diffuse(1.0f,1.0f,1.0f), diffuse_sampler(0) {}
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
services->setVertexShaderConstant(LIGHT_INDEX, (float*)(&light), 1);
services->setVertexShaderConstant(AMBIENTCOLOUR, (float*)(&ambient), 4);
services->setVertexShaderConstant(DIFFUSECOLOUR, (float*)(&diffuse), 4);
services->setPixelShaderConstant(DIFFUSEMAP,(float*)(&diffuse_sampler),1);
}
};
//***********************************************************************
class BlendToTerrain_Shader : public IShaderConstantSetCallBack
{
u32 light;
SColorf ambient;
SColorf diffuse;
int diffuse_sampler;
int blend_sampler;
public:
BlendToTerrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f),
diffuse(1.0f,1.0f,1.0f), diffuse_sampler(0) , blend_sampler(1) {}
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
services->setVertexShaderConstant(LIGHT_INDEX, (float*)(&light), 1);
services->setVertexShaderConstant(AMBIENTCOLOUR, (float*)(&ambient), 4);
services->setVertexShaderConstant(DIFFUSECOLOUR, (float*)(&diffuse), 4);
services->setPixelShaderConstant(DIFFUSEMAP,(float*)(&diffuse_sampler),1);
services->setPixelShaderConstant(BLENDTOMAP,(float*)(&blend_sampler),1);
}
};
//***********************************************************************
int main()
{
IrrlichtDevice *device = createDevice( video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, false, false, 0);
if (!device)
return 1;
device->setWindowCaption(L"Test mipmap");
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
// add spheres
IMeshSceneNode* sphereNode1 = smgr->addSphereSceneNode(50,16,smgr->getRootSceneNode(),999,vector3df(100.0f,0.0,0.0));
IMeshSceneNode* sphereNode2 = smgr->addSphereSceneNode(50,16,smgr->getRootSceneNode(),1000,vector3df(-100.0f,0.0,0.0));
// add camera
ICameraSceneNode* cameraNode = smgr->addCameraSceneNodeMaya();;
// add a light
ILightSceneNode* lightNode = smgr->addLightSceneNode(smgr->getRootSceneNode(),vector3df(0,0,0));
lightNode->setLightType(ELT_DIRECTIONAL);
// add camera space animator
ISceneNodeAnimator* anim = new CCamSpaceLightAnim(cameraNode,100.0f,false);
if(anim)
{
lightNode->addAnimator(anim);
anim->drop();
}
path blendtoVSfname = "../../media/blend_to_terrain.vert";
path blendtoPSfname = "../../media/blend_to_terrain.frag";
path terrainVSfname = "../../media/terrain.vert";
path terrainPSfname = "../../media/terrain.frag";
if (!driver->queryFeature(EVDF_PIXEL_SHADER_1_1) && !driver->queryFeature(EVDF_ARB_FRAGMENT_PROGRAM_1))
{
device->getLogger()->log("WARNING: Pixel shaders disabled ");
blendtoPSfname = "";
terrainVSfname = "";
}
if (!driver->queryFeature(EVDF_VERTEX_SHADER_1_1) && !driver->queryFeature(EVDF_ARB_VERTEX_PROGRAM_1))
{
device->getLogger()->log("WARNING: Vertex shaders disabled ");
blendtoVSfname = "";
terrainPSfname = "";
}
IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
s32 terrainShaderMat = 0;
s32 blendtoShaderMat = 0;
if (gpu)
{
Terrain_Shader* ts = new Terrain_Shader();
terrainShaderMat = gpu->addHighLevelShaderMaterialFromFiles( terrainVSfname, "main",
EVST_VS_1_1, terrainPSfname, "main", EPST_PS_1_1, ts, EMT_SOLID);
ts->drop();
BlendToTerrain_Shader* bts = new BlendToTerrain_Shader();
blendtoShaderMat = gpu->addHighLevelShaderMaterialFromFiles( blendtoVSfname, "main",
EVST_VS_1_1, blendtoPSfname, "main", EPST_PS_1_1, bts, EMT_SOLID);
bts->drop();
}
sphereNode1->setMaterialType((E_MATERIAL_TYPE)terrainShaderMat);
sphereNode2->setMaterialType((E_MATERIAL_TYPE)blendtoShaderMat);
ITexture* texture;
driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true);
texture = driver->getTexture("../../media/wall.jpg");
sphereNode1->setMaterialTexture(0, texture);
texture = driver->getTexture("../../media/wall.bmp");
sphereNode2->setMaterialTexture(0, texture);
texture = driver->getTexture("../../media/wall.jpg");
sphereNode2->setMaterialTexture(1, texture);
// dooo it
while(device->run())
{
driver->beginScene(true, true, SColor(255,127,127,140));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
uniform int glight;
uniform vec4 gAmbient;
uniform vec4 gDiffuse;
void main()
{
gl_Position = ftransform();
vec3 N = gl_NormalMatrix * gl_Normal;
vec3 L = gl_LightSource[glight].position;
float lambert = 0.5 * dot(N,L) + 0.5;
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
gl_TexCoord[0].zw = gl_MultiTexCoord1.xy;
gl_FrontColor = gl_Color * gl_LightSource[glight].diffuse * gDiffuse * (gAmbient + lambert * lambert);
}
uniform sampler2D diffuseMapTexture;
uniform sampler2D blendtoMapTexture;
void main()
{
/* normally this but needs second map channel to work
vec4 col = texture2D(diffuseMapTexture, vec2(gl_TexCoord[0].xy));
vec4 bld = texture2D(blendtoMapTexture, vec2(gl_TexCoord[0].zw));
gl_FragColor = gl_Color * lerp(bld,col,gl_Color.a); */
// so we've replaced with this
vec4 bld = texture2D(blendtoMapTexture, vec2(gl_TexCoord[0].xy));
gl_FragColor = gl_Color * bld;
}uniform int glight;
uniform vec4 gAmbient;
uniform vec4 gDiffuse;
void main()
{
gl_Position = ftransform();
vec3 N = gl_NormalMatrix * gl_Normal;
vec3 L = gl_LightSource[glight].position;
float lambert = 0.5 * dot(N,L) + 0.5;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color * gl_LightSource[glight].diffuse * gDiffuse * (gAmbient + lambert * lambert);
}uniform sampler2D diffuseMapTexture;
void main()
{
vec4 col = texture2D(diffuseMapTexture, vec2(gl_TexCoord[0]));
gl_FragColor = col * gl_Color;
} texture = driver->getTexture("../../media/wall.bmp");
sphereNode2->setMaterialTexture(0, texture);
texture = driver->getTexture("../../media/wall.jpg");
sphereNode2->setMaterialTexture(1, texture); texture = driver->getTexture("../../media/wall.bmp");
sphereNode2->setMaterialTexture(1, texture);
texture = driver->getTexture("../../media/wall.jpg");
sphereNode2->setMaterialTexture(0, texture);BlendToTerrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f),
diffuse(1.0f,1.0f,1.0f), diffuse_sampler(0), blend_sampler(1) {}BlendToTerrain_Shader() : light(0), ambient(0.0f,0.0f,0.0f),
diffuse(1.0f,1.0f,1.0f), diffuse_sampler(1), blend_sampler(0) {}Users browsing this forum: No registered users and 1 guest