# Game Engine problem

This topic is 3472 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

hello guyz im a university student and for our final yea project we thought of doing a game engine.i have a fairly good idea about the theory behind general 3D graphics and theory behind the DirecX API.but i havent used directX much prior to this so this is more of a learn by doing. i am creating a basic engine by gathering information from various sources.the DirectX stuff is hidden behind a DLL and loaded at run time so as other classes such as the camera class and 3d object class etc... the end user get the interface (abstract classes)to do his/her 3d application programming.the question is (this may sound stupid) im have trouble debugging the engine because it compiles and links but only thing is displays is the clear color .i have tried various things i cant pin point the problem (yes i have indexbuffers and i have setup the projection matrices and yes i also have called drawprimitave function as well :) ). the basic structure of using the frame work is ..... CThrimanaEngine *Engine; CThrimanaRD *RenderDevice; CTVertexBuffer *vb; CTSimpleCamera *Camera; .... struct mVert { public: float x,y,z; ULONG diffuse; }; .... Engine=new CThrimanaEngine(); Engine->Start(g_hInst,DX); Engine->RegisterRenderDevice(&RenderDevice); Engine->RegisterVertexBuffer(&vb); Engine->RegisterSimpleCamera(&Camera); Camera->init(640,360); Camera->setPosition(0,0,-5); Camera->activate(); RenderDevice->Activate(); vb->Create(36,D3DFVF_XYZ | D3DFVF_DIFFUSE,sizeof(Vert),STATIC); Vert myVert[36]={ { -2, 2, -2, RANDOM_COLOR}, { 2, 2, -2, RANDOM_COLOR }, { 2, -2, -2, RANDOM_COLOR}, { -2, 2, -2, RANDOM_COLOR }, {2, -2, -2, RANDOM_COLOR}, {-2, -2, -2, RANDOM_COLOR}, { -2, 2, 2, RANDOM_COLOR }, { 2, 2, 2, RANDOM_COLOR }, { 2, 2, -2, RANDOM_COLOR }, { -2, 2, 2, RANDOM_COLOR }, { 2, 2, -2, RANDOM_COLOR }, { -2, 2, -2, RANDOM_COLOR }, // Back Face { -2, -2, 2, RANDOM_COLOR }, { 2, -2, 2, RANDOM_COLOR }, { 2, 2, 2, RANDOM_COLOR }, { -2, -2, 2, RANDOM_COLOR }, { 2, 2, 2, RANDOM_COLOR }, { -2, 2, 2, RANDOM_COLOR }, // Bottom Face { -2, -2, -2, RANDOM_COLOR }, { 2, -2, -2, RANDOM_COLOR }, { 2, -2, 2, RANDOM_COLOR }, { -2, -2, -2, RANDOM_COLOR }, { 2, -2, 2, RANDOM_COLOR }, { -2, -2, 2, RANDOM_COLOR }, // Left Face { -2, 2, 2, RANDOM_COLOR }, { -2, 2, -2, RANDOM_COLOR }, { -2, -2, -2, RANDOM_COLOR }, { -2, 2, 2, RANDOM_COLOR }, {-2, -2, -2, RANDOM_COLOR }, { -2, -2, 2, RANDOM_COLOR }, // Right Face { 2, 2, -2, RANDOM_COLOR }, { 2, 2, 2, RANDOM_COLOR }, { 2, -2, 2, RANDOM_COLOR }, { 2, 2, -2, RANDOM_COLOR }, { 2, -2, 2, RANDOM_COLOR }, { 2, -2, -2, RANDOM_COLOR }, }; vb->Set(0,36,(void*)&myVert); while (!g_bDone) { while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&Message); DispatchMessage(&Message); } if (g_bIsActive) { if (RenderDevice->IsRunning()) { RenderDevice->ClearColor(3.4f,4.5f,6.7f); RenderDevice->BeginRendering(true,true,false); vb->Render(0,TRIANGLELIST,0); RenderDevice->EndRendering(); RenderDevice->Display(); } } i have taken out most of the code lines .this is to give a basic idea how how we intend to use the system.as i said i only get the background cleared according to the clear color.i have been trying to find the error for two weeks now but with no luck.i can provide the codeing to the above program as well as the framework. so can some one help me out figuring the problem.as you know i cant go head implimenting the other stuff with out figuring this out. thankz (and sorry if my English sounds odd its not my 1st language )

##### Share on other sites
Two things which have given me tons of problem:

Culling and lightning. Culling can cause your triangles to not get drawn if you try to render the vertices in the wrong order.

device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // something like that can be used to disable culling. It's there for a reason though, but you can try to disable it if things don't work as they should

The other one is lightning, which causes everything to be black if you don't setup lights and things like that. If you see your triangles but they are black, this might be your problem.

device->SetRenderState(D3DRS_LIGHTNING, 0); // something like that to disable lightning. Diffuse still works though.

##### Share on other sites
Quote:
 Original post by nirVaanvb->Render(0,TRIANGLELIST,0);

This seem bizarre to me. What do the two zero mean ?

##### Share on other sites
1st parameter starting vertex 3rd parameter number of primertives .if you specift zero to that inside te frame work it will calculate the number of primitives in this case since its trianglelist number of primitives = number of vertices /3
which is equal to 36/3 which is 12.

##### Share on other sites
It's difficult to tell much from the code because you don't use any DirectX calls and there's no way for us to know if the call parameters are correct.

However, shouldn't "vb->Render(0,TRIANGLELIST,0);" be "vb->Render(0,TRIANGLELIST,12);" (according to your response to Squallc)?

Also, what direction is the camera facing? It needs to be looking at (0,0,0) or facing (0,0,1).

##### Share on other sites
shouldn't "vb->Render(0,TRIANGLELIST,0);" be "vb->Render(0,TRIANGLELIST,12);" (according to your response to Squallc)?

yes you can put 12 as the 3rd parameter but you can also put zero and if you do put zero internally the framework calculates the number of primitives depending on render type you specifies (TRIANGLELIST, TRIANGLEFAN, etc...)

ok

when you call

Engine->Start(g_hInst,DX)

what happens is the correct DLL is loaded, if you specify GL instead of DX the DLL of the OpenGL implimentation will be loaded (OpenGL is not yet implimented)

Engine->RegisterRenderDevice(&RenderDevice);

the following function is invorked from the DLL

extern "C" _declspec(dllexport) HRESULT RegisterRD(HINSTANCE hDLL,CThrimanaRD **pDevice)
{

if(!*pDevice)
{
g_TD3DDDevice = new TD3D(hDLL);
*pDevice=g_TD3DDDevice;
return T_OK;
}
return T_FAIL;
}

here g_TD3DDDevice is global variable this is used so other objects such as the camera have access to the render device.

Engine->RegisterVertexBuffer(&vb);
Engine->RegisterSimpleCamera(&Camera);

these are implemented similarly but there is no global variable

ex:

extern "C" _declspec(dllexport) HRESULT RegisterVB(CTVertexBuffer **pDevice)
{

if(!*pDevice)
{
*pDevice = new TD3DVertexBuffer();
return T_OK;
}
return T_FAIL;
}

following is the implementation of the camera class

/*************************************************************************/
#include "TD3D.h"

using namespace ThrimanaMath;
extern TD3D *g_TD3DDDevice;

TD3DSimpleCam::TD3DSimpleCam()
{

m_pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
m_up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
m_look = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
m_fWidth=g_TD3DDDevice->m_dwWidth;
m_fHeight=g_TD3DDDevice->m_dwWidth;
m_bViewDirty=true;
m_bProjDirty=true;
D3DXMatrixIdentity( &m_mtxView );
D3DXMatrixIdentity( &m_mtxProj );

}
void TD3DSimpleCam::init(int w, int h)
{

m_fWidth=w;
m_fHeight=h;

}

TD3DSimpleCam::~TD3DSimpleCam()
{

}

void TD3DSimpleCam::getPosition(D3DXVECTOR3* pos)
{
*pos = m_pos;
}

void TD3DSimpleCam::setPosition(float x,float y, float z)
{
m_pos.x=x;
m_pos.y=y;
m_pos.z=z;
m_bViewDirty=true;
}

void TD3DSimpleCam::mooveForward(float units)
{

m_pos += m_look * units;

m_bViewDirty=true;
}

void TD3DSimpleCam::mooveSideways(float units)
{

m_pos += _right * units;

m_bViewDirty=true;
}

void TD3DSimpleCam::mooveUp(float units)
{
m_pos += _up * units;
m_bViewDirty=true;
}

void TD3DSimpleCam::pitch(float angle)
{
D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &m_right, angle);
D3DXVec3TransformCoord(&m_up,&_up, &T);
D3DXVec3TransformCoord(&m_look,&m_look, &T);
m_bViewDirty=true;
}

