Modification of engine

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
nucleon
Posts: 8
Joined: Tue Jan 25, 2005 8:56 am

Modification of engine

Post by nucleon »

Hello,

i'm trying irrlicht engine since 1 year now, and i find it really cool. I've got a passion for the simulation game, specially space simulation (like elite for example). Actually, i'm writing a game such elite (i'm trying in fact !! no really easy) using irrlicht engine. I've met some difficulty here is the list and how i solve them:

a) the double precision doesn't work

b) render size planet model not very efficient

c) include mouse control with directx (dinput)

solve:

a) in fact, it's not a problem with the engine but with directx. When you create a directx device, the FPU is forced to work in single precision only, to override this you must add in the device creation: FPU_PRESERVE. So i do in the irrlicht engine. Question to Nicklaus: could you add a boolean variable in the CreateDevice fonction to add this if needed ???

b) The problem is when you are far from a planet size model, you can have artifact (flickering) or for example the sun (which is far away) just beeing drawing before a planet (which is nearer of the camera) .This problem is related to the depth of the zbuffer, in the irrlicht when you create a device with no Shadow, the depth buffer is set to D8S8, i've modified to set it to D24S8, now the render of planet size model is OK

c) I've found a solution in this forum !! Thanks a lot !!


For Niklaus: Thank's a lot for this great engine.
Phenix
Posts: 51
Joined: Sat Nov 15, 2003 3:15 pm
Location: Earth
Contact:

Post by Phenix »

hi I'm working on a similar project,a "clone" of Frontier First Encounters.
I had the problem (a) too,I solved it calling the function _controlfp(0x10000,0x30000) after the creation of Irrlicht device.
I've solved the problem of depth like you have,I changed D3DFMT_D16 to D3DFMT_D24X8.If I set to D3DFMT_D24S8 device crash because my grafic card doesn't support stencil buffer.
Have you got a website about your project?
Guest

Post by Guest »

:D Hello Phenix

No i have no web site, sorry. I'm searching how to put file on my personnal page. If someone is interresting to look at my code, i'll put it. BUT !! Warning i'm a poor french so the code is documented but in French !! Sorry!!

Sometime i put comment in english (words are shorter than in french :D )

I'll post later the technic used to generate my game.

A good reference is www.gamedev.net or www.gamasutra.com (need registration)

Later .
clarke

space trading

Post by clarke »

Hi guys,

seems I'm not the only one using Irrlicht to reincarnate elite. nucleon, r u interested in exchanging experiences and or code? right now i've got a playable elite clone without trading and with very primitive ai. hope it doesn't become obsolete with the pc port of oolite :?

A toast to niko and his engine!
nucleon
Posts: 8
Joined: Tue Jan 25, 2005 8:56 am

Post by nucleon »

:lol:
High Clarke

OK for your proposition but i 'm working on this project only when i've got time so i think the state is not so advanced than yours.

For instance:
You can travel on a complete stellar system (distance are real)
You can land on planet
Each planet have their satellite (the most known !!)
You can switch to other system
No other actor (in development)
You can go on station
Radar can have 2 modes: Galactic and Actor


Work to do:
Display a good radar hehe
Graphic must be upgrade (for instance they are ugly houhou)
Make a good doc !!!!
upgrade the U.I
add some actor to destroy
make a mission generator
Display a navigation map
Realize some good model
and a lot of work which come in my head slowly

Irrlicht engine:

Some modification to accelerate the render:
i've got a file with all the modif i've realizd, so when i change version, ican do the modification....

Here is the modification:

Modification du moteur irrlicht

fichier iscenenode.h
class ISceneNode : public IUnknown
{
public:

//! Constructor
ISceneNode( ISceneNode* parent, ISceneManager* mgr, s32 id=-1,
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& rotation = core::vector3df(0,0,0),
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f))
: IsVisible(true), ID(id), Parent(parent), SceneManager(mgr),
AutomaticCullingEnabled(true), DebugDataVisible(false),
TriangleSelector(0), RelativeTranslation(position),
RelativeRotation(rotation), RelativeScale(scale)

{
if (Parent)
Parent->addChild(this);
setRotation(core::vector3df(0.0f,0.0f,0.0f));
updateAbsolutePosition();
}

//! Set a Rotation matrix with 3 vectors representing the new value of
//! the original axis of the node (X,Y and Z)

virtual void SetRotationVector(core::vector3df X,core::vector3df Y,core::vector3df Z)
{
M0=X.X;
M4=X.Y;
M8=X.Z;
M1=Y.X;
M5=Y.Y;
M9=Y.Z;
M2=Z.X;
M6=Z.Y;
M10=Z.Z;
}

