Irrlicht + SPE Integration

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Irrlicht + SPE Integration

Post by IrrNoob »

I've resently discovered a great physics engine called SPE (Simple Physics Engine) and am trying to integrate it into my Irrlicht project.

but I get a linker error:

Code: Select all

error LNK2019: unresolved external symbol "struct ISPEWorld * __cdecl CreateSPEWorld(void)" (?CreateSPEWorld@@YAPAUISPEWorld@@XZ) referenced in function "void __cdecl InitApp(void)" (?InitApp@@YAXXZ)
..\..\examples\SPEGame\SPEGame.exe : fatal error LNK1120: 1 unresolved externals
My code is based off of the first SPE sample which compiles.
there doesn't seem to be any syntax errors that I can notice.

Does anyone know what causes this error?
Last edited by IrrNoob on Fri Jan 09, 2009 7:33 am, edited 1 time in total.
Katsankat
Posts: 178
Joined: Sun Mar 12, 2006 4:15 am
Contact:

Post by Katsankat »

Tell to the linker where SPE.lib is. What is your IDE/compiler?
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

You were right, I use MSVC 2008 but I'm real new to this IDE.

But now the program crashes after execution.

Code: Select all

SOLVED
Why does this happen?
Last edited by IrrNoob on Fri Jan 09, 2009 9:47 pm, edited 7 times in total.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You cannot call InitApp (which uses the global device pointer) without having Irrlicht initialized first. Try to remove all your global variables, or at least clean up your init scheme to use only initialized stuff. Oh, and a debugger will easily point to the place that uses non-initialized pointers etc.
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

ok, I got rid of the globals, cleaned up initApp and made changes to the code in my last message to reflect this, but at this line in main.cpp:

Code: Select all

video::IVideoDriver* driver = device->getVideoDriver();
I get this error when debugging:

Code: Select all

Unhandled exception at 0x0043261f in GameDebug.exe: 0xC0000005: Access violation reading location 0x00000000.
What is going on and what is this unhandled exception?
How do I fix this?
drewbacca
Posts: 38
Joined: Tue Jan 30, 2007 6:49 pm

Post by drewbacca »

Your code pretty clearly sets device = 0, then you immediately try using the -> operator on your 0.

You can't do anything with your device pointer until you create the device.
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

drewbacca wrote:Your code pretty clearly sets device = 0, then you immediately try using the -> operator on your 0.

You can't do anything with your device pointer until you create the device.
Ah, I guess that was pretty dumb, I thought I setup Irrlicht right
here is the new code:

Code: Select all

#include <irrlicht.h>
#include <SPE.h>
#include <iostream>
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "SPE.lib")

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



struct LMesh
{
	SPEVertex *pVertex;
	int *pIndex;
	int NumVertices;
	int NumIndices;
	int NumFaces;

	LMesh()
	{
		pVertex=0;
		pIndex=0;
  NumVertices=0; 
  NumIndices=0;
	}

	bool Load(scene::IAnimatedMesh* mesh, const SPEVector& Scale=SPEVector(1,1,1))
	{  
        //Get number of vertices 
        u32 nMeshBuffer; 
        for( nMeshBuffer = 0 ; nMeshBuffer < mesh->getMeshBufferCount(); ++nMeshBuffer) 
        { 
          scene::IMeshBuffer *buffer = mesh->getMeshBuffer(nMeshBuffer); 
          NumVertices += buffer->getVertexCount(); 
        } 

		pVertex = new SPEVertex[NumVertices]; // causes bad allocation of memory.
		
		u32 n;
        for( n = 0 ; n < mesh->getMeshBufferCount(); ++n) 
        { 
          scene::IMeshBuffer *buffer2 = mesh->getMeshBuffer(n); 
          NumIndices += buffer2->getIndexCount(); 
        }

		pIndex = new int[NumIndices];
		NumFaces = NumIndices / 3;
		
		for(int i=0; i<NumVertices; i++)
		{
			pVertex[i].p.x*=Scale.x;
			pVertex[i].p.y*=Scale.y;
			pVertex[i].p.z*=Scale.z;
		}
		return true;
	}

	void Release()
	{
		if(pVertex) delete[] pVertex;
		if(pIndex) delete[] pIndex;
	}

	~LMesh()
	{
		Release();
	}
};

