Basic help with DirectX9

Started by
3 comments, last by Evil Steve 12 years, 1 month ago
Hello gamedev.net members. I have here a tutorial (slightly modified) I got online which I'm using to reverse engineer my way through windows api/direct x 9. The tutorial creates a flat terrain-like plane of triangles. I'm just trying to get a nice base rendering system down so I can move to game systems as fast as possible (the fun stuff). It compiles and runs fine I just have a few questions/problems I need answered.
Here are my questions:

A) I want to get this to run in fullscreen. I know there's a multitude of changes I have to make across the code to do this. Can someone point these out to me?

B) This current system does not allow for the adding of vertices/indices during the game loop. Would this be as simple as moving my FillVertices, FillIndices calls, and buffer>Release()'s into the loop, or would there be another way to go about that. Seems like that might get hard on the gpu.

C) Are any of the functions used here severely outdated in terms of directx9?


#include<windows.h>
#include<d3d9.h>
#include<d3dx9.h>

#define WIDTH 64
#define HEIGHT 64

struct OURCUSTOMVERTEX
{
float x,y,z;
DWORD color;
};

int int_AppRunning = 1;

LRESULT CALLBACK OurWindowProcedure(HWND han_Wind,UINT uint_Message,WPARAM parameter1,LPARAM parameter2)
{
switch(uint_Message)
{
case WM_KEYDOWN:
{
int_AppRunning = 0;
break;
}
break;
}

return DefWindowProc(han_Wind,uint_Message,parameter1,parameter2);
}

HWND NewWindow(LPCTSTR str_Title,int int_XPos, int int_YPos, int int_Width, int int_Height)
{
WNDCLASSEX wnd_Structure;

wnd_Structure.cbSize = sizeof(WNDCLASSEX);
wnd_Structure.style = CS_HREDRAW | CS_VREDRAW;
wnd_Structure.lpfnWndProc = OurWindowProcedure;
wnd_Structure.cbClsExtra = 0;
wnd_Structure.cbWndExtra = 0;
wnd_Structure.hInstance = GetModuleHandle(NULL);
wnd_Structure.hIcon = NULL;
wnd_Structure.hCursor = NULL;
wnd_Structure.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
wnd_Structure.lpszMenuName = NULL;
wnd_Structure.lpszClassName = "WindowClassName";
wnd_Structure.hIconSm = LoadIcon(NULL,IDI_APPLICATION);

RegisterClassEx(&wnd_Structure);

return CreateWindowEx(WS_EX_CONTROLPARENT, "WindowClassName", str_Title, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, int_XPos, int_YPos, int_Width, int_Height, NULL, NULL, GetModuleHandle(NULL), NULL);
}

LPDIRECT3DDEVICE9 InitializeDevice(HWND han_WindowToBindTo)
{
LPDIRECT3D9 p_dx_Object;
LPDIRECT3DDEVICE9 p_dx_Device;

p_dx_Object = Direct3DCreate9(D3D_SDK_VERSION);
if (p_dx_Object == NULL)
{
MessageBox(han_WindowToBindTo,"DirectX Runtime library not installed!","InitializeDevice()",MB_OK);
}

D3DPRESENT_PARAMETERS dx_PresParams;
ZeroMemory( &dx_PresParams, sizeof(dx_PresParams) );
dx_PresParams.Windowed = TRUE;
dx_PresParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
dx_PresParams.BackBufferFormat = D3DFMT_UNKNOWN;

if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, han_WindowToBindTo, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device)))
{
if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, han_WindowToBindTo, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device)))
{
MessageBox(han_WindowToBindTo,"Failed to create even the reference device!","InitializeDevice()",MB_OK);
}
}

p_dx_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
p_dx_Device->SetRenderState(D3DRS_LIGHTING,false);
p_dx_Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);

return p_dx_Device;
}

void DrawScene(LPDIRECT3DDEVICE9 p_dx_Device, LPDIRECT3DVERTEXBUFFER9 p_dx_VertexBuffer, LPDIRECT3DINDEXBUFFER9 p_dx_IndexBuffer)
{
p_dx_Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
p_dx_Device->BeginScene();

p_dx_Device->SetStreamSource( 0, p_dx_VertexBuffer, 0, sizeof(OURCUSTOMVERTEX) );
p_dx_Device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE);
p_dx_Device->SetIndices(p_dx_IndexBuffer);

D3DXMATRIX m_Translation;
D3DXMatrixTranslation(&m_Translation,32,-32,0);
p_dx_Device->SetTransform(D3DTS_WORLD, & m_Translation);

p_dx_Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,WIDTH*HEIGHT,0,(WIDTH-1)*(HEIGHT-1)*2);

p_dx_Device->EndScene();
p_dx_Device->Present(NULL, NULL, NULL, NULL);
}

LPDIRECT3DVERTEXBUFFER9 FillVertices(HWND han_Window, LPDIRECT3DDEVICE9 p_dx_Device)
{
LPDIRECT3DVERTEXBUFFER9 p_dx_VertexBuffer;
OURCUSTOMVERTEX cv_Vertices[WIDTH*HEIGHT];

for (int x=0;x< WIDTH;x++) {
for (int y=0; y< HEIGHT;y++) {
cv_Vertices[y*WIDTH + x].x = -x;
cv_Vertices[y*WIDTH + x].y = y;
cv_Vertices[y*WIDTH + x].z = 0;
cv_Vertices[y*WIDTH + x].color = 0xffffffff;
}
}

if (FAILED(p_dx_Device->CreateVertexBuffer(WIDTH*HEIGHT*sizeof(OURCUSTOMVERTEX), 0, D3DFVF_XYZ|D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &p_dx_VertexBuffer, NULL)))
{ MessageBox(han_Window,"Error while creating VertexBuffer","FillVertices()",MB_OK);
}

VOID* p_Vertices;
if (FAILED(p_dx_VertexBuffer->Lock(0, WIDTH*HEIGHT*sizeof(OURCUSTOMVERTEX), (void**)&p_Vertices, 0)))
{
MessageBox(han_Window,"Error trying to lock","FillVertices()",MB_OK);
}else{
memcpy(p_Vertices, cv_Vertices, WIDTH*HEIGHT*sizeof(OURCUSTOMVERTEX));
p_dx_VertexBuffer->Unlock();
}

return p_dx_VertexBuffer;
}

