Drawing a Texture

Started by
37 comments, last by falcon93 12 years, 9 months ago
Hi everyone!

Well, I'm stuck. I've tried learning the basics in DirectX 11 programming for about 3 weeks now, but so far, the only thing I've actually managed to do is a window. I've followed plenty of tutorials about initializing DirectX and then draw a picture on my window, but every try has just resulted in errors or crashs. I've rewritten my code so many times now that I've lost count... I've been programming in C# and XNA beore, but I never realised that it would be this huge difference between them. I would be so happy if someone could actually help me out from this swamp :(

As said, I've managed to write the code for a 800x600 window that successfully shows up. My goal now is just to draw i simple image in that window. I know that I have to somehow initialize DirectX and then create a sort of variable which will hold my texture, load the texture and finally draw it. I know that it isn't just that easy, for example I have to somehow create a square from 2 sets of triangles. The problem is that the tutorials I've found is just like a big shock to me, and they doesn't even work. I mean, 300-400 lines of code shouldn't be necessary for just drawing a simple image, even if it's C++ and DirectX, right?

I've posted my current code below. Could anyone please tell me, with maybe an example, the most simple way of drawing an image on my window? All help would be really nice, but examples and even step-by-step help would be even more helpfull :wink:

Please help,
Falcon93

<BR>#include <Windows.h><BR><BR><BR>LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);<BR><BR><BR>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)<BR>{<BR>WNDCLASSEX wc;<BR>HWND hWnd;<BR>MSG msg;<BR><BR>ZeroMemory(&wc, sizeof(WNDCLASSEX));<BR><BR>wc.cbSize = sizeof(WNDCLASSEX);<BR>wc.hbrBackground = (HBRUSH)COLOR_WINDOW;<BR>wc.hCursor = LoadCursor(NULL, IDC_ARROW);<BR>wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);<BR>wc.hInstance = hInstance;<BR>wc.lpfnWndProc = WindowProc;<BR>wc.lpszClassName = L"MFGCLASS";<BR>wc.style = CS_VREDRAW | CS_HREDRAW;<BR><BR>RegisterClassEx(&wc);<BR><BR>hWnd = CreateWindowEx(NULL, L"MFGCLASS", L"MyFirstGame", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, hInstance, NULL);<BR><BR>ShowWindow(hWnd, nCmdShow);<BR><BR>while(true)<BR>{<BR> if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))<BR> {<BR> TranslateMessage(&msg);<BR> DispatchMessage(&msg);<BR><BR> if (msg.message == WM_QUIT) break;<BR> }<BR><BR> else<BR> {<BR> }<BR>}<BR><BR>return msg.wParam;<BR>}<BR><BR><BR>LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)<BR>{<BR>switch(message)<BR>{<BR> case WM_DESTROY: PostQuitMessage(0); return 0;<BR>}<BR><BR>return DefWindowProc(hWnd, message, wParam, lParam);<BR>}<BR>
Advertisement
You should get a template code file for a basic DX program. There should be one that displays a triangle somewhere. Download it and use it for your starting point. None of the code you posted is actually DX and is just hard to understand windows code.

Also, get a damn book. Grabbing parts of information from random people is not going to give you a clear step by step goal to a final understanding. A book will say draw a triangle, ok next chapter you should know how to draw triangle, add an image on it, cool you know this now do this. books.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

Its kind of a loaded question =p

Using just DirectX11 there isn't really going to be a "simple" way of drawing your texture to your screen.

I personally cannot comment on specifics of DX11, but in DX9 you need to do the following to get a simple image to draw onto the screen using 3d as a 2d render (3d is a lot more complex)

- Get your vertex format setup
- Determine hardware capabilities
- Create your device
- Create vertex buffer
- Load a texture from file with D3DXCreateTextureFromFileEx
- BeginScene()
- Lock your vertex buffer
- Setup your vertices
- Unlock your vertex buffer
- Set your texture
- Draw your primitives
- EndScene()
- Present()

Its quite abit of setup and it took me awhile to get it working, many things could have changed with DX11.
Also keep in mind that this is setting up Dx9 to render as a 2d render in 3d so it may not apply to use but its a good example of what is involved.

Articles like this one helped me alot:
http://www.gamedev.net/page/resources/_/reference/programming/directx/directx-graphics/2d-rendering-in-directx-8-r1434
Ok, so I've jumped back two stages and today I tried creating a triangle out of three vartices with DX9 instead. However, now I've discovered a probelm that isn't related to programming, and I think that this is one thing that may have messed up my work before. The problem is between my two computers, my laptop and my desktop.

Yesterday when I just wrote the code for the window, it worked perfectly and then I worked on my desktop. However, today I continued my work on the laptop, and followed this tutorial: http://www.directxtu...asics/dx9B.aspx