int main()
{
      SPEVector Eye, At;
      LMesh Mesh;
      LPSPEWORLD  pWorld;
      LPSPERIGIDBODY  pMesh;

      IrrlichtDevice* device = 0;

	  // select opengl as driver type
	 video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;

	  // create device
	  device = createDevice(driverType, core::dimension2d<s32>(1024, 768), 32,
			/*fullscreen*/true, /*stencilbuffer*/false, /*vsync*/true, 0);

      ICameraSceneNode* camera = 0;
      video::IVideoDriver* driver = device->getVideoDriver();
      scene::ISceneManager* smgr = device->getSceneManager();
       
    scene::IAnimatedMesh* lilman = smgr->getMesh("media/LittleMan.md2");


	if (device == 0)
		return 1; // could not create selected driver.

	// add camera
    // CREATE WASD KEYMAP ARRAY 
    SKeyMap keyMapWASD[5]; 
    keyMapWASD[0].Action = EKA_MOVE_FORWARD; 
    keyMapWASD[0].KeyCode = KEY_KEY_W; 
    keyMapWASD[1].Action = EKA_MOVE_BACKWARD; 
    keyMapWASD[1].KeyCode = KEY_KEY_S; 
    keyMapWASD[2].Action = EKA_STRAFE_LEFT; 
    keyMapWASD[2].KeyCode = KEY_KEY_A; 
    keyMapWASD[3].Action = EKA_STRAFE_RIGHT; 
    keyMapWASD[3].KeyCode = KEY_KEY_D; 
    keyMapWASD[4].Action = EKA_JUMP_UP; 
    keyMapWASD[4].KeyCode = KEY_SPACE; 
    camera = smgr->addCameraSceneNodeFPS(0,100.0f,1.f,0,keyMapWASD, 5, true, 3);

	camera->setPosition(core::vector3df(3800,-350,7400));
	camera->setTarget(core::vector3df(4794,-686,3400));
	camera->setFarValue(12000.0f);
	camera->setNearValue(1.0f);
   
    
	// disable mouse cursor
	device->getCursorControl()->setVisible(false);

    Eye=SPEVector(10,20,10)*0.8;
	At=SPEVector(0,0,0);

	Mesh.Load( lilman, SPEVector(20, 20, 0.5f));
	

	pWorld = CreateSPEWorld();
	pWorld->SetGravity (SPEVector(0, -9.8f, 0));;  // this is the default value of gravity in SPE

	LPSPESHAPE pShape = pWorld->CreateShape();

	pShape->Initialize ((BYTE*)Mesh.pVertex, sizeof(SPEVertex), Mesh.pIndex, Mesh.NumFaces );
	pMesh=pWorld->AddRigidBody (pShape);
	pMesh->SetBeStatic(true);
	pMesh->SetPosition (SPEVector(0,0,0));	

	pWorld->ReleaseShape(pShape);	


    u32 previous = device->getTimer()->getTime();

	while(device->run()){
                         

//-----------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------                    
 
	  const u32 current = device->getTimer()->getTime(); 
      float fElapsedTime = (float*)current - (float*)previous;
	  pWorld->Update (fElapsedTime);
	  previous = current;

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

		smgr->drawAll();

		driver->endScene();


	 }}



 device->drop();
	
	return 0;
}
But still I am lost because I am getting a new error at this line:

Code: Select all

pVertex = new SPEVertex[NumVertices];
and this error message:

Code: Select all

Unhandled exception at 0x7c812aeb in SPEGameDebug.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0012fae4..
So why is it giving me a bad allocation of memory?
Last edited by IrrNoob on Sat Jan 10, 2009 1:32 am, edited 2 times in total.
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

I think the problem is maybe caused by the call to:

