Sign in to follow this  
jimbobmcgee

Cube not drawn

Recommended Posts

Hi, I hope someone here can help me: I'm trying to learn C++ and Direct3D9, having originally come from a VB6 background. I'm working from a book (Luna, Frank - Introduction to 3D Game Programming with DirectX 9.0) but am adapting his examples (figuring it to be the best way to actually understand the processes). I've got so far as to init my D3D device/window and am now trying to use DrawIndexedPrimitive() to draw a coloured cube to it. Now, the window appears (black, to start), the message loop begins and then device->Clear() occurs (white, to test). None of my routines return false but, for some reason, the cube is not shown. I think my buffers are losing scope but I can't see why or where. I hope someone here can help -- I've been trying for the past three days!! J. Download my project files here (you'll need to rename to .zip)

Share this post


Link to post
Share on other sites
Hi !

It's pretty hard to say. Maybe you should post your rendering code (and your cube definition). The source of the problem can be that you don't properly set renderstate (CCW/CW culling... look at the docs) or the parametres you send when calling DrawIndexedPrimitive are wrong.

Hope it helps... if not, post code.

Share this post


Link to post
Share on other sites
I posted a link to the code above (as I know pages and pages of code in a forum can put some people off) but I'll post the key bits here:

In doRenderScene.cpp

//// DIRECTIVES ///////////////////////////////////////////////////////////////
#define D3D_DEBUG_INFO
#include <d3dx9.h>
#include ".\initGlobals.h"
///////////////////////////////////////////////////////////////////////////////


//// PROTOTYPES ///////////////////////////////////////////////////////////////
bool createCubeObject(IDirect3DDevice9 *device);
bool doDisplayBuffer(IDirect3DDevice9 *device);
void killBuffers();
///////////////////////////////////////////////////////////////////////////////


//// USER DEFINED TYPES ///////////////////////////////////////////////////////
struct Vertex
{

Vertex(){}

Vertex(float x, float y, float z)
{
x = x; y = y; z = z;
c = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
}

Vertex(float x, float y, float z, float r, float g, float b, float a)
{
x = x; y = y; z = z;
c = D3DXCOLOR(r, g, b, a);
}

float x, y, z;
DWORD c;
static const DWORD fvf;

};
const DWORD Vertex::fvf = (D3DFVF_XYZ | D3DFVF_DIFFUSE);
///////////////////////////////////////////////////////////////////////////////


//// PRIVATE VARIABLES ////////////////////////////////////////////////////////
static IDirect3DVertexBuffer9 *D3DVertexBuffer = 0;
static IDirect3DIndexBuffer9 *D3DIndexBuffer = 0;
///////////////////////////////////////////////////////////////////////////////


bool createCubeObject(IDirect3DDevice9 *device)
{

Vertex *v;
WORD *i;

//// CREATE MEMORY BUFFERS TO STORE CUBE GEOMETRY /////////////////////////
if (device->CreateVertexBuffer(8 * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
Vertex::fvf,
D3DPOOL_MANAGED,
&D3DVertexBuffer,
0) != D3D_OK)
{
MessageBox(NULL, "Cannot create vertex buffer", "Error", MB_ICONSTOP | MB_OK);
return false;
}

if (device->CreateIndexBuffer(36 * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&D3DIndexBuffer,
0) != D3D_OK)
{
MessageBox(NULL, "Cannot create vertex buffer", "Error", MB_ICONSTOP | MB_OK);
return false;
}
///////////////////////////////////////////////////////////////////////////


//// STORE CUBE POINT GEOMETRY ////////////////////////////////////////////
D3DVertexBuffer->Lock(0, 0, (void**)&v, 0);

v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
v[1] = Vertex(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f);
v[2] = Vertex( 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f);
v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
v[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f);
v[5] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
v[6] = Vertex( 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f);
v[7] = Vertex( 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);

D3DVertexBuffer->Unlock();
///////////////////////////////////////////////////////////////////////////


//// STORE FACE GEOMETRY //////////////////////////////////////////////////
D3DIndexBuffer->Lock(0, 0, (void**)&i, 0);

i[0] = 0; i[1] = 1; i[2] = 2; // ) Front
i[3] = 0; i[4] = 2; i[5] = 3; // ) face

i[6] = 4; i[7] = 6; i[8] = 5; // ) Back
i[9] = 4; i[10] = 7; i[11] = 6; // ) face

i[12] = 4; i[13] = 5; i[14] = 1; // ) Left
i[15] = 4; i[16] = 1; i[17] = 0; // ) face

i[18] = 3; i[19] = 2; i[20] = 6; // ) Right
i[21] = 3; i[22] = 6; i[23] = 7; // ) face

i[24] = 1; i[25] = 5; i[26] = 6; // ) Top
i[27] = 1; i[28] = 6; i[29] = 2; // ) face

i[30] = 4; i[31] = 0; i[32] = 3; // ) Bottom
i[33] = 4; i[34] = 3; i[35] = 7; // ) face

D3DIndexBuffer->Unlock();
///////////////////////////////////////////////////////////////////////////

return true;

}


