Jump to content
  • Advertisement
Sign in to follow this  
23yrold3yrold

Full-screen fade (or, the big black not-so-translucent box)

This topic is 3172 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all. Something I've been kind of fighting with today is drawing a primitive with an alpha in a hackish attempt to fade a screen to black. Now, I can do the whole alpha of vertices, create the vertex buffer and lock thing ... but I want the alpha of that polygon to change over time. I can get a static poly with a static alpha, but I can't change things after the fact (as far as I know). I thought about using the diffuse alpha of a material but I can't figure out how to affect the polygon with it and most resources show how to do it with textures so I've got nothing to check my work against. Here's what I'm currently rolling with, and yes it currently draws my screen black as night. [rolleyes] And before anyone asks, yes I'm pretty inexperienced with DirectX, but it's what I'm told I'm using for this project. And no, the article here on playing with gamma settings doesn't work on this comp.

const DWORD myFVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE;

struct CUSTOMVERTEX
{
	float x, y, z, weight;
	DWORD color;
};

LPDIRECT3DVERTEXBUFFER9 pV = NULL;
D3DMATERIAL9 m_material;

LPDIRECT3DVERTEXBUFFER9 FillVertices(LPDIRECT3DDEVICE9 pDevice)
{
	ZeroMemory(&m_material, sizeof(m_material));
	m_material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
	m_material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
	m_material.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
	m_material.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
	m_material.Diffuse.a = 0.0f;
	m_material.Power = 5.0f;

	CUSTOMVERTEX cVertices[4];
	LPDIRECT3DVERTEXBUFFER9 pVertexBuffer;

	cVertices[0].x =   0;
	cVertices[0].y =   0;
	cVertices[0].z = 0;
	cVertices[0].weight = 1;
	cVertices[0].color = 0xFF000000;

	cVertices[1].x = 800;
	cVertices[1].y =   0;
	cVertices[1].z = 0;
	cVertices[1].weight = 1;
	cVertices[1].color = 0xFF000000;

	cVertices[2].x =   0;
	cVertices[2].y = 600;
	cVertices[2].z = 0;
	cVertices[2].weight = 1;
	cVertices[2].color = 0xFF000000;

	cVertices[3].x = 800;
	cVertices[3].y = 600;
	cVertices[3].z = 0;
	cVertices[3].weight = 1;
	cVertices[3].color = 0xFF000000;

	if (FAILED(pDevice->CreateVertexBuffer(4 * sizeof(CUSTOMVERTEX), 0, myFVF, D3DPOOL_DEFAULT, &pVertexBuffer, NULL ) ) )
		MessageBox(NULL, "Error while creating VertexBuffer", "FillVertices()", MB_OK);

	VOID* pVertices;
	if (FAILED(pVertexBuffer->Lock(0, 4 * sizeof(CUSTOMVERTEX), (void**)&pVertices, 0)))
		MessageBox(NULL, "Error trying to lock", "FillVertices()", MB_OK);
	else
	{
		memcpy(pVertices, cVertices, 4 * sizeof(CUSTOMVERTEX));
		pVertexBuffer->Unlock();
	}

	return pVertexBuffer;
}

void Blackfade()
{
	if(pV == NULL)
		pV = FillVertices(pDevice);

	// Set alpha blending states.
	pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

	pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
	pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	pDevice->SetMaterial(&m_material);

	pDevice->SetStreamSource(0, pV, 0, sizeof(CUSTOMVERTEX));
	pDevice->SetFVF(myFVF);
	pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

	//turn off alpha-blend
	pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
}


So how would you suggest I set it up so the alpha value of the drawn polygon can be changed over time? Or can you think of another way to do a fullscreen fade to black altogether? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
I would use DrawPrimitiveUP for this, since it's just 4 vertices and that makes it easy to change the array every frame.


struct Vert {
float x, y, z, rhw;
DWORD color;
};

// fade in [0, 255]
void drawFade(int fade) {
Vert vertices[] = {
0, 0, 0, 1, (fade << 24),
....
};
pDevice->DrawPrimitiveUP(..vertices..);
}


If you want the vertices in a vertex-buffer you can change them using Lock.

Share this post


Link to post
Share on other sites
I'd heard about DrawPrimitiveUP() but usually in derogatory terms, and I couldn't find any good examples of it's use. But it looks like I got it working now.


void Blackfade(unsigned char fade)
{
CUSTOMVERTEX vertices[4] = {
0, 0, 0, 1, (fade << 24),
800, 0, 0, 1, (fade << 24),
0, 600, 0, 1, (fade << 24),
800, 600, 0, 1, (fade << 24)
};

// Set alpha blending states.
pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

pDevice->SetFVF(myFVF);
pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(CUSTOMVERTEX));

//turn off alpha-blend
pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
}



Feel free to criticize that. Needs some other features but the functionality is there. Thanks for the help.

Share this post


Link to post
Share on other sites
One convenient way to vary alpha when using the fixed function pipeline is to use the texture factor (D3DRS_TEXTUREFACTOR), and get the alpha from it (use it as ARG2 and use D3DTOP_SELECTARG2 for alpha).

Frankly, I recommend using pixel shaders, even if you use fixed function for vertices. They're just clearer than the "fixed function" pixel pipeline.

Share this post


Link to post
Share on other sites
Quote:
Original post by 23yrold3yrold
I'd heard about DrawPrimitiveUP() but usually in derogatory terms, and I couldn't find any good examples of it's use. But it looks like I got it working now.


If you don't want to use that, just use Lock on your vertex buffer again, and change the vertices, without recreating the buffer. You can cast the pointer you memcpy to, to a CUSTOMVERTEX, and iterate through the vertices and set color to (fade << 24).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!