Moving cube issue ---

Started by
8 comments, last by pcbrainbuster 15 years, 11 months ago
Sup guys, In the following code for some reason my cube primitive is moving(when it shouldn't be), it should only rotate but it doesn't seem to just do that. I clearly can't figure out why --->

#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
#define ScreenW 640
#define ScreenH 480
#define CustomFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

const char *ClsName = "BasicApp";
const char *WndName = "DirectX";

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID InitD3D();
VOID InitGraphics();
VOID InitLights();
VOID Display();
VOID CleanProgram();

struct CustomV
{

 FLOAT x, y, z;
 D3DVECTOR vnormal;
 FLOAT u, v;

};

HINSTANCE hInstance;
HWND hWnd;
DWORD StartingCount;
D3DPRESENT_PARAMETERS D3DPP;
D3DLIGHT9 Light;
D3DMATERIAL9 LightM;
LPDIRECT3D9 D3D;
LPDIRECT3DDEVICE9 D3DDev;
LPDIRECT3DVERTEXBUFFER9 PrimitiveB;
LPDIRECT3DTEXTURE9 TexA;
D3DXMATRIX ViewM, ProjectionM, RotationXYZM;
FLOAT RotationIndex = 0.0f;
VOID* VertMemLoc;
CustomV Primitive[] =
{

 //Front Side - Cube
 {-3.0f, 3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0, 0, },
 {3.0f, 3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1, 0, },
 {-3.0f, -3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0, 1, },
 {3.0f, -3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1, 1, },

 //Right Side - Cube
 {3.0f, 3.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0, 0, },
 {3.0f, 3.0f, 6.0f, 1.0f, 0.0f, 0.0f, 1, 0, },
 {3.0f, -3.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0, 1, },
 {3.0f, -3.0f, 6.0f, 1.0f, 0.0f, 0.0f, 1, 1, },

 //Left Side - Cube
 {-3.0f, 3.0f, 6.0f, -1.0f, 0.0f, 0.0f, 0, 0, },
 {-3.0f, 3.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1, 0, },
 {-3.0f, -3.0f, 6.0f, -1.0f, 0.0f, 0.0f, 0, 1, },
 {-3.0f, -3.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1, 1, },

 //Back Side - Cube
 {3.0f, 3.0f, 6.0f, 0.0f, 0.0f, -1.0f, 0, 0, },
 {-3.0f, 3.0f, 6.0f, 0.0f, 0.0f, -1.0f, 1, 0, },
 {3.0f, -3.0f, 6.0f, 0.0f, 0.0f, -1.0f, 0, 1, },
 {-3.0f, -3.0f, 6.0f, 0.0f, 0.0f, -1.0f, 1, 1, },

 //Top Side - Cube
 {3.0f, 3.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0, 0, },
 {-3.0f, 3.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1, 0, },
 {3.0f, 3.0f, 6.0f, 0.0f, 1.0f, 0.0f, 0, 1, },
 {-3.0f, 3.0f, 6.0f, 0.0f, 1.0f, 0.0f, 1, 1, },

 //Bottom Side - Cube
 {-3.0f, -3.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0, 0, },
 {3.0f, -3.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1, 0, },
 {-3.0f, -3.0f, 6.0f, 0.0f, -1.0f, 0.0f, 0, 1, },
 {3.0f, -3.0f, 6.0f, 0.0f, -1.0f, 0.0f, 1, 1, },

};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

 MSG Msg;
 WNDCLASSEX WndClsEx;

 // Create the application window
 WndClsEx.cbSize = sizeof(WNDCLASSEX);
 WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
 WndClsEx.lpfnWndProc = WndProc;
 WndClsEx.cbClsExtra = 0;
 WndClsEx.cbWndExtra = 0;
 WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
 WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 WndClsEx.lpszMenuName = NULL;
 WndClsEx.lpszClassName = ClsName;
 WndClsEx.hInstance = hInstance;
 WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

 // Register the application
 RegisterClassEx(&WndClsEx);

 // Create the window object
 hWnd = CreateWindowEx(WS_EX_TOPMOST,
 ClsName,
 WndName,
 WS_POPUP,
 0,
 0,
 ScreenW,
 ScreenH,
 NULL,
 NULL,
 hInstance,
 NULL); 

 // Find out if the window was created
 if( !hWnd ) // If the window was not created,
 return 0; // stop the application 

 // Display the window to the user
 ShowWindow(hWnd, SW_SHOWNORMAL);
 UpdateWindow(hWnd); 
 InitD3D();

 // Decode and treat the messages
 // as long as the application is running
 while(true)
 {

  StartingCount = GetTickCount();

  if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
  {

   if (Msg.message == WM_QUIT) break;

   TranslateMessage(&Msg);
   DispatchMessage(&Msg);

  }

  Display();

  while((GetTickCount() - StartingCount) < 25);

 }

 CleanProgram();

 return Msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{

 switch (Msg) 
 {

  case WM_DESTROY :
  
   PostQuitMessage(WM_QUIT);
  
  break;

  case WM_CLOSE :

   DestroyWindow(hWnd);
 
  break;

  case WM_KEYUP :

   switch(wParam)
   {

    case VK_ESCAPE :

     DestroyWindow(hWnd);
 
    break;

	case 'R' :

	 Light.Diffuse.r = 1.0f;
	 Light.Diffuse.g = 0.0f;
	 Light.Diffuse.b = 0.0f;

	 D3DDev->SetLight(0, &Light);

	break;

	case 'G' :

	 Light.Diffuse.r = 0.0f;
	 Light.Diffuse.g = 1.0f;
	 Light.Diffuse.b = 0.0f;

	 D3DDev->SetLight(0, &Light);

	break;

	case 'B' :

	 Light.Diffuse.r = 0.0f;
	 Light.Diffuse.g = 0.0f;
	 Light.Diffuse.b = 1.0f;

	 D3DDev->SetLight(0, &Light);

	break;

	case 'A' :

	 Light.Diffuse.r = 1.0f;
	 Light.Diffuse.g = 1.0f;
	 Light.Diffuse.b = 1.0f;

	 D3DDev->SetLight(0, &Light);

	break;

   }  

  break;

 }

 return DefWindowProc(hWnd, Msg, wParam, lParam);

}

VOID InitD3D()
{

 D3D = Direct3DCreate9(D3D_SDK_VERSION);

 ZeroMemory(&D3DPP, sizeof(D3DPP));

 D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
 D3DPP.hDeviceWindow = hWnd;
 D3DPP.Windowed = false;
 D3DPP.BackBufferWidth = ScreenW;
 D3DPP.BackBufferHeight = ScreenH;
 D3DPP.BackBufferFormat = D3DFMT_X8R8G8B8;
 D3DPP.EnableAutoDepthStencil = true;
 D3DPP.AutoDepthStencilFormat = D3DFMT_D16;

 D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &D3DPP, &D3DDev);

 InitGraphics();
 InitLights();

}

