The following c++ code fully initializes a 3d object in my project using the irrlicht.dll 3d engine. Following that I have a class which can convert an avi movie into a texture which can be displayed on my 3d object.
It would be extremely helpful if you could tell me how to instantiate the class, what to pass through it and how I can throw it onto my model. After the VideoTexture class I added my main.cpp which holds all of my current code on this project in case it is needed.
IAnimatedMesh* mesh = smgr->getMesh("objects/F4E
-Phantom/F
4 E Phantom.3ds");
ISceneNode* node = smgr->addOctTreeSceneNode(
mesh->getM
esh(0));
//ISceneNode* node2 = 0;
video::SMaterial material;
material.Textures[0] = driver->getTexture("textur
es/bricks2
b.jpg");
material.Lighting = false; //true for lighting
if (node)
{
//node->setMaterialFlag(EM
F_LIGHTING
, false);
//node->setMD2Animation ( scene::EMAT_STAND );
node->setScale(core::vecto
r3df(10.0f
, 10.0f, 10.0f));
node->getMaterial(0) = material;
node->setPosition(core::ve
ctor3df(25
0000.00f,1
2000.00f,2
50000.00f)
);
node->setRotation(core::ve
ctor3df(0.
00f,0.00f,
0.00f));
//node2 = smgr->addOctTreeSceneNode(
mesh->getM
esh(0));
}
--------------------------
----------
----------
----------
----------
----------
----------
----------
----------
----------
------
/*
VideoTexture.cpp
From the Microsoft DirectX SDK
Modified by Matthew Fisher
VideoTexture is a DirectX-only object that allows you to use a video file as a source for textures in the scene.
It is really just an interface to CTextureRenderer, a Microsoft class that handles the interaction with DirectShow.
Note the this creates another (very intensive) thread to the program that handles the decompression,
so applications should sleep for between 5 and 30 milliseconds each frame (just set the SleepBetweenFrames
variable in God.cpp.)
*/
#ifdef USE_DIRECTX
#ifdef USE_VIDEO_TEXTURES
#include <mmsystem.h>
#include <atlbase.h>
#include "DSHowHeaders/streams.h"
void Msg(TCHAR *szFormat, ...);
//------------------------
----------
----------
----------
----------
----------
---
// Define GUID for Texture Renderer
// {71771540-2017-11cf-AE26-0
020AFD7976
7}
//------------------------
----------
----------
----------
----------
----------
---
struct __declspec(uuid("{71771540
-2017-11cf
-ae26-0020
afd79767}"
)) CLSID_TextureRenderer;
class CTextureRenderer : public CBaseVideoRenderer
{
public:
CTextureRenderer(LPUNKNOWN
pUnk,HRESULT *phr);
~CTextureRenderer();
public:
HRESULT CheckMediaType(const CMediaType *pmt ); // Format acceptable?
HRESULT SetMediaType(const CMediaType *pmt ); // Video format notification
HRESULT DoRenderSample(IMediaSampl
e *pMediaSample); // New video sample
LONG m_lVidWidth; // Video width
LONG m_lVidHeight; // Video Height
LONG m_lVidPitch; // Video Pitch
VideoTexture *Parent;
};
VideoTexture::VideoTexture
()
{
GD = 0;
myTexture = 0;
}
VideoTexture::~VideoTextur
e()
{
FreeMemory();
}
void VideoTexture::FreeMemory()
{
if(myTexture)
{
myTexture->Release();
myTexture = 0;
}
if (!(!g_pMC)) g_pMC->Stop();
if (!(!g_pMC)) g_pMC.Release();
if (!(!g_pME)) g_pME.Release();
if (!(!g_pMP)) g_pMP.Release();
if (!(!g_pGB)) g_pGB.Release();
}
void VideoTexture::Init(Graphic
sDevice *_GD, char *filename)
{
if(_GD->GetType() != GD_D3D) FatalMB("Video Textures require a DirectX Graphics Device.");
GD = (D3DGraphicsDevice *)_GD;
if(FAILED(InitGraph(filena
me))) FatalMB("InitGraph failed.");
}
HRESULT VideoTexture::InitGraph(ch
ar *filename)
{
HRESULT hr = S_OK;
CComPtr<IBaseFilter> pFTR; // Texture Renderer Filter
CComPtr<IPin> pFTRPinIn; // Texture Renderer Input Pin
CComPtr<IBaseFilter> pFSrc; // Source Filter
CComPtr<IPin> pFSrcPinOut; // Source Filter Output Pin
CTextureRenderer *pCTR; // DShow Texture renderer
// Create the filter graph
if (FAILED(g_pGB.CoCreateInst
ance(CLSID
_FilterGra
ph, NULL, CLSCTX_INPROC)))
{
FatalMB("CoCreate failed.");
return E_FAIL;
}
// Create the Texture Renderer object
pCTR = new CTextureRenderer(NULL, &hr);
if (FAILED(hr))
{
Msg(TEXT("Could not create texture renderer object! hr=0x%x"), hr);
return E_FAIL;
}
pCTR->Parent = this;
// Get a pointer to the IBaseFilter on the TextureRenderer, add it to graph
pFTR = pCTR;
if (FAILED(hr = g_pGB->AddFilter(pFTR, L"TEXTURERENDERER")))
{
Msg(TEXT("Could not add renderer filter to graph! hr=0x%x"), hr);
return hr;
}
TCHAR strFileName[MAX_PATH];
WCHAR wFileName[MAX_PATH];
lstrcpy( strFileName, filename );
MultiByteToWideChar(CP_ACP
, 0, strFileName, -1, wFileName, MAX_PATH);
// Add the source filter
if (FAILED(hr = g_pGB->AddSourceFilter (wFileName, L"SOURCE", &pFSrc)))
{
Msg(TEXT("Could not create source filter to graph! hr=0x%x"), hr);
return hr;
}
// Find the source's output pin and the renderer's input pin
if (FAILED(hr = pFTR->FindPin(L"In", &pFTRPinIn)))
{
Msg(TEXT("Could not find input pin! hr=0x%x"), hr);
return hr;
}
if (FAILED(hr = pFSrc->FindPin(L"Output", &pFSrcPinOut)))
{
Msg(TEXT("Could not find output pin! hr=0x%x"), hr);
return hr;
}
// Connect these two filters
if (FAILED(hr = g_pGB->Connect(pFSrcPinOut
, pFTRPinIn)))
{
Msg(TEXT("Could not connect pins! hr=0x%x"), hr);
return hr;
}
IPin *SourcePin;
IBaseFilter *AviSplitter;
g_pGB->FindFilterByName(L"
AVI Splitter", &AviSplitter);
AviSplitter->FindPin(L"Str
eam 01", &SourcePin);
if (FAILED(hr = g_pGB->Render(SourcePin)))
{
Msg(TEXT("Could not render Source Pin. hr=0x%x"), hr);
return hr;
}
// Get the graph's media control, event & position interfaces
g_pGB.QueryInterface(&g_pM
C);
g_pGB.QueryInterface(&g_pM
P);
g_pGB.QueryInterface(&g_pM
E);
g_pGB.QueryInterface(&g_pM
S);
// Start the graph running;
if (FAILED(hr = g_pMC->Run()))
{
Msg(TEXT("Could not run the DirectShow graph! hr=0x%x"), hr);
return hr;
}
return S_OK;
}
void VideoTexture::Loop()
{
long lEventCode;
long lParam1;
long lParam2;
HRESULT hr;
// Check for completion events
hr = g_pME->GetEvent(&lEventCod
e, (LONG_PTR *) &lParam1, (LONG_PTR *) &lParam2, 0);
if (SUCCEEDED(hr))
{
if (EC_COMPLETE == lEventCode)
{
hr = g_pMP->put_CurrentPosition
(0);
}
// Free any memory associated with this event
hr = g_pME->FreeEventParams(lEv
entCode, lParam1, lParam2);
}
}
void VideoTexture::Set()
{
if(GD)
{
GD->GetDevice()->SetTextur
e(0,myText
ure);
}
}
float VideoTexture::GetPosition(
)
{
REFERENCE_TIME TotalLength, CurrentPos, Useless;
g_pMS->GetDuration(&TotalL
ength);
g_pMS->GetPositions(&Curre
ntPos, &Useless);
return float(CurrentPos) / float(TotalLength);
}
void VideoTexture::Seek(float AbsolutePosition)
{
HRESULT hr;
REFERENCE_TIME TotalLength;
g_pMS->GetDuration(&TotalL
ength);
TotalLength = REFERENCE_TIME(TotalLength
* double(AbsolutePosition));
hr = g_pMS->SetPositions(
&TotalLength, AM_SEEKING_AbsolutePositio
ning,
NULL, AM_SEEKING_NoPositioning
);
}
void VideoTexture::SetRate(floa
t NewRate)
{
g_pMS->SetRate(NewRate);
}
HRESULT VideoTexture::Restore()
{
if(myTexture)
{
myTexture->Release();
myTexture = 0;
}
HRESULT hr;
if(!GD) FatalMB("Video Texture not associated.");
if( FAILED( hr = D3DXCreateTexture(GD->GetD
evice(),
1024, 1024,
1, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &myTexture ) ) )
{
Msg(TEXT("Could not create the D3DX texture! hr=0x%x"), hr);
return hr;
}
// D3DXCreateTexture can silently change the parameters on us
D3DSURFACE_DESC ddsd;
if ( FAILED( hr = myTexture->GetLevelDesc( 0, &ddsd ) ) ) {
Msg(TEXT("Could not get level Description of D3DX texture! hr = 0x%x"), hr);
return hr;
}
TextureFormat = ddsd.Format;
if (TextureFormat != D3DFMT_A8R8G8B8)
{
Msg(TEXT("Texture is format we can't handle! Format = 0x%x"), TextureFormat);
return VFW_E_TYPE_NOT_ACCEPTED;
}
return S_OK;
}
CTextureRenderer::CTexture
Renderer( LPUNKNOWN pUnk, HRESULT *phr )
: CBaseVideoRenderer(__uuido
f(CLSID_Te
xtureRende
rer),
NAME("Texture Renderer"), pUnk, phr)
{
// Store and AddRef the texture for our use.
*phr = S_OK;
}
//------------------------
----------
----------
----------
----------
----------
---
// CTextureRenderer destructor
//------------------------
----------
----------
----------
----------
----------
---
CTextureRenderer::~CTextur
eRenderer(
)
{
// Do nothing
}
//------------------------
----------
----------
----------
----------
----------
---
// CheckMediaType: This method forces the graph to give us an R8G8B8 video
// type, making our copy to texture memory trivial.
//------------------------
----------
----------
----------
----------
----------
---
HRESULT CTextureRenderer::CheckMed
iaType(con
st CMediaType *pmt)
{
HRESULT hr = E_FAIL;
VIDEOINFO *pvi;
// Reject the connection if this is not a video type
if( *pmt->FormatType() != FORMAT_VideoInfo ) {
return E_INVALIDARG;
}
// Only accept RGB24
pvi = (VIDEOINFO *)pmt->Format();
if(IsEqualGUID( *pmt->Type(), MEDIATYPE_Video) &&
IsEqualGUID( *pmt->Subtype(), MEDIASUBTYPE_RGB32))
{
hr = S_OK;
}
return hr;
}
//------------------------
----------
----------
----------
----------
----------
---
// SetMediaType: Graph connection has been made.
//------------------------
----------
----------
----------
----------
----------
---
HRESULT CTextureRenderer::SetMedia
Type(const
CMediaType *pmt)
{
// Retrive the size of this media type
VIDEOINFO *pviBmp; // Bitmap info header
pviBmp = (VIDEOINFO *)pmt->Format();
m_lVidWidth = pviBmp->bmiHeader.biWidth;
m_lVidHeight = abs(pviBmp->bmiHeader.biHe
ight);
m_lVidPitch = m_lVidWidth * 4;
return Parent->Restore();
}
//------------------------
----------
----------
----------
----------
----------
---
// DoRenderSample: A sample has been delivered. Copy it to the texture.
//------------------------
----------
----------
----------
----------
----------
---
HRESULT CTextureRenderer::DoRender
Sample( IMediaSample * pSample )
{
if(Parent->GD && Parent->GD->GetSystemActiv
e() && !Parent->GD->NeedToRestore
Devices() && Parent->myTexture)
{
BYTE *pBmpBuffer, *pTxtBuffer; // Bitmap buffer, texture buffer
LONG lTxtPitch; // Pitch of bitmap, texture
// Get the video bitmap buffer
pSample->GetPointer( &pBmpBuffer );
// Lock the Texture
D3DLOCKED_RECT d3dlr;
if (FAILED(Parent->myTexture-
>LockRect(
0, &d3dlr, 0, 0)))
return E_FAIL;
// Get the texture buffer & pitch
pTxtBuffer = static_cast<byte *>(d3dlr.pBits);
lTxtPitch = d3dlr.Pitch;
//memcpy(pTxtBuffer, pBmpBuffer, 4 * m_lVidHeight * m_lVidWidth);
int i;
for(i=0;i<m_lVidHeight;i++
)
{
memcpy(&pTxtBuffer[1024*i*
4], &pBmpBuffer[m_lVidWidth*i*
4], 4 * m_lVidWidth);
}
// Unlock the Texture
if(!Parent->myTexture) return E_FAIL;
if (FAILED(Parent->myTexture-
>UnlockRec
t(0)))
return E_FAIL;
}
return S_OK;
}
//------------------------
----------
----------
----------
----------
----------
---
// Msg: Display an error message box if needed
//------------------------
----------
----------
----------
----------
----------
---
void Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[512];
va_list pArgs;
va_start(pArgs, szFormat);
_vstprintf(szBuffer, szFormat, pArgs);
va_end(pArgs);
MessageBox(NULL, szBuffer, TEXT("DirectShow Texture3D Sample"),
MB_OK | MB_ICONERROR);
}
#endif
#endif
Top
--------------------------
----------
----------
----------
----------
----------
----------
----------
----------
----------
----------
---
#include <irrlicht.h>
#include <math.h>
#include <cstring>
#include <iostream>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
class skyBox{
private:
ISceneManager* sc; //scene
IVideoDriver* dr; //driver
char* name; //skybox name
char path[50];
public:
skyBox( ISceneManager* s, IVideoDriver* d, char p[50], char* n )
{
sc=s;
dr=d;
name=n;
strcpy(path,p); //path to all skyBox textures
/* skyboxes should all be named in the format *up.bmp, *dn.bmp,
*rt.bmp, *lt.bmp, *ft.bmp, *bk.bmp where * is all the same name
ie blue2
*/
}
void start(){ //create skybox
dr->setTextureCreationFlag
(video::ET
CF_CREATE_
MIP_MAPS, false);
char fileup[50]="";
strcat ( fileup, path );
strcat ( fileup, name );
strcat ( fileup, "up.bmp" );
char filedn[50]="";
strcat ( filedn, path );
strcat ( filedn, name );
strcat ( filedn, "dn.bmp" );
char filert[50]="";
strcat ( filert, path );
strcat ( filert, name );
strcat ( filert, "rt.bmp" );
char filelt[50]="";
strcat ( filelt, path );
strcat ( filelt, name );
strcat ( filelt, "lt.bmp" );
char fileft[50]="";
strcat ( fileft, path );
strcat ( fileft, name );
strcat ( fileft, "ft.bmp" );
char filebk[50]="";
strcat ( filebk, path );
strcat ( filebk, name );
strcat ( filebk, "bk.bmp" );
sc->addSkyBoxSceneNode(
dr->getTexture(fileup),
dr->getTexture(filedn),
dr->getTexture(filert),
dr->getTexture(filelt),
dr->getTexture(fileft),
dr->getTexture(filebk));
dr->setTextureCreationFlag
(video::ET
CF_CREATE_
MIP_MAPS, true);
}
};
class TravelDistance
{
private:
float x, y, z, x2, y2, z2, traveled;
public:
TravelDistance(){x=0,y=0,z
=0,x2=0,y2
=0,z2=0,tr
aveled=0;}
TravelDistance(float xx, float yy, float zz){x=xx,y=yy,z=zz,x2=xx,y
2=yy,z2=zz
,traveled=
0;}
float getTraveled(){return traveled;}
void updateTraveled(float xx, float yy, float zz){
x2=xx; //-10000 - -10001 = - 20001 10000 - 10001 = -1
y2=yy;
z2=zz;
traveled=traveled+(fabs((f
abs(x2))-(
fabs(x))))
;
traveled=traveled+(fabs((f
abs(y2))-(
fabs(y))))
;
traveled=traveled+(fabs((f
abs(z2))-(
fabs(z))))
;
x=x2;
y=y2;
z=z2;
}
};
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(scene::ISc
eneNode* terrain,
gui::IGUIStaticText* object1,
gui::IGUIStaticText* object2
)
{
// store pointer to terrain so we can change its drawing mode
Terrain = terrain;
Object1 = object1;
Object2 = object2;
}
bool OnEvent(SEvent event)
{
// check if user presses the key 'W' or 'D'
if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDow
n)
{
switch (event.KeyInput.Key)
{
case irr::KEY_KEY_W: // switch wire frame mode
Terrain->setMaterialFlag(v
ideo::EMF_
WIREFRAME,
!Terrain->getMaterial(0).W
ireframe);
Terrain->setMaterialFlag(v
ideo::EMF_
POINTCLOUD
, false);
return true;
case irr::KEY_KEY_P: // switch wire frame mode
Terrain->setMaterialFlag(v
ideo::EMF_
POINTCLOUD
, !Terrain->getMaterial(0).P
ointCloud)
;
Terrain->setMaterialFlag(v
ideo::EMF_
WIREFRAME,
false);
return true;
case irr::KEY_KEY_D: // toggle detail map
Terrain->setMaterialType(
Terrain->getMaterial(0).Ma
terialType
== video::EMT_SOLID ?
video::EMT_DETAIL_MAP : video::EMT_SOLID);
return true;
case irr::KEY_KEY_C: // toggle clear screen
Object1->setVisible(
Object1->isVisible() == 0 ?
1 : 0);
Object2->setVisible(
Object2->isVisible() == 0 ?
1 : 0);
return true;
case irr::KEY_KEY_S: // toggle clear screen
Object1->setVisible(
Object1->isVisible() == 0 ?
1 : 0);
Object2->setVisible(
Object2->isVisible() == 0 ?
1 : 0);
return true;
}
}
return false;
}
private:
scene::ISceneNode* Terrain;
gui::IGUIStaticText* Object1;
gui::IGUIStaticText* Object2;
int skyboxCounter;
};
class createLevel{
private:
IrrlichtDevice* device;//device
ISceneManager* smgr; //scene
IVideoDriver* driver; //driver
IGUIEnvironment* guienv;
public:
createLevel( IrrlichtDevice* id, ISceneManager* s, IVideoDriver* d, IGUIEnvironment* g )
{
device=id;
smgr=s;
driver=d;
guienv=g;
}
void start()
{
/*
We add a hello world label to the window, using the GUI environment.
*/
gui::IGUIStaticText* text1 = guienv->addStaticText(L"CA
SD3D v1.0",
rect<int>(10,10,260,30), true, true, 0, -1, true);
/*
To display something interesting, we load a Quake 2 model
and display it. We only have to get the Mesh from the Scene
Manager (getMesh()) and add a SceneNode to display the mesh.
(addAnimatedMeshSceneNode(
)). Instead of writing the filename
sydney.md2, it would also be possible to load a Maya object file
(.obj), a complete Quake3 map (.bsp) or a Milshape file (.ms3d).
By the way, that cool Quake 2 model called sydney was modelled
by Brian Collins.
*/
IAnimatedMesh* mesh = smgr->getMesh("objects/F4E
-Phantom/F
4 E Phantom.3ds");
ISceneNode* node = smgr->addOctTreeSceneNode(
mesh->getM
esh(0));
//ISceneNode* node2 = 0;
video::SMaterial material;
material.Textures[0] = driver->getTexture("textur
es/bricks2
b.jpg");
material.Lighting = false; //true for lighting
if (node)
{
//node->setMaterialFlag(EM
F_LIGHTING
, false);
//node->setMD2Animation ( scene::EMAT_STAND );
node->setScale(core::vecto
r3df(10.0f
, 10.0f, 10.0f));
node->getMaterial(0) = material;
node->setPosition(core::ve
ctor3df(25
0000.00f,1
2000.00f,2
50000.00f)
);
node->setRotation(core::ve
ctor3df(0.
00f,0.00f,
0.00f));
//node2 = smgr->addOctTreeSceneNode(
mesh->getM
esh(0));
}
//copyObject(1,1,mesh,node
,smgr);
IAnimatedMesh* mesh2 = smgr->getMesh("objects/wal
ls/wall25_
10_5.3DS")
;
ISceneNode* node2 = smgr->addOctTreeSceneNode(
mesh2->get
Mesh(0));
//ISceneNode* node2 = 0;
video::SMaterial material2;
material2.Textures[0] = driver->getTexture("textur
es/bricks2
b.jpg");
material2.Lighting = false; //true for lighting
if (node2)
{
//node->setMaterialFlag(EM
F_LIGHTING
, false);
//node->setMD2Animation ( scene::EMAT_STAND );
node2->setScale(core::vect
or3df(1000
0.0f, 10000.0f, 10000.0f));
node2->getMaterial(0) = material;
node2->setPosition(core::v
ector3df(-
120.f, 74000.f, 540000.f));
node2->setRotation(core::v
ector3df(0
.00f,0.00f
,0.00f));
//node2 = smgr->addOctTreeSceneNode(
mesh->getM
esh(0));
}
driver->setTextureCreation
Flag(video
::ETCF_ALW
AYS_32_BIT
, true);
// add irrlicht logo
// guienv->addImage(driver->g
etTexture(
"media/irr
lichtlogo2
.png"),
// core::position2d<s32>(10,1
0));
//set other font
guienv->getSkin()->setFont
(guienv->g
etFont("me
dia/fontlu
cida.png")
);
// add some help text
//gui::IGUIStaticText* text = guienv->addStaticText(
//L"Press 'W' to change wireframe mode\nPress 'D' to toggle detail map",
//core::rect<s32>(10,440,2
50,475), true, true, 0, -1, true);
gui::IGUIStaticText* text2 = guienv->addStaticText(
L"x,y,z",
core::rect<s32>(650,10,100
0,25), true, true, 0, -1, true);
gui::IGUIStaticText* text3 = guienv->addStaticText(
L"x,y,z",
core::rect<s32>(650,30,100
0,45), true, true, 0, -1, true);
// add camera
scene::ICameraSceneNode* camera =
smgr->addCameraSceneNodeFP
S(0,200.0f
,100000.f)
;
camera->setPosition(core::
vector3df(
220000.00f
,85000.00f
,220000.00
f));
camera->setTarget(core::ve
ctor3df(25
0000.00f,7
300.00f,25
0000.00f))
;
camera->setFarValue(102400
0.0f);
// disable mouse cursor
device->getCursorControl()
->setVisib
le(false);
// add billboard
scene::IBillboardSceneNode
* bill = smgr->addBillboardSceneNod
e();
bill->setMaterialType(vide
o::EMT_TRA
NSPARENT_A
DD_COLOR );
bill->setMaterialTexture(0
, driver->getTexture("media/
particle.b
mp"));
bill->setMaterialFlag(vide
o::EMF_LIG
HTING, false);
bill->setMaterialFlag(vide
o::EMF_ZBU
FFER, false);
bill->setSize(core::dimens
ion2d<f32>
(20.0f, 20.0f));
//smgr->addCameraSceneNode
(0, vector3df(0,30,-40), vector3df(0,5,0));
// add terrain scene node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"textures/bumpmap/mount2.b
mp",
0, // parent node
-1, // node id
core::vector3df(0.f, 0.f, 0.f), // position
core::vector3df(0.f, 0.f, 0.f), // rotation
core::vector3df(2000.f, 100.f, 2000.f),// scale
video::SColor ( 255, 255, 255, 255 ), // vertexColor,
5, // maxLOD
scene::ETPS_17, // patchSize
4 // smoothFactor
);
terrain->setMaterialFlag(v
ideo::EMF_
LIGHTING, true);
terrain->setMaterialTextur
e(0, driver->getTexture("textur
es/backgro
und2.bmp")
);
terrain->setMaterialTextur
e(1, driver->getTexture("textur
es/backgro
und2.bmp")
);
terrain->setMaterialType(v
ideo::EMT_
DETAIL_MAP
);
terrain->scaleTexture(1.0f
, 1.0f);
//terrain->setDebugDataVis
ible ( true );
/*
To be able to do collision with the terrain, we create a triangle selector.
If you want to know what triangle selectors do, just take a look into the
collision tutorial. The terrain triangle selector works together with the
terrain. To demonstrate this, we create a collision response animator
and attach it to the camera, so that the camera will not be able to fly
through the terrain.
*/
// create triangle selector for the terrain
scene::ITriangleSelector* selector
= smgr->createTerrainTriangl
eSelector(
terrain, 0);
terrain->setTriangleSelect
or(selecto
r);
selector->drop();
// create collision response animator and attach it to the camera
scene::ISceneNodeAnimator*
anim = smgr->createCollisionRespo
nseAnimato
r(
selector, camera, core::vector3df(60,100,60)
,
core::vector3df(0,0,0),
core::vector3df(0,50,0));
camera->addAnimator(anim);
anim->drop();
//test selector
scene::ITriangleSelector* selector2 = 0;
if (node)
{
selector2 = smgr->createOctTreeTriangl
eSelector(
mesh->getM
esh(0), node, 128);
node->setTriangleSelector(
selector2)
;
selector2->drop();
}
scene::ISceneNodeAnimator*
anim2 = smgr->createCollisionRespo
nseAnimato
r(
selector2, camera, core::vector3df(30,50,30),
core::vector3df(0,0,0),
core::vector3df(0,50,0));
camera->addAnimator(anim2)
;
anim2->drop();
/*
To make the user be able to switch between normal and wireframe mode, we create
an instance of the event reciever from above and let Irrlicht know about it. In
addition, we add the skybox which we already used in lots of Irrlicht examples.
*/
// create event receiver
MyEventReceiver receiver(terrain, text2, text3);
device->setEventReceiver(&
receiver);
// create skybox
skyBox SB(smgr, driver, "textures/skyBox/", "snow");
SB.start();
/*
// add sun
//ft
smgr->addLightSceneNode(0,
core::vector3df(254000,100
00,-20000)
,
video::SColorf(1.0f,0.0f,0
.0f,0.5f),
600000.0f);
//lt
smgr->addLightSceneNode(0,
core::vector3df(528000,100
00,256000)
,
video::SColorf(1.0f,1.0f,1
.0f,1.0f),
600000.0f);
//rt
smgr->addLightSceneNode(0,
core::vector3df(20000,1000
0,256000),
video::SColorf(1.0f,1.0f,1
.0f,1.0f),
600000.0f);
//bk
smgr->addLightSceneNode(0,
core::vector3df(254000,100
00,532000)
,
video::SColorf(1.0f,1.0f,1
.0f,1.0f),
600000.0f);
*/
/*
Ok, now we have set up the scene, lets draw everything:
We run the device in a while() loop, until the device does not
want to run any more. This would be when the user closed the window
or pressed ALT+F4 in windows.
*/
scene::ISceneNode* selectedSceneNode = 0;
scene::ISceneNode* lastSelectedSceneNode = 0;
int lastFPS = -1;
TravelDistance travel(camera->getAbsolute
Position()
.X,camera-
>getAbsolu
tePosition
().Y,camer
a->getAbso
lutePositi
on().Z);
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0 );
smgr->drawAll();
guienv->drawAll();
core::stringw xyz = L"";
xyz += camera->getAbsolutePositio
n().X;
xyz += " ";
xyz += camera->getAbsolutePositio
n().Y;
xyz += " ";
xyz += camera->getAbsolutePositio
n().Z;
text2->setText(xyz.c_str()
);
travel.updateTraveled(came
ra->getAbs
olutePosit
ion().X,ca
mera->getA
bsolutePos
ition().Y,
camera->ge
tAbsoluteP
osition().
Z);
core::stringw xyztravel = L"";
xyztravel += travel.getTraveled();
text3->setText(xyztravel.c
_str());
//collisions
/*
core::line3d<f32> line;
line.start = camera->getPosition();
line.end = line.start + (camera->getTarget() - line.start).normalize() * 1000.0f;
core::vector3df intersection;
core::triangle3df tri;
if (smgr->getSceneCollisionMa
nager()->g
etCollisio
nPoint(
line, selector2, intersection, tri))
{
bill->setPosition(intersec
tion);
driver->setTransform(video
::ETS_WORL
D, core::matrix4());
driver->setMaterial(materi
al);
driver->draw3DTriangle(tri
, video::SColor(0,255,0,0));
}
*/
/*
Another type of picking supported by the Irrlicht Engine is scene node picking
based on bouding boxes. Every scene node has got a bounding box, and because of
that, it's very fast for example to get the scene node which the camera looks
at. Again, we ask the collision manager for this, and if we've got a scene node,
we highlight it by disabling Lighting in its material, if it is not the
billboard or the quake 3 level.
*/
selectedSceneNode = smgr->getSceneCollisionMan
ager()->ge
tSceneNode
FromCamera
BB(camera)
;
if (lastSelectedSceneNode)
//lastSelectedSceneNode->s
etMaterial
Flag(video
::EMF_LIGH
TING, true);
if (selectedSceneNode == terrain || selectedSceneNode == bill)
selectedSceneNode = 0;
if (selectedSceneNode)
//selectedSceneNode->setMa
terialFlag
(video::EM
F_LIGHTING
, false);
lastSelectedSceneNode = selectedSceneNode;
driver->endScene();
// display frames per second in window title
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Terrain Renderer - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
// Also print terrain height of current camera position
// We can use camera position because terrain is located at coordinate origin
str += " Height: ";
str += terrain->getHeight(camera-
>getAbsolu
tePosition
().X, camera->getAbsolutePositio
n().Z);
device->setWindowCaption(s
tr.c_str()
);
lastFPS = fps;
}
}
device->drop();
}
};
int main()
{
void copyObject( int number, int distance, IAnimatedMesh* amesh, IAnimatedMeshSceneNode* anode, ISceneManager* sc );
/*
The most important function of the engine is the 'createDevice'
function. The Irrlicht Device can be created with it, which is the
root object for doing everything with the engine.
createDevice() has 7 paramters:
deviceType: Type of the device. This can currently be the Null-device,
the Software device, the second software renderer, D3D8, D3D9, or OpenGL.
In this example we use EDT_SOFTWARE, but to try out, you might want to change it to
EDT_BURNINGSVIDEO, EDT_NULL, EDT_DIRECT3D8 , EDT_DIRECT3D9, or EDT_OPENGL.
windowSize: Size of the Window or FullscreenMode to be created. In this
example we use 640x480.
bits: Amount of bits per pixel when in fullscreen mode. This should
be 16 or 32. This parameter is ignored when running in windowed mode.
fullscreen: Specifies if we want the device to run in fullscreen mode
or not.
stencilbuffer: Specifies if we want to use the stencil buffer for drawing shadows.
vsync: Specifies if we want to have vsync enabled, this is only useful in fullscreen
mode.
eventReceiver: An object to receive events. We do not want to use this
parameter here, and set it to 0.
*/
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select a device driver:\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");
char 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;b
reak;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
// create device
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(100
0, 700));
if (device == 0)
return 1; // could not create selected driver.
device->setWindowCaption(L
"DJINN v1.0");
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment(
);
createLevel level1(device, smgr, driver, guienv);
level1.start();
return 0;
}
/*
void copyObject( int number, int distance, IAnimatedMesh* amesh, IAnimatedMeshSceneNode* anode, ISceneManager* sc )
{
IAnimatedMesh* m = amesh;
IAnimatedMeshSceneNode* n = sc->addAnimatedMeshSceneNo
de( amesh );
//n->setMaterialFlag(anode
->getMater
ialFlag())
;
n->setMD2Animation ( scene::EMAT_STAND );
//n->setScale(core::vector
3df(10.0f,
10.0f, 10.0f));
n->setMaterialTexture( anode->getMaterial(1));
n->setPosition(core::vecto
r3df(11097
.88,6057.6
6,11046.94
));
n->setPosition(core::vecto
r3df(11097
.88,6057.6
6,12046.94
));
}
*/
Start Free Trial