void TD3DSimpleCam::yaw(float angle)
{
D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &m_up, angle);
D3DXVec3TransformCoord(&m_right,&m_right, &T);
D3DXVec3TransformCoord(&m_look,&m_look, &T);
m_bViewDirty=true;
}

void TD3DSimpleCam::roll(float angle)
{

D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &m_look,angle);

D3DXVec3TransformCoord(&m_right,&m_right, &T);
D3DXVec3TransformCoord(&m_up,&m_up, &T);

m_bViewDirty=true;
}

D3DXMATRIX& TD3DSimpleCam::getViewMatrix()
{
if(m_bViewDirty==true)
{

D3DXVec3Normalize(&m_look, &m_look);

D3DXVec3Cross(&m_up, &m_look, &m_right);
D3DXVec3Normalize(&m_up, &m_up);

D3DXVec3Cross(&m_right, &m_up, &m_look);
D3DXVec3Normalize(&m_right, &m_right);

float x = -D3DXVec3Dot(m_right, &m_pos);
float y = -D3DXVec3Dot(&m_up, &m_pos);
float z = -D3DXVec3Dot(&m_look, &m_pos);

(m_mtxView)(0,0) = m_right.x; (m_mtxView)(0, 1) = m_up.x; (m_mtxView)(0, 2) = m_look.x; (m_mtxView)(0, 3) = 0.0f;
(m_mtxView)(1,0) = m_right.y; (m_mtxView)(1, 1) = m_up.y; (m_mtxView)(1, 2) = m_look.y; (m_mtxView)(1, 3) = 0.0f;
(m_mtxView)(2,0) = m_right.z; (m_mtxView)(2, 1) = m_up.z; (m_mtxView)(2, 2) = m_look.z; (m_mtxView)(2, 3) = 0.0f;
(m_mtxView)(3,0) = x; (m_mtxView)(3, 1) = y; (m_mtxView)(3, 2) = z; (m_mtxView)(3, 3) = 1.0f;

m_bViewDirty=false;
}

return m_mtxView;

}

