Blending not working??

Started by
6 comments, last by Armadon 19 years, 6 months ago
Hi guys I pasted the code here... For some reason my blending is not working. It's supposed to draw the textured quad and then blend the teapot. it's not working? might someone point me in the right direction? Thanks alot in advance.

#include "CWindow.h"
#include "CDirect3d.h"
#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9math.h>
#include <windows.h>
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx.lib")
#pragma comment(lib, "DxErr9.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dinput8.lib")

CWindow Window;
CDirect3d Direct3d;
HRESULT hResult;
D3DXMATRIX matWorld;

/*		The Box		*/
D3DXMATRIX matbox;
IDirect3DVertexBuffer9 *vb;
IDirect3DTexture9 *tex;
D3DMATERIAL9 mtrlbox;

struct VERTEX
{
	float x, y, z;
	float nx, ny, nz;
	float u, v;
};
const DWORD VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
/*		The Box		*/

/*		The Teapot	*/
ID3DXMesh *mesh;
D3DMATERIAL9 mtrlteapot;
/*		The Teapot	*/

/*		The Light	*/
D3DLIGHT9 light;
/*		The Light	*/

bool InitDirect3d()
{
Direct3d.Create(&Window);

D3DXMatrixTranslation(&matWorld, 0.0f, 0.0f, 20.0f);

if(FAILED(hResult = Direct3d.pDevice->SetTransform(D3DTS_VIEW, &matWorld)))
        MessageBox(NULL, "Failed - Set Transform", "ERROR", MB_OK);

if(FAILED(hResult = Direct3d.pDevice->SetRenderState(D3DRS_LIGHTING, false)))
        MessageBox(NULL, "Set Render State(LIGHTING)", "ERROR", MB_OK);

if(FAILED(hResult = Direct3d.pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW)))
        MessageBox(NULL, "Set Render State(CULLMODE)", "ERROR", MB_OK);
        
return true;
}	