bool doDisplayBuffer(IDirect3DDevice9 *device)
{

if ((D3DVertexBuffer == 0) || (D3DIndexBuffer == 0))
{
MessageBox(NULL, "Display buffers empty", "Error", MB_ICONINFORMATION | MB_OK);
return false;
} //If buffers not populated, don't do anything

//// INITIALISE IMAGE STREAM //////////////////////////////////////////////
device->Clear(0, 0, //No dirty rectangles
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, //Things to clear
0xffffffff, //Colour to clear to
1.0f, 0); //Reset Z-Buffer & Stencil

device->SetStreamSource(0, D3DVertexBuffer, 0, sizeof(Vertex));
device->SetIndices(D3DIndexBuffer);
device->SetFVF(Vertex::fvf);
///////////////////////////////////////////////////////////////////////////


//// PLACE/TARGET CAMERA //////////////////////////////////////////////////
D3DXVECTOR3 vCamPos( 0.0f, 0.0f, -5.0f);
D3DXVECTOR3 vCamAim( 0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vCamUp ( 0.0f, 1.0f, 0.0f);

D3DXMATRIX mView, mProj, mWorld;

D3DXMatrixLookAtLH (&mView, &vCamPos, &vCamAim, &vCamUp);
D3DXMatrixIdentity (&mWorld);
D3DXMatrixPerspectiveFovLH (&mProj,
D3DX_PI * 0.5f, //Field of View (90deg)
(float)(giScrWidth / giScrHeight), //Aspect ratio
1.0f, 1000.0f); //Distance to near/far


device->SetTransform(D3DTS_VIEW, &mView);
device->SetTransform(D3DTS_PROJECTION, &mProj);
device->SetTransform(D3DTS_WORLD, &mWorld);
///////////////////////////////////////////////////////////////////////////


//// DRAW PRIMITIVES //////////////////////////////////////////////////////
device->BeginScene();

if (device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, //Type of primitives
0, //Base vertex adder
0, 8, //Start vertex / # vertices
0, 12) != D3D_OK) //Start index / # primitives
{
MessageBox(NULL, "Cannot draw primitive", "Error",
MB_ICONSTOP | MB_OK);
return false;
}

device->EndScene();

if (device->Present(0, 0, 0, 0) != D3D_OK)
{
MessageBox(NULL, "Cannot present display", "Error", MB_ICONINFORMATION | MB_OK);
return false;
}
///////////////////////////////////////////////////////////////////////////

return true;

}


void killBuffers(void)
{
if (D3DVertexBuffer != 0) D3DVertexBuffer->Release();
if (D3DIndexBuffer != 0) D3DIndexBuffer->Release();
}



In main.cpp

//// DIRECTIVES ///////////////////////////////////////////////////////////////
#define D3D_DEBUG_INFO
#include <windows.h>
#include <d3dx9.h>
#include ".\initWindow.h"
#include ".\initDirectX.h"
#include ".\initGlobals.h"
#include ".\doRenderScene.h"
///////////////////////////////////////////////////////////////////////////////