Code: Select all

  bool Load(scene::IAnimatedMesh* mesh, const SPEVector& Scale=SPEVector(1,1,1)) 
   {  
        //Get number of vertices 
        u32 nMeshBuffer; 
        for( nMeshBuffer = 0 ; nMeshBuffer < mesh->getMeshBufferCount(); ++nMeshBuffer) 
        { 
          scene::IMeshBuffer *buffer = mesh->getMeshBuffer(nMeshBuffer); 
          NumVertices += buffer->getVertexCount(); 
        } 

      pVertex = new SPEVertex[NumVertices]; // causes bad allocation of memory. 
       
      u32 n; 
        for( n = 0 ; n < mesh->getMeshBufferCount(); ++n) 
        { 
          scene::IMeshBuffer *buffer2 = mesh->getMeshBuffer(n); 
          NumIndices += buffer2->getIndexCount(); 
        } 

      pIndex = new int[NumIndices]; 
      NumFaces = NumIndices / 3; 
       
      for(int i=0; i<NumVertices; i++) 
      { 
         pVertex[i].p.x*=Scale.x; 
         pVertex[i].p.y*=Scale.y; 
         pVertex[i].p.z*=Scale.z; 
      } 
      return true; 
   } 
because I am trying to do in Irrlicht what is done in opengl in the first SPE sample:

Code: Select all

	bool Load(char *FileName, const SPEVector& Scale=SPEVector(1,1,1))
	{
		FILE *fp=0;
		fp=fopen(FileName,"rb");
		if(!fp)
		{
			MessageBox(0, "Model file not found!", "GLMesh", 0);
			return false;
		}

		fread(&NumVertices, sizeof(int), 1, fp);
		pVertex=new SPEVertex[NumVertices];
		fread(pVertex, sizeof(SPEVertex)*NumVertices, 1, fp);
		
		int n;
		fread(&n, sizeof(int), 1, fp);
		pIndex=new int[n];
		fread(pIndex, sizeof(int)*n, 1, fp);
		NumFaces=n/3;

		fclose(fp);
		
		for(int i=0; i<NumVertices; i++)
		{
			pVertex[i].p.x*=Scale.x;
			pVertex[i].p.y*=Scale.y;
			pVertex[i].p.z*=Scale.z;
		}
		return true;
	}
This is done so that one is able to make this call to:

Code: Select all

pShape->Initialize ((BYTE*)Mesh.pVertex, sizeof(SPEVertex), Mesh.pIndex, Mesh.NumFaces );
the documents say that the definition and usage of virtual SPERESULT Initialize is:

Code: Select all

struct ISPEShape
{
    virtual SPERESULT Initialize(BYTE *pVertex, int StrideSize, int *pIndex, int NumTriangles) = 0;
     Create a shape from tri-mesh data. 
 
Parameters
    pVertex
        [in] Pointer to vertex buffer.
    StrideSize
        [in] Stride of one vertex, in bytes.
    pIndex
        [in] Pointer to index buffer, index must be 32BIT.
    NumTriangles
        [in] Number of triangles.
    
Return
        SPE_OK if the method succeeds, else return SPE_FAILED. 
How would I then correctly write the Load() to get the correct information
for Initialize(), using Irrlicht to abstract this data instead of opengl?
drewbacca
Posts: 38
Joined: Tue Jan 30, 2007 6:49 pm

Post by drewbacca »

I didn't look at your code too in depth, so sorry if I'm not answering your bigger picture question. But anyway your crash says "bad_alloc" which is saying that it couldn't allocate the memory for your array of SPEVertex. If you were to use your debugger or just display the value of NumVertices, you'd see your problem.

You never initialize it to zero before adding to it, so its some random, probably huge number
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

Your correct again, thanks drewbacca. I needed to initialize
NumVertices and NumIndices to zero in the LMesh constructor.
But now I get another unhandled exception:

Code: Select all

Unhandled exception at 0x0035c4c8 in SPEGameDebug.exe: 0xC0000005: Access violation reading location 0xe69f5cdc.
But the debugger says it cannot point to a location in my code that is
the cause.
Would this have to do with my Load()?
I need to know how to get a pointer to the vertex buffer for the loaded mesh, the stride of a vertex, in bytes, a pointer to the 32bit index buffer for the loaded mesh, and the number of triangles.

How do I get this data from Irrlicht?

UPDATE:
I'm looking at the Irrlicht API documents, and see the member function
getVertexBuffer() and getIndexBuffer(), but I'm a little lost on how to implement anything with these...
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

After trying to get trying to implement getVertexBuffer() and getIndexBuffer() to get a pointer to the loaded mesh's vertex buffer and index buffer I have this for the LMesh class:

Code: Select all