void createBox()
{
	VERTEX data[] = {{-2.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f},
					 {-2.0f, 4.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
					 { 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f},
					 { 2.0f, 4.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f}};
	VERTEX *box;
	Direct3d.pDevice->CreateVertexBuffer(sizeof(VERTEX) * 4, D3DUSAGE_WRITEONLY, VERTEX_FVF, D3DPOOL_MANAGED, &vb, NULL);
	vb->Lock(0, 0, (void**)&box, 0);
		memcpy(box, data, sizeof(VERTEX) * 4);
	vb->Unlock();
	//Create the texture
	D3DXCreateTextureFromFile(Direct3d.pDevice, "crate.jpg", &tex);
	Direct3d.pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	Direct3d.pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	Direct3d.pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
	//Ambient material
	mtrlbox.Ambient.r = 1.0f;
	mtrlbox.Ambient.g = 1.0f;
	mtrlbox.Ambient.b = 1.0f;
	mtrlbox.Ambient.a = 1.0f;
	//Diffuse material
	mtrlbox.Diffuse.r = 1.0f;
	mtrlbox.Diffuse.g = 1.0f;
	mtrlbox.Diffuse.b = 1.0f;
	mtrlbox.Diffuse.a = 1.0f;
	//Specular material
	mtrlbox.Diffuse.r = 1.0f;
	mtrlbox.Diffuse.g = 1.0f;
	mtrlbox.Diffuse.b = 1.0f;
	mtrlbox.Diffuse.a = 1.0f;
	//Emissive
	mtrlbox.Emissive.r = 1.0f;
	mtrlbox.Emissive.g = 1.0f;
	mtrlbox.Emissive.b = 1.0f;
	mtrlbox.Emissive.a = 1.0f;
	//Power
	mtrlbox.Power = 2.0f;
}
void createTeapot()
{
	D3DXCreateTeapot(Direct3d.pDevice, &mesh, 0);
	//Ambient material
	mtrlteapot.Ambient.r = 1.0f;
	mtrlteapot.Ambient.g = 0.0f;
	mtrlteapot.Ambient.b = 0.0f;
	mtrlteapot.Ambient.a = 1.0f;
	//Diffuse material
	mtrlteapot.Diffuse.r = 1.0f;
	mtrlteapot.Diffuse.g = 0.0f;
	mtrlteapot.Diffuse.b = 0.0f;
	mtrlteapot.Diffuse.a = 1.0f;
	//Specular material
	mtrlteapot.Diffuse.r = 1.0f;
	mtrlteapot.Diffuse.g = 0.0f;
	mtrlteapot.Diffuse.b = 0.0f;
	mtrlteapot.Diffuse.a = 1.0f;
	//Emissive
	mtrlteapot.Emissive.r = 1.0f;
	mtrlteapot.Emissive.g = 0.0f;
	mtrlteapot.Emissive.b = 0.0f;
	mtrlteapot.Emissive.a = 1.0f;
	//Power
	mtrlteapot.Power = 2.0f;
}

void createLight()
{
	ZeroMemory(&light, sizeof(light));
	light.Type = D3DLIGHT_DIRECTIONAL;
	//Diffuse light
	light.Diffuse.r = 1.0f;
	light.Diffuse.r = 1.0f;
	light.Diffuse.r = 1.0f;
	light.Diffuse.r = 1.0f;
	//Specular light
	light.Specular.r = 0.2f;
	light.Specular.g = 0.2f;
	light.Specular.b = 0.2f;
	light.Specular.a = 0.2f;
	//Ambient light
	light.Ambient.r = 0.6f;
	light.Ambient.g = 0.6f;
	light.Ambient.b = 0.6f;
	light.Ambient.a = 0.6f;
	//Direction
	light.Direction = D3DXVECTOR3(0.707f, 0.0f, 0.707f);
	
	//Setup render states
	Direct3d.pDevice->SetLight(0, &light);
	Direct3d.pDevice->LightEnable(0, true);
	Direct3d.pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);
	Direct3d.pDevice->SetRenderState(D3DRS_SPECULARENABLE, true);

	//Use alpha in material's diffuse component for alpha
	Direct3d.pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
	Direct3d.pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

	//Set blending factors so that alpha component determines transparency
	Direct3d.pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	Direct3d.pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}

void DrawScene()
{
	Direct3d.Clear(0);
	Direct3d.BeginScene();

	//Draw the box
	Direct3d.pDevice->SetFVF(VERTEX_FVF);
	Direct3d.pDevice->SetStreamSource(0, vb, 0, sizeof(VERTEX));
	Direct3d.pDevice->SetMaterial(&mtrlbox);
	Direct3d.pDevice->SetTexture(0, tex);
	Direct3d.pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
	//Draw the teapot
	Direct3d.pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	Direct3d.pDevice->SetMaterial(&mtrlteapot);
	Direct3d.pDevice->SetTexture(0, 0);
	mesh->DrawSubset(0);
	Direct3d.pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

	Direct3d.EndScene();
	Direct3d.Present();
}

void Release()
{
Direct3d.Release();
mesh->Release();
vb->Release();
tex->Release();
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR CmdLine, int CmdShow)
{
Window.Create(hInstance, "::Armadon:: - Direct3D", "window", 800, 600);
InitDirect3d();
createLight();
createTeapot();
createBox();
while(1)
        {
        if(Window.CheckMessages() == -1)
                break;
        DrawScene();
        }
Direct3d.Release();
return 0;
}

Advertisement

Just been looking at your code really fast, it seems like you miss turn the z-write off just before rendering:

pDev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

Put it the beginning of DrawScene(), and remember to turn z-write on later if you need to draw objects on top.