D3DXMATRIX& TD3DSimpleCam::getProjMatrix ()
{
if(m_bProjDirty)
{
D3DVIEWPORT9 T;
T.Height=m_fHeight;
T.Width =m_fWidth ;
T.X=0;
T.Y=0;
T.MaxZ=0.0f;
T.MaxZ=1.0f;

if ( g_TD3DDDevice )
{
if(g_TD3DDDevice->m_pDevice)
g_TD3DDDevice->m_pDevice->SetViewport( &T );
}

float fAspect = (float)m_fWidth / (float)m_fHeight;
D3DXMatrixPerspectiveFovLH( &m_mtxProj, D3DXToRadian( 60.0f ), fAspect, 0.0f, 1.0f );
m_bProjDirty = false;
}
return m_mtxProj;
}

void TD3DSimpleCam::getRenderView ( )
{
if (!g_TD3DDDevice) return;
if (!g_TD3DDDevice->m_pDevice)return;

g_TD3DDDevice->m_pDevice->SetTransform( D3DTS_VIEW, &getViewMatrix() );

}
void TD3DSimpleCam::getRenderProj ( )
{
if (!g_TD3DDDevice) return;
if (!g_TD3DDDevice->m_pDevice)return;

g_TD3DDDevice->m_pDevice->SetTransform( D3DTS_PROJECTION, &getProjMatrix() );

}