LPDIRECT3DINDEXBUFFER9 FillIndices(HWND han_Window, LPDIRECT3DDEVICE9 p_dx_Device)
{
LPDIRECT3DINDEXBUFFER9 p_dx_IndexBuffer;
short s_Indices[(WIDTH-1)*(HEIGHT-1)*6];
for (int x=0;x< WIDTH-1;x++) {
for (int y=0; y< HEIGHT-1;y++) {
s_Indices[(x+y*(WIDTH-1))*6+2] = x+y*WIDTH;
s_Indices[(x+y*(WIDTH-1))*6+1] = (x+1)+y*WIDTH;
s_Indices[(x+y*(WIDTH-1))*6] = (x+1)+(y+1)*WIDTH;
s_Indices[(x+y*(WIDTH-1))*6+3] = (x+1)+(y+1)*WIDTH;
s_Indices[(x+y*(WIDTH-1))*6+4] = x+y*WIDTH;
s_Indices[(x+y*(WIDTH-1))*6+5] = x+(y+1)*WIDTH;
}
}
if (FAILED(p_dx_Device->CreateIndexBuffer((WIDTH-1)*(HEIGHT-1)*6*sizeof(short),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&p_dx_IndexBuffer,NULL)))
{
MessageBox(han_Window,"Error while creating IndexBuffer","FillIndices()",MB_OK);
}
VOID* p_Indices;
if (FAILED(p_dx_IndexBuffer->Lock(0, (WIDTH-1)*(HEIGHT-1)*6*sizeof(short), (void**)&p_Indices, 0)))
{
MessageBox(han_Window,"Error trying to lock","FillIndices()",MB_OK);
}else{
memcpy(p_Indices, s_Indices, (WIDTH-1)*(HEIGHT-1)*6*sizeof(short));
p_dx_IndexBuffer->Unlock();
}
return p_dx_IndexBuffer;
}
void SetUpCamera(LPDIRECT3DDEVICE9 p_dx_Device)
{
D3DXVECTOR3 m_EyePos(-40, 0, 50);
D3DXVECTOR3 m_TargetPos(-5, 0, 0);
D3DXVECTOR3 m_UpVector(1, 0, 0);
D3DXMATRIXA16 m_View;
D3DXMatrixLookAtLH(&m_View, &m_EyePos, &m_TargetPos, &m_UpVector);
p_dx_Device->SetTransform(D3DTS_VIEW, &m_View);

D3DXMATRIX m_Projection;
D3DXMatrixPerspectiveFovLH(&m_Projection, D3DX_PI/4, 500/500, 1, 100);
p_dx_Device->SetTransform(D3DTS_PROJECTION, &m_Projection);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow)
{
MSG msg_Message;

HWND han_Window = NewWindow("DirectX C++ Tutorial",100,100,500,500);
LPDIRECT3DDEVICE9 p_Device = InitializeDevice(han_Window);
LPDIRECT3DVERTEXBUFFER9 p_dx_VB = FillVertices(han_Window, p_Device);
LPDIRECT3DINDEXBUFFER9 p_dx_IB = FillIndices(han_Window, p_Device);
SetUpCamera(p_Device);

while(int_AppRunning)
{
if(PeekMessage(&msg_Message,han_Window,0,0,PM_REMOVE))
{
DispatchMessage(&msg_Message);
}
DrawScene(p_Device, p_dx_VB, p_dx_IB);
}

p_dx_VB->Release();
p_dx_IB->Release();
p_Device->Release();
DestroyWindow(han_Window);

return 0;
}
Advertisement
A) The easiest and safest way to get fullscreen is to just maximize the window and remove it's border. Some people think that it is not real fullscreen but it gives an advantage by allowing the user to press the windows button and respond to an instant message without closing the game.

B) I don't know exactly how it works in Direct3D 9 but I just create a new buffer for geometry when something has changed since the vertex shader can handle my performance critical animations.

C) If you are starting to learn DirectX then I recomend starting with DirectX 10/11 because the fixed pipeline that you are using has been removed. Instead, you write custom shaders for everything you see.
A)
The real fullscreen mode is about 10% faster, than a frameless window.
You would learn about implementing it in DirectX SDK or any book.

B)
You would consider calling DrawIndexedPrimitiveUP.
http://msdn.microsof...0(v=vs.85).aspx
Yeah, there's basically no point in learning DirectX 9 anymore, so actually the whole tutorial is outdated.

Yeah, there's basically no point in learning DirectX 9 anymore, so actually the whole tutorial is outdated.
I'd disagree. If you still want to target Windows XP, then DirectX 9 (or below) is your only option, and if you were to do X360 development (And indeed several other consoles on the market at the moment), it's essentially DirectX 9, and a lot of techniques are transferrable from DX9 to DX10/11 (So long as you avoid the fixed function pipeline like the plague). If you're just starting out, then it might be a better idea to start with DX11, but I wouldn't say that there was no point in learning DX9.

This topic is closed to new replies.

Advertisement