-
No Cube!!!
Hi all.
I have been learning from my book and you gurus on this message board what Vertices and Indices are and why do i need an abstract custom Vertex structure... Mayby you can help me a bit more.
Since you guys helped me understand a bit more about DirectX it has gone smoothly until i completed my spinning cube project from the book.
I don't get any errors or warnings... but the cube never displays.
Here is the code... It is quite long, so scan through it if you can.
d3dUtility.h
Code:
/*d3dUtility.h*/
#include <d3dx9.h>
namespace d3d /*Create a new namespace called d3d*/
{
/*Delcare some functions*/
bool InitD3D(
HINSTANCE hInstance, /*Application instance*/
int width, int height, /*Window width & height in pixels*/
bool windowed, /*Windowed?*/
D3DDEVTYPE deviceType, /*HAL or REF*/
IDirect3DDevice9** device); /*The Device*/
int EnterMsgLoop(
bool (*ptr_display)(float timeDelta));
LRESULT CALLBACK WndProc(
HWND hwnd, /*Window handle*/
UINT Msg, /*Message handle*/
WPARAM wParam,
LPARAM lParam);
template<class T>
void Release(T t)
{
if(t)
{
t->Release();
t = 0;
}
}
template<class T>
void Delete(T t)
{
if(t)
{
delete t;
t = 0;
}
}
}
d3dSetup.cpp
Code:
/*3d3Setup.cpp*/
#include "d3dUtility.h"
bool d3d::InitD3D(
HINSTANCE hInstance, /*Application instance*/
int width, int height, /*Window height, window width*/
bool windowed, /*Window windowed or fullscreen?*/
D3DDEVTYPE deviceType, /*Device type (HAL or REF)*/
IDirect3DDevice9** device) /*Device*/
{
WNDCLASS wc; /*Make wc an instance of WNDCLASS*/
/*Fill out the WNDCLASS class*/
/*Class style*/
wc.style = CS_HREDRAW | CS_VREDRAW;
/*Pointer to the window procedure*/
wc.lpfnWndProc = (WNDPROC)d3d::WndProc;
/*Extra memory slot*/
wc.cbClsExtra = 0;
/*Extra memory slot*/
wc.cbWndExtra = 0;
/*Handle to our application instance*/
wc.hInstance = hInstance;
/*Window icon*/
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
/*Window cursor*/
wc.hCursor = LoadCursor(0, IDC_ARROW);
/*Background colour of the client window*/
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
/*Window menu*/
wc.lpszMenuName = 0;
/*Name of the window class structure that we are creating*/
wc.lpszClassName = "Direct3D9App";
if (!RegisterClass(&wc))
{
MessageBox(0, "RegisterClass() - FAILED!", "Error", 0);
return 0;
}
HWND hwnd = 0; /*Handle for main window*/
hwnd = CreateWindowEx( /*Create a window using our handle for our main window*/
0, /*Extended styles*/
"Direct3D9App", /*ClassName*/
"Direct3D9App", /*Window name*/
WS_OVERLAPPEDWINDOW, /*Window styles*/
CW_USEDEFAULT, /*Where the window ends up(width)*/
CW_USEDEFAULT, /*Where the window ends up(height)*/
width, /*Width of the window in pixels*/
height, /*Height of the window in pixels*/
hwnd, /*Window handle*/
NULL, /*Menu*/
hInstance, /*Our window instance handle*/
NULL); /*Long pointer to the window*/
if(!hwnd)/*If hwnd fails*/
{
MessageBox(0, "CreateWindowEx() - FAILED!", "Error", 0);
return 0;
}
ShowWindow(hwnd, SW_SHOW); /*Show the window*/
UpdateWindow(hwnd); /*Update the window*/
HRESULT hr = 0; /*A variable to check if a function works properly*/
/*Step 1, Create the IDirect3D9 object*/
IDirect3D9* d3d9 = 0;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d9)
{
MessageBox(0, "Direct3DCreate9() - FAILED!", "Error", 0);
return 0; /*Return false*/
}
/*Step 2, Check for Hardware vp(VertexProcessing)*/
D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);
int vp = 0; /*Vertex processing variable*/
if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) /*If hardware vp is supported*/
{
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; /*Create hardware VertexProcessing*/
}
else
{
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; /*Create Software Vertwx Processing*/
}
/*Step 3, Fill out the D3DPRESENT_PARAMETERS structure*/
D3DPRESENT_PARAMETERS d3dpp;
/*The backbuffer width in pixels*/
d3dpp.BackBufferWidth = width;
/*The backbuffer height in pixels*/
d3dpp.BackBufferHeight = height;
/*The pixel format of the backbuffer
eg(Alpha - 8, Red - 8, Green - 8, Blue - 8 = 32-bit pixel format)*/
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
/*How many backbuffers we want*/
d3dpp.BackBufferCount = 1;
/*The type of multisampling we want to use with the backbuffer*/
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
/*The quality level of the multisampling*/
d3dpp.MultiSampleQuality = 0;
/*Specify how the buffers in the flipping chain will be swapped*/
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
/*The window handle associated with the device*/
d3dpp.hDeviceWindow = hwnd;
/*Specify true to run in windowed mode,
false to run in fullscreen mode*/
d3dpp.Windowed = windowed;
/*Set to true to have Direct3D create and
maintain the depth/stencil buffer automatically*/
d3dpp.EnableAutoDepthStencil = true;
/*The format of the depth/stencil format
eg(24-bit depth with 8 bits reserved for the stencil buffer*/
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
/*Some additional characteristics*/
d3dpp.Flags = 0;
/*Refresh rate*/
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
/*Describes the refresh rate between
the adapter refresh rate and the rate which
IDirect3DDevice9::Present operations are completed*/
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
/*Step 4, Create the Device*/
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, /*Primary Adapter*/
deviceType, /*Device type*/
hwnd, /*Window associated with the device*/
vp, /*VertexProcessing*/
&d3dpp, /*Present parameters*/
device); /*Return the created device*/
if(FAILED(hr)) /*If creating the device failed*/
{
/*Try again using a 16-bit depth buffer*/
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, /*Primary Adapter*/
deviceType, /*Device type*/
hwnd, /*Window associated with the device*/
vp, /*VertexProcessing*/
&d3dpp, /*Present parameters*/
device); /*Return the created device*/
}
if(FAILED(hr)) /*If it failed again*/
{
d3d9->Release(); /*Done with the d3d9 object*/
MessageBox(0, "CreateDevice() - FAILED!", "Error", 0);
return 0; /*Return false*/
}
d3d9->Release(); /*Done with the d3d9 object*/
return 1; /*Return true*/
}
int d3d::EnterMsgLoop(bool (*ptr_display)(float timeDelta))
{
MSG msg; /*Message handler*/
ZeroMemory(&msg, sizeof(MSG)); /*Set everything in the message loop to zero*/
static float lastTime = (float)timeGetTime();
/*While msg doesn't = WM_QUIT(quit the program), execute the message loop*/
while(msg.message != WM_QUIT) /*Start of message loop*/
{
/*Check to see for any messages in the message queue and see if any of them need processing*/
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
/*Translate virtual-key messages into character messages*/
TranslateMessage(&msg);
/*Dispatch a message to the windows procedure*/
DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime)* 0.001f;
ptr_display(timeDelta);
lastTime = currTime;
}
}
return msg.wParam;
}
d3dInit.cpp
Code:
/*d3dInit.cpp*/
#include "d3dUtility.h"
/*Global Variable*/
IDirect3DDevice9* Device = 0;
/*Hold the Vertex buffer*/
IDirect3DVertexBuffer9* VB = 0;
/*Hold the Index Buffer*/
IDirect3DIndexBuffer9* IB = 0;
/*Define the screen resolutions*/
const int Width = 640;
const int Height = 480;
struct Vertex /*Create a new custom abstract structure called Vertex*/
{
Vertex(){}; /*Constructor*/
Vertex(float x, float y, float z) /*Overloaded Constructor which takes 3 paremeters*/
{
_x = x; /*Make _x the same as x*/
_y = y; /*Make _y the same as y*/
_z = z; /*Make _z the same as z*/
}
float _x, _y, _z; /*Declare 3 floating point variables*/
static const DWORD FVF; /*Make a FVF(Flexible Vertex Format) variable*/
};
const DWORD Vertex::FVF = D3DFVF_XYZ; /*Set the FVF flags*/
/*Framework function*/
bool Setup()
{
/*Create the Vertex Buffer*/
Device->CreateVertexBuffer(
8 * sizeof(Vertex), /*The number of bytes to allocate for the buffer*/
D3DUSAGE_WRITEONLY, /*Specifies that the application will only write to the buffer*/
Vertex::FVF, /*Flexible Vertex Format of the vertices in the vertex buffer*/
D3DPOOL_MANAGED, /*The memory pool in which the buffer is placed*/
&VB, /*Pointer to receive the Vertex buffer*/
0); /*Not used, set to zero*/
/*Create the Index Buffer*/
Device->CreateIndexBuffer(
36 * sizeof(WORD), /*The number of bytes to allocate for the buffer*/
D3DUSAGE_WRITEONLY, /*Specifies that the application will only write to the buffer*/
D3DFMT_INDEX32, /*Specifies the size of the indices. e.g(D3DFMT_INDEX32 = 32-bit indices*/
D3DPOOL_MANAGED, /*The memory pool in which the buffer is placed*/
&IB, /*Pointer to receive the Index Buffer*/
0); /*Not used, Set to zero*/
/*Make vertices an instance of Vertex*/
Vertex* vertices;
/*Lock the Vertex buffer to access it's memory*/
VB->Lock(
0, /*Offset, in bytes, from the start of the buffer to the location to begin the lock*/
0, /*Number of bytes to lock*/
(void**)&vertices, /*A pointer to the start of the locked memory, converted from Vertex** to void** */
0); /*Flags describing how the lock is done*/
/*Vertices of a unit cube*/
vertices[0] = Vertex(-1.0f, -1.0f, -1.0f); /*Lower left front corner*/
vertices[1] = Vertex(-1.0f, 1.0f, -1.0f); /*Upper left front corner*/
vertices[2] = Vertex(1.0f, 1.0f, -1.0f); /*Upper right front corner*/
vertices[3] = Vertex(1.0f, -1.0f, -1.0f); /*Lower right front corner*/
vertices[4] = Vertex(-1.0f, -1.0f, 1.0f); /*Lower left back corner*/
vertices[5] = Vertex(-1.0f, 1.0f, 1.0f); /*Upper left back corner*/
vertices[6] = Vertex(1.0f, 1.0f, 1.0f); /*Upper right back corner*/
vertices[7] = Vertex(1.0f, -1.0f, 1.0f); /*Lower right back corner*/
VB->Unlock(); /*Unlock the Vertex buffer*/
/*Define the triangles of the cube*/
WORD* indices = 0;
/*Lock the index buffer to access it's memory*/
IB->Lock(
0, /*Offset, in bytes, from the start of the buffer to the location to begin the lock*/
0, /*Number of bytes to lock*/
(void**)&indices, /*A pointer to the start of the locked memory, converted from WORD** to void** */
0); /*Flags describing how the lock is done*/
/*Front side*/
indices[0] = 0; indices[1] = 1; indices[2] = 2;
indices[3] = 0; indices[4] = 2; indices[5] = 3;
/*Back side*/
indices[6] = 4; indices[7] = 6; indices[8] = 5;
indices[9] = 4; indices[10] = 7; indices[11] = 6;
/*Left side*/
indices[12] = 4; indices[13] = 5; indices[14] = 1;
indices[15] = 4; indices[16] = 1; indices[17] = 0;
/*Right side*/
indices[18] = 3; indices[19] = 2; indices[20] = 6;
indices[21] = 3; indices[22] = 6; indices[23] = 7;
/*Top*/
indices[24] = 1; indices[25] = 5; indices[26] = 6;
indices[27] = 1; indices[28] = 6; indices[29] = 2;
/*Bottom*/
indices[30] = 4; indices[31] = 0; indices[32] = 3;
indices[33] = 4; indices[34] = 3; indices[35] = 7;
IB->Unlock(); /*Unlock the Index buffer*/
/*Position and aim the camera*/
D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX V;
/*Calculate the view space transformation*/
D3DXMatrixLookAtLH(
&V, /*Pointer to recieve resulting in view matrix*/
&position, /*Position of the camera in the world*/
&target, /*The point that the camera is looking at in the world*/
&up); /*The world's up vector - (0, 1, 0)*/
/*Set the view space transformation*/
Device->SetTransform(D3DTS_VIEW, &V);
/*Calculate the Projection transformation*/
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj, /*Returns projection matrix*/
D3DX_PI * 0.5f, /*Vertical field of view angle in radians(90 degrees)*/
(float)Width / (float)Height, /*Aspect ratio = width/height*/
1.0f, /*Distance to near plane*/
1000.0f); /*Distance to far plane*/
/*Set the Projection matrix*/
Device->SetTransform(D3DTS_PROJECTION, &proj);
/*Set the Render state*/
Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
return 1; /*Return true*/
}
/*Framework Function*/
void CleanUp()
{
/*Release the vertex and index buffers with our template Release function*/
d3d::Release<IDirect3DVertexBuffer9*>(VB);
d3d::Release<IDirect3DIndexBuffer9*>(IB);
}
bool Display(float timeDelta)
{
if(Device) /*If we have a valid device*/
{
/*Declare variables that will spin the cube*/
D3DXMATRIX Rx, Ry;
/*Rotate the cube on a 45 degree angle on the x-axis*/
D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);
/*Increment the y-rotation angle at each frame*/
static float y = 0.0f;
D3DXMatrixRotationY(&Ry, y);
y += timeDelta;
/*Reset the angle to zero when it reaches 2*PI*/
if(y >= 6.28f)
y = 0.0f;
/*Combine rotations*/
D3DMATRIX p = Rx * Ry;
/*Set the World view matrix*/
Device->SetTransform(D3DTS_WORLD, &p);
/*Draw the scene*/
Device->Clear(
0, /*Number of rectangles in the pRects array*/
0, /*An array of screen rectangles to clear*/
/*Specify which surfaces to clear
eg(D3DCLEAR_TARGET = clear the backbuffer,
D3DCLEAR_ZBUFFER = clear the depth buffer)*/
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0xFFFFFFFF, /*Clear the colour to black*/
1.0f, /*The value of which we want to set our z buffer to*/
0); /*The value of which we want to set our stencil buffer to*/
/*Call the BeginScene and EndScene methods to start drawing the scene*/
Device->BeginScene();
Device->SetStreamSource(
0, /*Identifies the Stream scource to which we are hooking the vertex buffer*/
VB, /*A pointer to a Vertex buffer that we want to hook to the stream*/
0, /*An offset from the start of the stream, measure in bytes*/
sizeof(Vertex)); /*Size in bytes of each element in the Vertex buffer*/
/*Set the index buffer that we are using with our drawing operations*/
Device->SetIndices(IB);
/*Set the Vertex format that we are using in our drawing operations*/
Device->SetFVF(Vertex::FVF);
/*Draw the object*/
Device->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0,
0,
8,
0,
12);
Device->EndScene();
/*Swap the back and front buffers*/
Device->Present(0, 0, 0, 0);
}
return true;
}
/*windows procedure defenition*/
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if( wParam == VK_ESCAPE)
DestroyWindow(hwnd);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
/*WinMain definition*/
int WINAPI WinMain(
HINSTANCE hInstance, /*Handle to the current application instance*/
HINSTANCE hPrevInstance, /*Not used in 32-bit Win32 programming and is 0*/
LPSTR cmdLine, /*Command line argument string used to run the program*/
int cmdShow) /*Specifies how the application window should be displayed*/
{
if(!d3d::InitD3D( /*If InitD3D fails*/
hInstance, /*Application instance*/
450, /*Application width*/
375, /*Application height*/
true, /*Windowed?*/
D3DDEVTYPE_HAL, /*DeviceType*/
&Device)) /*Device*/
{
MessageBox(0, "InitD3D() - FAILED!", "Error", 0);
return 0;
}
if(!Setup()) /*If setup fails*/
{
MessageBox(0, "Setup() - FAILED!", "Error", 0);
return 0;
}
d3d::EnterMsgLoop(Display); /*Pump the message loop*/
CleanUp(); /*CleanUp*/
Device->Release(); /*Done with the device*/
return 0; /*Return false*/
}
Thanks in advance.... Oh yes, and any of you who can remember helping me with the classes thing, it didn't work, it WOULDN'T work!!! Thanks anyways though.
-
Your cube has no color, and I think DX uses white for the default color. Your back buffer is getting cleared to the color white ( even though the comment says black.. black == 0x0 ). So, I think your cube is there, you just can't see white on white.
-
It's in wireframe mode... And i cleared the back buffer colour to black and it still didn't work...
-
Let there be light.
I don't see any code that either sets a color per vertex or instead allows Direct3D to calc the light per vertex via lighting calculations.
With no light there is no picture.