How to use the terrain engine libmini with Irrlicht
-
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
heres v0.4, changed to FPS-camera instead of using scrolling with keys, i will change the download this evening to this version, again with help from Stefan Roettger, i think the demo is more his demo than mine...:
[code]
// Example Mars for libmini-terrainengine with Irrlicht
// try to fly with the cursor keys and mouse!
// v.01 16.10.2004
// v.02 17.10.2004
// v.03 18.10.2004 delete vertex behind line of sight (deleted in v.04 cause user-defined-culling isnt part of this tutorial)
// v.04 change from keyscrolling to FPS-camera, delete the userculling from v.03
// btw: if you want user-defined-culling, you can delete vertex/indices
// from buffer after the stub->draw-function
//
// The mini library is the core of the terrain renderer described in the
// paper "Real-Time Generation of Continuous Levels of Detail for Height Fields".
// Copyright (c) 1995-2004 by Stefan Roettger (Version 5.02 as of 18.August.2004).
//
// The terrain renderer is licensed under the terms of the LGPL (see
// http://www.gnu.org/copyleft/ for more information on the license).
// Any commercial use of the code or parts of it requires the explicit
// permission of the author!
//
// The libmini-author's contact address is:
//
// mailto:roettger@cs.fau.de
// http://www9.cs.fau.de/Persons/Roettger
//
// The original terrain rendering paper and the talk are available here:
//
// http://www9.cs.fau.de/Persons/Roettger/ ... ERRAIN.PDF
// http://www9.cs.fau.de/Persons/Roettger/ ... WSCG98.PPT
//
//
// example and Irrlicht-interface-functions by zenprogramming
// (with help from Stefan Roettger ;-) )
// mailto: zenprogramming at yahoo dot de
// http://zenprogramming.tripod.com
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
#pragma comment(lib, "Irrlicht.lib")
#include "ministub.hpp"
int triangleindex=-1;
int vertex0=0;
SMeshBuffer* buffer = 0;
video::S3DVertex vertex;
int size=256;
float dim=1.0f;
float scale=0.2f;
float res=1000.0f;
float ex=0.0f,ey=10.0f,ez=-30.0f;
float dx=0.0f,dy=-0.25f,dz=-1.0f;
float ux=0.0f,uy=1.0f,uz=0.0f;
//libmini->Irrlichtinterfacefunctions
//this function starts every trianglefan
void mybeginfan()
{
triangleindex=0;
vertex0=buffer->getVertexCount();
}
//libmini->Irrlichtinterfacefunctions
//this function gives one vertex
void myfanvertex(float i,float y,float j)
{
vertex.Pos.set(dim*i-size/2*dim,
y*scale,
size/2*dim-dim*j);
vertex.TCoords.set(1.0f-(float)i/(size-1),
1.0f-(float)j/(size-1));
// instead of using white vertex-colors with a texture,
// you could use the vertex-colors for shadows from heightdelta
// vertex.Color.set(255,from heightdelta,from heightdelta,from heightdelta);
buffer->Vertices.push_back(vertex);
if (triangleindex==2)
{
buffer->Indices.push_back(vertex0);
buffer->Indices.push_back(buffer->getVertexCount()-2);
buffer->Indices.push_back(buffer->getVertexCount()-1);
return;
}
triangleindex++;
}
int main(int argc,char *argv[])
{
scene::IAnimatedMesh* mesh = 0;
video::IVideoDriver* driver=0;
scene::ICameraSceneNode* camera=0;
video::SMaterial material;
vector3df cameraPos;
vector3df cameraTarget;
int cameraoffset=120;
IrrlichtDevice *device =
createDevice(video::EDT_DIRECTX8, core::dimension2d<s32>(640, 480));
driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
material.Texture1=0;
material.Lighting=false;
driver->setMaterial(material);
IImage* heightimage = driver->createImageFromFile("FaceOfMarsMap.bmp");
size = heightimage->getDimension().Width;
short int *hfield = new short int[size*size];
for (int i=0; i<size; i++)
for (int j=0; j<size; j++)
hfield[i+j*size] = heightimage->getPixel(i,size-1-j).getRed();
ministub *stub;
stub=new ministub(hfield,
&size,&dim,scale,1.0f,
mybeginfan,myfanvertex,0,0,
NULL);
int lastFPS = -1;
vertex.Normal.set(0,1,0);
vertex.Color.set(255,255,255,255);
scene::IAnimatedMeshSceneNode* terrainnode = 0;
ITexture* terraintexture = driver->getTexture("faceofmars.jpg");
camera = smgr->addCameraSceneNodeFPS(0, 100, 100);
camera->setPosition(vector3df(0.0f,0.0f,0.0f));
camera->setTarget(vector3df(0.0f,0.0f,-1.0f));
camera->setUpVector(vector3df(0.0f,1.0f,0.0f));
while(device->run())
{
buffer = new SMeshBuffer();
float aspect = camera->getAspectRatio();
float fovy = 180.0f/PI*camera->getFOV();
float nearp = camera->getNearValue();
float farp = camera->getFarValue();
vector3df pos = camera->getPosition();
vector3df tgt = camera->getTarget();
float glide = stub->getheight(pos.X,pos.Z)+10.0f*nearp;
if (glide<0.0f) glide = 100.0f;
camera->setPosition(vector3df(pos.X,glide,pos.Z));
if (tgt.X==pos.X && tgt.Y==pos.Y && tgt.Z==pos.Z) tgt.Z-=1.0f;
stub->draw(res,
pos.X,glide,pos.Z,
tgt.X-pos.X,tgt.Y-pos.Y,tgt.Z-pos.Z,
0.0f,1.0f,0.0f,
2.4f*fovy,aspect,
nearp,farp);
SMesh* meshtmp = new SMesh();
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
buffer->recalculateBoundingBox();
meshtmp->addMeshBuffer(buffer);
meshtmp->recalculateBoundingBox();
animatedMesh->addMesh(meshtmp);
animatedMesh->recalculateBoundingBox();
mesh = animatedMesh;
buffer->drop();
terrainnode = smgr->addAnimatedMeshSceneNode(mesh);
terrainnode->setMaterialFlag(video::EMF_LIGHTING, false);
terrainnode->setMaterialTexture(0, terraintexture);
driver->beginScene(true, true, video::SColor(0,150,50,0));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Marsdemo: Terrainengine-libmini and Irrlicht Engine (fps:%d) Triangles:%d",
fps, driver->getPrimitiveCountDrawn());
device->setWindowCaption(tmp);
lastFPS = fps;
}
terrainnode->remove();
meshtmp->drop();
animatedMesh->drop();
}
delete(stub);
delete(hfield);
heightimage->drop();
device->drop();
return 0;
}
[/code]
[code]
// Example Mars for libmini-terrainengine with Irrlicht
// try to fly with the cursor keys and mouse!
// v.01 16.10.2004
// v.02 17.10.2004
// v.03 18.10.2004 delete vertex behind line of sight (deleted in v.04 cause user-defined-culling isnt part of this tutorial)
// v.04 change from keyscrolling to FPS-camera, delete the userculling from v.03
// btw: if you want user-defined-culling, you can delete vertex/indices
// from buffer after the stub->draw-function
//
// The mini library is the core of the terrain renderer described in the
// paper "Real-Time Generation of Continuous Levels of Detail for Height Fields".
// Copyright (c) 1995-2004 by Stefan Roettger (Version 5.02 as of 18.August.2004).
//
// The terrain renderer is licensed under the terms of the LGPL (see
// http://www.gnu.org/copyleft/ for more information on the license).
// Any commercial use of the code or parts of it requires the explicit
// permission of the author!
//
// The libmini-author's contact address is:
//
// mailto:roettger@cs.fau.de
// http://www9.cs.fau.de/Persons/Roettger
//
// The original terrain rendering paper and the talk are available here:
//
// http://www9.cs.fau.de/Persons/Roettger/ ... ERRAIN.PDF
// http://www9.cs.fau.de/Persons/Roettger/ ... WSCG98.PPT
//
//
// example and Irrlicht-interface-functions by zenprogramming
// (with help from Stefan Roettger ;-) )
// mailto: zenprogramming at yahoo dot de
// http://zenprogramming.tripod.com
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
#pragma comment(lib, "Irrlicht.lib")
#include "ministub.hpp"
int triangleindex=-1;
int vertex0=0;
SMeshBuffer* buffer = 0;
video::S3DVertex vertex;
int size=256;
float dim=1.0f;
float scale=0.2f;
float res=1000.0f;
float ex=0.0f,ey=10.0f,ez=-30.0f;
float dx=0.0f,dy=-0.25f,dz=-1.0f;
float ux=0.0f,uy=1.0f,uz=0.0f;
//libmini->Irrlichtinterfacefunctions
//this function starts every trianglefan
void mybeginfan()
{
triangleindex=0;
vertex0=buffer->getVertexCount();
}
//libmini->Irrlichtinterfacefunctions
//this function gives one vertex
void myfanvertex(float i,float y,float j)
{
vertex.Pos.set(dim*i-size/2*dim,
y*scale,
size/2*dim-dim*j);
vertex.TCoords.set(1.0f-(float)i/(size-1),
1.0f-(float)j/(size-1));
// instead of using white vertex-colors with a texture,
// you could use the vertex-colors for shadows from heightdelta
// vertex.Color.set(255,from heightdelta,from heightdelta,from heightdelta);
buffer->Vertices.push_back(vertex);
if (triangleindex==2)
{
buffer->Indices.push_back(vertex0);
buffer->Indices.push_back(buffer->getVertexCount()-2);
buffer->Indices.push_back(buffer->getVertexCount()-1);
return;
}
triangleindex++;
}
int main(int argc,char *argv[])
{
scene::IAnimatedMesh* mesh = 0;
video::IVideoDriver* driver=0;
scene::ICameraSceneNode* camera=0;
video::SMaterial material;
vector3df cameraPos;
vector3df cameraTarget;
int cameraoffset=120;
IrrlichtDevice *device =
createDevice(video::EDT_DIRECTX8, core::dimension2d<s32>(640, 480));
driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
material.Texture1=0;
material.Lighting=false;
driver->setMaterial(material);
IImage* heightimage = driver->createImageFromFile("FaceOfMarsMap.bmp");
size = heightimage->getDimension().Width;
short int *hfield = new short int[size*size];
for (int i=0; i<size; i++)
for (int j=0; j<size; j++)
hfield[i+j*size] = heightimage->getPixel(i,size-1-j).getRed();
ministub *stub;
stub=new ministub(hfield,
&size,&dim,scale,1.0f,
mybeginfan,myfanvertex,0,0,
NULL);
int lastFPS = -1;
vertex.Normal.set(0,1,0);
vertex.Color.set(255,255,255,255);
scene::IAnimatedMeshSceneNode* terrainnode = 0;
ITexture* terraintexture = driver->getTexture("faceofmars.jpg");
camera = smgr->addCameraSceneNodeFPS(0, 100, 100);
camera->setPosition(vector3df(0.0f,0.0f,0.0f));
camera->setTarget(vector3df(0.0f,0.0f,-1.0f));
camera->setUpVector(vector3df(0.0f,1.0f,0.0f));
while(device->run())
{
buffer = new SMeshBuffer();
float aspect = camera->getAspectRatio();
float fovy = 180.0f/PI*camera->getFOV();
float nearp = camera->getNearValue();
float farp = camera->getFarValue();
vector3df pos = camera->getPosition();
vector3df tgt = camera->getTarget();
float glide = stub->getheight(pos.X,pos.Z)+10.0f*nearp;
if (glide<0.0f) glide = 100.0f;
camera->setPosition(vector3df(pos.X,glide,pos.Z));
if (tgt.X==pos.X && tgt.Y==pos.Y && tgt.Z==pos.Z) tgt.Z-=1.0f;
stub->draw(res,
pos.X,glide,pos.Z,
tgt.X-pos.X,tgt.Y-pos.Y,tgt.Z-pos.Z,
0.0f,1.0f,0.0f,
2.4f*fovy,aspect,
nearp,farp);
SMesh* meshtmp = new SMesh();
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
buffer->recalculateBoundingBox();
meshtmp->addMeshBuffer(buffer);
meshtmp->recalculateBoundingBox();
animatedMesh->addMesh(meshtmp);
animatedMesh->recalculateBoundingBox();
mesh = animatedMesh;
buffer->drop();
terrainnode = smgr->addAnimatedMeshSceneNode(mesh);
terrainnode->setMaterialFlag(video::EMF_LIGHTING, false);
terrainnode->setMaterialTexture(0, terraintexture);
driver->beginScene(true, true, video::SColor(0,150,50,0));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Marsdemo: Terrainengine-libmini and Irrlicht Engine (fps:%d) Triangles:%d",
fps, driver->getPrimitiveCountDrawn());
device->setWindowCaption(tmp);
lastFPS = fps;
}
terrainnode->remove();
meshtmp->drop();
animatedMesh->drop();
}
delete(stub);
delete(hfield);
heightimage->drop();
device->drop();
return 0;
}
[/code]
Last edited by knightoflight on Wed Oct 20, 2004 5:43 pm, edited 3 times in total.
I have seen that you made Round Based Strategy. On your web site exists examples for terrain rendering with multiple textures and alphablending.
How much difficult would be to use libmini to produce same thing? I'm interested in terrain rendering and possibilites to have renderer capable to do things like AOM or Empire Earth. I don't know how fast this can be with Irrlicht, but let say that we care only about visual impression right now.
What do you think?
How much difficult would be to use libmini to produce same thing? I'm interested in terrain rendering and possibilites to have renderer capable to do things like AOM or Empire Earth. I don't know how fast this can be with Irrlicht, but let say that we care only about visual impression right now.
What do you think?
-
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
-
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
The new demo from Stefan and me is for download ready. Thats all, i dont think there will be more versions. Now you can show us your demos.
-> download-Area, faceofmarsdemo
http://zenprogramming.tripod.com
-> download-Area, faceofmarsdemo
http://zenprogramming.tripod.com
-
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
The new demo from Stefan and me is for download ready. Thats all, i dont think there will be more versions.
http://zenprogramming.tripod.com -> download-Area, faceofmarsdemo
Now we want to see your demo with the engine ;-)
http://zenprogramming.tripod.com -> download-Area, faceofmarsdemo
Now we want to see your demo with the engine ;-)
-
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
The demo-version for UNIX is now online on Stefan Roesslers terrain-engine dowload-place, too:
http://www9.informatik.uni-erlangen.de/ ... /download/
http://www9.informatik.uni-erlangen.de/ ... /download/
libmini scenenode based on the well know demo
Header
Impl
usage:
Take a loook at the coments in the header file for a overall look of the api.
Have fun
Tom
Edit:
There's something wrong with the BoundingBox transformation so disable autoculling if you place your terrain somewhere other than at (0,0,0) with angles (0,0,0).
Header
Code: Select all
#ifndef __CLMTerrainSceneNode_h__
#define __CLMTerrainSceneNode_h__
#include <irrlicht.h>
#include <ministub.hpp>
#ifdef _DEBUG
#pragma comment(lib, "libMini_d.lib")
#else
#pragma comment(lib, "libMini.lib")
#endif
namespace irr
{
namespace scene
{
using namespace core;
using namespace video;
class CLMTerrainSceneNode : public ISceneNode
{
protected:
//////////////////////////////////////////////////////////////////
// globals for libMini callbacks
//////////////////////////////////////////////////////////////////
// prepares a buffer if the buffer is nonempty draws and then empties the buffer
// this function needs to be called after stub->draw one more time
static void _BeginFan();
// fills the buffer with vertecis
static void _FanVertex(float i,float y,float j);
// pointer to the scenenode
static CLMTerrainSceneNode* _self;
//////////////////////////////////////////////////////////////////
ministub *stub;
IVideoDriver* driver;
SMeshBuffer buffer; // a buffer for fan vertecis
S3DVertex vertex; // a default vertex
// draw the meshbuffer
void BeginFan();
// add point (i,y,j) to the meshbuffer
void FanVertex(float i,float y,float j);
// point spacing
float dim;
// height scaling factor
float scale;
// pixel width of the heightmap
s32 size;
// resolution
float res;
// field of view
float fovy;
// aspect ratio
float aspect;
// near value
float nearp;
// far value
float farp;
// the height field
float *hfield;
// material
SMaterial Material;
// invere of absolute transform to calculate hf coordinates from world coordinates
matrix4 invAbsoluteTransform;
// current camera pos in heightfield coordinate
vector3df pos;
// current camera target in heightfield coordinate
vector3df tgt;
// current camer up in heightfield coordinate
vector3df up;
// Bounding box of the heightfield
mutable aabbox3df Box;
public:
// constructor
CLMTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id);
// destructor
virtual ~CLMTerrainSceneNode();
/*!
\brief create the terrain
\param heightmap, image with height values
\param texture, texture used for texturing the terrain
\param detailmap, not used
\param gridPointSpacing, spacing between the gridpoints of the heightfield
\param heightScale, scaling value for image height values
\param resolution, 1000.0f ... 1000000.0f
*/
bool create(IImage* heightmap, ITexture* texture, ITexture* detailmap,
f32 gridPointSpacing, f32 heightScale, f32 resolution);
// prerender register node for rendering and call child nodes for registering
virtual void OnPreRender();
// render the node
virtual void render() ;
// post render, animation etc.
virtual void OnPostRender(u32 timeMs);
// get the material with given number
virtual SMaterial& getMaterial(s32 i)
{
return Material;
}
// get the boundingbox of the node
const aabbox3df& getBoundingBox() const
{
AbsoluteTransformation.transformBox(Box);
return Box;
}
// get the inverse of the absolute transformation
matrix4& getInvAbsoluteTransformation(){ return invAbsoluteTransform; }
// get the heightfield data
f32* getHeightField() { return hfield; }
// get the length of the square size of the heightfield
s32 getHeightFieldSize() { return size; }
// spacing between the sample points
f32 getPointSpacing() { return dim; }
// scaling factor to modify the height values
f32 getHeightScale() { return scale; }
// get height at grid point (i,j)
f32 getHeight(int i,int j);
// get height at heightfield coordinate (x,z)
// transformation is inv=AbsoluteTransform.getInverse();
// inv.transformVect(pos);
f32 getHeight(float x,float z);
// get fog height at heightfield coordinate (x,z)
// transformation is inv=AbsoluteTransform.getInverse();
// inv.transformVect(pos);
f32 getFogHeight(float x,float z);
// get normal at heightfield coordinate (x,z)
// transformation is inv=AbsoluteTransform.getInverse();
// inv.transformVect(pos);
vector3df getNormal(float x,float z);
};
}
}
#endif
Code: Select all
#include "CLMTerrainSceneNode.h"
namespace irr
{
namespace scene
{
using namespace core;
using namespace video;
// self pointer for callback
CLMTerrainSceneNode* CLMTerrainSceneNode::_self=0;
// prepares a buffer if the buffer is nonempty draws and then empties the buffer
// this function needs to be called after stub->draw one more time
void CLMTerrainSceneNode::_BeginFan()
{
if(_self) _self->BeginFan();
}
// fills the buffer with vertecis
void CLMTerrainSceneNode::_FanVertex(float i,float y,float j)
{
if(_self) _self->FanVertex(i,y,j);
}
//////////////////////////////////////////////////////////////////////////
// constructor
CLMTerrainSceneNode::CLMTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id):
ISceneNode(parent,mgr,id)
{
driver=SceneManager->getVideoDriver();
stub=0;
hfield=0;
AbsoluteTransformation.getInverse(invAbsoluteTransform);
}
CLMTerrainSceneNode::~CLMTerrainSceneNode()
{
if(stub) delete stub;
if(hfield) delete [] hfield;
}
//! loads the terrain
bool CLMTerrainSceneNode::create(IImage* heightmap, ITexture* texture, ITexture* detailmap,
f32 gridPointSpacing, f32 heightScale, f32 resolution)
{
if(stub) delete stub;
if(hfield) delete [] hfield;
res=resolution;
dim=gridPointSpacing;
scale=heightScale;
size = heightmap->getDimension().Width;
hfield = new float[size*size];
vector3df ext(size*dim,0,size*dim);
f32 hmin=10000000;
f32 hmax=-10000000;
for (int i=0; i<size; i++)
for (int j=0; j<size; j++)
{
hfield[i+j*size] = heightmap->getPixel(i,size-1-j).getRed()*scale;
if(hmin>hfield[i+j*size]) hmin=hfield[i+j*size];
if(hmax<hfield[i+j*size]) hmax=hfield[i+j*size];
}
Box.MinEdge.set(-ext.X/2.0f,hmin,-ext.Z/2.0f);
Box.MaxEdge.set(ext.X/2.0f,hmax,ext.Z/2.0f);
/*stub=new ministub(hfield,
&size,&dim,scale,1.0f,
CLMTerrainSceneNode::_BeginFan,
CLMTerrainSceneNode::_FanVertex,
0,0,0);*/
stub=new ministub(hfield,
&size,&dim,1.0f,1.0f,
CLMTerrainSceneNode::_BeginFan,
CLMTerrainSceneNode::_FanVertex,
0,0,0);
vertex.Normal.set(0,1,0);
vertex.Color.set(255,255,255,255);
Material.Texture1=texture;
Material.Texture2=detailmap;
return true;
}
// prepares a buffer if the buffer is nonempty draws and then empties the buffer
// this function needs to be called after stub->draw one more time
void CLMTerrainSceneNode::BeginFan()
{
if(buffer.Vertices.size()>0 && driver)
{
driver->drawIndexedTriangleFan(buffer.Vertices.const_pointer(),buffer.Vertices.size(),buffer.Indices.const_pointer(),buffer.Indices.size()-2);
buffer.Vertices.set_used(0);
buffer.Indices.set_used(0);
}
}
// fills the buffer with vertecis
void CLMTerrainSceneNode::FanVertex(float i,float y,float j)
{
//vertex.Pos.set(dim*i-size/2*dim, y*scale, size/2*dim-dim*j);
vertex.Pos.set(dim*i-size/2*dim, y, size/2*dim-dim*j);
//vertex.TCoords.set(1.0f-(float)i/(size-1),1.0f-(float)j/(size-1));
vertex.TCoords.set((float)i/(size-1),(float)j/(size-1));
buffer.Indices.push_back(buffer.Indices.size());
buffer.Vertices.push_back(vertex);
}
void CLMTerrainSceneNode::OnPreRender()
{
if(IsVisible)
SceneManager->registerNodeForRendering(this,SNRT_DEFAULT);
ISceneNode::OnPreRender();
AbsoluteTransformation.getInverse(invAbsoluteTransform);
}
void CLMTerrainSceneNode::render()
{
ICameraSceneNode* camera=SceneManager->getActiveCamera();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
if(stub && camera)
{
aspect = camera->getAspectRatio();
fovy = f32(GRAD_PI)*camera->getFOV();
nearp = camera->getNearValue();
farp = camera->getFarValue();
pos.set(camera->getPosition());
tgt.set(camera->getTarget());
up.set(camera->getUpVector());
invAbsoluteTransform.transformVect(pos);
invAbsoluteTransform.transformVect(tgt);
invAbsoluteTransform.transformVect(up);
vector3df dx=tgt-pos;
if(dx.getLengthSQ()==0.0)
{
dx.Z=-1.0f;
}
// make callbacks to this scenenode :)
_self=this;
driver->setMaterial(Material);
stub->draw(res,
pos.X,pos.Y,pos.Z,
dx.X,dx.Y,dx.Z,
up.X,up.Y,up.Z,
2.0f*fovy,
aspect,
nearp,
farp);
BeginFan();
if(DebugDataVisible)
{
SMaterial mat;
mat.Lighting=false;
mat.Wireframe=true;
mat.FogEnable=false;
mat.EmissiveColor=SColor(255,0,255,0);
mat.AmbientColor=SColor(255,0,255,0);
mat.DiffuseColor=SColor(255,0,255,0);
mat.Texture1=0;
mat.Texture2=0;
driver->setMaterial(mat);
driver->draw3DBox(Box, SColor(255,0,0,255));
stub->draw(res,
pos.X,pos.Y,pos.Z,
dx.X,dx.Y,dx.Z,
up.X,up.Y,up.Z,
2.0f*fovy,
aspect,
nearp,
farp);
BeginFan();
}
}
}
void CLMTerrainSceneNode::OnPostRender(u32 timeMs)
{
ISceneNode::OnPostRender(timeMs);
}
f32 CLMTerrainSceneNode::getHeight(int i,int j)
{
if(stub)
return stub->getheight(i,j);
else
return 0;
}
f32 CLMTerrainSceneNode::getHeight(float x,float z)
{
if(stub)
return stub->getheight(x,z);
else
return 0;
}
f32 CLMTerrainSceneNode::getFogHeight(float x,float z)
{
if(stub)
return stub->getfogheight(x,z);
else
return 0;
}
vector3df CLMTerrainSceneNode::getNormal(float x,float z)
{
vector3df n(0,1,0);
if(stub)
{
f32 nx,ny,nz;
stub->getnormal(x,z,&nx,&ny,&nz);
n.set(nx,ny,nz);
}
return n;
}
}
}
Code: Select all
CLMTerrainSceneNode* terrain = new CLMTerrainSceneNode(smgr->getRootSceneNode(), smgr, 9999);
terrain->create(heightimage,terraintexture,0,32.0f,10.0f,1000.0f);
terrain->getMaterial(0).FogEnable=true;
//terrain->setPosition(vector3df(0,4000,0)); // YES!!!
//terrain->setRotation(vector3df(0,45,0)); // and this too!!!
Have fun
Tom
Edit:
There's something wrong with the BoundingBox transformation so disable autoculling if you place your terrain somewhere other than at (0,0,0) with angles (0,0,0).
Code: Select all
terrain->setAutomaticCulling(false);
i get 2 errors if i try to compile my testproject.
can you tell me what i have done wrong? pleaaaaaaase i dont know how to do it
i dont know whats wrong, here is the project code:[Linker error] undefined reference to `irr::scene::CLMTerrainSceneNode::CLMTerrainSceneNode(irr::scene::ISceneNode*, irr::scene::ISceneManager*, int)'
[Linker error] undefined reference to `irr::scene::CLMTerrainSceneNode::create(irr::video::IImage*, irr::video::ITexture*, irr::video::ITexture*, float, float, float)'
Code: Select all
#include <stdio.h>
#include <irrlicht.h>
#include "CLMTerrainSceneNode.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;
using namespace io;
int main()
{
IrrlichtDevice* device =
createDevice(EDT_OPENGL, dimension2d<s32>(640,480), 32, false, false, false, 0);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
ITexture* terraintexture = driver->getTexture("data/textures/environment/grass_1024.jpg");
IImage* terrainheightmap = driver->createImageFromFile("data/textures/heightmaps/heightmap.jpg");
CLMTerrainSceneNode* terrain = new CLMTerrainSceneNode(smgr->getRootSceneNode(), smgr, 9999);
terrain->create(terrainheightmap,terraintexture,0,32.0f,10.0f,1000.0f);
terrain->getMaterial(0).FogEnable=true;
terrain->setPosition(vector3df(0,4000,0));
terrain->setRotation(vector3df(0,45,0));
terrain->setAutomaticCulling(false);
while(device->run())
{
driver->beginScene(true, true, SColor(0,128,128,128));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
can you tell me what i have done wrong? pleaaaaaaase i dont know how to do it
looks like You are not linking with the scenenode cpp file.
and maybe its a good idea to have a camera defined aswell, although this does not explane the link error.
my test app (a minor variation of K.o.L's demo
and maybe its a good idea to have a camera defined aswell, although this does not explane the link error.
my test app (a minor variation of K.o.L's demo
Code: Select all
// see original faceofmars.cpp for credits :)
#include <irrlicht.h>
#include "CLMTerrainSceneNode.h"
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;
int main(int argc,char *argv[])
{
int cameraoffset=120;
IrrlichtDevice *device =
createDevice(video::EDT_OPENGL, core::dimension2d<s32>(800, 600),32,false);
ISceneManager* smgr = device->getSceneManager();
IVideoDriver* driver= device->getVideoDriver();
IGUIEnvironment* env= device->getGUIEnvironment();
IGUIStaticText* txt=env->addStaticText(L"camera()", rect<s32>(0,0,350,40), true);
txt->setOverrideColor(SColor(255,0,0,0));
txt->enableOverrideColor(true);
IImage* heightimage = driver->createImageFromFile("terrain.bmp");
IImage* skyimage = driver->createImageFromFile("sky.jpg");
ITexture* terraintexture = driver->getTexture("terr_tex.jpg");
ITexture* skytexture = driver->getTexture("sky_tex.jpg");
CLMTerrainSceneNode* terrain = new CLMTerrainSceneNode(smgr->getRootSceneNode(), smgr, 9999);
terrain->create(heightimage,terraintexture,0,32.0f,10.0f,1000.0f);
terrain->getMaterial(0).FogEnable=true;
terrain->getMaterial(0).Lighting=false;
terrain->setAutomaticCulling(false);
terrain->setPosition(vector3df(100,100,0));
terrain->setRotation(vector3df(0,37,0));
//terrain->setDebugDataVisible(true);
terrain->drop();
scene::ICameraSceneNode* camera= smgr->addCameraSceneNodeFPS(0, 100, 900);
camera->setFarValue(120000.0f);
camera->setPosition(vector3df(0.0f,120.0f,0.0f));
camera->setTarget(vector3df(0.0f,120.0f,-10.0f));
camera->setUpVector(vector3df(0.0f,1.0f,0.0f));
int lastFPS=-1;
f32 fogDensity=0.0005f;
SColor backgroundColor=irr::video::SColor(255,155,155,155);
SColor fogColor=irr::video::SColor(0,155,155,155);
wchar_t tmp[1024];
matrix4 IDENTITY;
IDENTITY.makeIdentity();
SMaterial mat;
mat.Lighting=false;
matrix4 invTrans;
matrix4 Trans;
while(device->run())
{
vector3df pos = camera->getPosition();
f32 nearp = camera->getNearValue();
f32 farp=camera->getFarValue();
Trans=terrain->getAbsoluteTransformation();
Trans.getInverse(invTrans);
invTrans.transformVect(pos);
float glide = terrain->getHeight(pos.X,pos.Z)+30.0f*nearp;
if (glide<0.0f) glide = 0.0f;
pos.Y=pos.Y>glide? pos.Y:glide;
Trans.transformVect(pos);
camera->setPosition(vector3df(pos.X,pos.Y,pos.Z));
//camera->setTarget(tgt);
driver->setFog(fogColor, false, 10.0f, 2000.0f, fogDensity, false, false);
swprintf(tmp,1024,L"camera( %.3f, %.3f, %.3f )",pos.X,pos.Y,pos.Z);
txt->setText(tmp);
driver->beginScene(true, true, backgroundColor);
smgr->drawAll();
driver->setTransform(video::ETS_WORLD, IDENTITY);
driver->setMaterial(mat);
driver->draw3DLine(vector3df(0,200,0),vector3df(farp,0,0),SColor(255,255,0,0));
driver->draw3DLine(vector3df(0,200,0),vector3df(0,farp,0),SColor(255,0,255,0));
driver->draw3DLine(vector3df(0,200,0),vector3df(0,0,farp),SColor(255,0,0,255));
env->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
swprintf(tmp, 1024, L"Terrainengine-libmini and Irrlicht Engine (fps:%d) Triangles:%d",
fps, driver->getPrimitiveCountDrawn());
device->setWindowCaption(tmp);
lastFPS = fps;
}
}
device->drop();
return 0;
}
-
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
Read my post about cal3d integration. My opinion is that many of these things - that introduce dependencies into the irrlicht code - could go very good as a seperate addon and they don't have to be included in the irrlicht sources.brcolow wrote:Nice work Zola. Any chance of that being added to NX as a define (like the other things that require external libs)?
What would be nice to have is a common repository for addons maybe we can open an additional CVS folder for them?
Just copy the files to Your application sources and include them where You need to.brcolow wrote: Also, where do we include the two files...in what Irrlicht source file? Irrlicht.h?
Cheers
Tom