Jump to content
  • Advertisement
Sign in to follow this  
QuinnJohns

Transparency + X-Files

This topic is 3706 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

Alrighty, so if I'm not mistaken xfiles can have transparency, right? I believe I had seen before, that they were capable of being set to some transparent alpha value. Anyhow, how do I accomplish something such as that? I'm asking because I'm thinking about doing a simple single player RPG on the side, where I'll have the player models walking around a level on a specified camera angle. Now, the dilemna I'm going to be facing is that when the person walks under a tree, from the line of sight, how am I going to be able to handle some sort of transparency on-the-fly, of that xfile that he's hidden under? or near? ** I will mention, it doesn't have to be directly under, but anything I find obstructing the view of the player? Thanks in advance. -Quinn

Share this post


Link to post
Share on other sites
Advertisement
Are you using fixed-function or shaders? For shaders having transparency is easy: simply output a color value with alpha < 0 and make sure alpha blending is enabled in the device render states. If you're using the effects framework you can include those render states right in the fx file, and keep everything wrapped up in one tidy package.

With FFP you will have to set texture stage states that use data from either vertices, materials, textures, or a constant value to determine the final alpha value. For your purposes using a constant alpha value is probably best, as it won't require you to dynamically modify vertices or textures.

Share this post


Link to post
Share on other sites


void MeshAlpha(LPDIRECT3DDEVICE9 p_d3dDevice, float Alpha)
{

D3DXMATRIX matRotation,matTranslation;
D3DXMatrixTranslation(&matTranslation,0,0,0);
p_d3dDevice->SetTransform(D3DTS_TEXTURE0,&(matTranslation));

p_d3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );

for( DWORD i=0; i< NumMaterials; i++ )
{
// Set the material and texture for this subset
Materials.Diffuse.a = Alpha;
p_d3dDevice->SetMaterial( &Materials );
p_d3dDevice->SetTexture( 0, Textures );
p_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,true); //alpha blending enabled
p_d3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); //source blend factor
p_d3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); //destination blend factor


// Draw the mesh subset
Mesh->DrawSubset( i );
}
D3DXMatrixIdentity(&matRotation);
p_d3dDevice->SetTransform(D3DTS_TEXTURE0,&(matRotation));
p_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
p_d3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS,
D3DTTFF_DISABLE );

}





I basically copied my CMesh - MeshAlpha function in here. So, basically, what I did with my MeshAlpha function is all I need right? I'm not using shaders, I may learn shaders in the future, but this is something minimal I'm trying to accomplish for its uses.

Thanks for the help.

Share this post


Link to post
Share on other sites
So, theoretically, if what I posted is what I need, how would I go about checking if the objects that need transparency are in my line of sight (behind my tree, for example)? and then when I call that draw function MeshAlpha(), I can just specify a new alpha value, so instead of my 1.0f do like 0.5f.


Does that sound right? Thanks for any help.

Share this post


Link to post
Share on other sites
I don't think that code sets the texture stage state the way you want to. You need to specify that you're getting your alpha value from your diffuse albedo, which is where you're setting it. I believe you do that like this:


