Page 1 of 1

Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Tue Jun 05, 2012 9:13 am
by OmenFelix
Hey guys, I'm teaching my self Direct3D and I've got some code rendering a triangle, of which I somewhat understand. I've added code which should rotate the world matrix by 45 degrees and translate by yay-amount. Instead it just renders the pretty triangle, but with none of the transformations applied.

Here's the code:

Code: Select all

#include <d3d9.h> //include d3d stuff
#include <d3dx9.h>
#include <stdio.h>

#define _USE_MATH_DEFINES //tells math.h to define Mathematical constants
#include <math.h>

FILE *dlog;

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); //declare a window process
IDirect3D9 *d3d = NULL; //declare d3d as NULL
IDirect3DDevice9 *d3dDevice = NULL; //declare d3dDevice as NULL

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) //define the contents of the custom vertex

D3DXMATRIX matWorld;

D3DXMATRIX matTrans;
D3DXMATRIX matRot;

typedef struct { //declare a custom vertex
	float x, y, z, rhw;
	DWORD color;
} CustomVertex;

//STUFF
IDirect3DVertexBuffer9 *vbPtr; //pointer to the vertex buffer
void *pVertices; //pointer to the vertices

CustomVertex vertices[] = { //our vertices
    { 0.0f,  0.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), }, // x, y, z, rhw, color
    { 32.0f, 0.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
    { 0.0f, 64.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
	{ 32.0f, 64.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 255), },
};
//END OF STUFF

void exit();

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShow) {
	dlog = fopen("log.txt", "w");

	MSG msg;

    WNDCLASSEXA wc = { sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW | CS_OWNDC, WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH) (COLOR_WINDOW + 1), 
		NULL, "DX", NULL };

	RegisterClassExA(&wc);

	HWND hMainWnd = CreateWindowA("DX", "Fat Monkey Penises", WS_OVERLAPPEDWINDOW, 700, 400, 640, 480, NULL, NULL, 
		hInstance, NULL); //create window
	
	d3d = Direct3DCreate9(D3D_SDK_VERSION); //create d3d

    D3DPRESENT_PARAMETERS PresentParams;
    memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS));

    PresentParams.Windowed = TRUE;
    PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;

    d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams, 
		&d3dDevice); //create d3d device

	ShowWindow(hMainWnd, nShow);
    UpdateWindow(hMainWnd);

	//Handle Messages
    while(GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

	return(0);
}

//Exit and dealloc memory
void exit() {
	d3d->Release();
	d3dDevice->Release();
	PostQuitMessage(0);
}

//Message Handling
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch(msg) {
	case WM_DESTROY: //destruction handler
		exit();
		return(0);
		break;
	case WM_PAINT: //paint handler
		d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); //clear screen

		//VERTICES INITIALIZATION
		d3dDevice->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &vbPtr, NULL); //create vertex buffer
		vbPtr->Lock(0, sizeof(vertices), (void**) &pVertices, 0);
		memcpy(pVertices, vertices, sizeof(vertices));
		vbPtr->Unlock();
		//END OF VERTICES INITIALIZATION

		d3dDevice->BeginScene(); //glBegin(...);
		d3dDevice->SetStreamSource(0, vbPtr, 0, sizeof(CustomVertex));
		d3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

		//World Matrix Transformation
		D3DXMatrixRotationZ(&matRot, D3DXToRadian(45));
		D3DXMatrixTranslation(&matTrans, 100.f, 200.f, 0.f);
		D3DXMatrixMultiply(&matWorld, &matTrans, &matRot);
		d3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
		//End of World Matrix Transformation

		d3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); //LIST

		d3dDevice->EndScene(); //glEnd();

		d3dDevice->Present(NULL, NULL, NULL, NULL); //render back-buffer

		ValidateRect(hWnd, NULL); //tell d3d that we're handling the rendering ourselves

		return(0);
		break;
	case WM_KEYDOWN:
		switch (wParam) {
		case VK_ESCAPE:
			fprintf(dlog, "Escape pressed\n");
			exit();
			break;
		case 'W':
			fprintf(dlog, "W pressed\n");
			for (short i = 0; i < 4; i++) {
				vertices[i].y -= 8;
			}
			break;
		case 'A':
			fprintf(dlog, "A pressed\n");
			for (short i = 0; i < 4; i++) {
				vertices[i].x -= 8;
			}
			break;
		case 'S':
			fprintf(dlog, "S pressed\n");
			for (short i = 0; i < 4; i++) {
				vertices[i].y += 8;
			}
			break;
		case 'D':
			fprintf(dlog, "D pressed\n");
			for (short i = 0; i < 4; i++) {
				vertices[i].x += 8;
			}
			break;
		}
		break;
	}
	
	return(DefWindowProc(hWnd, msg, wParam, lParam));
}

