DirectX-Programm sehr langsam



  • Hallo!

    ich habe jetzt mit Direct-X angefangen.

    Hab ein kleines Programm geschrieben, bei dem zwei Dreiecke schwingen sollen.

    Wenn man die linke Pfeiltaste drückt, soll das Programm beenden.

    Das Programm funktioniert auch.

    // script3: Dreieck
    #include <windows.h>
    #include <d3d9.h>		
    #include <math.h>
    
    LPDIRECT3D9       g_pDirect3D = NULL;				
    LPDIRECT3DDEVICE9 MDevice = NULL;		
    		  float x=50.0f;
    		  int   C=0;
    
    LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
       switch(msg)
       {
          case WM_DESTROY:
             PostQuitMessage(0);
             return(0);
    	  case WM_PAINT:		
    		  MDevice->Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
    
    		  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    		  #define CUSTOMFVF (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)		
    		  // CUSTOMFVF für Position und Farbe 
    		  // D3DFVF_XYZRHW: Unser Format hat Position
    		  // D3DFVF_DIFFUSE: Unser Format hat Farbe
    
    		  // make a Point-Struct that fits to our CUSTOMFVF
    		  struct CUSTOMVERTEX
    		  {
    			  FLOAT x, y, z, rhw;		
    			  // FLOAT-Typ kommt daher, dass wir D3DFVF_XYZRHW eingebunden haben 
    
    			  DWORD color;				
    			  // DWORD " D3DFVF_DIFFUSE " (analog)
    		  };
    
    		  // Wir machen uns einen Punkt
    		  CUSTOMVERTEX OurVertex = {320.0f, 50.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0)}; 
    
    		  x += 0.05f;
    
    		  // Wir machen uns eine Punktliste
    		  CUSTOMVERTEX OurTriangleVertices[] = 
    		  {
    			  {100.0f-50.0f*sin(x), 200.0f-50.0f*sin(x), 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0  )},		// triangle1: to be ordered like a clock
    			  {200.0f-50.0f*sin(x), 200.0f-50.0f*sin(x), 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0  )},
    			  {100.0f-50.0f*sin(x), 300.0f-50.0f*sin(x), 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0  )},
    			  {200.0f+50.0f*sin(x), 200.0f+50.0f*sin(x), 1.0f, 1.0f, D3DCOLOR_XRGB(  0, 0, 255)},	// triangle2: to be ordered like a clock
    			  {100.0f+50.0f*sin(x), 200.0f+50.0f*sin(x), 1.0f, 1.0f, D3DCOLOR_XRGB(  0, 0, 255)},
    			  {200.0f+50.0f*sin(x), 100.0f+50.0f*sin(x), 1.0f, 1.0f, D3DCOLOR_XRGB(  0, 0, 255)}
    		  };
    
    		  // Create Vertex-Buffer that saves all data about our triangle
    		  LPDIRECT3DVERTEXBUFFER9 v_buffer;
    
    		  MDevice->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX),
    									 0,CUSTOMFVF,D3DPOOL_MANAGED,
    									 &v_buffer ,0);
    
    		  // lock our buffer
    		  VOID* pVoid;
    		  v_buffer->Lock(0, 0, (void**)&pVoid, 0);
    
    		  // copy vertices in vertex buffer
    		  memcpy(pVoid, OurTriangleVertices, sizeof(OurTriangleVertices));
    
    		  // tell DirectX: we're done, don't do anything further ; unlock the buffer
    		  v_buffer->Unlock();
    
    		  MDevice->BeginScene();
    
    		  // tell DirectX that we're working with CUSTOMFVF-Format
    		  MDevice->SetFVF(CUSTOMFVF);
    
    		  // we're drawing from v_buffer
    		  MDevice->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
    
    		  // copy vertex buffer to backbuffer
    		  MDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
    
    		  MDevice->EndScene();
    		  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    		  MDevice->Present(0, 0, 0, 0);
    		  ValidateRect(hwnd, NULL);
    		  return 0;
       }
    
       return(DefWindowProc(hwnd, msg, wParam, lParam));
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShow)
    {
       MSG msg;
    
       WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW, 
                        WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), 
                        NULL, "DX9_TUTORIAL1_CLASS", NULL};
    
       RegisterClassEx(&wc);
    
       HWND hMainWnd = CreateWindow("DX9_TUTORIAL1_CLASS",
    
                                    "DirectX 9 Bare Bones Tutorial 1", 
                                    WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
    
                                    NULL, NULL, hInstance, NULL);
    
    	g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
    
    	D3DPRESENT_PARAMETERS PresentParams;
    	memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS));
    
    	PresentParams.Windowed = TRUE;
    	PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
    
    	g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd,
                              D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,
                              &MDevice);
    
       ShowWindow(hMainWnd, nShow);
       UpdateWindow(hMainWnd);
    
       while(true)
       {
    	   SendMessage(hMainWnd, WM_PAINT, 0, 0);
    
    	   // Zusatz: Tastaturstatus verarbeiten
    	   MSG msg;		// windows-message
    
    	   GetMessage(&msg, 0, 0, 0);
    
    	   if(/*msg.message == WM_KEYDOWN */msg.wParam==VK_LEFT)
    		   return 0;
       }
    
    	MDevice->Release();	
    	g_pDirect3D->Release();			
    
    	return(0);
    }
    

    Mein Problem ist nur:
    das Programm ist extrem langsam.

    Weiß jemand woran das liegt, und wie man den Fehler beheben kann ?

    Danke im Voraus und Freundliche Grüße



  • Wie misst du langsamkeit?



  • Hallo!

    mit Langsamkeit meine ich:

    die Dreiecke werden tw. nur stockend gezeichnet.

    Wenn ich auf die linke Pfeiltaste (zum Beenden) drücke, dauert es, bis das Programm reagiert.

    Freundliche Grüße



  • Das könnte daran liegen, dass du die message queue mit WM_PAINT nachrichten überschüttest. Da muss deine Nachricht desTastendrucks halt so lange warten, bis die ganzen Zeichenbefehle durch sind.



  • Schreib eine ordentliche Message Loop.

    Du erzeugst ständig neue Vertex Buffer und leakest diese auch noch. Besser wäre es wohl, einen Vertex Buffer zu erzeugen und diesen dann dynamisch upzudaten... 😉

    Verwend InvalidateRect(), um ein Neuzeichnen deines Fensters zu erwirken. Eine Anwendung sollte niemals direkt WM_PAINT senden.

    Verwend 0 als Background Brush für dein Fenster. Behandle WM_ERASEBKGND in deiner WndProc, dort einfach nichts tun und irgendwas != 0 returnen, damit Windows nicht immer sinnlos den Hintergrund deines Fensters zeichnen muss, nur damit dieser von dir in weiterer Folge übermalt werden kann...

    Zusätzlicher Hinweis: Direct3D 9 ist steinalt.


Anmelden zum Antworten