Daten von der Grafikkarte zurück an den Hauptprozessor senden
-
Also ich komme echt nicht weiter, hier ist das fragliche Codefragment:
// determine the content of the code edit - control char buf[4096] = {"vs.1.1\nmov oD0,c0\nmov oPos,c1\nmov oPts,c3.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->SetPixelShader(0x00); float arrTmp1[12] = {1.0f,1.0f,1.0f,1.0f,0.0f,0.0f,0.0f,0.0f,10.0f,10.0f,10.0f,10.0f}; pDv->SetVertexShaderConstantF(0,arrTmp1,3); pDv->Clear(0,0x00,D3DCLEAR_TARGET,0x000000ff,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);
Was mache ich falsch?
-
setfvf vergessen?
-
Braucht man die nicht nur im Zusammenhang mit der Fixed Function Pipeline?
-
Nein, auch die Programmable Pipeline muss das Format deiner Vertices kennen. Aber eigentlich benutzt man da eher eine VertexDeclaration ( http://msdn.microsoft.com/en-us/library/bb174464(VS.85).aspx ) als das alte FVF. Wieso benutzt du eigentlich nicht HLSL?
-
@this->that
Aha, ok, aber aus welchem Grund muss denn die Programmable Pipeline mein Vertexformat kennen? Das kann ich gerade nicht nachvollziehen. Könntest du mir das erklären?
Mfg
-
aus welchem Grund muss denn die Programmable Pipeline mein Vertexformat kennen?
Weil die einzelnen Komponenten Deiner Vertexstruktur irgendwie in die Register des Vertexshaders gelangen muessen.
-
Ja aber tun sie dass nicht sowieso? Die ersten 4 Bytes in V0, die nächsten 4 in V1 usw...
-
Wenn die Vertexdaten einfach stupide der Reihe nach in den 4 Komponenten der VS-Register landen wuerden, muesstest Du die ja erst alle auseinanderpfriemeln.
Stell Dir vor:struct Vertex { float x,y,z; // position float nx,ny,nz; // normale float u,v; // texturkoordinate };
Dann moechte man ja zb:
v0= x,y,z,1
v1= nx,by,nz,0
v2= u,v,0,0Nach Deiner Logik waere dann nx in v0.w und ny,nz in v1.xy; das waer' ja wohl nix.
-
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...