//// FUNCTION PROTOTYPES //////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLn, int iShowCmd);
///////////////////////////////////////////////////////////////////////////////


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLn, int iShowCmd)
{

//// INITIALISATION ///////////////////////////////////////////////////////
HWND hMainWnd = initMainWindow(hInst, iShowCmd);
IDirect3DDevice9 *ID3DDevice = initDirect3D(&hMainWnd);

if (!hMainWnd) //If window not initialised...
{
MessageBox(NULL, "Could not initialise main window", "Error", MB_ICONSTOP | MB_OK);
}

if (!ID3DDevice) //If Direct3D not initialised...
{
MessageBox(NULL, "Could not initialise Direct3D", "Error", MB_ICONSTOP | MB_OK);
}

if (!createCubeObject(ID3DDevice))
{
MessageBox(NULL, "Could not create cube object", "Error", MB_ICONSTOP | MB_OK);
gbAppRunning = false;
}
///////////////////////////////////////////////////////////////////////////


//// MAIN PROGRAM LOOP ////////////////////////////////////////////////////
do
{

float fTime, fTimeDiff;

MSG MainWndMsg;
ZeroMemory(&MainWndMsg, sizeof(MSG)); //Create and clear space for window message

if (PeekMessage(&MainWndMsg, hMainWnd, 0, 0, PM_REMOVE))
{ //Real-time message check
if (MainWndMsg.message == WM_QUIT)
{
gbAppRunning = false; //Exit do{} if quitting
}
else
{
TranslateMessage(&MainWndMsg); //Let Windows do its thing with message
DispatchMessage(&MainWndMsg); //Send message to the right place
}
}

//// MAIN PROGRAM LOGIC TO GO HERE ////////////////////////////////////

///////////////////////////////////////////////////////////////////////

if (!doDisplayBuffer(ID3DDevice))
{
MessageBox(NULL, "Could not display buffer", "Error", MB_ICONSTOP | MB_OK);
gbAppRunning = false;
}

}
while (gbAppRunning == true);
///////////////////////////////////////////////////////////////////////////


//// CLEANUP //////////////////////////////////////////////////////////////
killBuffers();
if (ID3DDevice) ID3DDevice->Release(); ID3DDevice = NULL;
if (hMainWnd) DestroyWindow(hMainWnd); hMainWnd = NULL;
///////////////////////////////////////////////////////////////////////////


return 0;
}



The DX init and window creation are in separate source files.

J.

(edit: just cleaning up the source tags)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Not really able to compile your code without all of your files. However, could it be possible that you should be using "this->x = x" instead of "x = x" within your Vertex functions. I can only guess the compiler will optimize out your assignments to themselves (such as "x = x", "y = y" and so on).

Share this post


Link to post
Share on other sites
That did it; using the 'this' keyword. Thanks, whoever you are, you've saved my sanity.

I just took that (x = x; y = y...) bit straight from the book -- I guess I was just populating my vertex buffer with null values?

Thanks again.

J.

Share this post


Link to post
Share on other sites
Out of interest, two points that follow up from this:

  • Are variables declared outside a function(){} completely global, or are they only local to the source (.cpp) file they are declared from?


  • Do such variables retain their values when called in separate routines (within the same source file) if the program executes routines from another source file in between, without the use of the 'static' keyword?


J.

Share this post


Link to post
Share on other sites
Quote:
Original post by jimbobmcgee
That did it; using the 'this' keyword. Thanks, whoever you are, you've saved my sanity.

I just took that (x = x; y = y...) bit straight from the book -- I guess I was just populating my vertex buffer with null values?

Thanks again.

J.
The code from the book uses leading underscore for member variables but all the underscores are gone in the book and replaced by a space. If you download the code for the book it works.

Share this post


Link to post
Share on other sites
Quote:
Original post by Eriond
The code from the book uses leading underscore for member variables but all the underscores are gone in the book and replaced by a space. If you download the code for the book it works.


Of course -- I had spotted that with some of the D3D constants -- it makes perfect sense now.

Kind of an irritating flaw with the publishing, though -- you would have thought they'd have spotted that before mass-production!!

Thanks again,

J.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this