	struct LMesh
{
	SPEVertex *pVertex;
	int *pIndex;
	int NumVertices;
	int NumFaces;
    scene::IDynamicMeshBuffer *VertexBuffer; 
    scene::IDynamicMeshBuffer *IndexBuffer; 


	LMesh()
	{
		pVertex =0;
		pIndex=0;
        NumVertices =0;
		NumFaces =0;
		VertexBuffer =0;
		IndexBuffer =0;
	}

	bool Load(scene::IAnimatedMesh* mesh, const SPEVector& Scale=SPEVector(1,1,1))
	{  
 
			
			pVertex = (SPEVertex*)VertexBuffer->getVertexBuffer().getData();
	
			pIndex = (int*)IndexBuffer->getIndexBuffer().getData();
        
		//Get number of vertices
	    u32 nMeshBuffer;
        for( nMeshBuffer = 0 ; nMeshBuffer < mesh->getMeshBufferCount(); ++nMeshBuffer) 
        { 
          scene::IMeshBuffer *buffer = mesh->getMeshBuffer(nMeshBuffer); 
          NumVertices += buffer->getVertexCount(); 
        } 

		NumFaces = NumVertices / 3;
		
		for(int i=0; i<NumVertices; i++)
		{
			pVertex[i].p.x*=Scale.x;
			pVertex[i].p.y*=Scale.y;
			pVertex[i].p.z*=Scale.z;
		}
		return true;
	}

	void Release()
	{
		if(pVertex) delete[] pVertex;
		if(pIndex) delete[] pIndex;
        if(VertexBuffer) delete[] VertexBuffer;
        if(IndexBuffer) delete[] IndexBuffer;
    }

	~LMesh()
	{
		Release();
	}
};
But At this line of code

Code: Select all

pVertex = (SPEVertex*)VertexBuffer->getVertexBuffer().getData();
I am getting this error:

Code: Select all

Unhandled exception at 0x00432939 in SPEGameDebug.exe: 0xC0000005: Access violation reading location 0x00000000.
I'm still struggling to figure this out.
I need to provide a vertex buffer and indices to create the collision shape
Last edited by IrrNoob on Sat Jan 10, 2009 5:54 am, edited 1 time in total.
twilight17
Posts: 362
Joined: Sun Dec 16, 2007 9:25 pm

Post by twilight17 »

You initialise VertexBuffer to nothing, but you're getting data from it?
IrrNoob wrote:

Code: Select all

    pVertex = (SPEVertex*)VertexBuffer->getVertexBuffer().getData();
Post this userbar I made on other websites to show your support for Irrlicht!
Image
http://img147.imageshack.us/img147/1261 ... wernq4.png
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

Code: Select all

	LMesh()
	{
		pVertex =0;
		pIndex=0;
        NumVertices =0;
		NumFaces =0;
		VertexBuffer =0;
		IndexBuffer =0;
	}
I am initializing vertexBuffer here, correct? I want to get a pointer to the first vertex of a vertex buffer of a IAnimatedMesh* mesh. I'm not sure how to get that data from an IAnimatedMesh.

Do I need to create a vertex buffer, or does Irrlicht automatically produce one when calling the driver?

I want to do something like:

Code: Select all

            mesh = VertexBuffer->getVertexBuffer().getData();
			pVertex = (SPEVertex *)mesh;
but I the compiler is telling me I cannot convert from void * to irr::scene::IAnimatedMesh *.

Can someone show me the proper way to get a pointer to the first vertex of a vertex buffer of a IAnimatedMesh* mesh?
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

I have managed to put together this in order to get the pointer to the first vertex of a vertex buffer of a IAnimatedMesh* mesh:

Code: Select all

        irr::u32 meshBufferCount = (irr::u32)mesh->getMesh(0)->getMeshBufferCount(); 

		
        // pointer to the mesh buffer 
        scene::IMeshBuffer* mb = mesh->getMesh(0)->getMeshBuffer(0);

		NumVertices = mb->getVertexCount(); // get vertex number

        int* mbVertices = (int*)mb->getVertices(); // get pointer to vertices in the mesh buffer 

         irr::u32* mbIndices = (irr::u32*)mb->getIndices(); // get pointer to indices in the mesh buffer 

        pVertex = new SPEVertex[mbVertices];
But I'm stumped on how to get the first vertex of the vertex buffer into pVertex.
Post Reply