VOID InitGraphics()
{

 D3DDev->CreateVertexBuffer(24 * sizeof(CustomV), NULL, CustomFVF, D3DPOOL_MANAGED, &PrimitiveB, NULL);
 PrimitiveB->Lock(NULL, NULL, &VertMemLoc, NULL);

 memcpy(VertMemLoc, Primitive, sizeof(Primitive));

 PrimitiveB->Unlock();
 D3DDev->SetRenderState(D3DRS_LIGHTING, true);
 D3DDev->SetRenderState(D3DRS_ZENABLE, true); 
 D3DDev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));
 D3DDev->SetRenderState(D3DRS_NORMALIZENORMALS, true);

 D3DXCreateTextureFromFile(D3DDev, "C:\\Tile.bmp", &TexA);

}

VOID InitLights()
{

 D3DVECTOR LightDir = {-2.5f, -2.5f, -2.5f};

 ZeroMemory(&Light, sizeof(Light));
 ZeroMemory(&LightM, sizeof(LightM));

 Light.Type = D3DLIGHT_DIRECTIONAL;
 Light.Diffuse.r = 1.0f;
 Light.Diffuse.g = 1.0f;
 Light.Diffuse.b = 1.0f;
 Light.Diffuse.a = 1.0f;
 Light.Direction = LightDir;
 LightM.Diffuse.r = LightM.Ambient.r = 1.0f;
 LightM.Diffuse.g = LightM.Ambient.g = 1.0f;
 LightM.Diffuse.b = LightM.Ambient.b = 1.0f;
 LightM.Diffuse.a = LightM.Ambient.a = 1.0f;

 D3DDev->SetLight(0, &Light);
 D3DDev->LightEnable(0, true);
 D3DDev->SetMaterial(&LightM);

}