p_d3dDevice->SetTextureStageState( D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
p_d3dDevice->SetTextureStageState( D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );


This assumes you've set the current material as your source for lighting calculations, using IDirect3DDevice9::SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL ).

Share this post


Link to post
Share on other sites
So, what about finding out if the player model is behind the particular objects like trees, and such - to apply that transparency? I would think its something trivial, but I have no idea where to start.

-- added --
Like I posted earlier, my camera is gonna be on a fixed angle, basically like a tilted topdown view, so on the player can potentially be behind the object, so I'm just looking to find a way to 'determine' if its obstructing the view of my model and then give me an opportunity to apply my alpha to it.

Share this post


Link to post
Share on other sites
I don't have much experience with that sort of thing, but I'd imagine you'd do it by representing objects like trees as simple bounding volumes (such as a box or a square) and then doing a visibility test to see if the volume occludes the area where the player character is. So the basic algorithm would be:



-Convert object position to view space
-If object's view-space z is > 0 and < player's view-space x
-Calculate object's coverage in screen space
-If object's screen space height and width cover the player's height and width
-Make transparent

Share this post


Link to post
Share on other sites
So, basically, what you are saying is.... have two bounding volumes and do a collision test, if it is within the bounding volume's collision range, then set transparency right? Just trying to clarify...


and umm...

Quote:

-Convert object position to view space


How do you do that, per-se?

Share this post


Link to post
Share on other sites
Transform the object's world-space position by your view matrix.


D3DXVECTOR3 vObjectPosVS;
D3DXVec3TransformCoord( &vObjectPosVS, &matView, &vObjectPosWS );

Share this post


Link to post
Share on other sites
In response to your PM...

I wouldn't do a 3D collision test, I would instead do some kind of overlap test. Basically this would be like a collision test, but in 2D screen space. It would look something like this, assuming you've calculated a bounding radius for both the obstructing object and the player:



D3DXVECTOR3 vObjectPosVS, vPlayerPosVS;
D3DXVec3TransformCoord( &vObjectPosVS, &matView, &vObjectPosWS );
D3DXVec3TransformCoord( &vPlayerPosVS, &matView, &vPlayerPosWS );

if ( ( vObjectPosVS.z + fObjectRadius > 0 ) && ( vObjectPosVS.z - fObjectRadius < vPlayerPosVS.z ) )
{
D3DXVECTOR3 vPositionsVS [4];
D3DXVECTOR3 vPositionsSS [4];
D3DXVECTOR2 vObjectMaxSS;
D3DXVECTOR2 vObjectMinSS;
D3DXVECTOR2 vPlayerMaxSS;
D3DXVECTOR2 vPlayerMinSS;

// Calculate the area the object bounding volume takes up in view space
vPositionsVS[0] = D3DXVECTOR3( vObjectPosVS.x + fObjectRadius, vObjectPosVS.y, vObjectPosVS.z );
vPositionsVS[1] = D3DXVECTOR3( vObjectPosVS.x - fObjectRadius, vObjectPosVS.y, vObjectPosVS.z );
vPositionsVS[2] = D3DXVECTOR3( vObjectPosVS.x, vObjectPosVS.y + fObjectRadius, vObjectPosVS.z );
vPositionsVS[3] = D3DXVECTOR3( vObjectPosVS.x, vObjectPosVS.y - fObjectRadius, vObjectPosVS.z );

// Calculate the area the object bounding volume takes up in screen space
D3DXVec3TransformCoordArray( vPositionsSS, sizeof(D3DXVECTOR3), vPositionsVS, sizeof(D3DXVECTOR3), &matProjection, 4 );
vObjectMaxSS.x = vPositionsSS[0].x;
vObjectMinSS.x = vPositionsSS[1].x;
vObjectMaxSS.y = vPositionsSS[2].y;
vObjectMinSS.y = vPositionsSS[3].y;

// Calculate the area the player bounding volume takes up in view space
vPositionsVS[0] = D3DXVECTOR3( vPlayerPosVS.x + fPlayerRadius, vPlayerPosVS.y, vPlayerPosVS.z );
vPositionsVS[1] = D3DXVECTOR3( vPlayerPosVS.x - fPlayerRadius, vPlayerPosVS.y, vPlayerPosVS.z );
vPositionsVS[2] = D3DXVECTOR3( vPlayerPosVS.x, vPlayerPosVS.y + fPlayerRadius, vPlayerPosVS.z );
vPositionsVS[3] = D3DXVECTOR3( vPlayerPosVS.x, vPlayerPosVS.y - fPlayerRadius, vPlayerPosVS.z );

// Calculate the area the player bounding volume takes up in screen space
D3DXVec3TransformCoordArray( vPositionsSS, sizeof(D3DXVECTOR3), vPositionsVS, sizeof(D3DXVECTOR3), &matProjection, 4 );
vPlayerMaxSS.x = vPositionsSS[0].x;
vPlayerMinSS.x = vPositionsSS[1].x;
vPlayerMaxSS.y = vPositionsSS[2].y;
vPlayerMinSS.y = vPositionsSS[3].y;

// Check for overlap
if ( vObjectMaxSS.x < vPlayerMinSS.x )
return;
if ( vObjectMaxSS.y < vPlayerMinSS.y )
return;
if ( vObjectMinSS.x > vPlayerMaxSS.x )
return;
if ( vObjectMinSS.y < vPlayerMaxSS.y )
return;

// If we got here, the object is obstructing and should be made transparent

}





Also this is obvious but you wouldn't need to re-calculate the player's screen-space bounding volume for every object, I just do it there for ease of understanding.

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!