void TD3DSimpleCam::activate()
{
if(g_TD3DDDevice)
g_TD3DDDevice->m_pCam=this;
}

/*****************************************************************************/

RenderDevice->Activate();

when this is called device is enumerated and a dialog box appears where user can have its selection (full screen ,windowed) this part works. and it also initializes m_pDevice to a LPDIRECT3DDEVICE9

vb->Create(36,D3DFVF_XYZ | D3DFVF_DIFFUSE,sizeof(Vert),STATIC);

here the Create function is called the function is given below

BOOL TD3DVertexBuffer::Create( unsigned long NumVertices, DWORD Descriptor, long VertexSize,DWORD usage)
{
Free();

if( g_TD3DDDevice == NULL)
return FALSE;
if(g_TD3DDDevice->m_pDevice == NULL)
return FALSE;
if(!(m_NumVertices = NumVertices) || !(m_FVF = Descriptor) || !(m_VertexSize = VertexSize))
return FALSE;

VERTEXPROCESSING_TYPE vp;
vp = g_TD3DDDevice->m_Settings.GetSettings()->VertexProcessingType;

if ( vp != HARDWARE_VP && vp != PURE_HARDWARE_VP )
m_ulUsage |= D3DUSAGE_SOFTWAREPROCESSING;

if(usage==STATIC)
{
if(FAILED(g_TD3DDDevice->m_pDevice->CreateVertexBuffer(
m_NumVertices * m_VertexSize,
m_ulUsage, m_FVF,
D3DPOOL_MANAGED, &m_pVB,NULL)))
return FALSE;
m_nUsage=STATIC;
}
else if(usage==DYNAMIC)
{

if(FAILED(g_TD3DDDevice->m_pDevice->CreateVertexBuffer(
m_NumVertices * m_VertexSize,
D3DUSAGE_DYNAMIC|m_ulUsage, m_FVF,
D3DPOOL_DEFAULT, &m_pVB,NULL)))
return FALSE;
m_nUsage=DYNAMIC;
}

return TRUE;
}

here is the function Free() which is been called inside the create function

BOOL TD3DVertexBuffer::Free()
{
Unlock();
if(m_pVB)m_pVB->Release();

m_NumVertices = 0;
m_FVF = 0;
m_Locked = FALSE;
m_Ptr = NULL;
if(m_pDptr)
{
delete m_pDptr;
m_pDptr=NULL;
}

return TRUE;
}

vb->Set(0,36,(void*)&myVert);

this function copies the array of myVert Structure into the directX vertex buffer
the function implementation is given below

BOOL TD3DVertexBuffer::Set(unsigned long FirstVertex, unsigned long NumVertices, void *VertexList)
{
if(g_TD3DDDevice == NULL || VertexList == NULL || m_pVB == NULL)
return FALSE;
if(g_TD3DDDevice->m_pDevice == NULL)
return FALSE;

if(Lock(FirstVertex, NumVertices) == FALSE)
return FALSE;

memcpy(m_Ptr, VertexList, NumVertices * m_VertexSize);
if(m_nUsage==DYNAMIC)
{
memcpy(m_pDptr, VertexList, NumVertices * m_VertexSize);
}

if(Unlock() == FALSE)
return FALSE;

return TRUE;
m_NumVertices=NumVertices;
}

