Skip to main content
GameDev.net gamedev.net
🔒 Locked

Direct3D Begininner help

Started by NucleA Apr 3, 2011 at 2:50 PM 4 replies 1.1k views
Original Post
NucleA
NucleA
Below is my code, but when i run it, my triangle is not displayed, only a black screen! can any1 help please?


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

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

#define WIN_CLASS "Direct3D Primitives"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)

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

//Global Definitions
IDirect3D9* d3d=NULL;
IDirect3DDevice9* d3d_dev=NULL;
IDirect3DVertexBuffer9* d3d_triangleBuffer = NULL;

//Function Prototypes
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
bool init(HWND);
void render(void);
void clean(void);
void initMatrices(void);
void initVertices(void);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wincl={0};
HWND hwnd=NULL;
MSG msg;

wincl.cbSize = sizeof(WNDCLASSEX);
wincl.style = CS_HREDRAW | CS_VREDRAW;
wincl.lpfnWndProc = WinProc;
wincl.hInstance = hInstance;
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszClassName = WIN_CLASS;

if(!RegisterClassEx(&wincl))
return EXIT_FAILURE;

hwnd = CreateWindowEx(
NULL, WIN_CLASS, WIN_CLASS, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);

if(hwnd == NULL)
return EXIT_FAILURE;

if(!init(hwnd))
return EXIT_FAILURE;

ShowWindow(hwnd, nCmdShow);

while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
//Render Scene
render();
}
}
clean();
return msg.wParam;
}

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

bool init(HWND hwnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3d_param={0};

d3d_param.Windowed = TRUE;
d3d_param.hDeviceWindow = hwnd;
d3d_param.SwapEffect = D3DSWAPEFFECT_DISCARD;

if(FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3d_param, &d3d_dev)))
{
return false;
}

initVertices();

return true;
}

void initVertices(void)
{
CUSTOMVERTEX triangle[] =
{
{150.0f, 50.0f, 0.5f, D3DCOLOR_XRGB(255, 0, 255)},
{250.0f, 250.0f, 0.5f, D3DCOLOR_XRGB(0, 255, 0)},
{50.0f, 250.0f, 0.5f, D3DCOLOR_XRGB(255, 255, 0)}
};

if(FAILED(d3d_dev->CreateVertexBuffer(sizeof(CUSTOMVERTEX)*3, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_SYSTEMMEM, &d3d_triangleBuffer, NULL)))
MessageBox(NULL, "Create Vertex Buffer failed!", "Info", MB_OK);

void* tVertices = NULL;

if(FAILED(d3d_triangleBuffer->Lock(0, sizeof(triangle), &tVertices, 0)))
MessageBox(NULL, "Locking Vertex Buffer failed!", "Info", MB_OK);
memcpy(tVertices, triangle, sizeof(triangle));
d3d_triangleBuffer->Unlock();

}

void render()
{
d3d_dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

initMatrices();

d3d_dev->BeginScene();
d3d_dev->SetStreamSource(0, d3d_triangleBuffer, 0, sizeof(CUSTOMVERTEX));
d3d_dev->SetFVF(D3DFVF_CUSTOMVERTEX);
d3d_dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
d3d_dev->EndScene();

d3d_dev->Present(NULL, NULL, NULL, NULL);
}

void initMatrices(void)
{
//World Transformation
D3DXMATRIX TransformMatrix;
D3DXMatrixIdentity(&TransformMatrix);
D3DXMatrixTranslation(&TransformMatrix, 0.0f, 0.0f, 0.0f);

d3d_dev->SetTransform(D3DTS_WORLD, &TransformMatrix);

//View Transformation
D3DXMATRIX ViewMatrix;
D3DXVECTOR3 eye(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 lookAt(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

D3DXMatrixLookAtLH(&ViewMatrix, &eye, &lookAt, &up);
d3d_dev->SetTransform(D3DTS_VIEW, &ViewMatrix);

//Projection Transformation
D3DXMATRIX projection;
float fov = D3DX_PI/4;
float aspect = SCREEN_WIDTH/SCREEN_HEIGHT;

D3DXMatrixPerspectiveFovLH(&projection, fov, aspect, 1.0f, 500.0f);
d3d_dev->SetTransform(D3DTS_PROJECTION, &projection);

}

void clean()
{
if(d3d_triangleBuffer)
d3d_triangleBuffer->Release();

if(d3d_dev)
d3d_dev->Release();

if(d3d)
d3d->Release();
}
Tosh777
Tosh777
I think you are not transforming the vertices of the triangle by the view and projection matrix, so they can be in the same space and therefore rendered.
TomKQT
TomKQT
During such initial testing I highly recomment to clear your backbuffer to some general color, not black. I mean something like this:
d3d_dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(150, 50, 200), 1.0f, 0);

The reason is that with a black screen you can never tell a difference between these two cases (especialy in your situation they are both very likely to happen)
- is there nothing rendered?
- is the triangle rendered properly, but in a solid black color (and thus invisible on the black background)?

White is also not perfect, although still better than black.


[s]Btw, you don't seem to be setting any lights and enabling lighting, that's why your triangle can be rendered solid black.

[/s]Edit: I didn't notice you were using vertices with color. In this case you don't need lights nor materials, but AFAIK you should disable lighting (?).
d3d_dev->SetRenderState(D3DRS_LIGHTING, FALSE);

Anyway, the above (backbuffer color) still stays valid.
TomKQT
TomKQT
And after looking even better at your code I think I found the problem (maybe it is not the only problem, but it definitely is one of them).

Look at the definition of your triangle and try to draw it on a piece of paper. The triangle is quite huge (cca 200 x 200 units) and situated in the 1st quadrant (+x, +y).
{150.0f, 50.0f, 0.5f, D3DCOLOR_XRGB(255, 0, 255)},
{250.0f, 250.0f, 0.5f, D3DCOLOR_XRGB(0, 255, 0)},
{50.0f, 250.0f, 0.5f, D3DCOLOR_XRGB(255, 255, 0)}
Your camera is looking in the direction of the +z axis and is situated 5 units on the -z axis. That's alright, but the camera won't be able to see the triangle, because the triangle is too big and located too far right (+x) and top (+y) for the camera!

Try to either make the triangle much smaller (at least 100times smaller) or increase the -5 number (well, decrease in fact because it's a negative number) in your VIEW matrix definition to move the camera further from the triangle.
Tosh777
Tosh777
So here is the full working code.


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

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

#define WIN_CLASS "Direct3D Primitives"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)

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

//Global Definitions
IDirect3D9* d3d=NULL;
IDirect3DDevice9* d3d_dev=NULL;
IDirect3DVertexBuffer9* d3d_triangleBuffer = NULL;

//Function Prototypes
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
bool init(HWND);
void render(void);
void clean(void);
void initMatrices(void);
void initVertices(void);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wincl={0};
HWND hwnd=NULL;
MSG msg;

wincl.cbSize = sizeof(WNDCLASSEX);
wincl.style = CS_HREDRAW | CS_VREDRAW;
wincl.lpfnWndProc = WinProc;
wincl.hInstance = hInstance;
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszClassName = WIN_CLASS;

if(!RegisterClassEx(&wincl))
return EXIT_FAILURE;

hwnd = CreateWindowEx(
NULL, WIN_CLASS, WIN_CLASS, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);

if(hwnd == NULL)
return EXIT_FAILURE;

if(!init(hwnd))
return EXIT_FAILURE;

ShowWindow(hwnd, nCmdShow);

while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
//Render Scene
render();
}
}
clean();
return msg.wParam;
}

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

