[DirectX]Probleme mit Kamera



  • Vielleicht habe ich mich etwas unverständlich ausgedrückt. Ich möchte einfach nur eine ganz normale First-Person-Kamera haben. Wenn ich die Kamera z.B. nach links drehen will, drücke ich NUMPAD4 (Zeile 186). Die Kamera soll sich dann solange nach links drehen, solange ich die Taste gedrückt halte, was sie aber nicht macht, sondern immer nur etwas nach links dreht und dann stehenbleibt odwohl ich die Taste noch gedrückt halte 😮. Wenn ich die Taste dann wieder loslasse, sollte die Kamera ja wenigstens an dieser Stelle stehenbleiben, wo sie gerade hinguckt. Macht sie aber auch nicht, sondern schaut dann wieder in die ursprüngliche Richtung (geradeaus) 😮.



  • Ich hab mir deinen Code nicht durchgelesen, aber vermutlich überschreibst du deine Variable die für die Rotation zuständig ist jedesmal wieder mit 0 (bei jedem Schleifendurchlauf)

    lg, bloodycross


  • Mod

    @Barney Gumble
    tut mir leid, ich sehe nicht wo da die schwierigkeit sein soll. koenntest du genauer sagen wo du ein problem beim einfachen runterimplementieren deines vorhaben hast?
    wieso rotierst du die gamera immer nur ein bisschen, statt sie bei jedem durchgang mehr zu rotieren. wieso setzt du sie dann immer zurueck wenn nichts gedrueckt wird. du koenntest doch einfach das machen was du vor hast.



  • Habe den Code etwas abgeändert. Jetzt springt die Kamera nicht mehr in die Anfangsrichtung zurück, wenn ich die Taste zum Drehen loslasse, sondern bleibt da stehen, wo ich sie hingedreht habe. Allerdings habe ich jetzt ein anderes Problem. Wenn ich die Kamera z.B. nach links drehen lasse, dreht die Kamera sich zwar nach links, ändert aber nach einer bestimmten Zeit die Richtung und dreht sich nach rechts bis zu einem bestimmten Winkel und ändert dann wieder die Richtung und immer so weiter 😮.

    // globale Variablen
    float			radians = 0.079f;   // 5 Grad
    D3DXMATRIX		matView;
    D3DXVECTOR3		vecPosition (0.0f, 0.0f, 20.0f);
    D3DXVECTOR3		vecRight( 1.0f, 0.0f, 0.0f );
    D3DXVECTOR3		vecUp( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3		vecLookAt( 0.0f, 0.0f, 1.0f );
    
    //Render-Funktion
    if(KEY_DOWN(VK_NUMPAD4)) // Kamera nach links drehen
    {
    	D3DXMatrixRotationAxis( &matRotation, &vecUp, radians ); 
    	D3DXVec3TransformNormal( &vecRight, &vecRight, &matRotation ); 
    	D3DXVec3TransformNormal( &vecLookAt, &vecLookAt, &matRotation );
    }
    
    D3DXMatrixLookAtLH(&matView, &vecPosition, &vecLookAt, &vecUp);
    
    d3ddev->SetTransform(D3DTS_VIEW, &matView);
    


  • Keiner? 😞



  • Wie weit dreht es sich den nach rechts bzw links?
    und könntest du mir den ganzen code mal posten?
    damit ich sehen kann was du abgeändert hast?

    noch eine frage?

    wenn ich in c++ in ganz normals fenster compilieren will steht immer die exception file not found von der <d3d10.h> datei!
    es geht einfach nicht sdk installiert und sogar den verweis auf die d3d10.lib gelegt aber steht noch immer da?????

    mfg herao



  • Hier mal der komplette Code:

    // include the basic windows header files and the Direct3D header file
    #include <windows.h>
    #include <windowsx.h>
    #include <d3d9.h>
    #include <d3dx9.h>
    #include <stdio.h>
    
    // define the screen resolution and keyboard macros
    #define SCREEN_WIDTH 1280
    #define SCREEN_HEIGHT 1024
    
    // include the Direct3D Library files
    //#pragma comment (lib, "d3d9.lib")
    //#pragma comment (lib, "d3dx9.lib")
    
    // global declarations
    LPDIRECT3D9					d3d;    // the pointer to our Direct3D interface
    LPDIRECT3DDEVICE9			d3ddev;    // the pointer to the device class
    LPDIRECT3DVERTEXBUFFER9		t_buffer = NULL;    // the pointer to the vertex buffer
    LPD3DXFONT					lpD3DFont   = NULL; 
    RECT						fontRectangle;
    
    // function prototypes
    void initD3D(HWND hWnd);    // sets up and initializes Direct3D
    void render_frame(void);    // renders a single frame
    void cleanD3D(void);    // closes Direct3D and releases memory
    void initGraphics(void);    // 3D declarations
    //void InitD3DFont(void); 
    
    struct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR;};
    
    #define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
    #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
    
    float			radian = 0.079f;   // 5 Grad
    
    D3DXMATRIX		matWorld;			// the world matrix
    D3DXMATRIX		matView;			// the view matrix
    D3DXMATRIX		matProjection;		// the projection transform matrix
    D3DXMATRIX		matRotation;
    D3DXMATRIX		matTranslation, matRotationX, matRotationY, matRotationZ, matTemp;
    D3DXVECTOR3		vecPosition (0.0f, 0.0f, 20.0f);
    D3DXVECTOR3		vecRight( 1.0f, 0.0f, 0.0f );
    D3DXVECTOR3		vecUp( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3		vecLookAt( 0.0f, 0.0f, 1.0f );
    
    D3DCOLOR		fontColor = D3DCOLOR_ARGB(255,0,0,0);  
    //LPCSTR			Text = vecLookAt.x;
    char			szTemp[200];
    HWND hWnd;
    // the WindowProc function prototype
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    
    // the entry point for any Windows program
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        //HWND hWnd;
        WNDCLASSEX wc;
    
        ZeroMemory(&wc, sizeof(WNDCLASSEX));
    
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = (WNDPROC)WindowProc;
        wc.hInstance = hInstance;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.lpszClassName = "WindowClass";
    
        RegisterClassEx(&wc);
    
        hWnd = CreateWindowEx(	NULL, 
    							"WindowClass", 
    							"Our Direct3D Program",
    							WS_EX_TOPMOST | WS_POPUP, 
    							0, 
    							0, 
    							SCREEN_WIDTH, 
    							SCREEN_HEIGHT,
    							NULL, 
    							NULL, 
    							hInstance, 
    							NULL);
    
        ShowWindow(hWnd, nCmdShow);
    
        // set up and initialize Direct3D
        initD3D(hWnd);
    
        // enter the main loop:
    
        MSG msg;
    
        while(TRUE)
        {
            DWORD starting_point = GetTickCount();
    
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                if (msg.message == WM_QUIT)
                    break;
    
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
    
            render_frame();
    
            // check the 'escape' key
            if(KEY_DOWN(VK_ESCAPE))
                PostMessage(hWnd, WM_DESTROY, 0, 0);
    
            while ((GetTickCount() - starting_point) < 25);
        }
    
        // clean up DirectX and COM
        cleanD3D();
    
        return msg.wParam;
    }
    
    // this is the main message handler for the program
    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);
    }
    
    // this function initializes and prepares Direct3D for use
    void InitD3DFont(void)
    {
    
    	D3DXCreateFont( d3ddev, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial", &lpD3DFont );
    }
    void initD3D(HWND hWnd)
    {
        d3d = Direct3DCreate9(D3D_SDK_VERSION);
    
        D3DPRESENT_PARAMETERS d3dpp;
    
        ZeroMemory(&d3dpp, sizeof(d3dpp));
        d3dpp.Windowed = FALSE;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.hDeviceWindow = hWnd;
        d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
        d3dpp.BackBufferWidth = SCREEN_WIDTH;
        d3dpp.BackBufferHeight = SCREEN_HEIGHT;
    
        // create a device class using this information and the info from the d3dpp stuct
        d3d->CreateDevice(D3DADAPTER_DEFAULT,
                          D3DDEVTYPE_HAL,
                          hWnd,
                          D3DCREATE_HARDWARE_VERTEXPROCESSING,
                          &d3dpp,
                          &d3ddev);
    
        initGraphics();    // call the function to initialize the triangle
    	InitD3DFont();
        d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);    // turn off the 3D lighting
    
        return;
    }
    
    // this is the function used to render a single frame
    void render_frame(void)
    {
        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    
        d3ddev->BeginScene();
    
        // select which vertex format we are using
        d3ddev->SetFVF(CUSTOMFVF);
    
        if( KEY_DOWN(VK_UP) )
    	{
    		vecPosition = vecPosition - vecLookAt;
    		vecLookAt = vecPosition - vecLookAt;
    	}
    
    	if( KEY_DOWN(VK_DOWN) )
    	{
    		vecPosition = vecPosition + vecLookAt;
    		vecLookAt = vecPosition + vecLookAt;
    	}
    
    	if( KEY_DOWN(VK_LEFT) )
    	{
    		vecPosition = vecPosition - vecRight;
    		vecLookAt = vecLookAt - vecRight;
    	}
    
    	if( KEY_DOWN(VK_RIGHT) )
    	{
    		vecPosition = vecPosition + vecRight;
    		vecLookAt = vecLookAt + vecRight;
    	}
    
    	if( KEY_DOWN( VK_NUMPAD4 ) )
    	{
    		D3DXMatrixRotationAxis( &matRotation, &vecUp, radian ); 
    		D3DXVec3TransformNormal( &vecRight, &vecRight, &matRotation ); 
    		D3DXVec3TransformNormal( &vecLookAt, &vecLookAt, &matRotation );
    	}
    
    	if( KEY_DOWN( VK_NUMPAD6 ) )
    	{
    		D3DXMatrixRotationAxis( &matRotation, &vecUp, -radian ); 
    		D3DXVec3TransformNormal( &vecRight, &vecRight, &matRotation ); 
    		D3DXVec3TransformNormal( &vecLookAt, &vecLookAt, &matRotation );
    	}
    
    	if( KEY_DOWN(VK_NUMPAD8) )
    	{
    		D3DXMatrixRotationAxis( &matRotation, &vecRight, radian ); 
    		D3DXVec3TransformNormal( &vecUp, &vecUp, &matRotation ); 
    		D3DXVec3TransformNormal( &vecLookAt, &vecLookAt, &matRotation );
    	}
    
    	if( KEY_DOWN(VK_NUMPAD2) )
    	{
    		D3DXMatrixRotationAxis( &matRotation, &vecRight, -radian ); 
    		D3DXVec3TransformNormal( &vecUp, &vecUp, &matRotation ); 
    		D3DXVec3TransformNormal( &vecLookAt, &vecLookAt, &matRotation );
    	}
    	D3DXMatrixLookAtLH(&matView, &vecPosition, &vecLookAt, &vecUp);
    
    	d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView
    
    	D3DXMatrixPerspectiveFovLH( &matProjection, D3DXToRadian(45), (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, 0.0f, 100.0f );
    
        d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the projection
    
        // select the vertex buffer to display
        d3ddev->SetStreamSource(0, t_buffer, 0, sizeof(CUSTOMVERTEX));
    
        // copy the vertex buffer to the back buffer
        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);
    
    	SetRect( &fontRectangle, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
    	//wsprintf( szTemp, "%s", vecLookAt.x );
    	lpD3DFont->DrawText( NULL, "Text.", -1, &fontRectangle, DT_LEFT, D3DCOLOR_ARGB( 255,255,255,255 ) );
    
        d3ddev->EndScene();
    
        d3ddev->Present(NULL, NULL, NULL, NULL);
    
    	return;
    }
    
    // this is the function that cleans up Direct3D and COM
    void cleanD3D(void)
    {
        t_buffer->Release();    // close and release the vertex buffer
        d3ddev->Release();    // close and release the 3D device
        d3d->Release();    // close and release Direct3D
    	if( lpD3DFont )
    	{
    		lpD3DFont->Release();
    		lpD3DFont = NULL;
    	}
        return;
    }
    
    // this is the function that puts the 3D models into video RAM
    void initGraphics(void)
    {
    
    	// create the vertices using the CUSTOMVERTEX struct
        CUSTOMVERTEX t_vert[] =
        {
    		// hinten
    		{ -3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(255, 255, 0), },
    		{ 3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(255, 255, 0), },
    		{ -3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(255, 255, 0), },
    		{ 3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(255, 255, 0), },
    
    		// vorne
    		{ -3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(255, 0, 0), },
    		{ -3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(255, 0, 0), },
    		{ 3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(255, 0, 0), },
    		{ 3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(255, 0, 0), },
    
    		// oben
    		{ -3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    		{ 3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    		{ -3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    		{ 3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    
    		// unten
    		{ -3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    		{ -3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    		{ 3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    		{ 3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(0, 255, 0), },
    
    		// links
    		{ 3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    		{ 3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    		{ 3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    		{ 3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    
    		// rechts
    		{ -3.0f, 3.0f, -3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    		{ -3.0f, -3.0f, -3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    		{ -3.0f, 3.0f, 3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    		{ -3.0f, -3.0f, 3.0f, D3DCOLOR_XRGB(0, 0, 255), },
    
        };
    
        // create a vertex buffer interface called t_buffer
        d3ddev->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX),
                                   0,
                                   CUSTOMFVF,
                                   D3DPOOL_MANAGED,
                                   &t_buffer,
                                   NULL);
    
        VOID* pVoid;    // a void pointer
    
        // lock t_buffer and load the vertices into it
        t_buffer->Lock(0, 0, (void**)&pVoid, 0);
        memcpy(pVoid, t_vert, sizeof(t_vert));
        t_buffer->Unlock();
    
        return;
    }
    

    Wie weit läßt sich schlecht sagen. Geschätzt vielleicht nicht mal 30 Grad.



  • D3DXMatrixRotationAxis( &matRotation, &vecRight, -radian );
    D3DXVec3TransformNormal( &vecUp, &vecUp, &matRotation );
    D3DXVec3TransformNormal( &vecLookAt, &vecLookAt, &matRotation );

    Versuch mal nicht immer die matrix zu verändern sondern den radian!!!!

    zb: onkeydown
    {
    radian+=0.7; oder sowas
    }
    und sonst radian -= 0.7;
    und dann D3DXMatrixRotationAxis( &matRotation, &vecRight, radian );

    aber nicht vergessen die matrix immer vorher auf 0 zu setzen!!!!!!!

    so wird die rotation in dem wert gespeichert und nicht in der matrix!



  • Mit radian += 0.07f passiert genau das Gleiche nur viel schneller. Was meinst du mit "die Matrix immer vorher auf 0 setzen"?



  • Habe die Kamerarotation jetzt mit Quaternionen implementiert. Funktioniert soweit auch ganz gut. Nun habe ich aber noch zwei Fragen:
    1. Wie kann ich aus dem LookAt-Vektor den ich aus dem View-Quaternion bekomme, den Right- und Up-Vektor berechnen?
    2. Wenn ich die Kamera rotiere sieht das immer etwas ruckelig aus. Wie kriege ich eine fließendere Bewegung hin? Habe es schon mit D3DXQuaternionSlerp probiert. Scheint sich aber nichts zu verändern.

    void CCamera::YawPitchRoll( long mouseX, long mouseY, long mouseZ )
    {
    	m_quatOrientation = D3DXQUATERNION( m_vecLookAt.x, m_vecLookAt.y, m_vecLookAt.z, 0 );
    
        D3DXQuaternionRotationYawPitchRoll( &m_quatRotation, 0.035f * mouseX, 0 /*-0.035f * mouseY*/, 0 /*0.007 * mouseZ*/ );
    
    	D3DXQuaternionMultiply( &m_quatView ,&m_quatOrientation, &m_quatRotation 
    
        //D3DXQuaternionSlerp( &m_quatView, &m_quatOrientation, &m_quatView, 0.25f );
    
    	m_vecLookAt = D3DXVECTOR3( m_quatView.x, m_quatView.y, m_quatView.z );
    
    	/* liefert komische Ergebnisse
    	D3DXMatrixRotationQuaternion( &m_matYawPitchRoll, &m_quatView );
    	D3DXVec3TransformNormal( &m_vecRight, &m_vecRight, &m_matYawPitchRoll );
    	D3DXVec3TransformNormal( &m_vecUp, &m_vecUp, &m_matYawPitchRoll );
    	*/	
    }
    


  • Ausgehend von Deinem ersten Post habe ich den Eindruck, dass Du die Grundlagen Deines Programmablaufs einfach nicht verstanden hast. Und nun versuchst Du Dein Problem zu umgehen indem Du Konzepte einsetzt, die Du noch weniger verstehst...



  • Kannst du das ganze mal schnell binär bei www.rapdishare.combzw www.rapdishare.de uploaden. Ich habe auf dem PC hier dummerweise keine SDK-Integration und deswegen möchte ich einfach mal dein Spiel sehen.

    binär = .exe

    Wenn es mehrere Files sind(was icht nicht annehme,hast keine Libs oder) dann musst du es mit WinRAR packen. Danke!

    /edit Mit Anwendungen auf anderen PCs ausführen kenne ich mich aber nicht so aus.


Anmelden zum Antworten