My first post ^^ Hi all.
I want to try some of those cool programs made here on the forums.
I just dont know how to compile them.
I put all the source files from download dir to my project and then replaced my main with his. Errors errors and more bs.
Before you go yelling and telling me to do some tuts, I did do ém all. Its just that I have not worked with external sources before where you have to include several files.
Here is the error:
[/img]http://img103.imageshack.us/my.php?imag ... ionib1.jpg[/img]
And here is the grass node project by bitplane incase u missed it:
http://irrlicht.sourceforge.net/phpBB2/ ... sc&start=0
Any suggestions?
Maybe if I provide som additional info on the problem, someone will get an idea to what the cause of the problem is.
Bitplane uses #include "CGrassPatchSceneNode.h" - where as in the examples i've seen the individual has used <CGrassPatchSceneNode.h>
The difference is clear. <CGrassPatchSceneNode.h> gets the following:
Cannot open include file: 'CGrassPatchSceneNode.h': No such file or directory
"CGrassPatchSceneNode.h" gets me:
10 of these:
main.obj : error LNK2001: unresolved external symbol "public: unsigned int __thiscall irr::scene::CGrassPatchSceneNode::getWindRes(void)" (?getWindRes@CGrassPatchSceneNode@scene@irr@@QAEIXZ)
This might be my limited amount of knowledge talking but maybe <> defines an external .h file and "" is internal... who knows?.
At this point I add the other .cpp either by using #include "CGrassPatchSceneNode.cpp" or adding it as a sourcefile in the project.
And now we are back to crashing the application
First-chance exception at 0x100b4ded in Irrlicht.exe: 0xC0000005: Access violation reading location 0x01712570.
Unhandled exception at 0x100b4ded in Irrlicht.exe: 0xC0000005: Access violation reading location 0x01712570.
The program '[1236] Irrlicht.exe: Native' has exited with code 0 (0x0).
A new development is that now I get this:
Debugging information for 'Irrlicht.exe cannot be found or does not match. No symbols loaded.
I mean seriously HOW ****ing hard can it be. Im just trying to compile a program.
Give me a reason not to give up. I was so looking forward to making games but this is seems hopeless.
I spend yesterday trying to get a premade maze script working, no luck. But that doesnt worry me, it was regular c++ and not specificly made for Irrlicht so I moved on and saved that one for later. Later that day I spend several hours getting Alpha to work on a mesh exported from Max.
The problem was that I was getting equal overall transparency on my mesh. Alpha channel wasn't working.
Thought first it was because I used multiple textures on one mesh. Or that maybe I should adjust the alpha level. Maybe the problem was the PNG/TGA.
At last I figured out that it was because I was using the "hello" tut code as foundation - it runs software render. DOH! My point is, I have no problem figuring these Irrlicht related problems out on my own, even though I have to work on it for several hours.
But I can't pinpoint the problem when its something like this. What words do I search for. Do I find a regular C++ manual and start from basics? Not worth it atm. I think. If I just learn how to compile others premade scripts, then I dont see any other problems related to general programming pop up in a long future.
This little thing might help others btw. Noticed some others with same problem during my travel of the forum. Some said that Multiple textures on one mesh was not possible. IT IS. Works wonders for me.
If I'm going down and out of the wonderful world of game making because of some compiler issues I might aswell share my experiences.
Help me please. Don't let this be my last post
Error running grass node
-
- Posts: 7
- Joined: Tue Oct 30, 2007 8:55 pm
Maybe someone could just link me a tutorial on compiling sourcecode.
Or tell me how you would normally do it in steps.
I am using Visual C++ Express 2005 as shown in the picture.
Btw. this is my first post EVER on ANY forum. so please just give me a friendly hello atleast
and no its not because im 8 years old, I am 23 - not that it really matters.
I will keep on searching for a solution but dont hesitate to reply so I can get on with the fun stuff.
Or tell me how you would normally do it in steps.
I am using Visual C++ Express 2005 as shown in the picture.
Btw. this is my first post EVER on ANY forum. so please just give me a friendly hello atleast
and no its not because im 8 years old, I am 23 - not that it really matters.
I will keep on searching for a solution but dont hesitate to reply so I can get on with the fun stuff.
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
First, you must solemly promise that you intend to use the grass scene node for Good, rather than for Evil, and by Evil, I of course mean trying to write a MMORPG.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
-
- Posts: 7
- Joined: Tue Oct 30, 2007 8:55 pm
Oh I will conquer the world with it, no doubt about it!
First I will make WoW 2 then run for president.
Actually I'm making a FPS.
The scene is a maze with deadly obsticles. Objective is to hunt down the 'pacman' monster to get key and escape.
So I need that grass node BAAD.
Got a crew of 3d artist to make some stuff for me.
I will post more details about the project when I get further in progress.
I will kick MMOPRG ass!
First I will make WoW 2 then run for president.
Actually I'm making a FPS.
The scene is a maze with deadly obsticles. Objective is to hunt down the 'pacman' monster to get key and escape.
So I need that grass node BAAD.
Got a crew of 3d artist to make some stuff for me.
I will post more details about the project when I get further in progress.
I will kick MMOPRG ass!
-
- Posts: 7
- Joined: Tue Oct 30, 2007 8:55 pm
Update
Even though non of you aided me in times of need, I found my way around the previous problem. Hurray! Spend ALL day on this one.
But now I have a new problem and this one is more Irrlicht related so maybe you will help me with this one. Thank you very much!
http://img116.imageshack.us/my.php?imag ... llywa9.jpg
This code from his sourcecode makes the game crash during startup.
//height = Terrain->getHeight(p.X, p.Z);
I'm not exactly sure why, but I tried someone elses suggestion from the 'grass node' post and switched with this:
f32 ay = TerrainHeightMap->getPixel(x1,z1).getBlue()* Terrain->getScale().Y;
f32 by = TerrainHeightMap->getPixel(x1+1,z1).getBlue()* Terrain->getScale().Y;
f32 cy = TerrainHeightMap->getPixel(x1,z1+1).getBlue()* Terrain->getScale().Y;
f32 dy = TerrainHeightMap->getPixel(x1+1,z1+1).getBlue()* Terrain->getScale().Y;
f32 u = xz.X - (f32)x1;
f32 v2 = xz.Z - (f32)z1;
height = ay*(1.0f-u)*(1.0f-v2) + by*u*(1.0f-v2) + cy*(1.0f-u)*v2 + dy*u*v2;
------------------------------------------------------
Seems to locate the 'Y' coordinate like it should, and I dont see why that has anything to do with the odd effect of grass gone wild. Why does the original code not work.
Another thing, I cannot switch render mode (this also makes the game crash) and even though I use his terrain the grass area is offset by a few hundred X, Y.
Come on guys, I need you on this one. I dont use paypal sorry
Oh yeah and the code (didnt want to include it because it just takes up alot of space but if it helps then why not):
main.cpp
And CGrassPatchSceneNode.cpp
But now I have a new problem and this one is more Irrlicht related so maybe you will help me with this one. Thank you very much!
http://img116.imageshack.us/my.php?imag ... llywa9.jpg
This code from his sourcecode makes the game crash during startup.
//height = Terrain->getHeight(p.X, p.Z);
I'm not exactly sure why, but I tried someone elses suggestion from the 'grass node' post and switched with this:
f32 ay = TerrainHeightMap->getPixel(x1,z1).getBlue()* Terrain->getScale().Y;
f32 by = TerrainHeightMap->getPixel(x1+1,z1).getBlue()* Terrain->getScale().Y;
f32 cy = TerrainHeightMap->getPixel(x1,z1+1).getBlue()* Terrain->getScale().Y;
f32 dy = TerrainHeightMap->getPixel(x1+1,z1+1).getBlue()* Terrain->getScale().Y;
f32 u = xz.X - (f32)x1;
f32 v2 = xz.Z - (f32)z1;
height = ay*(1.0f-u)*(1.0f-v2) + by*u*(1.0f-v2) + cy*(1.0f-u)*v2 + dy*u*v2;
------------------------------------------------------
Seems to locate the 'Y' coordinate like it should, and I dont see why that has anything to do with the odd effect of grass gone wild. Why does the original code not work.
Another thing, I cannot switch render mode (this also makes the game crash) and even though I use his terrain the grass area is offset by a few hundred X, Y.
Come on guys, I need you on this one. I dont use paypal sorry
Oh yeah and the code (didnt want to include it because it just takes up alot of space but if it helps then why not):
main.cpp
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#include "CGrassPatchSceneNode.h"
//#include "CWindGenerator.h"
#include "RealisticWater.h"
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
core::array<video::E_MATERIAL_TYPE> modes;
video::ITexture *tex1;
video::ITexture *tex2;
scene::IWindGenerator *wind;
#define width 10
#define height 10
#define total width*height
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(scene::ISceneNode* terrain, scene::CGrassPatchSceneNode** grass)
{
// store pointer to terrain so we can change its drawing mode
Terrain = terrain;
Grass = &grass[0];
mode = 0;
tex = false;
}
bool OnEvent(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())
++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_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_Y: // increase refresh delay
if (Grass[0]->getRefreshDelay() < 500)
{
for (int n=0; n<total; ++n)
{
Grass[n]->setRefreshDelay(Grass[n]->getRefreshDelay() + 10);
}
}
return true;
}
}
return false;
}
private:
scene::ISceneNode* Terrain;
u32 mode;
bool tex;
scene::CGrassPatchSceneNode** Grass;
};
int main()
{
// ask if user would like shadows
char i;
printf("Please press 'y' if you want to use realtime shadows.\n");
std::cin >> i;
bool shadows = (i == 'y');
// ask user for driver
video::E_DRIVER_TYPE driverType;
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) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
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 and exit if creation failed
IrrlichtDevice *device =
createDevice(driverType, core::dimension2d<s32>(1000, 760),
32, false, shadows);
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);
// add some help text
gui::IGUIStaticText* text = 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,320,200,450), true, true, 0, -1, true);
//Object
scene::IAnimatedMesh* mesh = smgr->getMesh(
"3d/objects/milka.b3d");
//node->setAnimationSpeed(30);
IAnimatedMeshSceneNode* hero = smgr->addAnimatedMeshSceneNode( mesh );
//hero->setMaterialTexture( 0, driver->getTexture("256.gif") );
hero->setFrameLoop(1*50, 20*50);
hero->setAnimationSpeed (15 * 100);
hero->setScale(vector3df(10,10,10));
// add shadow
hero->addShadowVolumeSceneNode();
smgr->setShadowColor(video::SColor(150,0,0,0));
hero->setPosition(vector3df(1000,500,1000));
hero->setMaterialFlag(EMF_LIGHTING, true);
//node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
//node->setMaterialFlag(EMF_BACK_FACE_CULLING, false);
//hero->setRotation(vector3df(270,0,0));
// create light
scene::ISceneNode* node = 0;
node = smgr->addLightSceneNode(0, core::vector3df(0,0,0),
video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 800.0f);
scene::ISceneNodeAnimator* anim = 0;
anim = smgr->createFlyCircleAnimator (core::vector3df(1000,650,1000),250.0f);
node->addAnimator(anim);
anim->drop();
// attach billboard to light
node = smgr->addBillboardSceneNode(node, core::dimension2d<f32>(50, 50));
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
node->setMaterialTexture(0, driver->getTexture("particlewhite.bmp"));
//Camera
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
camera->setPosition(core::vector3df(550,550,1000));
// add terrain scene node
scene::ITerrainSceneNode* terrain2 = smgr->addTerrainSceneNode("media/terrain-heightmap.bmp");
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");
core::vector3df ts(40, 4.0f, 40);
terrain2->setScale(ts);
terrain2->setPosition( core::vector3df(0,0,0) );
terrain2->setMaterialFlag(video::EMF_LIGHTING, false);
terrain2->setMaterialTexture(0, driver->getTexture("media/terrain-texture.jpg"));
terrain2->setMaterialTexture(1, driver->getTexture("media/detailmap3.jpg"));
terrain2->setMaterialType(video::EMT_DETAIL_MAP);
terrain2->scaleTexture(1.0f, 20.0f);
/*
RealisticWaterSceneNode* pWater;
pWater = new RealisticWaterSceneNode(smgr, 2100.0f, 2100.0f, driver->getTexture("data/terrain-grassmap.png"),device->getTimer(),core::dimension2di(256,256));
pWater->setPosition(vector3df(1000,500,1000));
pWater->setMaterialFlag(video::EMF_LIGHTING, false);
*/
// create skybox
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
smgr->addSkyBoxSceneNode(
driver->getTexture("irrlicht2_up.jpg"),
driver->getTexture("irrlicht2_dn.jpg"),
driver->getTexture("irrlicht2_lf.jpg"),
driver->getTexture("irrlicht2_rt.jpg"),
driver->getTexture("irrlicht2_ft.jpg"),
driver->getTexture("irrlicht2_bk.jpg"));
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
// create triangle selector for the terrain
scene::ITriangleSelector* selector
= smgr->createTerrainTriangleSelector(terrain2, 0);
terrain2->setTriangleSelector(selector);
selector->drop();
// create collision response animator and attach it to the camera
scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator(
selector, camera, core::vector3df(60,100,60),
core::vector3df(0,-3,0),
core::vector3df(0,50,0));
camera->addAnimator(anim2);
anim2->drop();
// create event receiver
scene::CGrassPatchSceneNode *grass[width*height];
MyEventReceiver receiver(terrain2,&grass[0]);
device->setEventReceiver(&receiver);
// create wind...
wind = scene::createWindGenerator( 30.0f, 3.0f );
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(terrain2, 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]->setMaterialTexture(0,tex1);
grass[x*width + z]->drop();
}
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
env->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Irrlicht Engine - SpecialFX example [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
And CGrassPatchSceneNode.cpp
Code: Select all
// Grass node by Gaz Davidson 2006
// created from Irrlicht's particle system node by Nikolaus Gebhardt
#include "CGrassPatchSceneNode.h"
#include "CWindGenerator.h"
namespace irr
{
namespace scene
{
#pragma comment(lib, "Irrlicht.lib")
//! constructor
CGrassPatchSceneNode::CGrassPatchSceneNode(
ITerrainSceneNode* terrain, ISceneManager* mgr, s32 id, core::vector3d<s32> gridpos,
char *filepath, video::IImage* heightMap, video::IImage* colourMap,
video::IImage* grassMap, scene::IWindGenerator *windgen) :
ISceneNode((ITerrainSceneNode*)terrain, mgr, -1),
DrawDistanceSQ(GRASS_PATCH_SIZE*1.5*GRASS_PATCH_SIZE*1.5),
MaxDensity(800),
TerrainHeightMap(heightMap),
TerrainColourMap(colourMap),
TerrainGrassMap(grassMap),
Terrain(terrain),
WindGen(windgen),
lastwindtime(0),
lastdrawcount(0),
redrawnextloop(true),
fpsLock(30)
{
#ifdef _DEBUG
setDebugName("CGrassPatchSceneNode");
#endif
// set position
setPosition(core::vector3df((f32)(gridpos.X*GRASS_PATCH_SIZE),0 , (f32)(gridpos.Z*GRASS_PATCH_SIZE)));
setWindRes(5);
// set default image count
setImageCount(core::dimension2d<s32>(4,2));
// create grass
Create();
}
//! destructor
CGrassPatchSceneNode::~CGrassPatchSceneNode()
{
}
void CGrassPatchSceneNode::setWindRes(u32 newres)
{
// set size of wind grid
windGridRes = newres < 2 ? 2 : newres;
WindGrid.set_used((windGridRes+1)*(windGridRes+1));
/*for (u32 i=0; i < WindGrid.size(); ++i)
{
WindGrid[i] = core::vector2df(0,0);
}*/
}
u32 CGrassPatchSceneNode::getWindRes() { return windGridRes; }
video::SMaterial& CGrassPatchSceneNode::getMaterial(u32 i) { return Material; }
u32 CGrassPatchSceneNode::getMaterialCount() { return 1; }
core::dimension2d<s32> CGrassPatchSceneNode::getImageCount() { return imagecount; }
void CGrassPatchSceneNode::setImageCount(core::dimension2d<s32> ic)
{
imagecount = ic;
imagesize.Width= 1.0f / f32(imagecount.Width);
imagesize.Height=1.0f / f32(imagecount.Height);
v1.set_used(imagecount.Width * imagecount.Height);
v2.set_used(imagecount.Width * imagecount.Height);
v3.set_used(imagecount.Width * imagecount.Height);
v4.set_used(imagecount.Width * imagecount.Height);
for (int x=0;x<imagecount.Width; ++x)
for (int y=0;y<imagecount.Height; ++y)
{
v1[ (imagecount.Width*y)+x ] = imagesize.Width * x;
v2[ (imagecount.Width*y)+x ] = imagesize.Height * (y+1);
v3[ (imagecount.Width*y)+x ] = imagesize.Height * y;
v4[ (imagecount.Width*y)+x ] = imagesize.Width * (x+1);
}
}
void CGrassPatchSceneNode::setRefreshDelay(u32 ms) { fpsLock = ms; }
u32 CGrassPatchSceneNode::getRefreshDelay() { return fpsLock; }
void CGrassPatchSceneNode::setDrawDistance(f32 draw) { DrawDistanceSQ = draw*draw; }
f32 CGrassPatchSceneNode::getDrawDistance() { return (f32)sqrt(DrawDistanceSQ); }
void CGrassPatchSceneNode::setMaxDensity(u32 max) { MaxDensity = max; }
u32 CGrassPatchSceneNode::getMaxDensity() { return MaxDensity; }
// creates random grass,
bool CGrassPatchSceneNode::Create()
{
srand((100 * gridpos.X) + gridpos.Z);
// particle count
s32 count = 3000; // lots. we dont need them all
// create them
Particles.set_used(count);
Box.reset(0,0,0);
core::matrix4 m;
m.setRotationDegrees(Terrain->getRotation());
m.setTranslation(Terrain->getAbsolutePosition());
m.makeInverse();
for(s32 i=0; i<count; ++i)
{
// get random x and z axis
f32 x = (rand() % (GRASS_PATCH_SIZE*10) ) / 1.0f;
f32 z = (rand() % (GRASS_PATCH_SIZE*10) ) / 1.0f;
x -= GRASS_PATCH_SIZE/2.0f;
z -= GRASS_PATCH_SIZE/2.0f;
Particles[i].pos.X = x;
Particles[i].pos.Z = z;
Particles[i].sprite.Width = rand() % imagecount.Width;
if (i<30)
Particles[i].sprite.Height = 1 *(rand() % imagecount.Height); // usually grass, sometimes a flower
else
Particles[i].sprite.Height = 0;
m.transformVect(Particles[i].pos);
// patch position + particle position - terrain position = position in terrain
core::vector3df p = getPosition() + Particles[i].pos; // - Terrain->getPosition();
core::dimension2d<f32> size;
/* core::vector3df xz((p.X - Terrain->getPosition().X)/Terrain->getScale().X, 0.0f,
(p.Z - Terrain->getPosition().Z)/Terrain->getScale().Z);*/
core::vector3df xz(p.X/Terrain->getScale().X,0.0f,p.Z/Terrain->getScale().Z);
s32 x1 = (s32) floorf( xz.X );
s32 z1 = (s32) floorf( xz.Z );
f32 height;
// drop blades that are outside the terrain
if ( x1 < 1 ||
z1 < 1 ||
x1 > TerrainHeightMap->getDimension().Width - 1 ||
z1 > TerrainHeightMap->getDimension().Height - 1 )
{
--count; --i;
Particles.set_used(count);
continue;
}
// drop blades that aren't so dense
video::SColor cDensity = TerrainGrassMap->getPixel(x1,z1);
if ((u32)(rand() % 255) > cDensity.getAlpha() || cDensity.getAlpha() < 1 )
{
--count; --i;
Particles.set_used(count);
continue;
}
f32 ay = TerrainHeightMap->getPixel(x1,z1).getBlue()* Terrain->getScale().Y;
f32 by = TerrainHeightMap->getPixel(x1+1,z1).getBlue()* Terrain->getScale().Y;
f32 cy = TerrainHeightMap->getPixel(x1,z1+1).getBlue()* Terrain->getScale().Y;
f32 dy = TerrainHeightMap->getPixel(x1+1,z1+1).getBlue()* Terrain->getScale().Y;
f32 u = xz.X - (f32)x1;
f32 v2 = xz.Z - (f32)z1;
height = ay*(1.0f-u)*(1.0f-v2) + by*u*(1.0f-v2) + cy*(1.0f-u)*v2 + dy*u*v2;
//height = 1000;//Terrain->getHeight(p.X, p.Z);
size = core::dimension2d<f32> ((f32)(rand() % 50 + 20), 100.0f);
size.Height *= (f32)cDensity.getBlue()/200.0f;
Particles[i].flex = size.Height / 120.0f;
Particles[i].pos.Y = height + (size.Height*0.5f);
Particles[i].color = TerrainColourMap->getPixel(x1,z1);
Particles[i].startColor = TerrainColourMap->getPixel(x1,z1);
Box.addInternalPoint(Particles[i].pos);
f32 rotation = (rand() % 3600) / 10.0f;
core::matrix4 m2;
m2.setRotationDegrees(core::vector3df(0,rotation,0)) ; //rand() % 20,rotation,rand() % 20));
core::vector3df dimensions(0.5f * size.Width,
-0.5f * size.Height,0);
m2.rotateVect(dimensions);
core::vector3df h = core::vector3df(dimensions.X,0.0f,dimensions.Z);
core::vector3df v = core::vector3df(0.0f,dimensions.Y,0.0f);
Particles[i].points[0] = Particles[i].pos + core::vector3df(dimensions.X,dimensions.Y,dimensions.Z);
Particles[i].points[1] = Particles[i].pos + core::vector3df(dimensions.X,-dimensions.Y,dimensions.Z);
Particles[i].points[2] = Particles[i].pos - core::vector3df(dimensions.X,dimensions.Y,dimensions.Z);
Particles[i].points[3] = Particles[i].pos - core::vector3df(dimensions.X,-dimensions.Y,dimensions.Z);
/*
core::vector3d<f32> xz1(Particles[i].points[0].X/Terrain->getScale().X,0.0f,Particles[i].points[0].Z/Terrain->getScale().Z);
x1 = (s32) xz1.X;
z1 = (s32) xz1.Z;
video::SColor c1 = TerrainHeightMap->getPixel(x1, z1);
f32 height1 = c1.getBlue()* Terrain->getScale().Y;
core::vector3d<f32> xz2(Particles[i].points[3].X/Terrain->getScale().X,0.0f,Particles[i].points[3].Z/Terrain->getScale().Z);
x1 = (s32) xz2.X - 10;
z1 = (s32) xz2.Z - 10;
video::SColor c2 = TerrainHeightMap->getPixel(x1, z1);
f32 height2 = c2.getBlue()* Terrain->getScale().Y;
Particles[i].points[0].Y = Particles[i].pos.Y + height1;
Particles[i].points[3].Y = Particles[i].pos.Y + height2;
*/
// Particles[i].points[0].Y -= 30;
// Particles[i].points[3].Y -= 30;
// Particles[i].points[1].Y += 30;
// Particles[i].points[2].Y += 30;
}
return true;
}
//! pre render
void CGrassPatchSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
{
if (Particles.size() != 0)
{
core::vector3df campos = SceneManager->getActiveCamera()->getPosition();
if ( (Box.getCenter() + getPosition()).getDistanceFromSQ(campos) < DrawDistanceSQ*1.5 )
{
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
}
}
}
void CGrassPatchSceneNode::OnAnimate(u32 timeMs)
{
//only change the grass if so many ms have passed since the last time we did it
// at 0 = 140fps, at 30 = 320fps, at 3000 = 370fps. woot!
if (lastwindtime < timeMs - fpsLock)
{
lastwindtime = timeMs;
redrawnextloop = true;
// populate wind grid
f32 dist =(Box.getCenter() + getPosition()).getDistanceFromSQ(SceneManager->getActiveCamera()->getPosition()) + 1;
if ( WindGen && dist < DrawDistanceSQ*1.5)
for (u32 x=0; x<windGridRes+1; ++x)
for (u32 z=0; z<windGridRes+1; ++z)
WindGrid[x*windGridRes + z] = //core::vector2df(0,0);
WindGen->getWind(core::vector3df(
( (f32)(gridpos.X*GRASS_PATCH_SIZE) + (f32)x*((f32)GRASS_PATCH_SIZE/(f32)windGridRes) - (GRASS_PATCH_SIZE/2.0f) ),
0.0f,
( (f32)(gridpos.X*GRASS_PATCH_SIZE) + (f32)x*((f32)GRASS_PATCH_SIZE/(f32)windGridRes) - (GRASS_PATCH_SIZE/2.0f) )),
timeMs);
}
else
{
redrawnextloop = false;
}
ISceneNode::OnAnimate(timeMs);
}
//! render
void CGrassPatchSceneNode::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
ICameraSceneNode* camera = SceneManager->getActiveCamera();
if (!camera || !driver)
return;
if (!redrawnextloop)
{
// just draw the old buffer
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(Material);
driver->drawIndexedTriangleList(Vertices.pointer(), lastdrawcount*4,
Indices.pointer(), lastdrawcount*4);
}
else
{
// reallocate arrays, if they are too small
reallocateBuffers();
core::vector3df campos = camera->getAbsolutePosition();
core::aabbox3d<f32> cbox = camera->getViewFrustum()->getBoundingBox();
core::vector3df pos = getPosition();
u32 drawcount=0;
u32 max = (Particles.size() < MaxDensity) ? Particles.size() : MaxDensity;
// in far boxes we dont loop so deep
// 175 to 255 fps
f32 d = getPosition().getDistanceFromSQ(campos) / (f32)(GRASS_PATCH_SIZE*GRASS_PATCH_SIZE);
if (d > 1.0)
{
//printf("max = %d, %d\n", max, (int)(max/d));
max = u32(f32(max)/d) ;
}
// i likes teh oldenpointer
f32 *v1p = &v1[0];
f32 *v2p = &v2[0];
f32 *v3p = &v3[0];
f32 *v4p = &v4[0];
// make the matrix outside the main loop
core::matrix4 m;
// create particle vertex data
for (u32 i=0; i< max; ++i)
{
s32 idx = drawcount*4;
SGrassParticle& particle = Particles[i];
core::vector3df gpos = particle.pos + pos;
// bounding box check: 150fps to 175fps
if ( !cbox.isPointInside(gpos) )
continue;
// distance checks: 145fps to 175fps
f32 dist = campos.getDistanceFromSQ(gpos);
if (dist > DrawDistanceSQ) // too far
{
continue;
}
else if (dist > DrawDistanceSQ * 0.5) // if we're fading in
{
f32 i1 = f32(i)/f32(max);
f32 i2 = (dist/DrawDistanceSQ)/2;
if (particle.sprite.Height) // first row is boring grass, the rest doesnt fade
{
//particle.color = video::SColor(255,255,255,255);
}
else
{
if ( i1 < i2)
{
continue;
}
else
{
// fade this particle
s32 c = s32(255.0f-f32(i2/i1)*255.0f);
}
}
}
else
{
// particle.color = video::SColor(255,255,255,255);
}
//
// wind
//
s32 igridsize = GRASS_PATCH_SIZE/(windGridRes-1);
s32 ihalfres = (windGridRes-1)/2;
// get wind modifier from wind grid
u32 xgrid = u32((particle.pos.X/(f32)igridsize) +(f32)ihalfres);
u32 zgrid = u32((particle.pos.Z/(f32)igridsize) +(f32)ihalfres);
// get fraction to next grid pos
f32 xnext = particle.pos.X/((f32)GRASS_PATCH_SIZE/(f32)windGridRes)+ (windGridRes/2.0f) - xgrid;
f32 znext = particle.pos.Z/((f32)GRASS_PATCH_SIZE/(f32)windGridRes)+ (windGridRes/2.0f) - zgrid;
// get wind positions
core::vector2df wind1 = WindGrid[ xgrid * windGridRes +zgrid];
core::vector2df wind2 = WindGrid[(xgrid+1)* windGridRes +zgrid];
core::vector2df wind3 = WindGrid[ xgrid *(windGridRes+1)+zgrid];
core::vector2df wind4 = WindGrid[(xgrid+1)*(windGridRes+1)+zgrid];
core::vector2df wind2d = wind1*(1.0f-xnext)*(1.0f-znext) +
wind2*xnext*(1.0f-znext) +
wind3*(1.0f-xnext)*znext +
wind4*xnext*znext;
// flexibility of this grass strand
wind2d *= particle.flex;
// convert to 3d vector
core::vector3df wind(wind2d.X,0.0f,wind2d.Y);
// blade colour change along Y axis
video::SColor gcol( particle.color.getAlpha(),
(s32) (particle.color.getRed() *0.8f),
(s32) (particle.color.getGreen()*0.8f),
(s32) (particle.color.getBlue() *0.8f) );
Vertices[0+idx].Pos = particle.points[0]; //particle.pos + core::vector3df(dimensions.X,dimensions.Y,dimensions.Z);
Vertices[0+idx].Color = gcol; // particle.color;
//Vertices[0+idx].Normal = ??
Vertices[1+idx].Pos = particle.points[1] + wind; //particle.pos + core::vector3df(dimensions.X,-dimensions.Y,dimensions.Z) + wind;
Vertices[1+idx].Color = particle.color;
//Vertices[1+idx].Normal = ??
Vertices[2+idx].Pos = particle.points[2] + wind; //particle.pos - core::vector3df(dimensions.X,dimensions.Y,dimensions.Z) + wind;
Vertices[2+idx].Color = particle.color;
//Vertices[2+idx].Normal = ??
Vertices[3+idx].Pos = particle.points[3]; //particle.pos - core::vector3df(dimensions.X,-dimensions.Y,dimensions.Z);
Vertices[3+idx].Color = gcol ; //particle.color;
//Vertices[3+idx].Normal = ??
//printf("%f, %f, %f, %f\n",v1p[particle.sprite.Width],v2p[particle.sprite.Height],v3p[particle.sprite.Height],v4p[particle.sprite.Width]);
s32 arrpos = (imagecount.Width*particle.sprite.Height)+particle.sprite.Width;
// set tcoords
Vertices[0+idx].TCoords.set(v1p[arrpos], v2p[arrpos] );
Vertices[1+idx].TCoords.set(v1p[arrpos], v3p[arrpos] );
Vertices[2+idx].TCoords.set(v4p[arrpos], v3p[arrpos] );
Vertices[3+idx].TCoords.set(v4p[arrpos], v2p[arrpos] );
drawcount++;
}
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(Material);
driver->drawIndexedTriangleList(Vertices.pointer(), drawcount*4,
Indices.pointer(), drawcount*4);
lastdrawcount = drawcount;
}
// for debug purposes only:
if (DebugDataVisible)
{
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
video::SMaterial m;
m.Lighting = false;
driver->setMaterial(m);
driver->draw3DBox(Box, video::SColor(0,255,255,255));
core::aabbox3d<f32> b2;
b2.reset(core::vector3df(0,0,0));
b2.addInternalPoint(Box.MaxEdge*0.01f);
driver->draw3DBox(b2, video::SColor(0,255,255,255));
}
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CGrassPatchSceneNode::getBoundingBox() const
{
return Box;
}
void CGrassPatchSceneNode::reallocateBuffers()
{
if (Particles.size() * 4 > Vertices.size() ||
Particles.size() * 6 > Indices.size())
{
s32 oldSize = Vertices.size();
Vertices.set_used(Particles.size() * 4);
u32 i;
// fill remaining vertices
for (i=oldSize; i<Vertices.size(); i+=4)
{
Vertices[0+i].Normal = core::vector3df(0,1,0);
Vertices[1+i].Normal = core::vector3df(0,1,0);
Vertices[2+i].Normal = core::vector3df(0,1,0);
Vertices[3+i].Normal = core::vector3df(0,1,0);
}
// fill remaining indices
s32 oldIdxSize = Indices.size();
s32 oldvertices = oldSize;
Indices.set_used(Particles.size() * 12);
for (i=oldIdxSize; i<Indices.size(); i+=12)
{
Indices[0+i] = 0+oldvertices;
Indices[1+i] = 2+oldvertices;
Indices[2+i] = 1+oldvertices;
Indices[3+i] = 0+oldvertices;
Indices[4+i] = 3+oldvertices;
Indices[5+i] = 2+oldvertices;
Indices[6+i] = 1+oldvertices;
Indices[7+i] = 2+oldvertices;
Indices[8+i] = 0+oldvertices;
Indices[9+i] = 2+oldvertices;
Indices[10+i] = 3+oldvertices;
Indices[11+i] = 0+oldvertices;
oldvertices += 4;
}
}
}
} // end namespace scene
} // end namespace irr
-
- Posts: 7
- Joined: Tue Oct 30, 2007 8:55 pm
Sorry
I dont mean to bump this post its just the best way to update you on my current status.
--> I tried to use bitplane's original sourcefiles again and this time with no crash. Wierd to say the least. But the crazy grass is still there.
So now im back to using height = Terrain->getHeight(p.X, p.Z);
I hope you get what im saying
LOL! My mistake, it was still running off my edited files. This **** makes me want to pull my hair and make it look like the grass...
--> I tried to use bitplane's original sourcefiles again and this time with no crash. Wierd to say the least. But the crazy grass is still there.
So now im back to using height = Terrain->getHeight(p.X, p.Z);
I hope you get what im saying
LOL! My mistake, it was still running off my edited files. This **** makes me want to pull my hair and make it look like the grass...