   Rendering disappears if camera looks along the 'up' axis
  I'm abit new to direct3d and im having this problem with my program where if i rotate the camera to point straight down or straight up then my textures all vanish. (when im just using diffuse colours then the colours switch places)I've tried searching around for a solution and checking all my math but i cant seem to find the problem.left and right moves the camera right and leftup and down zooms in and outpgup and pgdn moves the camera up and downIn my program when you move the camera all the way up or down everything vanishes.I have the .cpp code below, just make any png file called wood.png in the program directoryThanks in advanceedit: oh if anyone is wondering i am using this tutorial http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B.aspx// include the basic windows header file#include <windows.h>#include <windowsx.h>#include <d3d9.h>#include <d3dx9.h>// include the Direct3D Library file#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// define the screen resolution#define SCREEN_WIDTH  640#define SCREEN_HEIGHT 480// global declarationsLPDIRECT3D9 d3d;    // the pointer to our Direct3D interfaceLPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device classLPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;    // the pointer to the vertex buffer// texture declarationsLPDIRECT3DTEXTURE9 texture_1;// function prototypesvoid initD3D(HWND hWnd);    // sets up and initializes Direct3Dvoid render_frame(void);    // renders a single framevoid cleanD3D(void);    // closes Direct3D and releases memoryvoid init_graphics(void);    // 3D declarationsstruct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR; FLOAT U, V;};#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)// the WindowProc function prototypeLRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);// the entry point for any Windows programint WINAPI WinMain(HINSTANCE hInstance,    HINSTANCE hPrevInstance,    LPSTR lpCmdLine,    int nCmdShow){    // the handle for the window, filled by a function    HWND hWnd;    // this struct holds information for the window class    WNDCLASSEX wc;    // clear out the window class for use    ZeroMemory(&wc, sizeof(WNDCLASSEX));    // fill in the struct with the needed information    wc.cbSize = sizeof(WNDCLASSEX);    wc.style = CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc = WindowProc;    wc.hInstance = hInstance;    wc.hCursor = LoadCursor(NULL, IDC_ARROW);    wc.lpszClassName = "WindowClass1";    // register the window class    RegisterClassEx(&wc);    // create the window and use the result as the handle    hWnd = CreateWindowEx(NULL, "WindowClass1",    // name of the window class "Our First Windowed Program",   // title of the window WS_EX_TOPMOST | WS_POPUP,    // fullscreen values    // window style 0,0,    // x-position of the window    // y-position of the window SCREEN_WIDTH, SCREEN_HEIGHT,    // set window to new resolution // width of the window NULL,    // we have no parent window, NULL NULL,    // we aren't using menus, NULL hInstance,    // application handle NULL);    // used with multiple windows, NULL    // display the window on the screen    ShowWindow(hWnd, nCmdShow);    // set up and initialize Direct3D    initD3D(hWnd);    // enter the main loop:    // this struct holds Windows event messages    MSG msg;// Enter the infinite message loopwhile(TRUE){// Check to see if any messages are waiting in the queuewhile(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){// Translate the message and dispatch it to WindowProc()TranslateMessage(&msg);DispatchMessage(&msg);}// If the message is WM_QUIT, exit the while loopif(msg.message == WM_QUIT)break;init_graphics();render_frame();// check the 'escape' keyif(KEY_DOWN(VK_ESCAPE)){PostMessage(hWnd, WM_DESTROY, 0, 0); }// Run game code here// ...// ...}cleanD3D();    // return this part of the WM_QUIT message to Windows    return msg.wParam;}// this is the main message handler for the programLRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    // sort through and find what code to run for the message given    switch(message)    {   // this message is read when the window is closed   case WM_DESTROY:  { // close the application entirely PostQuitMessage(0); return 0;  } break;    }    // Handle any messages the switch statement didn't    return DefWindowProc (hWnd, message, wParam, lParam);} // this function initializes and prepares Direct3D for usevoid initD3D(HWND hWnd){    d3d = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface    D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information    ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use    d3dpp.Windowed = true;    // program windowed, not fullscreen    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames    d3dpp.hDeviceWindow = hWnd;    // set the window to be used by Direct3Dd3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;    // set the back buffer format to 32-bit    d3dpp.BackBufferWidth = SCREEN_WIDTH;    // set the width of the buffer    d3dpp.BackBufferHeight = SCREEN_HEIGHT;    // set the height of the buffer    d3dpp.EnableAutoDepthStencil = TRUE;    // automatically run the z-buffer for us    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;    // 16-bit pixel format for the z-buffer    // create a device class using this information and information from the d3dpp stuct    d3d->CreateDevice(D3DADAPTER_DEFAULT,  D3DDEVTYPE_HAL,  hWnd,  D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp,  &d3ddev);init_graphics();    // call the function to initialize the triangled3ddev->SetRenderState(D3DRS_LIGHTING, FALSE); // turn off the 3D lightingd3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW );//draw one side //D3DCULL_CCW draws noned3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer}// this is the function used to render a single framevoid render_frame(void){    // clear the window to a deep blue    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);    d3ddev->BeginScene();    // begins the 3D scene    // do 3D rendering on the back buffer here// select which vertex format we are using    d3ddev->SetFVF(CUSTOMFVF);// SET UP THE PIPELINEstatic float distance = 10.0f;static float horiangle = 0.0f;static float vertangle = 90.0f;static float xpos = 0.0f;static float zpos = 0.0f;static float ypos = 0.0f;static float rotationx = 0.0f;static float rotationy = 0.0f;static float rotationz = 0.0f;if(KEY_DOWN(VK_UP) && distance >= 7.0f){distance -=  0.5f;}if(KEY_DOWN(VK_DOWN)){distance += 0.5f;}if(KEY_DOWN(VK_RIGHT)){horiangle += 4.0f;}if(KEY_DOWN(VK_LEFT)){horiangle -= 4.0f;}if(KEY_DOWN(VK_PRIOR) && vertangle > 0){vertangle -=3.0f;}if(KEY_DOWN(VK_NEXT) && vertangle < 180){vertangle +=3.0f;}xpos = distance * sin(D3DXToRadian(horiangle)) * sin(D3DXToRadian(vertangle));ypos = distance * cos(D3DXToRadian(vertangle)) ;zpos = distance * cos(D3DXToRadian(horiangle)) * sin(D3DXToRadian(vertangle));    // tell Direct3D about our matrix    D3DXMATRIX matView;    // the view transform matrix    D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3 (xpos, ypos, zpos),    // the camera position&D3DXVECTOR3 (0.0f, 0.0f, 0.0f),    // the look-at position&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView    D3DXMATRIX matProjection;// the projection transform matrix    D3DXMatrixPerspectiveFovLH(&matProjection, D3DXToRadian(45),    // the horizontal field of view (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio 1.0f,    // the near view-plane 1000.0f);    // the far view-plane    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);  // set the projection    // select the vertex buffer to display    // select the vertex buffer to display    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));D3DXMATRIX matRotateX;// a matrix to store the translationD3DXMatrixRotationX(&matRotateX, D3DXToRadian(rotationx));d3ddev->SetTransform(D3DTS_WORLD, &matRotateX);    // build MULTIPLE matrices to translate the model and one to rotate// the front side    // tell Direct3D about each world transform, and then draw another triangled3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));    // set the texture    d3ddev->SetTexture(0, texture_1);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);texture_1->Release();v_buffer->Release();    // close and release the vertex buffer    // copy the vertex buffer to the back buffer    d3ddev->EndScene();    // ends the 3D scene    d3ddev->Present(NULL, NULL, NULL, NULL);    // displays the created frame}// this is the function that cleans up Direct3D and COMvoid cleanD3D(void){v_buffer->Release();    // close and release the vertex buffertexture_1->Release();    // close and release the texture    d3ddev->Release();    // close and release the 3D deviced3d->Release();// close and release Direct3D}// this is the function that puts the 3D models into video RAMvoid init_graphics(void){// load the texture we will use    D3DXCreateTextureFromFile(d3ddev,"wood.png",&texture_1);    // create the vertices using the CUSTOMVERTEX struct    CUSTOMVERTEX vertices[] =    {    // side 1    { -3.0f, 3.0f, -3.0f, 0xffffffff,1 ,0 ,},    { 3.0f, 3.0f, -3.0f, 0xffffffff,0 ,0 ,},    { -3.0f, -3.0f, -3.0f, 0xffffffff,1 ,1 ,},    { 3.0f, -3.0f, -3.0f, 0xffffffff,0 ,1 ,},    // side 2    { -3.0f, 3.0f, 3.0f, 0xffffffff ,1 ,0 ,},    { -3.0f, -3.0f, 3.0f, 0xffffffff ,0 ,0 ,},    { 3.0f, 3.0f, 3.0f, 0xffffffff ,1 ,1 ,},    { 3.0f, -3.0f, 3.0f, 0xffffffff ,0 ,1 ,},    // side 3    { -3.0f, 3.0f, 3.0f, 0xffffffff ,1 ,0 ,},    { 3.0f, 3.0f, 3.0f, 0xffffffff ,0 ,0 ,},    { -3.0f, 3.0f, -3.0f, 0xffffffff ,1 ,1 ,},    { 3.0f, 3.0f, -3.0f, 0xffffffff ,0 ,1 ,},    // side 4    { -3.0f, -3.0f, 3.0f, 0xffffffff ,1 ,0 ,},    { -3.0f, -3.0f, -3.0f, 0xffffffff ,0 ,0 ,},    { 3.0f, -3.0f, 3.0f, 0xffffffff ,1 ,1 ,},    { 3.0f, -3.0f, -3.0f, 0xffffffff ,0 ,1 ,},    // side 5    { 3.0f, 3.0f, -3.0f, 0xffffffff ,1 ,0 ,},    { 3.0f, 3.0f, 3.0f, 0xffffffff ,0 ,0 ,},    { 3.0f, -3.0f, -3.0f, 0xffffffff ,1 , 1 ,},    { 3.0f, -3.0f, 3.0f, 0xffffffff ,0 , 1 ,},    // side 6    { -3.0f, 3.0f, -3.0f, 0xffffffff ,1 ,0 ,},    { -3.0f, -3.0f, -3.0f, 0xffffffff ,0 ,0 ,},    { -3.0f, 3.0f, 3.0f, 0xffffffff ,1 ,1 ,},    { -3.0f, -3.0f, 3.0f, 0xffffffff ,0 , 1 ,},    };    // create a vertex buffer interface called v_buffer    d3ddev->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL);VOID* pVoid;    // a void pointer// lock v_buffer and load the vertices into itv_buffer->Lock(0, 0, (void**)&pVoid, 0);memcpy(pVoid, vertices, sizeof(vertices));v_buffer->Unlock();}[Edited by - jollyjeffers on May 16, 2009 9:51:27 AM]
  Welcome to the GDNet forums [smile]May I request that you choose more descriptive thread titles than "Help please." A good subject line will get you the attention you need in order to get a swift response as many people will skip over threads with poor descriptions. Thanks.Anyway, your problem.I'm pretty sure it'll be due to your specifying the 'up' vector in D3DXMatrixLookAtLH() as being (0,1,0). When you rotate your view to look +/- along the same axis then, quite simply, the mathematics do not work out - the look-at and up vectors should define a coordinate space along with an implicit 3rd vector defined from the two you specify. This basically collapses when the two vectors you provide are the same (iirc the cross product will tend towards a zero-length vector).Basically you will need to rotate your 'up' vector along with your look-at vector so that they remain perpendicular to each other and never actually meet. You may also wish to read up on 'gimbal lock' as another problem you'll have to watch out for.hthJack   ;Quote:I'm pretty sure it'll be due to your specifying the 'up' vector in D3DXMatrixLookAtLH() as being (0,1,0).I second. Try to calculate a up vector rather than using a static one.Try this to compute your view matrix:D3DXMATRIX matView;    // the view transform matrixD3DXVECTOR3 CamPos(xpos, ypos, zpos);D3DXVECTOR3 LookAt(0.0f, 0.0f, 0.0f);D3DXVECTOR3 Right(1.0f, 0.0f, 0.0f);D3DXVECTOR3 ViewVec = LookAt - CamPos;D3DXVECTOR3 Up;D3DXVec3Cross(&Up, &Right, &ViewVec);D3DXVec3Normalize(&Up, &Up);D3DXMatrixLookAtLH(&matView,   &CamPos,    // the camera position   &LookAt,    // the look-at position   &Up);    // the up directiond3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matViewThis uses a static right vector to compute a up vector by taking the cross product of your view direction and the right vector. But note, that this will no longer work if you change your camera code to enable panning. Then you will have to use a variable right vector that you compute from your camera orientation.Also, from your code I can see that you are loading and releasing your texture every frame. This is terribly slow and inefficient and you should rather load it once at the program start, keep it during program execution and release it at the end of the program.Edit: Changed the code to make it more understandable.   ;  Thanks for the help, i thought I might have to alter the up axis but found the math of changing the way axis face abit confusing. I couldnt really think of a good way to phrase it when i wrote the title (which was also part of the reason i found trouble searching for the problem online) And I added the part that clears textures during every render because when I didnt the program would run and eventually get slower. I checked my memory usage in task manager while i ran it and noticed that as the program ran it continually accumulated more and more memory until it slowed eveything down. Please tell me if you know why that is.   ;  You are loading the texture every frame from your hard drive when you call CreateTexture() and override the pointer that points to the texture you created the previous frame (texture_1). This is called am memory leak since your program hasn't any means anymore to free the memory of the texture from the last frame and this memory is lost. So your use of memory is increasing during runtime. But when you release the texture every frame this doesn't happen since you freed the memory your pointer was pointing to before you overwrite it again. Therefore your program doesn't leak memory any more. But loading your texture every frame is, like I already said, very unefficient and slow.So try instead to remove the CreateTexture() and the release() call from your rendering function and load the texture at program start (i.e. before your main loop starts), keep the pointer and pass it to your render function every frame and release it when your program ends (after your mainloop).Basically your init_graphics() function is supposed to be called only ONCE to create your texture and vertex buffer and you should release them also only once after your main loop.If anything is still unclear, feel free to post here again, I will try to elaborate.And BTW this is exactly the kind of problem many people encounter who learn from directxtutorial.com. You might be better off buying a good DirectX book that will teach you right.   ;  DirectX is based around COM, and all its resource objects inherit from IUnknown.  Therefore all D3D Resource objects are reference counted.  When you pass your null texture pointer into CreateTexture, D3D "new's" a texture object, and assigns the address to the pointer you passed in.  It also increments the reference count by 1.  (Remember all resource objects derive from the common IUnknown interface)From there on it is your responsibility to use your resource and then when you have finished with it you need to call Release(), which will decrement the ref count and effectivily delete the memory if the ref count is 0.  If you don't release it, it will never get cleaned up....e.g// DirectX // (Whats happening)Foo* obj = 0;CreateFoo(&obj); //obj = new Foo();  obj->refCount++;obj->Release();  //obj->refCount--;   if(obj->refCount == 0) delete obj;If you look at the C++ equivelent of whats happening in the code above, it should be preety clear on why you was leaking memory before, if not then I recommend you look over some C++ books in regards to mem managament.Its a good idea to run DX in debug mode because it can detect any memory leaks.  To do this go to your dx control panel and select the debug mode.   ;  Ok I think i get the perpindicular thing now but i want to be able to control the up vector of the camera using shift + left or shift + right and i cant quite figure out the math behind it. Here's an attempt.static float distance = 10.0f;static float horiangle = 0.0f;static float vertangle = 90.0f;static float camrightangle = 0.0f;static float xpos = 0.0f;static float zpos = 0.0f;static float ypos = 0.0f;static float rotationx = 0.0f;static float rotationy = 0.0f;static float rotationz = 0.0f;static float xright = 1.0f;static float yright = 0.0f;static float zright = 0.0f;if(KEY_DOWN(VK_UP) && distance >= 7.0f){distance -=  0.5f;}if(KEY_DOWN(VK_DOWN)){distance += 0.5f;}if(KEY_DOWN(VK_RIGHT) && KEY_UP(VK_SHIFT)){horiangle += 4.0f;}if(KEY_DOWN(VK_LEFT) && KEY_UP(VK_SHIFT)){horiangle -= 4.0f;}if(KEY_DOWN(VK_PRIOR) && vertangle > 0){vertangle -=3.0f;}if(KEY_DOWN(VK_NEXT) && vertangle < 180){vertangle +=3.0f;}if(KEY_DOWN(VK_RIGHT) && KEY_DOWN(VK_SHIFT)){camrightangle += 4.0f;}if(KEY_DOWN(VK_LEFT) && KEY_DOWN(VK_SHIFT)){camrightangle -= 4.0f;}xpos = distance * sin(D3DXToRadian(horiangle)) * sin(D3DXToRadian(vertangle));ypos = distance * cos(D3DXToRadian(vertangle)) ;zpos = distance * cos(D3DXToRadian(horiangle)) * sin(D3DXToRadian(vertangle));xright = xpos + distance * sin(D3DXToRadian(camrightangle)) * sin(D3DXToRadian(horiangle));yright = ypos + distance * cos(D3DXToRadian(vertangle)) ;zright = zpos + distance * cos(D3DXToRadian(camrightangle)) * sin(D3DXToRadian(horiangle));D3DXMATRIX matView;    // the view transform matrixD3DXVECTOR3 CamPos(xpos, ypos, zpos);D3DXVECTOR3 LookAt(0.0f, 0.0f, 0.0f);D3DXVECTOR3 Right(xright, yright, zright);D3DXVECTOR3 ViewVec = LookAt - CamPos;D3DXVECTOR3 Up;D3DXVec3Cross(&Up, &Right, &ViewVec);D3DXVec3Normalize(&Up, &Up);D3DXMatrixLookAtLH(&matView,   &CamPos,    // the camera position   &LookAt,    // the look-at position   &Up);    // the up directionIm thinking it would be something along the lines of a slanted circle perpindicular to th camera lookat vector with the 'right' placed somewhere on this circle but i cant get my head around the parametrics.   ;static float distance = 10.0f;static float horiangle = 0.0f;static float vertangle = 0.0f;static float camrightangle = 0.0f;static float xpos = 0.0f;static float zpos = 0.0f;static float ypos = 0.0f;static float rotationx = 0.0f;static float rotationy = 0.0f;static float rotationz = 0.0f;static float xright = 1.0f;static float yright = 0.0f;static float zright = 0.0f;if(KEY_DOWN(VK_UP) && distance >= 7.0f){distance -=  0.5f;}if(KEY_DOWN(VK_DOWN)){distance += 0.5f;}if(KEY_DOWN(VK_RIGHT) && KEY_UP(VK_SHIFT)){horiangle += 4.0f;}if(KEY_DOWN(VK_LEFT) && KEY_UP(VK_SHIFT)){horiangle -= 4.0f;}if(KEY_DOWN(VK_PRIOR) && vertangle > -90){vertangle -=3.0f;}if(KEY_DOWN(VK_NEXT) && vertangle < 90){vertangle +=3.0f;}if(KEY_DOWN(VK_RIGHT) && KEY_DOWN(VK_SHIFT)){camrightangle += 4.0f;}if(KEY_DOWN(VK_LEFT) && KEY_DOWN(VK_SHIFT)){camrightangle -= 4.0f;}xpos = distance * sin(D3DXToRadian(horiangle)) * cos(D3DXToRadian(vertangle));ypos = distance * sin(D3DXToRadian(vertangle)) ;zpos = distance * cos(D3DXToRadian(horiangle)) * cos(D3DXToRadian(vertangle));xright = sin(D3DXToRadian(horiangle-90));yright = 0.0f;zright = cos(D3DXToRadian(horiangle-90));D3DXMATRIX matView;    // the view transform matrixD3DXVECTOR3 CamPos(xpos, ypos, zpos);D3DXVECTOR3 LookAt(0.0f, 0.0f, 0.0f);D3DXVECTOR3 Right(xright, yright, zright);D3DXVECTOR3 ViewVec = LookAt - CamPos;D3DXVECTOR3 Up;D3DXVec3Cross(&Up, &Right, &ViewVec);D3DXVec3Normalize(&Up, &Up);D3DXMatrixLookAtLH(&matView,   &CamPos,    // the camera position   &LookAt,    // the look-at position   &Up);    // the up directionD3DXMATRIX matRoll;D3DXMatrixRotationZ(&matRoll, D3DXToRadian(camrightangle));matView *= matRoll;This should work.But first I'll try to explaining it (I'm not so good at explaining complicated stuff in english, but I'll give it a try :P). Its pretty important, that you understand what this does.You computed your 'right' vector like this.xright = xpos + distance * sin(D3DXToRadian(camrightangle)) * sin(D3DXToRadian(horiangle));yright = ypos + distance * cos(D3DXToRadian(vertangle)) ;zright = zpos + distance * cos(D3DXToRadian(camrightangle)) * sin(D3DXToRadian(horiangle));This is nonsense since your 'right', 'up' and your cameras view direction should build a relative coordinate system that defines the camera space that your hole scene ist transformed into during rendering. So they should have the lenght 1 and be perpendicular (at least in this case since you don't want to scale or stretch the hole scene). You computed a vector from the origin to a point somewhere near the camera, rather than a vector representing the new coordinate spaces' x vector after transformation.I also didn't directly rotate the right and up vectors by camrightangle to create the roll effect you wanted, but rather ignored roll and set the camera only up to face the box and applied a rotation around the z-axis after camera transformation, since this is a lot easier to do.Like this:D3DXMATRIX matRoll;D3DXMatrixRotationZ(&matRoll, D3DXToRadian(camrightangle));matView *= matRoll;I simply created a rotation matrix that will rotate the hole scene around the z-axis (using D3DXMatrixRotationZ())and multiplied it to the camera matrix.This way the hole scene will be first transformed to camera space and then rotated around the z-axis (which is you cameras viewing direction in camera space).I don't think I made things cristal clear, but just ask if you have problems with this. Also it might help you to understand if you read up a bit about linear transformations and matrices in general and about the DirectX transformation pipeline.MSDN - Transformations