VOID Display()
{

 RotationIndex += 0.05f;

 D3DXMatrixLookAtLH(&ViewM, &D3DXVECTOR3 (8.0f, 5.0f, -20.0f), &D3DXVECTOR3 (0.0f, 0.0f, 0.0f), &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));
 D3DXMatrixPerspectiveFovLH(&ProjectionM, D3DXToRadian(45), (FLOAT)ScreenW / (FLOAT)ScreenH, 1.0f, 100.0f);
 D3DXMatrixRotationYawPitchRoll(&RotationXYZM, RotationIndex, RotationIndex, RotationIndex);

 D3DDev->Clear(NULL, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, NULL);
 D3DDev->BeginScene();
 D3DDev->SetFVF(CustomFVF);
 D3DDev->SetStreamSource(NULL, PrimitiveB, NULL, sizeof(CustomV));
 D3DDev->SetTransform(D3DTS_VIEW, &ViewM);
 D3DDev->SetTransform(D3DTS_PROJECTION, &ProjectionM);
 D3DDev->SetTransform(D3DTS_WORLD, &RotationXYZM);
 D3DDev->SetTexture(NULL, TexA);
 D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
 D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 2);
 D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 8, 2);
 D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 12, 2);
 D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 16, 2);
 D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 20, 2);
 D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 24, 2);
 D3DDev->EndScene();
 D3DDev->Present(NULL, NULL, NULL, NULL);

}

VOID CleanProgram()
{

 D3D->Release();
 D3DDev->Release();
 PrimitiveB->Release();
 TexA->Release();

}
Can anyone see what's wrong? Thank you.
Advertisement
Since your cube is centered about <0,0,3.5> and not <0,0,0>, it will move around in circles.
Just to elaborate a bit...

Rotations are defined as being about the origin (<0,0,0>) so if you want to apply a rotation about another arbitrary point (such as the <0,0,3.5> your cube is centred on) you need two additional transformations.

First you need to TRANSLATE by the negative of the arbitrary centre of rotation (<0,0,-3.5>) then do your rotation and finally translate it back to the arbitrary centre again - <0,0,3.5>. You can chain these together using D3DXMatrixMultiply().

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Thanks for the replies! But how can you guys tell that it is off by 3.5? i don't see that number used in my prog.

Thanks.
The minimum Z coordinate is 1, and the max is 6. That means the center of the cube is at (1 + 6)/2, which is 3.5
Thanks for that man. OK, so all I need to do is translate the cube to (0, 0, 0) right?

Thankx.
Quote:Original post by pcbrainbuster
Thanks for that man. OK, so all I need to do is translate the cube to (0, 0, 0) right?

Thankx.
Yep. Either translate, rotate then re-translate, or change the vertices in your declaration so they're centered on (0, 0, 0)
Hmm, I decided that I should work on the origin instead because its more memory efficient. Just one question; how can you work out the CURRENT origin? Is it always the same forumula((MIN + MAX) / 2)?
Quote:Original post by pcbrainbuster
Hmm, I decided that I should work on the origin instead because its more memory efficient. Just one question; how can you work out the CURRENT origin? Is it always the same forumula((MIN + MAX) / 2)?
Yes.

Although it's not really much more memory efficient; it's only 12 bytes per object (Translation offset).
Oh is that all? Well thanks anyway!

RESOLVED

This topic is closed to new replies.

Advertisement