Advertisement

08.16.2007 at 06:17AM PDT, ID: 22766721
[x]
Attachment Details

c++ class to convert avi to texture to wrap onto 3d object

Asked by alexatsearidge in Video Editing, 3D Game Programming, DirectX Graphics & Game Programming

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/F4 E Phantom.3ds");
      ISceneNode* node = smgr->addOctTreeSceneNode(mesh->getMesh(0));
      //ISceneNode* node2 = 0;
      
      video::SMaterial material;
      material.Textures[0] = driver->getTexture("textures/bricks2b.jpg");
      material.Lighting = false; //true for lighting


      if (node)
      {
            //node->setMaterialFlag(EMF_LIGHTING, false);
            //node->setMD2Animation ( scene::EMAT_STAND );
            node->setScale(core::vector3df(10.0f, 10.0f, 10.0f));
            node->getMaterial(0) = material;
            node->setPosition(core::vector3df(250000.00f,12000.00f,250000.00f));
            node->setRotation(core::vector3df(0.00f,0.00f,0.00f));
            //node2 = smgr->addOctTreeSceneNode(mesh->getMesh(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-0020AFD79767}
//-----------------------------------------------------------------------------
struct __declspec(uuid("{71771540-2017-11cf-ae26-0020afd79767}")) 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(IMediaSample *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::~VideoTexture()
{
    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(GraphicsDevice *_GD, char *filename)
{
    if(_GD->GetType() != GD_D3D) FatalMB("Video Textures require a DirectX Graphics Device.");
    GD = (D3DGraphicsDevice *)_GD;
    if(FAILED(InitGraph(filename))) FatalMB("InitGraph failed.");
}

HRESULT VideoTexture::InitGraph(char *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.CoCreateInstance(CLSID_FilterGraph, 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"Stream 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_pMC);
    g_pGB.QueryInterface(&g_pMP);
    g_pGB.QueryInterface(&g_pME);
    g_pGB.QueryInterface(&g_pMS);

    // 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(&lEventCode, (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(lEventCode, lParam1, lParam2);
    }
}

void VideoTexture::Set()
{
    if(GD)
    {
        GD->GetDevice()->SetTexture(0,myTexture);
    }
}

float VideoTexture::GetPosition()
{
    REFERENCE_TIME TotalLength, CurrentPos, Useless;
    g_pMS->GetDuration(&TotalLength);
    g_pMS->GetPositions(&CurrentPos, &Useless);
    return float(CurrentPos) / float(TotalLength);
}

void VideoTexture::Seek(float AbsolutePosition)
{
    HRESULT hr;

    REFERENCE_TIME TotalLength;

    g_pMS->GetDuration(&TotalLength);
    TotalLength = REFERENCE_TIME(TotalLength * double(AbsolutePosition));

    hr = g_pMS->SetPositions(
        &TotalLength, AM_SEEKING_AbsolutePositioning,
        NULL, AM_SEEKING_NoPositioning
        );
}

void VideoTexture::SetRate(float 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->GetDevice(),
                    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::CTextureRenderer( LPUNKNOWN pUnk, HRESULT *phr )
                                   : CBaseVideoRenderer(__uuidof(CLSID_TextureRenderer),
                                   NAME("Texture Renderer"), pUnk, phr)
{
    // Store and AddRef the texture for our use.
    *phr = S_OK;
}


//-----------------------------------------------------------------------------
// CTextureRenderer destructor
//-----------------------------------------------------------------------------
CTextureRenderer::~CTextureRenderer()
{
    // Do nothing
}


//-----------------------------------------------------------------------------
// CheckMediaType: This method forces the graph to give us an R8G8B8 video
// type, making our copy to texture memory trivial.
//-----------------------------------------------------------------------------
HRESULT CTextureRenderer::CheckMediaType(const 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::SetMediaType(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.biHeight);
    m_lVidPitch = m_lVidWidth * 4;
    return Parent->Restore();
}

//-----------------------------------------------------------------------------
// DoRenderSample: A sample has been delivered. Copy it to the texture.
//-----------------------------------------------------------------------------
HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample )
{
    if(Parent->GD && Parent->GD->GetSystemActive() && !Parent->GD->NeedToRestoreDevices() && 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->UnlockRect(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::ETCF_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::ETCF_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,traveled=0;}
        TravelDistance(float xx, float yy, float zz){x=xx,y=yy,z=zz,x2=xx,y2=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((fabs(x2))-(fabs(x))));
             traveled=traveled+(fabs((fabs(y2))-(fabs(y))));
             traveled=traveled+(fabs((fabs(z2))-(fabs(z))));
             x=x2;
             y=y2;
             z=z2;
        }
};

class MyEventReceiver : public IEventReceiver
{
public:

      MyEventReceiver(scene::ISceneNode* 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.PressedDown)
            {
                  switch (event.KeyInput.Key)
                  {
                  case irr::KEY_KEY_W: // switch wire frame mode
                        Terrain->setMaterialFlag(video::EMF_WIREFRAME, !Terrain->getMaterial(0).Wireframe);
                        Terrain->setMaterialFlag(video::EMF_POINTCLOUD, false);
                        return true;
                  case irr::KEY_KEY_P: // switch wire frame mode
                        Terrain->setMaterialFlag(video::EMF_POINTCLOUD, !Terrain->getMaterial(0).PointCloud);
                        Terrain->setMaterialFlag(video::EMF_WIREFRAME, false);
                        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_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"CASD3D 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/F4 E Phantom.3ds");
      ISceneNode* node = smgr->addOctTreeSceneNode(mesh->getMesh(0));
      //ISceneNode* node2 = 0;
      
      video::SMaterial material;
      material.Textures[0] = driver->getTexture("textures/bricks2b.jpg");
      material.Lighting = false; //true for lighting


      if (node)
      {
            //node->setMaterialFlag(EMF_LIGHTING, false);
            //node->setMD2Animation ( scene::EMAT_STAND );
            node->setScale(core::vector3df(10.0f, 10.0f, 10.0f));
            node->getMaterial(0) = material;
            node->setPosition(core::vector3df(250000.00f,12000.00f,250000.00f));
            node->setRotation(core::vector3df(0.00f,0.00f,0.00f));
            //node2 = smgr->addOctTreeSceneNode(mesh->getMesh(0));
            
      }
    //copyObject(1,1,mesh,node,smgr);
    IAnimatedMesh* mesh2 = smgr->getMesh("objects/walls/wall25_10_5.3DS");
      ISceneNode* node2 = smgr->addOctTreeSceneNode(mesh2->getMesh(0));
      //ISceneNode* node2 = 0;
      
      video::SMaterial material2;
      material2.Textures[0] = driver->getTexture("textures/bricks2b.jpg");
      material2.Lighting = false; //true for lighting


      if (node2)
      {
            //node->setMaterialFlag(EMF_LIGHTING, false);
            //node->setMD2Animation ( scene::EMAT_STAND );
            node2->setScale(core::vector3df(10000.0f, 10000.0f, 10000.0f));
            node2->getMaterial(0) = material;
            node2->setPosition(core::vector3df(-120.f, 74000.f, 540000.f));
            node2->setRotation(core::vector3df(0.00f,0.00f,0.00f));
            //node2 = smgr->addOctTreeSceneNode(mesh->getMesh(0));
            
      }
      
      driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);

      // add irrlicht logo
//      guienv->addImage(driver->getTexture("media/irrlichtlogo2.png"),
//            core::position2d<s32>(10,10));

      //set other font
      guienv->getSkin()->setFont(guienv->getFont("media/fontlucida.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,250,475), true, true, 0, -1, true);
            
            gui::IGUIStaticText* text2 = guienv->addStaticText(
            L"x,y,z",
            core::rect<s32>(650,10,1000,25), true, true, 0, -1, true);
            
            gui::IGUIStaticText* text3 = guienv->addStaticText(
            L"x,y,z",
            core::rect<s32>(650,30,1000,45), true, true, 0, -1, true);
            

      // add camera
      scene::ICameraSceneNode* camera =
            smgr->addCameraSceneNodeFPS(0,200.0f,100000.f);

      camera->setPosition(core::vector3df(220000.00f,85000.00f,220000.00f));
      camera->setTarget(core::vector3df(250000.00f,7300.00f,250000.00f));
      camera->setFarValue(1024000.0f);

      // disable mouse cursor
      device->getCursorControl()->setVisible(false);
      
      // add billboard

      scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
      bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
      bill->setMaterialTexture(0, driver->getTexture("media/particle.bmp"));
      bill->setMaterialFlag(video::EMF_LIGHTING, false);
      bill->setMaterialFlag(video::EMF_ZBUFFER, false);
      bill->setSize(core::dimension2d<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.bmp",
            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(video::EMF_LIGHTING, true);

      terrain->setMaterialTexture(0, driver->getTexture("textures/background2.bmp"));
      terrain->setMaterialTexture(1, driver->getTexture("textures/background2.bmp"));
      
      terrain->setMaterialType(video::EMT_DETAIL_MAP);

      terrain->scaleTexture(1.0f, 1.0f);
      
      
      //terrain->setDebugDataVisible ( 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->createTerrainTriangleSelector(terrain, 0);
      terrain->setTriangleSelector(selector);
      selector->drop();

      // create collision response animator and attach it to the camera
      scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
            selector, camera, core::vector3df(60,100,60),
            core::vector3df(0,0,0),
            core::vector3df(0,50,0));
      camera->addAnimator(anim);
      anim->drop();
      
      //test selector
scene::ITriangleSelector* selector2 = 0;
      
      if (node)
      {            
            selector2 = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), node, 128);
            node->setTriangleSelector(selector2);
            selector2->drop();
      }
      
      scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator(
          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,10000,-20000),
            video::SColorf(1.0f,0.0f,0.0f,0.5f),
            600000.0f);

      //lt      
            smgr->addLightSceneNode(0, core::vector3df(528000,10000,256000),
            video::SColorf(1.0f,1.0f,1.0f,1.0f),
            600000.0f);
      //rt
            smgr->addLightSceneNode(0, core::vector3df(20000,10000,256000),
            video::SColorf(1.0f,1.0f,1.0f,1.0f),
            600000.0f);
      //bk      
            smgr->addLightSceneNode(0, core::vector3df(254000,10000,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->getAbsolutePosition().X,camera->getAbsolutePosition().Y,camera->getAbsolutePosition().Z);

      while(device->run())
      if (device->isWindowActive())
      {
            driver->beginScene(true, true, 0 );

            smgr->drawAll();
            guienv->drawAll();
            
            core::stringw xyz = L"";
            xyz += camera->getAbsolutePosition().X;
            xyz += " ";
            xyz += camera->getAbsolutePosition().Y;
            xyz += " ";
            xyz += camera->getAbsolutePosition().Z;
            
            text2->setText(xyz.c_str());
            
            travel.updateTraveled(camera->getAbsolutePosition().X,camera->getAbsolutePosition().Y,camera->getAbsolutePosition().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->getSceneCollisionManager()->getCollisionPoint(
                  line, selector2, intersection, tri))
            {
                  bill->setPosition(intersection);
                        
                  driver->setTransform(video::ETS_WORLD, core::matrix4());
                  driver->setMaterial(material);
                  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->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera);

            if (lastSelectedSceneNode)
                  //lastSelectedSceneNode->setMaterialFlag(video::EMF_LIGHTING, true);

            if (selectedSceneNode == terrain || selectedSceneNode == bill)
                  selectedSceneNode = 0;

            if (selectedSceneNode)
                  //selectedSceneNode->setMaterialFlag(video::EMF_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->getAbsolutePosition().X, camera->getAbsolutePosition().Z);

                  device->setWindowCaption(str.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;break;
            case 'f': driverType = video::EDT_NULL;     break;
            default: return 1;
      }      

      // create device

      IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(1000, 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->addAnimatedMeshSceneNode( amesh );
         
        //n->setMaterialFlag(anode->getMaterialFlag());
            n->setMD2Animation ( scene::EMAT_STAND );
            //n->setScale(core::vector3df(10.0f, 10.0f, 10.0f));
            n->setMaterialTexture( anode->getMaterial(1));
            n->setPosition(core::vector3df(11097.88,6057.66,11046.94));
         
          
            n->setPosition(core::vector3df(11097.88,6057.66,12046.94));
     }
*/
Start Free Trial
[+][-]08.16.2007 at 07:18PM PDT, ID: 19714231

View this solution now by starting your 7-day free trial. Setting up your free trial is quick, easy, and secure. We will return you to this solution, unlocked, when you're done.

 

About this solution

Zones: Video Editing, 3D Game Programming, DirectX Graphics & Game Programming
Sign Up Now!
Solution Provided By: JoseParrot
Participating Experts: 1
Solution Grade: B
 
 
[+][-]08.28.2008 at 10:59AM PDT, ID: 22337753

Experts Exchange has a courteous staff of administrators who help members get the most out of the website by means of administrative comments like this one.

Start your 7-day free trial to view this Administrative Comment or ask the Experts your question.

 
 
Loading Advertisement...
20080716-EE-VQP-32 / EE_QW_1_20070628