BOOL TD3DVertexBuffer::Lock(unsigned long FirstVertex, unsigned long NumVertices)
{
if(m_pVB == NULL)
return FALSE;

if(FAILED(m_pVB->Lock(FirstVertex * m_VertexSize,
NumVertices * m_VertexSize, (void**)&m_Ptr,
return FALSE;

m_Locked = TRUE;

return TRUE;
}

RenderDevice->ClearColor(3.4f,4.5f,6.7f);

this clears the frame buffer with a given color this works.

RenderDevice->BeginRendering(true,true,false);

this calls the begin render function in directX parameters passed are coloe ,depth, stencil .function implementation is given below

HRESULT TD3D::BeginRendering(bool bClearColor, bool bClearDepth, bool bClearStencil)
{
DWORD dw=0;
if (bClearColor || bClearDepth || bClearStencil)
{
if (bClearColor) dw |= D3DCLEAR_TARGET;
if (bClearDepth) dw |= D3DCLEAR_ZBUFFER;
if (bClearStencil && m_bStencil)
dw |= D3DCLEAR_STENCIL;

if (FAILED(m_pDevice->Clear(0, NULL, dw, m_ClearColor, 1.0f, 0)))
{

return T_FAIL;
}

}
if(m_pCam)
{
m_pCam->getRenderView();
m_pCam->getRenderProj();
}

if (FAILED(m_pDevice->BeginScene()))
return T_FAIL;
m_bIsSceneRunning = true;
return T_OK;
}

vb->Render(0,TRIANGLELIST,0)

this render the vertex buffer .the function implantation is

BOOL TD3DVertexBuffer::Render(unsigned long FirstVertex,DWORD Type,unsigned long NumPrimitives)
{

if(g_TD3DDDevice->m_pDevice == NULL || m_pVB == NULL)
return FALSE;
if(NumPrimitives==0)
{
if (Type==POINTLIST)
{
NumPrimitives=m_NumVertices;
}
else if(Type==LINELIST)
{
NumPrimitives=m_NumVertices/2;

}
else if(Type==LINESTRIP)
{
NumPrimitives=m_NumVertices-1;
}
else if(Type==TRIANGLELIST)
{
NumPrimitives=m_NumVertices/3;
}
else if(Type==TRIANGLESTRIP)
{
NumPrimitives=m_NumVertices-2;
}
else if(Type==TRIANGLEFAN)
{
NumPrimitives=m_NumVertices-2;
}
}

g_TD3DDDevice->m_pDevice->SetStreamSource(0, m_pVB,NULL, m_VertexSize);
g_TD3DDDevice->m_pDevice->SetFVF(m_FVF);
g_TD3DDDevice->m_pDevice->DrawPrimitive((D3DPRIMITIVETYPE)Type, FirstVertex, NumPrimitives);

return TRUE;
}

RenderDevice->EndRendering()

this calls the directX endscene function. the implementation is

void TD3D::EndRendering()
{
m_pDevice->EndScene();
m_bIsSceneRunning = false;
}

RenderDevice->Display();

this functions present the screen. implimentation is

void TD3D::Display()
{
if(m_bUsingDifWindow && m_bEntryActivateWin)
{
m_pChain[m_nActivehWnd]->Present(NULL, NULL, NULL, NULL,0);
}
else
{
m_pDevice->Present(NULL, NULL, NULL, NULL);
}

}

note idea for the vertex buffer class was taken from the book visual c++ Directx RPG game programming book

[Edited by - nirVaan on July 13, 2008 1:49:28 PM]

##### Share on other sites
Quote:
 D3DXMatrixPerspectiveFovLH( &m_mtxProj, D3DXToRadian( 60.0f ), fAspect, 0.0f, 1.0f );

1. The near plane should never be set to 0.
2. The far plane is 1.0, which means, with your camera at z=-5, you'll never see anything beyond z=-4.

Try setting your projection near and far planes to something like 0.5f and 1000.0f.

##### Share on other sites
im still havening no luck. i did what buckeye told me and changed the near and far planes to .5f and 1000.0f still i see nothing?

any ideas whats wrong here

thankz

##### Share on other sites
I agree with DvDmanDT, I didn't see lights here

##### Share on other sites
well actually after what DvDmanDT i added these two lines to the vertexbuffer class render function just as a test i also changed the near and far clipping planes to .5f and 1000.0f still i have no luck i have set the clear color to blue and i clear the frame buffer at iteration of the loop followed by actually rendering the verticies.but still all i get is the blue color.

g_TD3DDDevice->m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_TD3DDDevice->m_pDevice->SetRenderState(D3DRS_LIGHTING, 0);

the modified Render function in the vertex buffer looks like

BOOL TD3DVertexBuffer::Render(unsigned long FirstVertex,DWORD Type,unsigned long NumPrimitives)
{

if(g_TD3DDDevice->m_pDevice == NULL || m_pVB == NULL)
return FALSE;
if(NumPrimitives==0)
{
if (Type==POINTLIST)
{
NumPrimitives=m_NumVertices;
}
else if(Type==LINELIST)
{
NumPrimitives=m_NumVertices/2;

}
else if(Type==LINESTRIP)
{
NumPrimitives=m_NumVertices-1;
}
else if(Type==TRIANGLELIST)
{
NumPrimitives=m_NumVertices/3;
}
else if(Type==TRIANGLESTRIP)
{
NumPrimitives=m_NumVertices-2;
}
else if(Type==TRIANGLEFAN)
{
NumPrimitives=m_NumVertices-2;
}
}

g_TD3DDDevice->m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_TD3DDDevice->m_pDevice->SetRenderState(D3DRS_LIGHTING, 0);
g_TD3DDDevice->m_pDevice->SetStreamSource(0, m_pVB,NULL, m_VertexSize);
g_TD3DDDevice->m_pDevice->SetFVF(m_FVF);
g_TD3DDDevice->m_pDevice->DrawPrimitive((D3DPRIMITIVETYPE)Type, FirstVertex, NumPrimitives);

return TRUE;
}

but still as i have said no luck

##### Share on other sites
Quote:
 Original post by nirVaan1st parameter starting vertex 3rd parameter number of primertives .if you specift zero to that inside te frame work it will calculate the number of primitives in this case since its trianglelist number of primitives = number of vertices /3which is equal to 36/3 which is 12.

Why not just provide an overloaded function that doesn't have the third parameter then?

##### Share on other sites
yea could have done it like that but initially made it as a parameter with a default value. this was in the implementation. but then when i did the same to the abstract class which implementation class inherits from the compiler complained that you cant define default parameters two places so i took it out from the function in the abstract class.o i have to specify it when im using it lol i just went with it cuz i wanted to make sure it was working.but i cant get anything to come up to the screen

##### Share on other sites

so far the framework does not support lighting as you can see the vertex structure
does not include a normal from what i know (correct me if im wrong) you should be able to see things with lighting off as long as you dont have a vertex normal but instead a diffuse color comportment.isnt it when you have lighting on and no vertex normals that you get clear color.that what i know i may be wrong any how ill try what you have said as well

thankz

##### Share on other sites
Quote:
 If you turn off lighting you won't see anything

That's not true at all. The default state of the device in the fixed function pipeline is to render Gouraud shading just as he has it programmed.
Quote:
 the only reason to turn off lighting is to be using shaders

Incorrect.

##### Share on other sites
FYI: you should get a compiler error with:
float x = -D3DXVec3Dot(m_right, &m_pos); // should be &m_right

I'm wondering if there's a problem somewhere with the camera.
if(m_pCam){m_pCam->getRenderView();m_pCam->getRenderProj();}

You might want to try to eliminate the camera for trouble-shooting purposes by replacing the above code with something like the following:
    D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5.0f );    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );    D3DXMATRIXA16 matView;    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );    m_pDevice->SetTransform( D3DTS_VIEW, &matView );    D3DXMATRIXA16 matProj;    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );    m_pDevice->SetTransform( D3DTS_PROJECTION, &matProj );

##### Share on other sites
why dont you try to render another thing, just to be sure