www.pokersniffer.org
You've setup to use vertex or material alpha (which ever is select for lighting). You don't have DIFFUSE in your FVF, so regardless of COLORVERTEX and DIFFUSEMATERIALSOURCE, you alpha will come from Material.Diffuse.a... except you never set it. You set diffuse red 4 times by accident. D'oh! ;)
Ok I have modified the code I have done the following and I still don't understand what you guys are saying but...
[source = "cpp"]#include "CWindow.h"#include "CDirect3d.h"#include <d3d9.h>#include <d3dx9.h>#include <d3dx9math.h>#include <windows.h>#pragma comment(lib, "d3dx9.lib")#pragma comment(lib, "d3d9.lib")#pragma comment(lib, "d3dx.lib")#pragma comment(lib, "DxErr9.lib")#pragma comment(lib, "dxguid.lib")#pragma comment(lib, "dinput8.lib")CWindow Window;CDirect3d Direct3d;HRESULT hResult;D3DXMATRIX matWorld;/*		The Box		*/D3DXMATRIX matbox;IDirect3DVertexBuffer9 *vb;IDirect3DTexture9 *tex;D3DMATERIAL9 mtrlbox;struct VERTEX{	float x, y, z;	float nx, ny, nz;	float u, v;};const DWORD VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;/*		The Box		*//*		The Teapot	*/ID3DXMesh *mesh;D3DMATERIAL9 mtrlteapot;/*		The Teapot	*//*		The Light	*/D3DLIGHT9 light;/*		The Light	*/bool InitDirect3d(){Direct3d.Create(&Window);D3DXMatrixTranslation(&matWorld, 0.0f, 0.0f, 20.0f);if(FAILED(hResult = Direct3d.pDevice->SetTransform(D3DTS_VIEW, &matWorld)))        MessageBox(NULL, "Failed - Set Transform", "ERROR", MB_OK);if(FAILED(hResult = Direct3d.pDevice->SetRenderState(D3DRS_LIGHTING, false)))        MessageBox(NULL, "Set Render State(LIGHTING)", "ERROR", MB_OK);if(FAILED(hResult = Direct3d.pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW)))        MessageBox(NULL, "Set Render State(CULLMODE)", "ERROR", MB_OK);        return true;}	void createBox(){	VERTEX data[] = {{-2.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f},					 {-2.0f, 4.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},					 { 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f},					 { 2.0f, 4.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f}};	VERTEX *box;	Direct3d.pDevice->CreateVertexBuffer(sizeof(VERTEX) * 4, D3DUSAGE_WRITEONLY, VERTEX_FVF, D3DPOOL_MANAGED, &vb, NULL);	vb->Lock(0, 0, (void**)&box, 0);		memcpy(box, data, sizeof(VERTEX) * 4);	vb->Unlock();	//Create the texture	D3DXCreateTextureFromFile(Direct3d.pDevice, "crate.jpg", &tex);	Direct3d.pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);	Direct3d.pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);	Direct3d.pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);	//Ambient material	mtrlbox.Ambient.r = 1.0f;	mtrlbox.Ambient.g = 1.0f;	mtrlbox.Ambient.b = 1.0f;	mtrlbox.Ambient.a = 1.0f;	//Diffuse material	mtrlbox.Diffuse.r = 1.0f;	mtrlbox.Diffuse.g = 1.0f;	mtrlbox.Diffuse.b = 1.0f;	mtrlbox.Diffuse.a = 1.0f;	//Specular material	mtrlbox.Diffuse.r = 1.0f;	mtrlbox.Diffuse.g = 1.0f;	mtrlbox.Diffuse.b = 1.0f;	mtrlbox.Diffuse.a = 1.0f;	//Emissive	mtrlbox.Emissive.r = 1.0f;	mtrlbox.Emissive.g = 1.0f;	mtrlbox.Emissive.b = 1.0f;	mtrlbox.Emissive.a = 1.0f;	//Power	mtrlbox.Power = 2.0f;}void createTeapot(){	D3DXCreateTeapot(Direct3d.pDevice, &mesh, 0);	//Ambient material	mtrlteapot.Ambient.r = 1.0f;	mtrlteapot.Ambient.g = 0.0f;	mtrlteapot.Ambient.b = 0.0f;	mtrlteapot.Ambient.a = 1.0f;	//Diffuse material	mtrlteapot.Diffuse.r = 1.0f;	mtrlteapot.Diffuse.g = 0.0f;	mtrlteapot.Diffuse.b = 0.0f;	mtrlteapot.Diffuse.a = 0.5f;	//Specular material	mtrlteapot.Specular.r = 1.0f;	mtrlteapot.Specular.g = 0.0f;	mtrlteapot.Specular.b = 0.0f;	mtrlteapot.Specular.a = 1.0f;	//Emissive	mtrlteapot.Emissive.r = 1.0f;	mtrlteapot.Emissive.g = 0.0f;	mtrlteapot.Emissive.b = 0.0f;	mtrlteapot.Emissive.a = 1.0f;	//Power	mtrlteapot.Power = 2.0f;}void createLight(){	ZeroMemory(&light, sizeof(light));	light.Type = D3DLIGHT_DIRECTIONAL;	//Diffuse light	light.Diffuse.r = 1.0f;	light.Diffuse.r = 1.0f;	light.Diffuse.r = 1.0f;	light.Diffuse.r = 1.0f;	//Specular light	light.Specular.r = 0.2f;	light.Specular.g = 0.2f;	light.Specular.b = 0.2f;	light.Specular.a = 0.2f;	//Ambient light	light.Ambient.r = 0.6f;	light.Ambient.g = 0.6f;	light.Ambient.b = 0.6f;	light.Ambient.a = 0.6f;	//Direction	light.Direction = D3DXVECTOR3(0.707f, 0.0f, 0.707f);		//Setup render states	Direct3d.pDevice->SetLight(0, &light);	Direct3d.pDevice->LightEnable(0, true);	Direct3d.pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);	Direct3d.pDevice->SetRenderState(D3DRS_SPECULARENABLE, true);	//Use alpha in material's diffuse component for alpha	Direct3d.pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);	Direct3d.pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);	//Set blending factors so that alpha component determines transparency	Direct3d.pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);	Direct3d.pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);}void DrawScene(){	Direct3d.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);	Direct3d.Clear(0);	Direct3d.BeginScene();	//Draw the box	Direct3d.pDevice->SetFVF(VERTEX_FVF);	Direct3d.pDevice->SetStreamSource(0, vb, 0, sizeof(VERTEX));	Direct3d.pDevice->SetMaterial(&mtrlbox);	Direct3d.pDevice->SetTexture(0, tex);	Direct3d.pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);	//Draw the teapot	Direct3d.pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);	Direct3d.pDevice->SetMaterial(&mtrlteapot);	Direct3d.pDevice->SetTexture(0, 0);	mesh->DrawSubset(0);	Direct3d.pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);	Direct3d.EndScene();	Direct3d.Present();}void Release(){Direct3d.Release();mesh->Release();vb->Release();tex->Release();}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR CmdLine, int CmdShow){Window.Create(hInstance, "::Armadon:: - Direct3D", "window", 800, 600);InitDirect3d();createLight();createTeapot();createBox();while(1)        {        if(Window.CheckMessages() == -1)                break;        DrawScene();        }Direct3d.Release();return 0;}
I've never used .x files, so I can't say for sure, but is DrawSubset setting it's own material, overwriting yours?
The Ambient propery of a material represents the brightness and colour of the material irrespective of light sources. Its really just a hack used to approximate light thats undergone many refelctions around the scene. In your teapot material, the ambient value is set to full alpha and so will be completely opaque no matter what direction your light hits it or you view it from. If you want the teapot to be transparent you'll have to lower the ambients alpha value. Just one other thing, your light.diffuse initialisation looks a bit dodgy :)
[size="1"] [size="4"]:: SHMUP-DEV ::
try to change light.whatever.a to 0.1 and material.whatever.a to 0.1 to see if it become transparant or not.
i think it's because your light.diffuse.a*material.diffuse.a + light.ambient.a*material.ambient.a + light.emmisive.a*material.emmisive.a > 1.0
I got it working guys. I left out a simple SetRenderState()
Had to enable light :)
But thanks for your comments :)

This topic is closed to new replies.

Advertisement