Daten von der Grafikkarte zurück an den Hauptprozessor senden



  • Geht leider auch nicht! Ich habe echt das Gefühl, dass das Problem an einem anderen Ort liegen muss...

    Hier noch der Initialisierungscode:

    // --------------------------------- global function "WinMain" --------------------------------
    int __stdcall WinMain(HINSTANCE hIns,HINSTANCE hPrv,LPSTR pCmd,int nShowCmd){
     // create the IDirect3D interface and determine the device caps
     IDirect3D9 *p3D = Direct3DCreate9(D3D_SDK_VERSION);
    
     // define the behaviour of the main - window
     WNDCLASSEX wc    = {0x00};
     wc.cbSize        = sizeof(WNDCLASSEX);
     wc.lpszClassName = APP;
     wc.hInstance     = hIns;
     wc.style         = CS_HREDRAW|CS_VREDRAW;
     wc.lpfnWndProc   = &WndProc;
     wc.hIcon         = wc.hIconSm = 0x00;
     wc.hCursor       = LoadCursor(0,IDC_ARROW);
     wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE+1);
     RegisterClassEx(&wc);
    
     // create a new window, init Kyrivial and set the mainscreen as focused
    	HWND hWnd = CreateWindowEx(0,APP,APP,WS_OVERLAPPEDWINDOW,0,0,640,480,0,0,hIns,p3D);
    
     // determine the current display mode
     D3DDISPLAYMODE dm;
     p3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&dm);
    
     // define the behaviour of the renderdevice
     D3DPRESENT_PARAMETERS pp;
    	ZeroMemory(&pp,sizeof(D3DPRESENT_PARAMETERS));
    	pp.hDeviceWindow          = hWnd;
    	pp.Windowed               = true;
    	pp.PresentationInterval   = D3DPRESENT_INTERVAL_ONE;
    	pp.BackBufferCount        = 1;
    	pp.BackBufferWidth        = dm.Width;
    	pp.BackBufferHeight       = dm.Height;
    	pp.BackBufferFormat       = dm.Format;
    	pp.MultiSampleType        = D3DMULTISAMPLE_NONE;
    	pp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
    
     // finally create the render - device
     IDirect3DDevice9 *pDv = 0x00;
     p3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,HWD,&pp,&pDv);
     SetWindowLong(hWnd,GWL_USERDATA,reinterpret_cast<long>(pDv));
    
     // show and update the window
    	ShowWindow(hWnd,SW_SHOW);
    	UpdateWindow(hWnd);
    
     // declare a message identifier
     MSG uMsg;
    
     // start a loop for catching all system - events
     while(GetMessage(&uMsg,0,0,0)){
      // translate and dispatch the current system - event
      TranslateMessage(&uMsg);
      DispatchMessage(&uMsg);
     }
    
     // release the render device and the Direct3D interface
     pDv->Release();
     p3D->Release();
    
     // return the return code of the quit message
     return uMsg.wParam;
    }
    // --------------------------------------------------------------------------------------------
    


  • this->that: Nun verwirr' den Mann doch nicht unnoetig. Denk Dir "col" als dword und dann passt's doch:

    float arrTmp2[3][5] = {
    //  x     y     z     w      col
      {0.0f, 0.0f, 0.0f, 1.0f,  0.0f},
      {5.0f, 0.0f, 0.0f, 1.0f,  0.0f},
      {5.0f, 5.0f, 0.0f, 1.0f,  0.0f}
    };
    


  • @hellihjb Sag ich doch!!! :xmas1:



  • Setz' mal D3DPRESENT_PARAMETERS::EnableAutoDepthStencil und D3DPRESENT_PARAMETERS::AutoDepthStencilFormat



  • hellihjb schrieb:

    this->that: Nun verwirr' den Mann doch nicht unnoetig. Denk Dir "col" als dword und dann passt's doch:

    float arrTmp2[3][5] = {
    //  x     y     z     w      col
      {0.0f, 0.0f, 0.0f, 1.0f,  0.0f},
      {5.0f, 0.0f, 0.0f, 1.0f,  0.0f},
      {5.0f, 5.0f, 0.0f, 1.0f,  0.0f}
    };
    

    Was heißt verwirren? IMO ist das falsch. DIFFUSE erwartet einen DWORD und nur weil es geht, da er einfach das Bitmuster des Floats als DWORD interpretiert soll es richtig sein?

    edit: @D3DPRESENT_PARAMETERS::EnableAutoDepthStencil: Sollte eigentlich keine Rolle spielen, da er eh nur transformierte Vertices benutzt.



  • es geht doch darum dass er nichts sieht.
    dass der code erhebliche neustrukturierung benoetigt brauchen wir nicht zu diskutieren.

    EnableAutoDepthStencil: Sollte eigentlich keine Rolle spielen, da er eh nur transformierte Vertices benutzt

    stimmt.



  • hellihjb schrieb:

    es geht doch darum dass er nichts sieht.
    dass der code erhebliche neustrukturierung benoetigt brauchen wir nicht zu diskutieren.

    Japp, aber da er leider nie genau schreibt was nun passiert, kann das auch bedeuten dass er nirgends die Punkte (oder Dreiecke) sieht.
    Nicht ohne Grund hab ich bereits auf Seite 2 gefragt:

    this->that schrieb:

    Zeichnet er wenigstens einen roten Hintergrund?

    Aber leider hat er darauf ja nicht geantwortet. 🙄



  • p3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,HWD,&pp,&pDv);
    

    was ist "HWD" ?



  • dass der code erhebliche neustrukturierung benoetigt brauchen wir nicht zu diskutieren.

    Das sehe ich genauso, allerdings möchte ich diesen Aufwand nicht betreiben, solange noch nicht einmal ein Dreieck gerendert wird.

    @this->that
    Es wird ein "blauer" Hintergrund gezeichnet (durch das Clear Target) allerdings wird eben im Folgenden nichts gerendert.

    #define HWD D3DCREATE_HARDWARE_VERTEXPROCESSING



  • Also ich bin nun einen Schritt weiter gekommen: Folgender Code rendert in der Fixed Function Pipeline. Sobald ich jedoch auf den Vertex Shader umschalte, rendert er gar nichts mehr 😕
    Sieht hier jemand den Fehler? Ich komme echt nicht mehr weiter!

    // determine the content of the code edit - control
      char buf[] = {
       "vs.1.1\n"
       "dcl_position v0\n"
       "dcl_color v1\n"
       "mov oPos,v0\n"
       "mov oD0,v1"
      }; 
    
    IDirect3DVertexShader9 *pVs = 0x00;
    
      // try to assemble the vertex - shader machine instructions
      if(D3DXAssembleShader(buf,strlen(buf),0x00,0x00,0,&pBufShd,&pBufErr) == D3D_OK){
       // create the vertex - shader
       pDv->CreateVertexShader((DWORD*)pBufShd->GetBufferPointer(),&pVs);
       pDv->SetVertexShader(pVs);
    
       D3DVERTEXELEMENT9 ve[] = {
        {0,0,D3DDECLTYPE_FLOAT4,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION},
        {0,4,D3DDECLTYPE_UBYTE4,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR},
        D3DDECL_END()
       };
    
       IDirect3DVertexDeclaration9 *pVd;
       pDv->CreateVertexDeclaration(ve,&pVd);
    
       // wenn ich diesen Kommentar wegnehme und somit den vertex shader aktiviere,
       // rendert er nichts mehr. WTF???
       //pDv->SetVertexDeclaration(pVd);
    
       pDv->Clear(0,0x00,D3DCLEAR_TARGET,0xffffffff,1.0f,0);
       pDv->BeginScene();
       float arrVt[3][5] = {{50.0f,50.0f,0.0f,1.0f,0.0f},{250.0f,250.0f,0.0f,1.0f,0.0f},{50.0f,250.0f,0.0f,1.0f,0.0f}};
       pDv->DrawPrimitiveUP(D3DPT_TRIANGLELIST,1,arrVt,5*sizeof(float));
       pDv->EndScene();
       pDv->Present(0x00,0x00,0,0x00);
    


  • Der Offset deiner Color VertexDecl ist falsch. Der Offset wird in Byte angegeben, muss also bei dir 16 statt 4 sein.



  • @this->that

    Danke für den Hinweis, das war tatsächlich falsch! Siehst du noch einen Fehler? Es wird leider noch immer nichts gerendert.



  • Naja, mir würden noch einige Sachen einfallen, die du ausprobieren könntest (Pixelshader, Viewport, Renderstates checken etc.), aber am auffälligsten find ich folgendes:
    1. Meiner Meinung nach ergibt deine Farbangabe nach wir vor keinen Sinn. Du sagst der Pipeline, dass deine Farben als ubyte4 vorliegen, aber definierst sie per float. Definier doch auch deine Farben so, wie du es in der VertexDecl beschreibst.

    2. Vermutlich sollen deine Vertexpositionen Screenspace Positionen darstellen, oder? Das ergibt aber wenig Sinn, da du einen Pass through VS hast und die Pipeline erwartet, dass die Positionen, die aus dem VS rauskommen, im Projection Space sind (-w <= x,y <= w und 0 <= z <= w). Diese Positionen werden dann noch dividiert durch w (bei dir egal, da die alle 1 sind) und dann noch durchs Viewport Mapping gejagt, was Müll ergibt.
    Versuch es mal mit Vertices, deren Positionen bereits im Clip Space sind, also z.B. sowas:

    float arrVt[3][5] = {
    {0.0f, 0.0f, 0.0f, 1.0f, 0xFF0000FF},
    {0.0f, 0.5f, 0.0f, 1.0f, 0xFF0000FF},
    {0.5f, 0.0f, 0.0f, 1.0f, 0xFF0000FF}}
    


  • Ja jetzt rendert er tatsächlich etwas! Yuhuuuu! 🙂

    Aber jetzt noch mal zum mitschreiben...

    Pipeline erwartet, dass die Positionen, die aus dem VS rauskommen, im Projection Space sind (-w <= x,y <= w und 0 <= z <= w).

    Siehst du, genau da liegt mein Problem! Woher weisst du das? In der offiziellen Referenz von Microsoft steht folgendes geschrieben:

    oPos Position Register FERTIG!
    http://msdn.microsoft.com/en-us/library/bb172960(VS.85).aspx

    Ich habe ein Buch neben mir liegen, dass fast ausschliesslich von Vertexshadern und Pixelshadern handelt und da steht folgendes geschrieben:

    Zitat:

    The position data must be in transformed homogeneous screen coordinates, or you don't see anything on the screen.

    Kannst du mir eine gute Resource angeben, wo genau beschrieben wird, wie die Programmable Rendering Pipeline aufgebaut ist, wie sie funktioniert und in welcher Form die Parameter vorliegen müssen?

    PS.
    Ich habe für die Farbe float verwendet, weil es meiner Meinung nach für die Problemlösung irrelevant ist, ich meine 0.0f hat das bitmuster 00000000.....$
    ob ich das nun als float oder DWORD oder UINT oder int oder was auch immer definiere.. (Ich kenne Assembler relativ gut, denke ich 🙂



  • Ishildur schrieb:

    Siehst du, genau da liegt mein Problem! Woher weisst du das? In der offiziellen Referenz von Microsoft steht folgendes geschrieben:

    Meiner Meinung nach sind die DX Dokus eher mäßig und verdienen eigentlich auch nicht die Bezeichnung Doku. IMO ist es eher eine Referenz für Leute, die schon Erfahrung mit 3D-Programmierung/DX haben. Das gilt für die DX10 Doku noch mehr als für die DX9 Doku...

    Ich kenne leider auch keine guten Tutorials, die die DX Pipeline beschreiben. Ich habe mir mehrere kleinere Artikel/Tutorials ergoogelt und daraus dann versucht ein Gesamtbild zu bauen. Ziemlich hilfreich fand ich dieses Poster: http://www.xmission.com/~legalize/book/preview/poster/pipeline-9.0.png

    The position data must be in transformed homogeneous screen coordinates, or you don't see anything on the screen.

    In welchem Kontext steht das? Meistens (leider wird nicht immer die gleiche Terminologie verwendet) bezeichnet man mit den Screen Coordinates die finalen 2D Koordinaten im Rendertarget.

    Ishildur schrieb:

    Ich habe für die Farbe float verwendet, weil es meiner Meinung nach für die Problemlösung irrelevant ist, ich meine 0.0f hat das bitmuster 00000000.....$

    Das Bitmuster von 0.0f muss NICHT zwangsläufig aus lauter Nullern bestehen. Und selbst wenn es so wäre, finde ich es einfach unschön völlig grundlos einen anderen Datentyp anzugeben, weil vielleicht das Bitmuster uminterpretiert auch stimmen könnte. Aber naja, ist ja dein Code;)



  • bezeichnet man mit den Screen Coordinates die finalen 2D Koordinaten im Rendertarget.

    Ja, aber was bedeutet das? Wo ist der Koordinatenursprung und wie sieht die skalierung aus.

    Wo ist x=0,y=0 ? Am linken oberen Rand? am linken unteren Rand? in der Mitte?
    Welche Position is ganz rechts? Ist es abhänging von der Auflösung des Rendertargets? Ist es von 0.0f - 1.0f ? von -1.0f - 1.0f oder 0.0f - 640.0f

    Das sind alles Fragen, auf die ich nirgends eine Antwort finde... 😞



  • Damit die ganzen Transformationen (Projektion etc.) unabhängig von der konkreten Auflösung des Rendertargets (z.B. 800x600 sind), verwendet man sog. Normalized Device Coordinates (Koordinaten im Normalized Device Space).

    Nach der Projektionstransformation (+ Homogenen Division) befinden sich die Positionen in diesem Normalized Device Space. In OpenGL ist das ein Einheitswürfel [-1,1]^3 und in DX sieht der genauso aus, nur das die z-Achse von 0 bis 1 geht, anstatt von -1 bis 1. Das kannst du dir einfach als relative Koordinaten vorstellen: (1,1) ist ganz oben rechts im finalen Bild und (-1,-1) ganz links unten. Um nun konkrete Pixelkoordinaten zu erzeugen (also eine Transformation vom NDS => Screenspace), verwendet man das Viewport Mapping. Das ist im Grunde nur eine Translation (da der Ursprung des NDS im Zentrum liegt und der Ursprung im Screen Space in einer Ecke; meistens links oben) + Skalierung (um eben die 2x2 Fläche auf die absolute Größe (z.B. 800x600) zu skalieren) sowie eine Spiegelung entlang der y-Achse (da im NDS die y-Koordinate nach obne zeigt aber im Screenspace für gewöhnlich nach unten). Der Ursprung (0,0) des Screenspace ist also oben links und bei einem 800x600 Rendertarget wäre der Pixel rechts unten (799,599).



  • Hehe, was du alles weisst! 😉
    Ich glaube, ich habe alles verstanden, bis auf diese Homogenität. Ich dachte, um ein Bild zu rastern, müssen die x sowie die y koordinaten eines Positionsvektor durch die z koordinate dividiert werden? Aber wofür braucht es dann nocht w? Welchen Zweck erfüllt es?

    Ach ja, eines noch. Wo findet dieses Mapping statt? Offenbar nicht im Vertexshader, sondern erst hinterher vom Rasterizer?

    Mein Problem ist, dass ich ja die Daten wieder aus dem Rendertarget rauslesen will und ich dachte mir, der 1ste Pixel ist das Resultat der ersten Berchnung, der zweiter Pixel das Resultat der 2ten Berechnung usw.

    Auf diese Weise kann ich ja aber nie genau wissen, an welcher Position im Rendertarget denn nun mein Punkt des Vertex liegt, oder sehe ich das falsch?



  • Ishildur schrieb:

    Ich dachte, um ein Bild zu rastern, müssen die x sowie die y koordinaten eines Positionsvektor durch die z koordinate dividiert werden? Aber wofür braucht es dann nocht w? Welchen Zweck erfüllt es?

    Genau diesen;) Wenn du einen Vektor v=(x,y,z,1) im View Space mit der Projektionsmatrix transformierst, ergibt das einen Vektor v'z=(x'z, y'z, z'z, z) im Projection Space. Schau dir mal die Matrix an, die D3DXMatrixPerspectiveFovLH ( http://msdn.microsoft.com/en-us/library/bb205350(VS.85).aspx ) liefert. Der letzte Spaltenvektor ist (0,0,1,0)^T, ergo wird w von v' lediglich auf z gesetzt. Bei der perspektivischen Division (alias Homogeneous Division) wird nun durch w geteilt (sprich: durch z), um aus v'z Vektor v' zu machen.

    Ishildur schrieb:

    Ach ja, eines noch. Wo findet dieses Mapping statt? Offenbar nicht im Vertexshader, sondern erst hinterher vom Rasterizer?

    Nach dem VS und vor dem Triangle Setup (also auch vorm PS).

    Ishildur schrieb:

    Mein Problem ist, dass ich ja die Daten wieder aus dem Rendertarget rauslesen will und ich dachte mir, der 1ste Pixel ist das Resultat der ersten Berchnung, der zweiter Pixel das Resultat der 2ten Berechnung usw.

    Was meinst du genau mit "Berechnung"? Der Pixelshader wird für jedes Fragment eines sichtbaren Polygons aufgerufen.



  • Auf diese Weise kann ich ja aber nie genau wissen, an welcher Position im Rendertarget denn nun mein Punkt des Vertex liegt, oder sehe ich das falsch?

    Du beschreibst einen Teilbereich eines 2D-Arrays (Framebuffer) indem Du diesen mit einem Polygon fuellst - die Vertexpositionen legen also lediglich das Ausmass dieses Bereiches fest. Die eigentlichen zur Berechnung notwendigen Parameter musst Du zb als zusaetzliche Vertexattribute bereitstellen.
    Es nuetzt Dir ja nichts eine Berechnung durchzufuehren deren Ergebnis dann an einer unbekannten Speicherstelle abgelegt wird...


Anmelden zum Antworten