Code:
#include <irrlicht.h>
#include <iostream>
#include <windows.h>
#include <cstdlib>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#include "CGrassPatchSceneNode.h"
#include "CWindGenerator.h"
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
video::ITexture *tex1;
video::ITexture *tex2;
scene::IWindGenerator *wind;
#define width 10
#define height 10
#define total width*height
class MyEventReceiver : public IEventReceiver
{
public:
void shell(){
ShellExecute(NULL, "open","irrlicht-welt.exe", NULL, NULL, SW_SHOW);
exit(0);
}
MyEventReceiver(scene::ISceneNode* terrain, scene::CGrassPatchSceneNode** grass,
scene::ICameraSceneNode* camera)
{
// store pointer to terrain so we can change its drawing mode
Terrain = terrain;
Grass = &grass[0];
mode = 0;
tex = false;
Camera = camera;
modes.set_used(4);
modes[0] = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
modes[1] = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
modes[2] = video::EMT_TRANSPARENT_ADD_COLOR;
modes[3] = video::EMT_TRANSPARENT_VERTEX_ALPHA;
}
bool OnEvent(const SEvent &event)
{
// check if user presses the key 'W' or 'D'
if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case irr::KEY_KEY_W: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_WIREFRAME, !Terrain->getMaterial(0).Wireframe);
return true;
case irr::KEY_KEY_D: // toggle detail map
Terrain->setMaterialType(
Terrain->getMaterial(0).MaterialType == video::EMT_SOLID ?
video::EMT_DETAIL_MAP : video::EMT_SOLID);
return true;
case irr::KEY_KEY_Z: // change draw distance
for (int n=0; n<total; ++n)
{
if (Grass[n]->getDrawDistance() > GRASS_PATCH_SIZE + 50)
Grass[n]->setDrawDistance(Grass[n]->getDrawDistance()- 50.0f);
}
return true;
case irr::KEY_KEY_X: // change draw distance
for (int n=0; n<total; ++n)
{
Grass[n]->setDrawDistance(Grass[n]->getDrawDistance()+ 50.0f);
}
return true;
case irr::KEY_KEY_C: // change max density
for (int n=0; n<total; ++n)
{
if (Grass[n]->getMaxDensity() > 55 )
Grass[n]->setMaxDensity(Grass[n]->getMaxDensity()- 50);
}
return true;
case irr::KEY_KEY_V: // change max density
for (int n=0; n<total; ++n)
{
Grass[n]->setMaxDensity(Grass[n]->getMaxDensity()+ 50);
}
return true;
case irr::KEY_KEY_B: // change mode
if (mode > 0)
--mode;
for (int n=0; n<total; ++n)
{
Grass[n]->setMaterialType(modes[mode]);
}
return true;
case irr::KEY_KEY_N: // change mode
if (mode < modes.size()-1)
++mode;
for (int n=0; n<total; ++n)
{
Grass[n]->setMaterialType(modes[mode]);
}
return true;
case irr::KEY_KEY_M: // change mode
tex = !tex;
for (int n=0; n<total; ++n)
{
Grass[n]->setMaterialTexture(0,tex ? tex1:tex2);
}
return true;
case irr::KEY_KEY_S: // switch terrain invisible
Terrain->setVisible( !Terrain->isVisible());
return true;
case irr::KEY_KEY_Y: // switch terrain invisible
//float a,b,c;
//Camera->getAbsolutePosition()+ core::vector3df(0,100,0);
Camera->setPosition(Camera->getAbsolutePosition()+ core::vector3df(0,1000,0));
return true;
case irr::KEY_KEY_K: // less wind
if ( wind->getStrength() > 5 )
wind->setStrength( wind->getStrength() - 5 );
return true;
case irr::KEY_KEY_L: // more wind
if ( wind->getStrength() < 100 )
wind->setStrength( wind->getStrength() + 5 );
return true;
case irr::KEY_KEY_O: // blustery wind
if ( wind->getRegularity() > 1 )
wind->setRegularity( wind->getRegularity() - 1 );
return true;
case irr::KEY_KEY_P: // regular wind
if ( wind->getRegularity() < 20 )
wind->setRegularity( wind->getRegularity() + 1 );
return true;
case irr::KEY_KEY_U: // decrease wind resolution
if (Grass[0]->getWindRes() > 1)
{
for (int n=0; n<total; ++n)
{
Grass[n]->setWindRes(Grass[n]->getWindRes() - 1);
}
}
return true;
case irr::KEY_KEY_I: // decrease wind resolution
if (Grass[0]->getWindRes() < 20)
{
for (int n=0; n<total; ++n)
{
Grass[n]->setWindRes(Grass[n]->getWindRes() + 1);
}
}
return true;
case irr::KEY_KEY_T: // decrease refresh delay
if (Grass[0]->getRefreshDelay() > 4)
{
for (int n=0; n<total; ++n)
{
Grass[n]->setRefreshDelay(Grass[n]->getRefreshDelay() - 10);
}
}
return true;
case irr::KEY_KEY_8: // increase refresh delay
if (Grass[0]->getRefreshDelay() < 500)
{
for (int n=0; n<total; ++n)
{
Grass[n]->setRefreshDelay(Grass[n]->getRefreshDelay() + 10);
}
}
return true;
case irr::KEY_SPACE: // increase refresh delay
if(Camera->getAbsolutePosition().X >= 1900 && Camera->getAbsolutePosition().X <=2000
&& Camera->getAbsolutePosition().Z >= 900 && Camera->getAbsolutePosition().Z <=1000){
shell();
}
return true;
default:
break;
}
}
return false;
// if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
// {
// if(irr::KEY_SPACE){
// Camera->setPosition(core::vector3df(0,100,0)+ Camera->getAbsolutePosition());
// std::cout <<Camera->getAbsolutePosition().Y;
// }
//
// }
}
private:
scene::ISceneNode* Terrain;
scene::ICameraSceneNode* Camera;
u32 mode;
bool tex;
scene::CGrassPatchSceneNode** Grass;
core::array<video::E_MATERIAL_TYPE> modes;
};
/*
The start of the main function starts like in most other example. We ask the user
for the desired renderer and start it up.
*/
int main(int argc,char* argv[])
{
// (int) test =argv[2];
// std::cout << test*2;
// if( strcmp(argv[1],"t")== 0 ){
// exit(0);
// }
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
std::cout<<argv[1];
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
c8 i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// create device
#if (IRRLICHT_VERSION_MAJOR>1) || (IRRLICHT_VERSION_MINOR>5)
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<u32>(1000, 760),true,true);
#else
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(1000, 760),true,true);
#endif
enum
{
// I use this ISceneNode ID to indicate a scene node that is
// not pickable by getSceneNodeAndCollisionPointFromRay()
ID_IsNotPickable = 0,
// I use this flag in ISceneNode IDs to indicate that the
// scene node can be picked by ray selection.
IDFlag_IsPickable = 1 << 0,
// I use this flag in ISceneNode IDs to indicate that the
// scene node can be highlighted. In this example, the
// homonids can be highlighted, but the level mesh can't.
IDFlag_IsHighlightable = 1 << 1
};
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* env = device->getGUIEnvironment();
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
driver->setFog(video::SColor(0,138,125,125), video::EFT_FOG_LINEAR, 1000, 3000, .001f, true, false);
video::SLight Licht;
// Licht.Position(core::vector3df(0,0,0));
//Licht->AmbientColor();
//
// // add irrlicht logo
// env->addImage(driver->getTexture("../../media/irrlichtlogoalpha.tga"),
// core::position2d<s32>(10,10));
IAnimatedMesh* ersteMesh = smgr->getMesh("tor40-.mitMauer.obj");
// IAnimatedMesh* zweiteMesh = smgr->getMesh("dritte_test.obj");
IAnimatedMesh* dritteMesh = smgr->getMesh("dritte_test.obj");
// IAnimatedMesh* vierteMesh = smgr->getMesh("dritte_test.obj");
if (!dritteMesh) //TODO, die Anderen noch hinzufügen
{
device->drop();
return 1;
}
//IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
//IAnimatedMeshSceneNode* node2 = smgr->addAnimatedMeshSceneNode( mesh2 );
IMeshSceneNode* ersteNode = 0;
IMeshSceneNode* zweiteNode = 0;
IMeshSceneNode* dritteNode = 0;
IMeshSceneNode* vierteNode = 0;
if (ersteMesh)
ersteNode = smgr->addOctTreeSceneNode(ersteMesh->getMesh(0), 0, IDFlag_IsPickable);
// if (zweiteMesh)
// zweiteNode = smgr->addOctTreeSceneNode(zweiteMesh->getMesh(0), 0, IDFlag_IsPickable);
if (dritteMesh){
dritteNode = smgr->addOctTreeSceneNode(dritteMesh->getMesh(0),0, IDFlag_IsPickable);
// dritteMesh->addShadowVolumeSceneNode();
// smgr->setShadowColor(video::SColor(150,0,0,0));
}
// if (vierteMesh)
// vierteNode = smgr->addOctTreeSceneNode(vierteMesh->getMesh(0), 0, IDFlag_IsPickable);
// if (dritteMesh)
// {
// smgr->getMeshManipulator()->makePlanarTextureMapping(
// dritteMesh->getMesh(0), 0.003f);
//
// video::ITexture* normalMap =
// driver->getTexture("rockwall_height.bmp");
//
// if (normalMap)
// driver->makeNormalMapTexture(normalMap, 9.0f);
//
//
// scene::IMesh* tangentMesh = smgr->getMeshManipulator()->createMeshWithTangents(
// dritteMesh->getMesh(0));
//
// dritteNode = smgr->addMeshSceneNode(tangentMesh);
// dritteNode->setMaterialTexture(0,
// driver->getTexture("texturmauer.jpg"));
// dritteNode->setMaterialTexture(1, normalMap);
//
// dritteNode->getMaterial(0).SpecularColor.set(0,0,0,0);
//
// dritteNode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
// dritteNode->setMaterialType(video::EMT_PARALLAX_MAP_SOLID);
// // adjust height for parallax effect
// dritteNode->getMaterial(0).MaterialTypeParam = 0.035f;
//
// // drop mesh because we created it with a create.. call.
// tangentMesh->drop();
// }
// if (node)
// {
//
// node->setMaterialFlag(EMF_LIGHTING, false);
// node->setPosition(core::vector3df(1000,50,1000));
// node->setScale(vector3df(50,50,50));
//
// }
// The Quake mesh is pickable, but doesn't get highlighted.
// env->addStaticText(
// L"Press 'S' to toggle terrain\nPress 'W' to toggle wireframe mode\nPress 'D' to toggle detail map\nZ and X for distance\nC and V for max density\nB and N to change render mode\nM to swap texture\nK and L to change wind strength\nO and P to change wind regularity\nU and I for wind resolution\nT and Y for buffer refresh rate",
// core::rect<s32>(10,620,200,750), true, true, 0, -1, true);
// add camera
scene::ITriangleSelector* selectorH1 = 0;
scene::ITriangleSelector* selectorH2 = 0;
scene::ITriangleSelector* selectorH3 = 0;
scene::ITriangleSelector* selectorH4 = 0;
scene::ICameraSceneNode* camera =
smgr->addCameraSceneNodeFPS(0, 100.0f, 1.20f, ID_IsNotPickable, 0, 0, true,3.f);
camera->setPosition(core::vector3df(300,300,300));
camera->setFarValue(12000.0f);
camera->setTarget(core::vector3df(1000,0,1000));
camera->setScale(core::vector3df(0.8f,0.8f,0.8f));
if (dritteNode)
{
dritteNode->setPosition(core::vector3df(1000,80,1000));
dritteNode->setScale(core::vector3df(60,60,60));
dritteNode->setMaterialFlag(EMF_LIGHTING,false);
dritteNode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
//smgr->setShadowColor(video::SColor(150,0,0,0));
selectorH3 = smgr->createOctTreeTriangleSelector(
dritteNode->getMesh(), dritteNode, 128);
dritteNode->setTriangleSelector(selectorH3);
}
if (selectorH3)
{
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selectorH3, camera, core::vector3df(30,50,30),
core::vector3df(0,0,0), core::vector3df(0,50,0));//vorher 0,30,0
// 60,100,60),
// core::vector3df(0,-5,0),
// core::vector3df(0,50,0));
selectorH3->drop(); // As soon as we're done with the selector, drop it.
camera->addAnimator(anim);
anim->drop(); // And likewise, drop the animator when we're done referring to it.
}
if (ersteNode)
{
ersteNode->setPosition(core::vector3df(1000,100,3000));
ersteNode->setScale(core::vector3df(300,300,300));
ersteNode->setMaterialFlag(EMF_LIGHTING,1);
ersteNode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
selectorH1 = smgr->createOctTreeTriangleSelector(
ersteNode->getMesh(), ersteNode, 128);
ersteNode->setTriangleSelector(selectorH1);
}
if (selectorH1)
{
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selectorH1, camera, core::vector3df(30,50,30),
core::vector3df(0,0,0), core::vector3df(0,30,0));
selectorH1->drop(); // As soon as we're done with the selector, drop it.
camera->addAnimator(anim);
anim->drop(); // And likewise, drop the animator when we're done referring to it.
}
// create wind...
wind = scene::createWindGenerator( 30.0f, 3.0f );
// Die Sonne
// scene::ISceneNode* nodeSonne = 0;
// nodeSonne = smgr->addLightSceneNode(0, core::vector3df(0,0,0),
// video::SColorf(1.0f, 1, 1, 1), 1800000.0f);
//
//
// nodeSonne = smgr->addBillboardSceneNode(nodeSonne, core::dimension2d<f32>(500, 500));
// nodeSonne->setMaterialFlag(video::EMF_LIGHTING, false);
// //nodeSonne->setMaterialType(video::EMF_LIGHTING,false);
// nodeSonne->setPosition(core::vector3df(0,10000,0));
// nodeSonne->setScale(core::vector3df(1000,1000,1000));
// disable mouse cursor
device->getCursorControl()->setVisible(false);
// add terrain scene node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode("media/terrain-heightmap.bmp");
if (!terrain)
return 1;
video::IImage* heightMap = driver->createImageFromFile ("media/terrain-heightmap.bmp");
video::IImage* textureMap = driver->createImageFromFile ("media/terrain-grasscol.bmp");
video::IImage* grassMap = driver->createImageFromFile ("media/terrain-grassmap.png");
terrain->setScale(core::vector3df(40, 1.0f, 40));
terrain->setPosition( core::vector3df(0,0,0) );
terrain->setMaterialFlag(video::EMF_LIGHTING, 0);
terrain->setMaterialTexture(0, driver->getTexture("media/terrain-texture.jpg"));
terrain->setMaterialTexture(1, driver->getTexture("media/detailmap3.jpg"));
terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->setMaterialFlag(video::EMF_FOG_ENABLE, true);
terrain->scaleTexture(1.0f, 20.0f);
// create triangle selector for the terrain
scene::ITriangleSelector* selector
= smgr->createTerrainTriangleSelector(terrain, 0);
terrain->setTriangleSelector(selector);
selector->drop();
// create collision response animator and attach it to the camera
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector, camera, core::vector3df(60,100,60),
core::vector3df(0,-5,0),
core::vector3df(0,50,0));
camera->addAnimator(anim);
anim->drop();
// create event receiver
scene::CGrassPatchSceneNode *grass[width*height];
MyEventReceiver receiver(terrain,&grass[0],camera);
device->setEventReceiver(&receiver);
int lastFPS = -1;
tex1 = driver->getTexture("media/grass.png");
tex2 = driver->getTexture("media/grass2.bmp");
driver->makeColorKeyTexture(tex2, core::position2d<s32>(0,0));
//now we add some grass nodes
for (int x=0; x<width; ++x)
for (int z=0; z<height; ++z)
{
// add a grass node
grass[x*width + z] = new scene::CGrassPatchSceneNode(terrain, smgr, -1, core::vector3d<s32>(x,0,z), "grass", heightMap, textureMap, grassMap, wind);
grass[x*width + z]->setMaterialFlag(video::EMF_LIGHTING, false);
grass[x*width + z]->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
grass[x*width + z]->getMaterial(0).TextureLayer[0].TextureWrap = video::ETC_CLAMP;
grass[x*width + z]->getMaterial(0).MaterialTypeParam = 0.5f;
grass[x*width + z]->setMaterialTexture(0, tex1);
//grass[x*width + z]->setDebugDataVisible(-1);
grass[x*width + z]->drop();
}
smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
device->getCursorControl()->setVisible(false);
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, video::SColor(0,50,50,200) );
// smgr->addSkyDomeSceneNode(driver->getTexture("skydome.jpg"),16,8,0.95f,2.0f);
smgr->drawAll();
env->drawAll();
driver->endScene(); if (camera->getPosition().Y < -300.0f)
camera->setPosition(core::vector3df(1000,500,1000));
// display frames per second in window title
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Grass! [";
// str += driver->getName();
// str += "] FPS:";
// str += fps;
// str += ", Tri:";
// str += s32(driver->getPrimitiveCountDrawn());
// str += ", Draw Distance:";
// str += s32(grass[0]->getDrawDistance());
// str += ", Max density:";
// str += s32(grass[0]->getMaxDensity());
// str += ", Wind Reg:";
// str += s32(wind->getRegularity());
// str += ", Wind Str:";
// str += s32(wind->getStrength());
// str += ", Wind Res:";
// str += s32(grass[0]->getWindRes());
// str += ", DelayMS:";
// str += s32(grass[0]->getRefreshDelay());
str += "X:"; //1900-200
str += camera->getAbsolutePosition().X;
str += ", Z:";//930-950
str += camera->getAbsolutePosition().Z;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
heightMap->drop();
textureMap->drop();
grassMap->drop();
device->drop();
return 0;
}