//! Returns the relative transformation of the scene node.
//! The relative transformation is stored internally as 3 vectors:
//! translation, rotation and scale. To get the relative transformation
//! matrix, it is calculated from these values.
//! \return Returns the relative transformation matrix.
virtual core::matrix4 getRelativeTransformation() const
{
core::matrix4 mat;
// mat.setRotationDegrees(RelativeRotation);
// Mise en place des coef de la matrice de rotation
mat.M[0]=M0;
mat.M[1]=M1;
mat.M[2]=M2;
mat.M[4]=M4;
mat.M[5]=M5;
mat.M[6]=M6;
mat.M[8]=M8;
mat.M[9]=M9;
mat.M[10]=M10;
mat.setTranslation(RelativeTranslation);

if (RelativeScale != core::vector3df(1,1,1))
{
core::matrix4 smat;
smat.setScale(RelativeScale);
mat *= smat;
}

return mat;
}
virtual void setRotation(const core::vector3df& rotation)
{
RelativeRotation = rotation;
core::vector3df rot;
rot=rotation * (f32)3.1415926535897932384626433832795 / 180.0;
// Calcul des valeurs
cr = cos( rot.X );
sr = sin( rot.X );
cp = cos( rot.Y );
sp = sin( rot.Y );
cy = cos( rot.Z );
sy = sin( rot.Z );


srsp = sr*sp;
crsp = cr*sp;

M0 = (f32)( cp*cy );
M1 = (f32)( cp*sy );
M2 = (f32)( -sp );

M4 = (f32)( srsp*cy-cr*sy );
M5 = (f32)( srsp*sy+cr*cy );
M6 = (f32)( sr*cp );

M8 = (f32)( crsp*cy+sr*sy );
M9 = (f32)( crsp*sy-sr*cy );
M10 = (f32)( cr*cp );


}
protected:
// Definition des variables de calcul des angles
f64 cr ;
f64 sr ;
f64 cp ;
f64 sp ;
f64 cy ;
f64 sy ;
f64 srsp;
f64 crsp;
f32 M0,M1,M2,M4,M5,M6,M8,M9,M10;

Fichier CVideoDirectX8.cpp:


fonction initDriver:
if (!StencilBuffer)
{
present.AutoDepthStencilFormat = D3DFMT_D24S8;
}
// create device

if (pureSoftware)
{
hr = pID3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE, &present, &pID3DDevice);

if (FAILED(hr))
os::Printer::log("Was not able to create Direct3D8 software device.", ELL_ERROR);
}
else
{
hr = pID3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE, &present, &pID3DDevice);

if(FAILED(hr))
{
hr = pID3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_MIXED_VERTEXPROCESSING |D3DCREATE_FPU_PRESERVE, &present, &pID3DDevice);

if(FAILED(hr))
{
hr = pID3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE, &present, &pID3DDevice);

if (FAILED(hr))
os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR);
}
}
}

Fonction Draw2DImage (1 definition)
// ok, we've clipped everything.
// now draw it.

if (useAlphaChannelOfTexture)
setRenderStates2DMode(true, true, true);
else
setRenderStates2DMode(true, true, false);

Fonction SetRenderStates2DMode:

if (texture)
{
pID3DDevice->SetTextureStageState (0, D3DTSS_MINFILTER, D3DTEXF_POINT);
pID3DDevice->SetTextureStageState (0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
pID3DDevice->SetTextureStageState (0, D3DTSS_MAGFILTER, D3DTEXF_POINT);

if (alphaChannel)
{
// Nouvelle Version du 15/09/2004
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);



}
else
{
if (alpha)
{
// Nouvelle Version du 15/09/2004
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
}
else
{
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
}
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

Ditto, Doing a simular project in c#
ChrML
Posts: 30
Joined: Sun Oct 03, 2004 2:45 pm
Location: Norway

Post by ChrML »

nucleon: Huge objects are NEVER efficient, nor good looking, when rendered in 3D. All spacegames today uses tricks to make things look big. Keeping objects close, make sure they are rendered after closer objects, and scale them as they get closer should work quite well, I think. You will need to work out some system atleast.
nucleon
Posts: 8
Joined: Tue Jan 25, 2005 8:56 am

Post by nucleon »

Hello,

you are right and that's the same technic i use. You can find good article on the site www.gamedev.net and usefull technic to render a complete solar system. But to use thoose technic you must modify the engine. In fact i do this for the fun :lol:

Sometime it's not very easy sometime it's very excited :P
nucleon
Posts: 8
Joined: Tue Jan 25, 2005 8:56 am

Post by nucleon »

Mistake in my function SetRotationVector:

in order to display properly the node, we must use the transpose of the matrix:

here is the correct function
virtual void SetRotationVector(core::vector3df X,core::vector3df ,core::vector3df Z)
{
M0=X.X;
M1=X.Y;
M2=X.Z;
M4=Y.X;
M5=Y.Y;
M6=Y.Z;
M8=Z.X;
M9=Z.Y;
M10=Z.Z;
}
cartoonit
Posts: 286
Joined: Mon Nov 15, 2004 6:36 pm

Post by cartoonit »

So to complain, but come on some code brackets would be nice :o
cartoonit
Posts: 286
Joined: Mon Nov 15, 2004 6:36 pm

Post by cartoonit »

Sorry to complain, but come on some code brackets would be nice :o
nucleon
Posts: 8
Joined: Tue Jan 25, 2005 8:56 am

Post by nucleon »

here is the code use for the example movement. I don't use the function drawall() because i must call onpostrender before the function render, the explanation is because i use one node to display 2 different positions.

#include <stdio.h>
#include <wchar.h>
#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#pragma comment(lib, "Irrlicht.lib")


scene::ISceneNode* node = 0;
scene::ISceneNode* node1 = 0;
IrrlichtDevice* device = 0;

vector3df OldX,OldY,OldZ;
matrix4 m;

class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(SEvent event)
{

if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
!event.KeyInput.PressedDown)
{
switch(event.KeyInput.Key)
{
case KEY_KEY_W:
{
m.setRotationDegrees(vector3df(.4f,.6f,.8f));
break;
}
case KEY_KEY_S:
{
m.setRotationDegrees(vector3df(-.4f,-.6f,-.8f));
break;
}
return true;
}
}

return false;
}
};


int main()
{
MyEventReceiver receiver;

device = createDevice(video::EDT_DIRECTX8, core::dimension2d<s32>(640, 480),
16, false, false, false, &receiver);

video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
ITexture *t1,*t2;
SMaterial m1,m2;

m.setRotationDegrees(vector3df(0.0f,0.0f,.0f));
OldX=vector3df(1.0f,0.0f,0.0f);
OldY=vector3df(0.0f,1.0f,0.0f);
OldZ=vector3df(0.0f,0.0f,1.0f);

t1= driver->getTexture("d:\\christophe\\irrlicht\\irrlicht-0.7\\media\\wall.bmp");
t2= driver->getTexture("d:\\christophe\\irrlicht\\irrlicht-0.7\\media\\t351sml.jpg");

node = smgr->addOctTreeSceneNode(smgr->getMesh("d:\\christophe\\elite\\irrlichtelite\\ressources\\model\\armes\\ap-missile.3ds"));
node1 = smgr->addOctTreeSceneNode(smgr->getMesh("d:\\christophe\\elite\\irrlichtelite\\ressources\\model\\armes\\ap-missile.3ds"));

scene::ICameraSceneNode *cam=smgr->addCameraSceneNode();
device->getCursorControl()->setVisible(true);
cam->setPosition(vector3df(0.0f,0.0f,0.0f));
cam->setTarget(OldZ);
cam->setUpVector(OldY);
int lastFPS = -1;

while(device->run())
{
driver->beginScene(true, true, video::SColor(255,113,113,133));

// smgr->drawAll();
cam->setTarget(OldZ);
cam->setUpVector(OldY);
OldX=OldZ.crossProduct(OldY);
cam->OnPreRender();
cam->render();
cam->OnPostRender(0);

node->setMaterialTexture(0,t1);
node->setPosition(OldZ*10.0f);
node->SetRotationVector(vector3df(OldX.X,OldY.X,OldZ.X),
vector3df(OldX.Y,OldY.Y,OldZ.Y),
vector3df(OldX.Z,OldY.Z,OldZ.Z));
node->OnPostRender(0);
node->render();

node1->setMaterialTexture(0,t2);
node1->SetRotationVector(vector3df(1.0f,0.0f,0.0f),
vector3df(0.0f,1.0f,0.0f),
vector3df(0.0f,0.0f,1.0f));
node1->setPosition(core::vector3df(0.0f,0.0f,10.0f));
node1->OnPostRender(0);
node1->render();

driver->endScene();

// Mise a jour des vecteurs d'orientation
m.transformVect(OldX);
m.transformVect(OldY);
m.transformVect(OldZ);
int fps = driver->getFPS();

if (lastFPS != fps)
{
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Movement Example - Irrlicht Engine [%s] fps:%d",
driver->getName(), fps);

device->setWindowCaption(tmp);
lastFPS = fps;
}
}

device->drop();

return 0;
}
Post Reply