I successfully created that colored triangle on my laptop, and built the program without any problems. When I later was going to continue the work on my desktop, I couldn't build the program anymore. It still works on my laptop, but not on my desktop. The errors I get on my desktop is:


1>Main.obj : error LNK2019:
unresolved external symbol _Direct3DCreate9@4 referenced in function "void
__cdecl initD3D(struct HWND__*)" (initD3D@@YAXPAUHWND__@@@Z)




error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced in
function "void __cdecl initD3D(struct HWND__ *)"
(?initD3D@@YAXPAUHWND__@@@Z) C:\Users\Simon
Blom\Desktop\MyFirstGame\MyFirstGame\Main.obj




error LNK1120: 1 unresolved externals C:\Users\Simon
Blom\Desktop\MyFirstGame\Debug\MyFirstGame.exe



Please help me, what is wrong? I have installed the DirectX SDK (June 2010) on both computers and I've set up the directories the same on both computers aswell. What is wrong? :(
I am unfamiliar with building things with PYGame, but it looks like your library was not included on the machine spitting the errors
is visual studio you would need to tell it to link d3d9.lib d3dx9.lib

I am thinking thats the problem you are running into.
The errors on my desktop computer has been solved, stupid me :wink: My laptop runs x86 Windows 7, while my desktop runs x64 Windows 7. Due to this, I thought that I could use the x64 library file on my desktop, instead for the x86 library file I used on my laptop. That was the problem. I changed the Library Directories path to:
Microsoft DirectX SDK (June 2012)\Lib\x86 and now it works.

Ok, so back to the programming. I've followed a tutorial (DirectX 9) and managed to initialize DirectX, creating a triangle from 3 vertices and color it. However the tutorial then justs goes stright into 3D programming instead of telling how to create a quad and give it a texture. I've pasted my new code below, and I think that I've now completed most of the steps you gave me Yewbie. How will I now create a quad and assign a texture to it?



#include <Windows.h>
#include <d3d9.h>


#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600


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


LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 v_buffer;


void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D(void);
void init_graphics(void);


struct CUSTOMVERTEX { float X, Y, Z, RHW; DWORD COLOR; };
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = L"MFGCLASS";
wc.style = CS_VREDRAW | CS_HREDRAW;

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL, L"MFGCLASS", L"MyFirstGame", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);

initD3D(hWnd);

while(true)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

if (msg.message == WM_QUIT) break;

render_frame();
}

cleanD3D();

return msg.wParam;
}


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY: PostQuitMessage(0); return 0; break;
}

return DefWindowProc(hWnd, message, wParam, lParam);
}


void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));

d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;

d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

init_graphics();
}


void render_frame(void)
{
d3ddev->Clear(9, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

d3ddev->BeginScene();

d3ddev->SetFVF(CUSTOMFVF);

d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));

d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

d3ddev->EndScene();

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


void cleanD3D(void)
{
v_buffer->Release();
d3ddev->Release();
d3d->Release();
}


void init_graphics(void)
{
CUSTOMVERTEX vertices[] =
{
{ 400.0f, 62.5f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 650.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ 150.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
};

d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL);

VOID* pVoid;

v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
}

The errors on my desktop computer has been solved, stupid me :wink: My laptop runs x86 Windows 7, while my desktop runs x64 Windows 7. Due to this, I thought that I could use the x64 library file on my desktop, instead for the x86 library file I used on my laptop. That was the problem. I changed the Library Directories path to:
Microsoft DirectX SDK (June 2012)\Lib\x86 and now it works.

Ok, so back to the programming. I've followed a tutorial (DirectX 9) and managed to initialize DirectX, creating a triangle from 3 vertices and color it. However the tutorial then justs goes stright into 3D programming instead of telling how to create a quad and give it a texture. I've pasted my new code below, and I think that I've now completed most of the steps you gave me Yewbie. How will I now create a quad and assign a texture to it?



#include <Windows.h>
#include <d3d9.h>


#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600


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


LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 v_buffer;


void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D(void);
void init_graphics(void);


struct CUSTOMVERTEX { float X, Y, Z, RHW; DWORD COLOR; };
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = L"MFGCLASS";
wc.style = CS_VREDRAW | CS_HREDRAW;

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL, L"MFGCLASS", L"MyFirstGame", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);

initD3D(hWnd);

while(true)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

if (msg.message == WM_QUIT) break;

render_frame();
}

cleanD3D();

return msg.wParam;
}


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY: PostQuitMessage(0); return 0; break;
}

return DefWindowProc(hWnd, message, wParam, lParam);
}


void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));

d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;

d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

init_graphics();
}


