Daten von der Grafikkarte zurück an den Hauptprozessor senden
-
Ja, das verstehe ich, aber wieso steht dann in der Doku, isch zitiere:
A vertex declaration is an IDirect3DVertexDeclaration9 object that defines the data members of a vertex (i.e. texture coordinates, colors, normals, etc.). This data can be useful for implementing vertex shaders and pixel shaders.
CAN be useful, also wenn ich das richtig verstehe, ist es nicht zwinged erforderlich.
Naja, wie dem auch sei, ich habe es mal Versuchsweise gemacht, leider ohne Erfolg, es wird noch immer nicht gerendert, hier der angepasste Code:
// determine the content of the code edit - control char buf[4096] = {"vs.1.1\nmov oD0,c0\nmov oPos,c1\nmov oPts,c2.x"}; //GetWindowText(hTbxCod,buf,4096); // 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); pDv->SetFVF(D3DFVF_XYZRHW); pDv->SetPixelShader(0x00); float arrTmp1[12] = {1.0f,0.3f,0.3f,1.0f,0.0f,0.0f,0.0f,0.0f,4.0f,4.0f,4.0f,0.0f}; pDv->SetVertexShaderConstantF(0,arrTmp1,3); pDv->Clear(0,0x00,D3DCLEAR_TARGET,0xff0000ff,1.0f,0); pDv->BeginScene(); float arrTmp2[] = {0.0f,0.0f,0.0f,0.0f}; pDv->DrawPrimitiveUP(D3DPT_POINTLIST,1,arrTmp2,4*sizeof(float)); pDv->EndScene(); pDv->Present(0x00,0x00,0,0x00);
-
Du setzt in deinem Code wieder keine VertexDeclaration, sondern nur das alte FVF.
Wie ich bereits gesagt habe: Wieso benutzt du frickelige Asm Shader und nicht HLSL Shader?
Außerdem bestehen deine "Punkte" aus 4mal 0. Wieso erwartest du, dass er da überhaupt was zeichnet? Zeichnet er wenigstens einen roten Hintergrund? (und wieso benutzt du überhaupt überall Hex-Zahlen. Macht den Code IMO nur unnötig kryptisch)
-
@this->that
Außerdem bestehen deine "Punkte" aus 4mal 0
Aber ich rendere doch eine POINTLIST??
pDv->DrawPrimitiveUP(D3DPT_POINTLIST,1,arrTmp2,4*sizeof(float));
Wenn du den "frickeligen Assemblercode" anschaust, wirst du auch bemerken, dass der shader die Vertexdaten überhaupt nicht verarbeitet, sondern nur auch Konstanten zurückgreift...
Was soll ich denn bei der D3DVERTEXELEMENT::Stream für eine Nummer übergeben, wenn ich DrawPrimitiveUP übergebe?
Lg
-
@this->that
Ich habs nun mit diesem VertexDeclaration gemacht, leider ohne Erfolg:IDirect3DVertexShader9 *pVs = 0x00; // determine the content of the code edit - control char buf[4096] = {"vs.1.1\nmov oD0,c0\nmov oPos,c1\nmov oPts,c2.x"}; //GetWindowText(hTbxCod,buf,4096); // 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; ve.Method = D3DDECLMETHOD_DEFAULT; ve.Offset = 0; ve.Stream = 0; ve.Type = D3DDECLTYPE_FLOAT4; ve.Usage = D3DDECLUSAGE_POSITION; ve.UsageIndex = 0; IDirect3DVertexDeclaration9 *pVd; pDv->CreateVertexDeclaration(&ve,&pVd); pDv->SetVertexDeclaration(pVd); pDv->SetPixelShader(0x00); float arrTmp1[12] = {1.0f,0.3f,0.3f,1.0f,0.0f,0.0f,0.0f,0.0f,4.0f,4.0f,4.0f,0.0f}; pDv->SetVertexShaderConstantF(0,arrTmp1,3); pDv->Clear(0,0x00,D3DCLEAR_TARGET,0xff0000ff,1.0f,0); pDv->BeginScene(); float arrTmp2[] = {0.0f,0.0f,0.0f,0.0f}; pDv->DrawPrimitiveUP(D3DPT_POINTLIST,1,arrTmp2,sizeof(float)); pDv->EndScene(); pDv->Present(0x00,0x00,0,0x00);
-
Ishildur schrieb:
Was soll ich denn bei der D3DVERTEXELEMENT::Stream für eine Nummer übergeben, wenn ich DrawPrimitiveUP übergebe?
Mit Stream gibst du den Index des Streams an, aus dem die Vertexdaten gelesen werden sollen. Damit kannst du deine Vertexdaten auf mehrere Streams (Vertexbuffer) aufteilen und dann automatisch in der Pipeline zusammenbauen lassen, z.B. Positionen und Normalen aus Stream0 und TexCoords aus Stream1. Da du aber nur einen Stream hast bzw. nicht mal Streams benutzt, sondern deine Daten aus dem Systemspeicher gelesen werden, gibst du da einfach 0 an.
CreateVertexDeclaration erwartet ein Array von VertexDeclarations, wobei das letzte Element speziell markiert sein muss (irgendwas mit D3DDECL_END oder so).
Dein Code ergibt nach wie vor keinen Sinn. Du definierst deine Vertices als untransformierte float4 Positionen, aber als Eingabe schiebst du lediglich floats in die Pipeline. Das Format deiner Eingabedaten muss schon mit deiner VertexDeclaration übereinstimmen.
Nur als Anmerkung: Du hast die Semantik deines Programms geändert (vorhin hast du XYZRHW benutzt, was für transformierte Vertexpositionen in Projectionspace steht. Jetzt benutzt du D3DDECLUSAGE_POSITION, das steht für UNtransformierte Vertices).
-
Ich habe vermutlich einfach das Prinzip dieser Shader nicht verstanden. Wieso um alles in der Welt muss ich ausserhalb des Shaders definieren, ob es sich nun um transformtierte Vertices handelt oder nicht. Ich kann das echt nicht nachvollziehen. Wichtig ist doch, ob ich im Vertexshader die Daten einfach mit mov durchreichen (passthrough) oder ob ich diese eben noch transformiere?
Ich meine, das Ganze macht einen Sinn, wenn man noch einen Tesselator dazuschaltet, aber das ist ja in meiner Applikation nicht der Fall.
Gibt es irgend eine Möglichkeit, um festzustellen, ob die Daten überhaupt in den Shader gelangten? Sowas wie einen Shaderdebugger?
-
Ishildur schrieb:
Ich habe vermutlich einfach das Prinzip dieser Shader nicht verstanden. Wieso um alles in der Welt muss ich ausserhalb des Shaders definieren, ob es sich nun um transformtierte Vertices handelt oder nicht. Ich kann das echt nicht nachvollziehen. Wichtig ist doch, ob ich im Vertexshader die Daten einfach mit mov durchreichen (passthrough) oder ob ich diese eben noch transformiere?
Naja, in DX9 besteht leider die Programmable Pipeline parallel zur Fixedfunction Pipeline und man musste DX so designen, dass man beide nebeneinander benutzen kann. Davon machst du ja bereits Gebrauch in deinem Code: Du setzt den Pixelshader auf 0 aber erwartest dann natürlich dennoch, das was gerendert wird (nämlich per Fixed Multitexturing Stage).
Drum gibt es diese DECL Teile, damit die Pipeline weiß WAS diese Daten darstellen. Stell dir vor du willst Vertexfog aber ohne selbstimplementierten Vertexshader. Dann definierst du dir eine VertexDecl mit D3DDECLUSAGE_FOG und die Multitexturing Stage weiß dann, wozu der Wert da ist (Blending mit der FogColor).Anmerkung am Rande: Drum finde ich DX10 so schön. Da gibt es keine FFP mehr und du musst einfach alles mit Shadern machen. Da definierst du dann z.B. die Semantik eines Vertex-Eingabedatums per String und du kannst Daten einfach die Semantik "BLUMENTOPF" zuweisen.
Ishildur schrieb:
Gibt es irgend eine Möglichkeit, um festzustellen, ob die Daten überhaupt in den Shader gelangten? Sowas wie einen Shaderdebugger?
IMO ist Shader debuggen nach wie vor ein absoluter Krampf. Unter VS03 ging das mal, aber unverständlicherweise haben sie das in den Nachfolgerversionen wieder entfernt. Ansonsten geht es (theoretisch) noch per PIX (ein Tool im DX SDK), aber das verweigert bei mir regelmäßig den Dienst.
Render doch einfach erstmal ein simples farbiges Dreieck, damit du siehst das dein "Rahmencode" funktioniert. Einfach eine Struktur mit Position und Farbe anlegen, eine passende VertexDecl definieren (Array mit 2 Elementen + Endtoken), 3 Elemente deiner Vertexstruktur anlegen und diese dann rendern.
-
Ich habe jetzt auf die Fixed Function Pipeline zurückgegriffen. Aber nicht mal damit rendert er etwas!
pDv->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); pDv->SetRenderState(D3DRS_LIGHTING,false); pDv->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); pDv->Clear(0,0x00,D3DCLEAR_TARGET,0xff0000ff,1.0f,0); pDv->BeginScene(); float arrTmp2[3][5] = {{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}}; pDv->DrawPrimitiveUP(D3DPT_TRIANGLELIST,3,arrTmp2,5*sizeof(float)); pDv->EndScene(); pDv->Present(0x00,0x00,0,0x00);
Was ist da los? Ich kapiers nicht!
P.S.
Ich finde Direct 10 auch viel schöner, aber läuft leider auf meinem winXP nicht und Vista ist mir noch viel zu langsam und schwerfällig
-
Das kann auch nicht gehen mit deinem 3x5 Array...
Laut deinem FVF haben deine Vertices eine Position und Farbe und laut Doku besteht diese Farbe aus ARGB.
Leg dir doch einfach mal eine ordentliche Vertexstruktur an.
-
Hhhmmmm.... Mein Gott Walter...
pDv->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); pDv->SetRenderState(D3DRS_LIGHTING,false); pDv->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); pDv->Clear(0,0x00,D3DCLEAR_TARGET,0xff0000ff,1.0f,0); pDv->BeginScene(); //float arrTmp2[3][5] = {{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}}; VT arrVt[3]; arrVt[0].x = arrVt[0].y = arrVt[0].z = 0.0f; arrVt[1].x = 5; arrVt[1].y = arrVt[1].z = 0.0f; arrVt[2].x = arrVt[2].y = 5.0; arrVt[2].z = 0.0f; arrVt[0].r = arrVt[1].r = arrVt[2].r = 1.0f; arrVt[0].c = arrVt[1].c = arrVt[2].c = 0xff0000ff; pDv->DrawPrimitiveUP(D3DPT_TRIANGLELIST,3,arrVt,sizeof(VT)); pDv->EndScene(); pDv->Present(0x00,0x00,0,0x00);
Immer nocht nichts...
-
pDv->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); pDv->SetRenderState(D3DRS_LIGHTING,false); pDv->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); pDv->Clear(0,0x00,D3DCLEAR_TARGET,0xff0000ff,1.0f,0); pDv->BeginScene(); float arrTmp2[3][5] = {{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}}; pDv->DrawPrimitiveUP(D3DPT_TRIANGLELIST,3,arrTmp2,5*sizeof(float)); pDv->EndScene(); pDv->Present(0x00,0x00,0,0x00);
Funktioniert doch. Kleines schwarzes (eben 0.0f) Dreieck oben links.
-
Bei mir nicht... Gar nichts...
-
Geh doch einfach mal die DX SDK Tutorials durch. Da findest du zahlreiche Code Beispiele. Gleich das 2. Tutorial würde deine Fragen beantworten:
struct CUSTOMVERTEX { FLOAT x, y, z, rhw; // The transformed position for the vertex. DWORD color; // The vertex color. }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE) CUSTOMVERTEX vertices[] = { { 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, }, { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, }, };
-
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.