Problem bei Alpha Blending



  • Hiho,
    leider habe ich wieder ein Problem und zwar betrifft es Alpha Blending.
    Ich zeichne 2 Primitiven und nen Boden, und würde gerne den Alpha Blending Effekt sehen, aber alles ist völlig opak, außerdem hat der Boden ein komisches Rot. (Siehe Screen unten)
    Hier ist InitScene und Render:

    bool InitScene()
    {
    	if(D3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) != D3D_OK)
    	{
    		MessageBox(0, TEXT("Failed to set Vertex Format!"), AppName.c_str(), MB_ICONERROR);
    		return false;
    	}
    
    	//D3DDevice->SetRenderState(D3DRS_LIGHTING, false);
    	D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    	D3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    
    	// Licht
    	D3DLIGHT9 Light;
    	Light.Type = D3DLIGHT_POINT;
    	D3DCOLORVALUE color = {1.0f, 1.0f, 1.0f, 1.0f }; 
    	Light.Diffuse = color;
    	Light.Ambient = color;
    	Light.Specular = color;
    	Light.Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
    	Light.Range = 500.0f;
    	Light.Attenuation0 = 0.0f;
    	Light.Attenuation1 = 0.025f;
    	Light.Attenuation2 = 0.0f;
    
    	D3DDevice->SetLight(0, &Light);
    	D3DDevice->LightEnable(0, TRUE);
    
    	float Aspect = ScreenX / ScreenY;
    
    	D3DXMATRIX projection;
    	D3DXMatrixPerspectiveFovLH(&projection, 90.0f * 0.0174532925199432957692369076848f, Aspect, 0.1f, 100.0f);
    	D3DDevice->SetTransform(D3DTS_PROJECTION, &projection);
    
    	triangle[0].pos = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
    	triangle[0].color = D3DCOLOR_ARGB(120, 255, 0, 0);
    	triangle[0].tex.x = 0.5f;
         triangle[0].tex.y = 0.0f;
    	triangle[1].pos = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
    	triangle[1].color = D3DCOLOR_ARGB(120, 0, 255, 0);
         triangle[1].tex.x = 1.0f;
         triangle[1].tex.y = 1.0f;
    	triangle[2].pos = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
    	triangle[2].color = D3DCOLOR_ARGB(120, 0, 0, 255);
         triangle[2].tex.x = 0.0f;
         triangle[2].tex.y = 1.0f;	
    	rectangle[0].pos = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
    	rectangle[0].color = D3DCOLOR_ARGB(120, 255, 0, 0);
    	rectangle[0].tex.x = 0.0f;
         rectangle[0].tex.y = 0.0f;
    	rectangle[1].pos = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
    	rectangle[1].color = D3DCOLOR_ARGB(120, 0, 255, 0);
    	rectangle[1].tex.x = 1.0f;
         rectangle[1].tex.y = 0.0f;
    	rectangle[2].pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
    	rectangle[2].color = D3DCOLOR_ARGB(120, 0, 0, 255);
    	rectangle[2].tex.x = 0.0f;
         rectangle[2].tex.y = 1.0f;
    	rectangle[3].pos = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
    	rectangle[3].color = D3DCOLOR_ARGB(120, 0, 0, 0);
    	rectangle[3].tex.x = 1.0f;
         rectangle[3].tex.y = 1.0f;
    
    	if(D3DXCreateTextureFromFileEx(D3DDevice, TEXT("Texture.bmp"), D3DX_DEFAULT, D3DX_DEFAULT,
    							 D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE,
    							 D3DX_DEFAULT, 0, NULL, NULL, &chess) != D3D_OK)
    	{
    		MessageBox(0, TEXT("Failed to Create the Texture!"), AppName.c_str(), MB_ICONERROR);
    		return false;
    	}
    
    	if(D3DXCreateTextureFromFileEx(D3DDevice, TEXT("Ground.bmp"), D3DX_DEFAULT, D3DX_DEFAULT, 
    							 D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, 
    							 D3DX_DEFAULT, 0, NULL, NULL, &GroundTexture) != D3D_OK)
    	{
    		MessageBox(0, TEXT("Failed to Create the Texture Ground!"), AppName.c_str(), MB_ICONERROR);
    		return false;
    	}
    
    	// Das Bodenmodell laden
    	if(D3DXLoadMeshFromX(TEXT("Ground.x"), D3DXMESH_MANAGED, D3DDevice, 
    					NULL, NULL, NULL, NULL, &GroundModel) != D3D_OK)
    	{
    		MessageBox(0, TEXT("Failed to Create the Mesh Ground!"), AppName.c_str(), MB_ICONERROR);
    		return false;
    	}
    
    	return true;
    }
    
    bool Render(float NumSecsPassed)
    {
    	D3DXMATRIX rotation;
    	D3DXMatrixRotationY(&rotation, 90.0f * 0.0174532925199432957692369076848f * (timeSum));
    	D3DXMATRIX translation;
    	D3DXMatrixTranslation(&translation, -2.0f, 0.0f, 4.0f);
    	D3DXMATRIX world = rotation * translation;
    	D3DXMATRIX translationRect;
    	D3DXMatrixTranslation(&translationRect, 2.0f, 0.0f, 4.0f);
    	D3DXMATRIX translationGround;
    	D3DXMatrixTranslation(&translationGround, 0.0f, -20.0f, 0.0f);
    	D3DXMATRIX worldRect = rotation * translationRect;
    	D3DXMATRIX worldGround = rotation * translationGround;
    
    	if(D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0),
    				     1.0f, 0) != D3D_OK)
    	{
    		MessageBox(0, TEXT("D3DDevice->Clear failed!"), AppName.c_str(), MB_ICONERROR);
    		return false;
    	}
    
    	D3DMATERIAL9 Material;
    	D3DCOLORVALUE colordif = {0.5f, 0.8f, 0.8f, 0.8f }; 
    	D3DCOLORVALUE colorspec = {0.5f, 0.3f, 0.3f, 0.3f }; 
    	D3DCOLORVALUE coloremi = {0.5f, 0.0f, 0.0f, 0.0f }; 
    	Material.Diffuse = colordif;
    	Material.Ambient = colorspec;
    	Material.Emissive = coloremi;
    	Material.Specular = colorspec;
    	Material.Power = 5.0f;
    	D3DDevice->SetMaterial(&Material);
    
    	D3DDevice->BeginScene();
    
    	D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    	D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    	D3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
    
    	D3DDevice->SetTransform(D3DTS_WORLD, &worldGround);
    	D3DDevice->SetTexture(0, GroundTexture);
    	GroundModel->DrawSubset(0);
    
    	D3DDevice->SetTexture(0, chess);
    	D3DDevice->SetTransform(D3DTS_WORLD, &world);
    	D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    	D3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    	D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    	D3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLEND_INVSRCALPHA);
    	D3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
    
    	if(D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, triangle, sizeof(Vertex)) != D3D_OK)
    	{
    		MessageBox(0, TEXT("Failed to draw the triangle!"), AppName.c_str(), MB_ICONERROR);
    		return false;
    	}
    
    	D3DDevice->SetTransform(D3DTS_WORLD, &worldRect);
    	if(D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, rectangle, sizeof(Vertex)) != D3D_OK)
    	{
    		MessageBox(0, TEXT("Failed to draw the triangle!"), AppName.c_str(), MB_ICONERROR);
    		return false;
    	}
    
    	D3DDevice->EndScene();
    
    	D3DDevice->Present(NULL, NULL, NULL, NULL);
    	return true;
    }
    

    Hier ist der ganze Code: http://codepad.org/f7cgwQtj
    Screenshot: http://img522.imageshack.us/img522/1695/unbenanntis.png
    Texturen und Boden falls man es benötigt:
    http://www.file-upload.net/download-1929987/tex.zip.html
    Wäre toll, wenn mir damit jemand helfen könnte.
    Ich verstehe das ganze noch nicht so richtig, da ich noch Anfänger auf diesem Gebiet bin und durch den Debugger finde ich auch nichts heraus 😞



  • Hallo.

    Ist schwer zu sagen, woher das rot kommt.. Ich würde mal sagen, dass du irgendwo etwas nicht richtig leerst..(also mit einer Farbe übermalst) und dann mit dem Alpha wird das halt geblendet.

    Grundsätzlich würde ich mal raten hier zu schauen:
    http://www.codesampler.com/dx9src/dx9src_4.htm#dx9_alpha_blending_material

    Da kannst du mal vergleichen.

    Helfen könnte auch noch, wenn du das ganze ein wenig vereinfachst. Sprich z.B das Licht ausschaltest, dann bist du mal sicher, dass das rot nicht irgendwie von einem falsch gesetzten Licht kommt, sondern du hast lediglich Textur und Diffuse.

    btw:
    Hast du mal im DX Debugger geschaut?
    Unter den mitgelieferten Tools: DirectX Control Panel aufrufen und dann kannst du dort Debug Output von DirectX höher schalten. Da findet man oft sehr vieles raus.



  • danke für die Tipps und den Link Drakon 🙂
    hab

    D3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); 
    ...
    D3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
    

    hinzugefügt und es klappt 😃
    Aber ich find seltsam, dass ich diesen Debug Output bekomme:
    D3D9 Helper: Enhanced D3DDebugging disabled; Application was not compiled with D3D_DEBUG_INFO
    obwohl ich im Debugmode kompiliere und dann ist es ja definiert 😕



  • Hehe. Den Fehler habe ich glaube ich auch immer. Habe bis jetzt nocht nicht nachgeschaut, was das genau sein soll. 😉

    Naja. Afaik ist der Output auch nicht immer ganz wahr. Ich kriege auch immer einen Standard Fehler beim ersten Aufruf von Present. Keine Ahung, was dort ist, aber glaube ich nichts wirklich schlimmes.

    Wirklich aufpassen solltest du bei den Fehlern, die regelmässig kommen. Da stimmt definitiv etwas nicht. Wenn z.B beim DrawPrimitiveXXX etwas nicht ganz stimmt (Anzahl Vertices mit den Objekten), dann wird stilltschweigend nichts, oder etwas merkwürdiges gerendert. Und zu erkennen ist das lediglich in der Debug Ausgabe.

    Hatte letztens einen sehr merkwürdigen Fehler, wo, wenn ich 1 Sprite gerendert habe alles passte, aber sobald ich 2 gleichzeitig gerendert habe, hat es irgendwie die zweite Textur an den Ort der ersten gerendert, ohne dass ich die Textur geändert hätte. Habe zuerst natürlich im Render Code geschaut, weil ich dachte, dass ich da ev. was mit den SetTexture verkehrt hatte, hat sich dann aber rausgestellt (nachdem ich den Output analysiert habe), dass es daran lag, dass die Anzahl Vertices nicht durch 3 Teilbar war (bei Dreiecken) und das ist natürlich falsch. Aber anstatt irgendwas verkehrt mit den Vertices zu machen ändert er mir was mit den Texturen..
    Du siehst.. Der Output hilft dir enorm viel verborgene Fehler zu entdecken, die nicht offensichtlich scheinen.


Anmelden zum Antworten