void render_frame(void)
{
d3ddev->Clear(9, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

d3ddev->BeginScene();

d3ddev->SetFVF(CUSTOMFVF);

d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));

d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

d3ddev->EndScene();

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


void cleanD3D(void)
{
v_buffer->Release();
d3ddev->Release();
d3d->Release();
}


void init_graphics(void)
{
CUSTOMVERTEX vertices[] =
{
{ 400.0f, 62.5f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 650.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ 150.0f, 500.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
};

d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL);

VOID* pVoid;

v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
}

I use the following for my custom vertex format:

//Custom vertex format
const DWORD D3DFVF_TLVERTEX = D3DFVF_XYZRHW| D3DFVF_DIFFUSE | D3DFVF_TEX1;
//Custom vertex
struct TLVERTEX
{
float x;
float y;
float z;
float rhw;
D3DCOLOR colour;
float u;
float v;
};


And something like this will make a square:

int x = 50;
int y = 50;
vertexBuffer->Lock(0, 0, (void **)&vertices, NULL);//Lock the vertex buffer
TLVERTEX* vertices; //my vertices
vertices[0].colour = D3DCOLOR_ARGB (255,255,255,255);
vertices[0].x = x;
vertices[0].y = y;
vertices[0].z = 0.0f;
vertices[0].rhw = 1.0f;
vertices[0].u = 0.0f;//1 - 0
vertices[0].v = 0.0f;//1 - 0

vertices[1].colour = D3DCOLOR_ARGB (255,255,255,255);
vertices[1].x = x + 64;
vertices[1].y = y;
vertices[1].z = 0.0f;
vertices[1].rhw = 1.0f;
vertices[1].u = 1.0f;//0 - 1
vertices[1].v = 0.0f;//0 - 0

vertices[2].colour = D3DCOLOR_ARGB (255,255,255,255);
vertices[2].x = x + 64;
vertices[2].y = y + 64;
vertices[2].z = 0.0f;
vertices[2].rhw = 1.0f;
vertices[2].u = 1.0f;//0 - 1
vertices[2].v = 1.0f;//0 - 0

vertices[3].colour = D3DCOLOR_ARGB (255,255,255,255);
vertices[3].x = x;
vertices[3].y = y + 64;
vertices[3].z = 0.0f;
vertices[3].rhw = 1.0f;
vertices[3].u = 0.0f;//0 - 1
vertices[3].v = 1.0f;//0 - 0
vertexBuffer->Unlock();//Unlock the vertex buffer

d3dDevice->SetTexture ( 0, MyTexture );
d3dDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 0, 2);


MyTexture can be obtained via



IDirect3DTexture9 *d3dTexture;
D3DCOLOR colorkey = 0xFFFF00FF;
colorkey = D3DCOLOR_XRGB(0,0,0);
// Load image from file
if (FAILED(D3DXCreateTextureFromFileEx (D3d, "Texture.jpg", 0,0, 1, 0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, 0,colorkey, NULL, NULL, &d3dTexture)))
{
cout << "Failed to load texture" << endl;
return;
}


So whats going on here is this:
The U and the V are the texture coordinates thats how we specify how the texture is drawn to the surface of our triangles, notice I used triangle fan to draw them so we only have to create 4 vertexes.
Thanks very much for the code samples. I've successfully managed to create a quad from 4 vertices now. However, I have a small problem with the D3DXCreateTextureFromFileEx method. I've dubble checked all parameters but it still gives me these two errors when I compile:



error LNK2019: unresolved external symbol _D3DXCreateTextureFromFileExW@56 referenced in function "void __cdecl InitializeGraphics(void)" (?InitializeGraphics@@YAXXZ) C:\Users\Simon
Blom\Desktop\MyFirstGame\MyFirstGame\Main.obj




error LNK1120: 1 unresolved externals C:\Users\Simon Blom\Desktop\MyFirstGame\Debug\MyFirstGame.exe 1



I've pasted my code below so you can check if everything is correct. The method is located on line 150. And thanks very much for helping me :)


[source lang="cpp"]
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9tex.h>


#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600


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


LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 v_buffer;


IDirect3DTexture9 *texture;


void InitializeD3D(HWND hWnd);
void InitializeGraphics(void);
void Update(void);
void Draw(void);
void Clean(void);


struct CUSTOMVERTEX { float X, Y, Z, RHW, U, V; DWORD COLOR; };
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)


CUSTOMVERTEX vertices[4];


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = L"MFGCLASS";
wc.style = CS_VREDRAW | CS_HREDRAW;

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL, L"MFGCLASS", L"MyFirstGame", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);

InitializeD3D(hWnd);

while(true)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

if (msg.message == WM_QUIT) break;

