Navigation
Artikel
Stuff
RSS Feeds
|
Tutorials - Vertex Shader & Pixel Shader Unterstützung in DirectX 9Sprachenübersicht/Programmierung/C / C++/ C#/Spieleprogrammierung/DirectX Keywords: C++, Vertex, Pixel, Tutorial, DirectX9, Spieleprogrammierung, OpenGL, Tutorials, Pixel, Hilfe, Unterstützung, Vertex Shader, Effekte, Pixel Shader Inhaltsverzeichnis
Was sind Shader? Top
Was kann man mit Shadern machen ? Top
Warum sollte ich die Effekte in Vertex Shadern oder Pixel-Shader und nicht direkt in C++ schreiben ? Top
Was soll dieses Tutorial erklären ? Top
Welche Klassen und Variablen muss ich in meinem Programm anlegen und wie? Top
Vertex/Pixel Shader Code: #define SAFE_RELEASE(p) {if(p) { (p)->Release(); (p)=NULL;}} #define MAX_NAMELENGTH 255
Code: #include <vector>
Vertex Shader & Pixel Shader Code: CSshader: class CShader { public: bool bActive; LPD3DXEFFECT pEffect; LPD3DXBUFFER pBufferErrors; char name[MAX_NAMELENGTH]; CShader(char filename[MAX_NAMELENGTH], LPDIRECT3DDEVICE9 pd3dDevice) { pBufferErrors = NULL; bActive=true; strcpy(name,filename); HRESULT hr; hr = D3DXCreateEffectFromFile(pd3dDevice,filename,NULL,NULL,NULL,NULL,&pEffect,&pBufferErrors); if(FAILED(hr)) bActive=false; } ~CShader() { SAFE_RELEASE(pBufferErrors); SAFE_RELEASE(pEffect); } };
Shader Klasse: TShader: typedef struct { char cTechnology[MAX_NAMELENGTH]; CShader *shader; } TShader;
Code: { ... TShader ShaderInfo; ... }
Code: std::vector<CShader*> ShaderList; //der schon oft erwähnte STL-Vektor CShader* CreateShader(char *filename); //Funktion zum laden eines Shaders CShader* SetShader(TObject *obj,bool bActive,char *tech,char *filename=NULL); //Funktion zum setzen eines Shaders auf ein Objekt bool SetUpShader(TObject *obj); //Funktion zum bereitstellen wichtiger Daten CShader* GetShader(char name[MAX_NAMELENGTH]); //Funktion zum suchen eines bereits erstellten Shaders
Code: CShader* CEngine::GetShader(char name[MAX_NAMELENGTH]) { for(int i=0; i<RessourceManager->ShaderList.size(); i++) if(strcmp(RessourceManager->ShaderList->name,name)==0) return RessourceManager->ShaderList[i]; return NULL; }
Code: CShader* CEngine::CreateShader(char *filename) { CShader *pShader=NULL; //suche ob es den Shader schon gibt if((pShader=GetShader(filename))!=NULL) return pShader; pShader=new CShader(filename,m_pd3dDevice); if(pShader && pShader->pBufferErrors) return NULL; //am besten noch eine Fehlermeldung ausgeben if(!pShader) { //am besten noch eine Fehlermeldung ausgeben return NULL; } RessourceManager->ShaderList.push_back(pShader); return pShader; }
Code: CShader* CEngine::SetShader(TObject *obj,bool bActive,char *tech,char *filename) { if(bActive) { obj->ShaderInfo.shader=NULL; obj->ShaderInfo.shader=CreateShader(filename); strcpy(obj->ShaderInfo.cTechnology,tech); return obj->ShaderInfo.shader; } else { obj->ShaderInfo.shader=NULL; return NULL; } return NULL; }
Shader setzen: bool CEngine::SetUpShader(TObject *obj) { //die braucht nur ausgeführt werden wenn ein Shader benutzt werden soll if(!obj->ShaderInfo.shader || !obj->ShaderInfo.shader->pEffect) return false; //Dies ist auch sehr wichtig da ansonsten der Shader möglicherweise nicht funktioniert obj->ShaderInfo.shader->pEffect->SetTechnique( obj->material.ShaderInfo.cTechnology ); D3DXMATRIXA16 matViewProject; D3DXMatrixMultiply( &matViewProject, &camera->movement.matrix, &matProj ); D3DXMATRIXA16 matViewInv; D3DXMatrixInverse( &matViewInv, NULL, &camera->movement.matrix ); D3DXVECTOR4 vecPosition( matViewInv._41, matViewInv._42, matViewInv._43, 1.0f ); //Hier wird die Transformationsmatrix des zu rendernden Objektes übergeben obj->ShaderInfo.shader->pEffect->SetMatrix( "matWorld", &obj->movement.matrix ); //Und hier die der Kamera (man kann ja nie wissen wann man das braucht) obj->ShaderInfo.shader->pEffect->SetMatrix( "matView", &camera->movement.matrix ); //und so weiter obj->ShaderInfo.shader->pEffect->SetMatrix( "matViewProject", &matViewProject ); obj->ShaderInfo.shader->pEffect->SetMatrix( "matProject", &matProj ); obj->ShaderInfo.shader->pEffect->SetVector( "vecPosition", &vecPosition ); obj->ShaderInfo.shader->pEffect->SetVector( "lightDir", &lightDir ); for(int i=0; i<MAX_TEXTURESTAGES; i++) { char texture[MAX_NAMELENGTH]; sprintf(texture,"texture%d",i); obj->ShaderInfo.shader->pEffect->SetTexture( texture,obj->texture); } return true; }
Code: for(int i=0; i<RessourceManager->ShaderList.size(); i++) delete ShaderList; ShaderList.clear();
Und wie benutze ich die Shader beim Rendern? Top
Shader Rendern: ... //als erstes sollten alle Transformationen und andere wichtige Dinge gemacht werden die auch beim rendern ohne Shader gebraucht werden //das hier sollte direkt vor dem eigentlichen Rendern (DrawIndexedPrimitive,...) stehen //damit wird wenn irgendein Fehler auftritt bei zugewiesenem Shader der Shader deaktiviert //das überprüfen auf Fehler geschieht in SetUpShader if(!SetUpShader(obj)) { if(obj->ShaderInfo.shader) { delete obj->ShaderInfo.shader; obj->ShaderInfo.shader=NULL; } ... //hier sollte nun gerendert werden (DrawIndexedPrimitive,...) return; } UINT uPasses; obj->ShaderInfo.shader->pEffect->Begin( &uPasses, 0 ); for( UINT uPass = 0; uPass < uPasses; ++uPass ) { obj->ShaderInfo.shader->pEffect->Pass( uPass ); ... //hier sollte nun gerendert werden (DrawIndexedPrimitive,...) } obj->ShaderInfo.shader->pEffect->End();
Das funktioniert noch nicht so richtig. Warum? Top
Kann ich mal so einen simplen Shader sehen? Top
Vertex Shader & Pixel Shader: SimpleShader.fx: // transformations float4x4 matWorld : WORLD; float4x4 matView : VIEW; float4x4 matProject : PROJECTION; float4 roteFarbe = { 1.0, 0.0, 0.0, 1.0 }; struct VS_OUTPUT { float4 Pos : POSITION; float4 Diff : COLOR0; }; VS_OUTPUT VS(float3 Pos : POSITION) { VS_OUTPUT Out = (VS_OUTPUT)0; float4x4 WorldView = mul(matWorld, matView); float3 P = mul(float4(Pos, 1), (float4x3)WorldView); // position (view space) Out.Pos = mul(float4(P,1), matProject); // position (projected) Out.Diff = roteFarbe; return Out; } technique Simple { pass P0 { VertexShader = compile vs_1_1 VS(); } }
Was muss man noch beachten ? Top
Gibt es noch irgendwelche Fragen, oder wollen Sie über den Artikel diskutieren? Sprachenübersicht/Programmierung/C / C++/ C#/Spieleprogrammierung/DirectX/Vertex Shader & Pixel Shader Unterstützung in DirectX 9 |