nur 60 FPS??



  • Hey,

    ich hab mit DirectX-Programmierung angefangen und nun bin ich jedoch sehr verwundert, dass ich nur 60FPS hab, wenn kein Objekt rendern lasse, sondern nur den Bildschirm blau mache. Die Beispiele aus dem DX-SDK laufen mit mindestens 100FPS.
    Ich habe mir dafür eine Klasse erstellt:

    #include "bky_tictimer.h"
    #include <stdio.h>
    
    struct CREATE_D3DDEVICE {
        int Adapter;
    	D3DDEVTYPE DeviceType;
    	HWND hFocusWindow;
    	ULONG BehaviorFlags;
    	D3DPRESENT_PARAMETERS *pPresentationParameters;
    	LPDIRECT3DDEVICE9 d3ddev;
    };
    
    struct CUSTOMVERTEX {
    	FLOAT X, 
    		Y, 
    		Z, 
    		RHW; 
    	DWORD COLOR;
    };
    #define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
    
    class BkyEngine
    {
    	private:
    		DWORD FPSTime,FPSLength;
    		HWND hWnd;
    		CREATE_D3DDEVICE D3DDev;
    		LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface
    		LPDIRECT3DVERTEXBUFFER9 VertBuff;    // the pointer to the vertex buffer
    		CUSTOMVERTEX t_vert;
    
    		LPD3DXFONT font;
    		HFONT hFont;
    
    		float index;
    	public:
    		BOOL bPause;
    		TicTimer *tics; //Klasse zur Exakten Framedauer- und FPS-berechnung
    
    		BkyEngine();
    		void __fastcall Start(void);
    		void __fastcall SetD3DParameter(HWND hWnd, CREATE_D3DDEVICE D3DParameter);
    		void __fastcall Init3DObjects(void);
    		void __fastcall CalcFrame(void);
    		void __fastcall RenderFrame(void);
    		void __fastcall Resize(void);
    		void __fastcall Clean(void);
    		void __fastcall ShowText(LPCSTR text, int top, int left, int width, int height);
    };
    
    BkyEngine::BkyEngine()
    {
    	tics = new TicTimer();
    	VertBuff = NULL;
    	bPause = false;
    	index = 0.0f;
    }
    
    void __fastcall BkyEngine::SetD3DParameter(HWND hWND, CREATE_D3DDEVICE D3DParameter)
    {
    	hWnd = hWND;
    	D3DDev = D3DParameter;
    }
    
    void __fastcall BkyEngine::Start(void)
    {
        d3d = Direct3DCreate9(D3D_SDK_VERSION);
    
        // create a device class using this information and the info from the d3dpp stuct
        d3d->CreateDevice(D3DDev.Adapter,
                          D3DDev.DeviceType,
                          D3DDev.hFocusWindow,
                          D3DDev.BehaviorFlags,
                          D3DDev.pPresentationParameters,
                          &D3DDev.d3ddev);
    
    	D3DDev.d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);    // turn off the 3D lighting
    	D3DDev.d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
    
        return;
    }
    void __fastcall BkyEngine::Init3DObjects(void)
    {
    
        // create a vertex buffer interface called t_buffer
        D3DDev.d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
                                   0,
                                   CUSTOMFVF,
                                   D3DPOOL_MANAGED,
                                   &VertBuff,
                                   NULL);
    
    	hFont = CreateFont(20,              // Logische Höhe
    				0,               // Logische durchschnittliche Breite
    				0,          
    				0,         
    				FW_BOLD,             // "Gewicht" der Schriftzeichen
    				false,          // Italic ja/nein
    				false,       // Unterstrichen ja/nein
    				false,       // Durchgestrichen ja/nein
    				ANSI_CHARSET,         // Verwendeter Zeichensatz
    				OUT_DEFAULT_PRECIS, // Grad der Übereinstimmung
    				CLIP_DEFAULT_PRECIS,   // Clipping Verhalten
    				ANTIALIASED_QUALITY,         // Darstellungsqualität
    				DEFAULT_PITCH,  // Zeichenabstand und Schriftartenfamilie
    				L"Arial"          // Name der Schriftart
    			);
    
    	D3DXCreateFont(D3DDev.d3ddev,hFont,&font);
    }
    void __fastcall BkyEngine::CalcFrame(void){
    //Hier kommen später Berechnungen für die ganzen Objekte rein
    }
    void __fastcall BkyEngine::RenderFrame(void)
    {//Stellt sätliche Objekte dar
    
         // clear the window to a deep blue
    	D3DDev.d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
        D3DDev.d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
    
    	D3DDev.d3ddev->BeginScene();    // begins the 3D scene
    
    		//FPS-Zeit ausgeben
    		char frequenz[16];
    		sprintf(frequenz, "FPS: %d", tics->FPS);
    		ShowText(frequenz,10,10,100,20);
    
    	// end 3D rendering on the back buffer here
    
        index += 0.05f; // an ever-increasing float value
        D3DXMATRIX matRotateZ;
        D3DXMatrixRotationZ(&matRotateZ, index);
        // copy the vertex buffer to the back buffer
        D3DDev.d3ddev->SetTransform(D3DTS_WORLD, &(matRotateZ));
    		D3DDev.d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
    
        D3DDev.d3ddev->EndScene();    // ends the 3D scene
        D3DDev.d3ddev->Present(NULL, NULL, NULL, NULL);   // displays the created frame on the screen
    }
    void __fastcall BkyEngine::Resize(void)
    {}
    void __fastcall BkyEngine::Clean(void)
    {
    	font->Release();
      	VertBuff->Release();    // close and release the vertex buffer
    	D3DDev.d3ddev->Release();    // close and release the 3D device
    	d3d->Release();    // close and release Direct3D
    }
    void __fastcall BkyEngine::ShowText(LPCSTR text, int top, int left, int width, int height)
    {
    	// Create a rectangle to indicate where on the screen it should be drawn
    	RECT textbox;
    	SetRect(&textbox, left, top, left+width, top+height); 
    
    	font->DrawTextA(text,-1,&textbox,DT_VCENTER,D3DCOLOR_ARGB(255, 255, 255, 255));
    
    }
    

    SO, das war der erste batzen Quelltext, nun kommt noch die WinMain:

    #define SCREEN_WIDTH  640
    #define SCREEN_HEIGHT 480
    BkyEngine *bky_engine = new BkyEngine();
    
    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.hbrBackground = (HBRUSH)COLOR_WINDOW;
        wc.lpszClassName = L"WindowClass";
    
        RegisterClassEx(&wc);
    
        hWnd = CreateWindowEx(NULL,
    						L"WindowClass",
    						L"Our First Direct3D Program",
    						WS_EX_TOPMOST | WS_POPUP,
    //						WS_OVERLAPPED,
    						0, 0,
    						SCREEN_WIDTH, SCREEN_HEIGHT,
    						NULL,
    						NULL,
    						hInstance,
    						NULL);
    
        ShowWindow(hWnd, nCmdShow);
    
        // set up and initialize Direct3D
    
        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 Direct3D
    	//für Vollbild:
    	d3dpp.Windowed = false;
        d3dpp.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
    
    	CREATE_D3DDEVICE myD3Ddev;
    	myD3Ddev.Adapter = D3DADAPTER_DEFAULT;
    	myD3Ddev.DeviceType = D3DDEVTYPE_HAL;
    	myD3Ddev.hFocusWindow = hWnd;
    	myD3Ddev.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    	myD3Ddev.pPresentationParameters = &d3dpp;
    	myD3Ddev.d3ddev = NULL;
    
    	bky_engine->SetD3DParameter(hWnd,myD3Ddev);
    	bky_engine->Start();
    	bky_engine->Init3DObjects();
    
        // enter the main loop:
    
        MSG msg;
    	ZeroMemory(&msg,sizeof(msg));
    
    	while(msg.message != WM_QUIT)
    	{
    		if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    		else
    		{
    			bky_engine->tics->CalcTimer();
    			if(bky_engine->bPause == false)
    			{
    				bky_engine->CalcFrame();
    			}
    			bky_engine->RenderFrame();
    		}
    	}
    
        // clean up DirectX and COM
    	bky_engine->Clean();
    
        return msg.wParam;
    }
    

    Neben den nur 60 FPS habe ich noch ein 2. Problem:
    Was muss in die Funktion BkyEngine::Resize() rein, damit das Programm auch nach der Größenänderung des Fensters noch seinen dienst tut?

    Danke schon mal! 🤡


  • Mod

    vsync ist aktiviert. die doku oder forensuche duerfte dir detaillierte hilfe bieten 😉



  • Wunderbar, Danke:)
    Weist du auch was zu dem Resize?
    Wenn ich das Fenster minimiere und wiederherstellen will, kommt da kein Bild mehr.


  • Mod

    vielleicht device lost? da hilft dir die doku auch weiter, ich glaube bei present bekommst du das als return value.
    sorry, zu lange her und das macht man ja auch nur einmal und dann geht's 😉



  • Ich werd mir mal bei gelegenheit code ausm internet fischen, das ist ja erst mal nicht so wichtig. Viel wichtiger ist aber, dass ich komischerweise keine Transformationen durchführen kann und auch nicht die Kameraposition exakt setzten.
    In Zeile 135 des bereits geposteten Quelltextes steht, dass mein Vertex (Koordinaten hatte ich aus dem posting gelöscht) etwas rotiert werden soll. Den Increment-wert habe ich auf die FPS-Zahl angepasst. Jedoch bleibt das Dreieck einfach still stehen.
    In vorherigen Projekten ohne die Klasse hat das jedoch funktioniert. 😕



  • Es lag an meinem CUSTOMFVF-struct. Das RHW ist zu viel...


Anmelden zum Antworten