bool init(HWND hwnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3d_param;

ZeroMemory(&d3d_param, sizeof(d3d_param));

d3d_param.Windowed = TRUE;
d3d_param.hDeviceWindow = hwnd;
d3d_param.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3d_param.BackBufferHeight = SCREEN_HEIGHT;
d3d_param.BackBufferWidth = SCREEN_WIDTH;

if(FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3d_param, &d3d_dev)))
{
return false;
}

initVertices();

d3d_dev->SetRenderState(D3DRS_LIGHTING, FALSE);

return true;
}

void initVertices(void)
{
CUSTOMVERTEX triangle[] =
{
{0.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255)},
{0.5f, 1.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0)},
{1.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0)}
};

if(FAILED(d3d_dev->CreateVertexBuffer(sizeof(CUSTOMVERTEX)*3, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_SYSTEMMEM, &d3d_triangleBuffer, NULL)))
MessageBox(NULL, "Create Vertex Buffer failed!", "Info", MB_OK);

void* tVertices = NULL;

if(FAILED(d3d_triangleBuffer->Lock(0, sizeof(triangle), &tVertices, 0)))
MessageBox(NULL, "Locking Vertex Buffer failed!", "Info", MB_OK);
memcpy(tVertices, triangle, sizeof(triangle));
d3d_triangleBuffer->Unlock();

}

void render()
{
d3d_dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

initMatrices();

d3d_dev->BeginScene();

d3d_dev->SetFVF(D3DFVF_CUSTOMVERTEX);

d3d_dev->SetStreamSource(0, d3d_triangleBuffer, 0, sizeof(CUSTOMVERTEX));

d3d_dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
d3d_dev->EndScene();

d3d_dev->Present(NULL, NULL, NULL, NULL);
}

void initMatrices(void)
{
//World Transformation
D3DXMATRIX TransformMatrix;
D3DXMatrixIdentity(&TransformMatrix);
D3DXMatrixTranslation(&TransformMatrix, 0.0f, 0.0f, 0.0f);



//View Transformation
D3DXMATRIX ViewMatrix;
D3DXVECTOR3 eye(0.0f, 0.0f, -1.0);
D3DXVECTOR3 lookAt(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

D3DXMatrixLookAtLH(&ViewMatrix, &eye, &lookAt, &up);
d3d_dev->SetTransform(D3DTS_VIEW, &ViewMatrix);

//Projection Transformation
D3DXMATRIX projection;
float fov = D3DX_PI/4;
float aspect = SCREEN_WIDTH/SCREEN_HEIGHT;

D3DXMatrixPerspectiveFovLH(&projection, fov, aspect, 0.1f, 10000.0f);
d3d_dev->SetTransform(D3DTS_PROJECTION, &projection);

d3d_dev->SetTransform(D3DTS_WORLD, &(TransformMatrix*ViewMatrix*projection));

}

void clean()
{
if(d3d_triangleBuffer)
d3d_triangleBuffer->Release();

if(d3d_dev)
d3d_dev->Release();

if(d3d)
d3d->Release();
}


So:
1. You need to disable the lights. Fucks you up.
2. You need to lower the dimensions of the triangle as Tom said.
3. Not mandatory, but will be good to pass the dimension of the back bufffer to present parameters when creating device. BackBufferWidht = screen_width; BackBufferHeight = screen_height;
ENd.
NucleA
NucleA
Thanks you so much guys..am still a beginner with directX..

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.