Anybody know how I can fix this?

Thanks in advance. :)

EDIT: I've updated the code.

Image

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Tue Jun 05, 2012 12:07 pm
by qpHalcy0n
Here you're not actually rotating, just translating. I suspect it may actually be translating, but its a static translation and may not be sufficiently large to see.

Those D3DX functions load a matrix into the array there. They don't actually concatenate them. You must concatenate the matrices. OpenGL does this for you (via glRotate, glScale, etc..) while D3DX does not. You need to know your linear algebra concepts. Check D3DXMatrixMultiply

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Tue Jun 05, 2012 12:53 pm
by OmenFelix
qpHalcy0n wrote:Here you're not actually rotating, just translating. I suspect it may actually be translating, but its a static translation and may not be sufficiently large to see.

Those D3DX functions load a matrix into the array there. They don't actually concatenate them. You must concatenate the matrices. OpenGL does this for you (via glRotate, glScale, etc..) while D3DX does not. You need to know your linear algebra concepts. Check D3DXMatrixMultiply
So the matrix I created, contains basis vectors of the sort?

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Tue Jun 05, 2012 1:24 pm
by qpHalcy0n
No, you've loaded a translation matrix. Those D3DX functions simply load a matrix into the array.

Code: Select all

D3DXMatrixRotationZ(&matWorld, rotAngle);    // Load a Z-rotation matrix into "matWorld"
D3DXMatrixTranslation(&matWorld, x, y, z);     // Load a translation matrix into "matWorld"
See the problem?

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Tue Jun 05, 2012 1:57 pm
by OmenFelix
qpHalcy0n wrote:No, you've loaded a translation matrix. Those D3DX functions simply load a matrix into the array.

Code: Select all

D3DXMatrixRotationZ(&matWorld, rotAngle);    // Load a Z-rotation matrix into "matWorld"
D3DXMatrixTranslation(&matWorld, x, y, z);     // Load a translation matrix into "matWorld"
See the problem?
So I multiply them by doing this?

Code: Select all

D3DXMatrixMultiply(&matWorld, &matTrans, &matRot);
It still doesn't have any effect on the shape. :\

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Tue Jun 05, 2012 5:32 pm
by lalacomun
Really, not working! and you were planning to do a tutorial about it !!?? :nono: LOL

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Wed Jun 06, 2012 9:33 am
by OmenFelix
lalacomun wrote:Really, not working! and you were planning to do a tutorial about it !!?? :nono: LOL
Heh. xD

Doing several on using OpenGL for 2D graphics later, Martin. ;)

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Wed Jun 06, 2012 1:58 pm
by qpHalcy0n
Oh, I didn't notice this before.

D3DFVF_XYZRHW indicates a vertex that is already transformed, so it should not be affected by the transformation pipeline.
You should change this to D3DFVF_XYZ, as it is not yet transformed.

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Wed Jun 06, 2012 7:05 pm
by OmenFelix
qpHalcy0n wrote:Oh, I didn't notice this before.

D3DFVF_XYZRHW indicates a vertex that is already transformed, so it should not be affected by the transformation pipeline.
You should change this to D3DFVF_XYZ, as it is not yet transformed.
Ooh...should that fix it?

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Wed Jun 06, 2012 7:14 pm
by OmenFelix
qpHalcy0n wrote:Oh, I didn't notice this before.

D3DFVF_XYZRHW indicates a vertex that is already transformed, so it should not be affected by the transformation pipeline.
You should change this to D3DFVF_XYZ, as it is not yet transformed.
Now it's just not rendering the shape.

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Wed Jun 06, 2012 11:37 pm
by qpHalcy0n
Good, that means its working. Your transform is not correct ;]

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Thu Jun 07, 2012 4:23 am
by OmenFelix
qpHalcy0n wrote:Good, that means its working. Your transform is not correct ;]
Sooooo? What do you mean? As in, how do I fix it? Lol. :3

Re: Direct3D 9 World Matrix Transformation --NOT WORKING

Posted: Thu Jun 07, 2012 9:52 am
by qpHalcy0n
Now you need to read up on the T&L pipeline (just the transform part) and on linear transformations. DX just doesn't do any of this for you. You must do this yourself.