Game Engine problem

Started by
15 comments, last by nirVaan 15 years, 9 months ago
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 )
Advertisement
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.
Quote:Original post by nirVaan
vb->Render(0,TRIANGLELIST,0);


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

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.
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).

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

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,
0)))// LAST PARAMETER 0 USED INSTEAD OF D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD
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]
Quote:D3DXMatrixPerspectiveFovLH( &m_mtxProj, D3DXToRadian( 60.0f ), fAspect, 0.0f, 1.0f );

This looks very bad!

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.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

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
I agree with DvDmanDT, I didn't see lights here
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

This topic is closed to new replies.

Advertisement