Problem z jednoczesnym obracaniem bryły w dwóch osiach DirectX9

0

Problem opisałem w komentarzu.

#include <d3dx9.h>
#include <stdio.h>

#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ | D3DFVF_DIFFUSE )

LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_d3dDev = NULL;
LPDIRECT3DVERTEXBUFFER9 g_VB = NULL;

double eX = 0.5f, eY = 2.0f, eZ = -4.0;
double fAngleX = NULL, fAngleY = NULL;
bool czyWcisniety = false;

struct CUSTOMVERTEX
{
	FLOAT x,y,z;
	D3DCOLOR color;
};

struct MOUSEPOINT
{
	int mX, mY;
};

MOUSEPOINT poprzedni;
MOUSEPOINT aktualny;

VOID Matrices(HWND hWnd)
{
	D3DXMATRIXA16 matWorld;

	if(czyWcisniety == true)
	{
		int poprzedniT = GetTickCount();
		GetCursorPos((LPPOINT)&poprzedni);
		
		while(true)
		{
			int aktualnyT = GetTickCount();
			GetCursorPos((LPPOINT)&aktualny);
			if( (aktualnyT - poprzedniT)>= 15)
			{
				if(  (aktualny.mX - poprzedni.mX) < 0)
					fAngleY += 0.1 ;
				else if(  (aktualny.mX - poprzedni.mX) > 0)
					fAngleY -= 0.1 ;
				else if(  (aktualny.mY - poprzedni.mY) > 0)
					fAngleX -= 0.1;
				else if(  (aktualny.mY - poprzedni.mY) < 0)
					fAngleX += 0.1;
				break;
			}
		}	
	}

	CHAR tab[60];
	sprintf_s(tab, "mX: %i mY: %i fAngleX: %f fAngleY: %f", poprzedni.mX, poprzedni.mY, fAngleX, fAngleY);
	SetWindowText(hWnd, tab);
	{
	  D3DXMatrixRotationX(&matWorld, (FLOAT)fAngleX);// dziala tylko jedna funkcja druga, pierwsza cos
	  D3DXMatrixRotationY(&matWorld, (FLOAT)fAngleY);// nie chce zalapac i mozemy krecic bryla tylko wokol osi y
           }
	g_d3dDev->SetTransform(D3DTS_WORLD, &matWorld);

	D3DXMATRIXA16 matView;
	D3DXVECTOR3 vEye	( 0.5f, 3.0f, -4.0);
	D3DXVECTOR3 vLookAt	( (FLOAT)eX, (FLOAT)eY, (FLOAT)eX);
	D3DXVECTOR3 vUp		( 0.0f, 1.0f,  0.0f);
	D3DXMatrixLookAtLH(&matView, &vEye, &vLookAt, &vUp);
	g_d3dDev->SetTransform(D3DTS_VIEW, &matView);

	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/2, 1.0f, 1.0f, 100.0f);
	g_d3dDev->SetTransform(D3DTS_PROJECTION, &matProj);
}

HRESULT InitGeometry(void)
{
	CUSTOMVERTEX Vertices[] =
	{	
		{ -1.0f,-1.0f,-1.0f, 0xffff0000 }, 
		{ -1.0f, 1.0f,-1.0f, 0xff00ff00 }, 
		{  1.0f,-1.0f,-1.0f, 0xff0000ff }, 
		{  1.0f, 1.0f,-1.0f, 0xff0000ff }, 
		{  1.0f,-1.0f, 1.0f, 0xff00ff00 }, 
		{  1.0f, 1.0f, 1.0f, 0xffff0000 }, 
		{ -1.0f,-1.0f, 1.0f, 0xff00ff00 }, 
		{ -1.0f, 1.0f, 1.0f, 0xff0000ff }, 
		{ -1.0f,-1.0f,-1.0f, 0xff0000ff }, 
		{ -1.0f, 1.0f,-1.0f, 0xff00ff00 },
	};

	g_d3dDev->CreateVertexBuffer(sizeof(Vertices), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_VB, 0);

	VOID* pVertices;

	g_VB->Lock(0, sizeof(Vertices), (void**)&pVertices, 0 );
	memcpy(pVertices, Vertices, sizeof(Vertices) );
	g_VB->Unlock();

	return S_OK;
}

