Archived

This topic is now archived and is closed to further replies.

gerbrost

Billboarding, Light Halos, Alpha Blending

Recommended Posts

gerbrost    122
Hi all! I want to create a partly transparent bitmap facing the camera so i can simulate a lights halo. So far so good... The billboarding works fine, the image is always facing the camera. Unfortunately, the texture is not always displayed and the texture is affected by the lights in the scene. It should not be the case since the vertices are set to diffuse lighting. Here is my code:
  
// define my FVF and custom vertex (included in header file)

#define D3DFVF_HALOVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
struct HALOVERTEX
{
    D3DXVECTOR3 p;      // Vertex position

    DWORD       color;  // Vertex color

    FLOAT       tu, tv; // Vertex texture coordinates

};
// a texture and a vertex buffer are declared for our halo

    LPDIRECT3DVERTEXBUFFER8 m_pHaloVB;  // Vertex buffer for rendering a Halo

    LPDIRECT3DTEXTURE8      m_pHaloTexture; // Halo image

//This is run once in the scene init:

// get us a texture and a vertex buffer for the halo

	if( FAILED( D3DXCreateTextureFromFile( device, "halo.tga", &m_pHaloTexture))) {
		LogError("CreateTextureFromFile for halo failed!");
		return false;
	}
	if( FAILED( device->CreateVertexBuffer( 4*sizeof(HALOVERTEX),0,D3DFVF_HALOVERTEX,D3DPOOL_DEFAULT, &m_pHaloVB))) {
		LogError("CreateVertexBuffer failed!");
        return false;
    }

// so far so good this seems to work

// this is taken from the billboard sample to set the color of the vertices

    DWORD r = 255;
    DWORD g = 255;
    DWORD b = 255;
    DWORD dwColor = 0xff000000 + (r<<16) + (g<<8) + (b<<0);
// here we fill the Vertex buffer

    if( FAILED(m_pHaloVB->Lock( 0, 0, (BYTE**)&pHaloVertices, 0 )) ) {
		LogError("pVBfloor->Lock failed!");
        return false;
	}

        pHaloVertices[0].p		= D3DXVECTOR3(0.0f, 0.0f, 0.3f );
        pHaloVertices[0].color = dwColor;
        pHaloVertices[0].tu    = 0.0f;   
		pHaloVertices[0].tv    = 1.0f;
        pHaloVertices[1].p     = D3DXVECTOR3(0.0f, 1.0f, 0.3f  );
        pHaloVertices[1].color = dwColor;
        pHaloVertices[1].tu    = 0.0f;   
		pHaloVertices[1].tv    = 0.0f;
        pHaloVertices[2].p     = D3DXVECTOR3(1.0f, 0.0f, 0.3f  );
        pHaloVertices[2].color = dwColor;
        pHaloVertices[2].tu    = 1.0f;   
		pHaloVertices[2].tv    = 1.0f;
        pHaloVertices[3].p     = D3DXVECTOR3(1.0f, 1.0f, 0.3f  );
        pHaloVertices[3].color = dwColor;
        pHaloVertices[3].tu    = 1.0f;   
		pHaloVertices[3].tv    = 0.0f;
	
	m_pHaloVB->Unlock();

// until here everything looks good, the plane is displayed like it should be


// this is run every frame:

	D3DXMATRIX matHaloWorld;
	D3DXMATRIX matHaloWorldTemp;
	D3DXMatrixIdentity(&matHaloWorld);    
	D3DXVECTOR3 vDir = vLookatPt - vEyePt;
    if( vDir.x > 0.0f )
        D3DXMatrixRotationY( &matHaloWorld, -atanf(vDir.z/vDir.x)+D3DX_PI/2 );
    else
        D3DXMatrixRotationY( &matHaloWorld, -atanf(vDir.z/vDir.x)-D3DX_PI/2 );

    // Set diffuse blending for alpha set in vertices.

    device->SetRenderState( D3DRS_ALPHABLENDENABLE,   TRUE );
    device->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
    device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

    // Enable alpha testing (skips pixels with less than a certain alpha.)

    if( device_caps.AlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL )
    {
        device->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
        device->SetRenderState( D3DRS_ALPHAREF,        0x08 );
        device->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
    }

    device->SetStreamSource( 0, m_pHaloVB, sizeof(HALOVERTEX) );
    if(FAILED(device->SetVertexShader( D3DFVF_HALOVERTEX ))) {
		LogError("SetVertexShader for Halovertex failed");
	}
    if(FAILED(device->SetTexture( 0, m_pHaloTexture))) {
		LogError("SetTexture for HaloTex failed!");
	}

    // Translate the billboard into place

	
	D3DXMatrixTranslation(&matHaloWorldTemp,-3.0f,-3.0f,-3.0f);
	D3DXMatrixMultiply(&matHaloWorld,&matHaloWorldTemp,&matHaloWorld);


    device->SetTransform( D3DTS_WORLD, &matHaloWorld );

    // Render the billboard

	device->SetMaterial(&Material);
	device->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

    D3DXMATRIX  matWorld;
    D3DXMatrixIdentity( &matWorld );
    device->SetTransform( D3DTS_WORLD, &matWorld );
    device->SetRenderState( D3DRS_ALPHATESTENABLE,    FALSE );
    device->SetRenderState( D3DRS_ALPHABLENDENABLE,   FALSE );
  
What happens? I see the texture. As soon as i rotate my camera, the texture disappears. And the texture is affected by light. So when i move the camera back (when i dont rotate it, the texture can be seen), the texture turns invisible since its out of the light range. Since the vertices are diffuse colored, that should not happen. I also seem to have a slight problem with matrix translation since the position of the plane is not always right. The rotating is fine, the billboard always faces the camera. Please help me with that! Thank you!

Share this post


Link to post
Share on other sites