Update();
Draw();
}

Clean();

return msg.wParam;
}


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY: PostQuitMessage(0); return 0; break;
}

return DefWindowProc(hWnd, message, wParam, lParam);
}


void InitializeD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));

d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;

d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

InitializeGraphics();
}


void InitializeGraphics(void)
{
d3ddev->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL);

vertices[0].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[0].X = 200;
vertices[0].Y = 200;
vertices[0].Z = 0;
vertices[0].RHW = 1;
vertices[0].U = 0;
vertices[0].V = 0;

vertices[1].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[1].X = 500;
vertices[1].Y = 200;
vertices[1].Z = 0;
vertices[1].RHW = 1;
vertices[1].U = 0;
vertices[1].V = 0;

vertices[2].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[2].X = 500;
vertices[2].Y = 500;
vertices[2].Z = 0;
vertices[2].RHW = 1;
vertices[2].U = 0;
vertices[2].V = 0;

vertices[3].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[3].X = 200;
vertices[3].Y = 500;
vertices[3].Z = 0;
vertices[3].RHW = 1;
vertices[3].U = 0;
vertices[3].V = 0;

D3DXCreateTextureFromFileEx(d3ddev, L"texture.jpg", 0, 0, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, 0, NULL, NULL, NULL, &texture);
}


void Update(void)
{
VOID* pVoid;

v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
}


void Draw(void)
{
d3ddev->Clear(9, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

d3ddev->BeginScene();

d3ddev->SetFVF(CUSTOMFVF);

d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));

d3ddev->SetTexture(0, texture);

d3ddev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);

d3ddev->EndScene();

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


void Clean(void)
{
v_buffer ->Release();
d3ddev ->Release();
d3d ->Release();
}
[/source]
Ok, so I've managed to solve my problem with the build error. The problem was that I hadn't referenced to the d3dx9 library, so I simply add this snippet:


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



However, now I have a new problem again (yes, it seems the problems don't want to let go from me). I can successfully build my program now, but the texture isn't showing up, just my quad in black color. I've tried to put the .jpg image in both my project folder and the debug folder, but none makes any difference. What have I done wrong? This is my current code:


[source lang="cpp"]
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9tex.h>


#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600


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


LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 v_buffer;


IDirect3DTexture9 *texture;


void InitializeD3D(HWND hWnd);
void InitializeGraphics(void);
void Update(void);
void Draw(void);
void Clean(void);


struct CUSTOMVERTEX { float X, Y, Z, RHW, U, V; DWORD COLOR; };
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)


CUSTOMVERTEX vertices[4];


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = L"MFGCLASS";
wc.style = CS_VREDRAW | CS_HREDRAW;

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL, L"MFGCLASS", L"MyFirstGame", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);

InitializeD3D(hWnd);

while(true)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

if (msg.message == WM_QUIT) break;

Update();
Draw();
}

Clean();

return msg.wParam;
}


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY: PostQuitMessage(0); return 0; break;
}

return DefWindowProc(hWnd, message, wParam, lParam);
}


void InitializeD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));

d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;

d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

InitializeGraphics();
}


void InitializeGraphics(void)
{
d3ddev->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL);

vertices[0].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[0].X = 200;
vertices[0].Y = 200;
vertices[0].Z = 0;
vertices[0].RHW = 1;
vertices[0].U = 0;
vertices[0].V = 0;

vertices[1].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[1].X = 500;
vertices[1].Y = 200;
vertices[1].Z = 0;
vertices[1].RHW = 1;
vertices[1].U = 0;
vertices[1].V = 0;

vertices[2].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[2].X = 500;
vertices[2].Y = 500;
vertices[2].Z = 0;
vertices[2].RHW = 1;
vertices[2].U = 0;
vertices[2].V = 0;

vertices[3].COLOR = D3DCOLOR_ARGB(255, 255, 255, 255);
vertices[3].X = 200;
vertices[3].Y = 500;
vertices[3].Z = 0;
vertices[3].RHW = 1;
vertices[3].U = 0;
vertices[3].V = 0;

D3DXCreateTextureFromFileEx(d3ddev, L"texture.jpg", 0, 0, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, 0, NULL, NULL, NULL, &texture);
}


void Update(void)
{
VOID* pVoid;

v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
}


void Draw(void)
{
d3ddev->Clear(9, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

d3ddev->BeginScene();

d3ddev->SetFVF(CUSTOMFVF);

d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));

d3ddev->SetTexture(0, texture);

d3ddev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);

d3ddev->EndScene();

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


void Clean(void)
{
v_buffer ->Release();
d3ddev ->Release();
d3d ->Release();
}
[/source]

This topic is closed to new replies.

Advertisement