VOID RenderFrame(HWND hWnd)
{
	g_d3dDev->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0 ,0), 1.0f, 0);
	
	if(SUCCEEDED( g_d3dDev->BeginScene() ) )
	{
		Matrices(hWnd);
		g_d3dDev->SetStreamSource( 0, g_VB, 0, sizeof(CUSTOMVERTEX) );
		g_d3dDev->SetFVF(D3DFVF_CUSTOMVERTEX);
		g_d3dDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 8); 
		g_d3dDev->EndScene();
	}
	
	g_d3dDev->Present(0, 0, 0, 0);
}

HRESULT InitD3D(HWND hWnd)
{
	if( (g_D3D = Direct3DCreate9(D3D_SDK_VERSION) ) == NULL)
		return E_FAIL;

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

	d3dParam.Windowed = TRUE;
	d3dParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dParam.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dParam.EnableAutoDepthStencil = true;
	d3dParam.AutoDepthStencilFormat = D3DFMT_D16;

	if(FAILED( g_D3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
									hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
									&d3dParam, &g_d3dDev) ) ) 
								return E_FAIL;

	g_d3dDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	g_d3dDev->SetRenderState(D3DRS_LIGHTING, FALSE);
	g_d3dDev->SetRenderState(D3DRS_ZENABLE, TRUE); 
	return S_OK;
}

VOID Cleanup(void)
{
	if(g_VB != NULL )
		g_VB->Release();

	if(g_d3dDev != NULL)
		g_d3dDev->Release();

	if(g_D3D != NULL)
		g_D3D->Release();
}

LRESULT _stdcall WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_DESTROY:
			Cleanup();
			PostQuitMessage(0);
			return 0;

		case WM_LBUTTONDOWN:
			czyWcisniety = true;
			return 0;

		case WM_LBUTTONUP:
			czyWcisniety = false;
			return 0;

		case WM_CHAR:

			switch(wParam)
			{
				case 'w':
					eY+=0.1;
					return 0;
				case 's':
					eY-=0.1;
					return 0;
				case 'a':
					eX-=0.1;
					return 0;
				case 'd':
					eX+=0.1;
					return 0;
				default:
					MessageBox(NULL, "Zly klawisz", "", MB_OK);
					return 0;
			}
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
	WNDCLASSEX wndClass;

	ZeroMemory(&wndClass, sizeof(wndClass));
	
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.hInstance = hInstance;
	wndClass.lpfnWndProc = WndProc;
	wndClass.lpszClassName = "cDirectX";
	wndClass.style = CS_CLASSDC;
	wndClass.hCursor = LoadCursor(NULL, (LPCSTR)IDC_CROSS);


	if( !RegisterClassEx(&wndClass) ) 
			return E_FAIL;

	HWND hWnd = CreateWindow("cDirectX", "DirectX - Practic",
							 WS_OVERLAPPEDWINDOW, 
							 100, 100, 800, 600,
							 0, 0, wndClass.hInstance,
							 0); 
	
	ShowWindow(hWnd, SW_NORMAL);
	
	if( SUCCEEDED ( InitD3D(hWnd) ) )
	{
		InitGeometry();

		MSG msg;
		ZeroMemory(&msg, sizeof(msg) );

		while(msg.message != WM_QUIT)///WM_QUIT
		{
			if( PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) )
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			else
				RenderFrame(hWnd);
		}
	}
	
	UnregisterClass("cDirectX", wndClass.hInstance);

	return 0;
}
1

Na początku zapisujesz jedną macierz przekształcenia do matworld, następnie nadpisujesz ją drugą macierzą.

1 użytkowników online, w tym zalogowanych: 0, gości: 1