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


color inversion during transparency?

Recommended Posts

Hey all, I am trying to use transparency for a game and I am running into trouble with the textures. None of the textures have an alpha channel (.bmps). When I create the polygons, I set a material which has an alpha of 50% and then apply the texture to it. During rendering, i enable the appropriate alpha blending flags, but the colors show up inverted.. does this ring a bell to any of you who have run on this problem before? Here is part of my initialization code:
    // calculate the width, height, and length of each block based on walls
    float width = ((right_wall_x - left_wall_x) / BLOCKS_WIDTH)-2;
    float height = ((top_wall_y - bottom_wall_y) / BLOCKS_WIDTH)-2;
    float length = ((back_wall_z - front_wall_z) / BLOCKS_WIDTH)-2;

	// Mesh generation and material set up for Target
    // for each block, load a mesh (bc each mesh has a separate material)
    float block_loc_x = left_wall_x + (width/2.0f);
    float block_loc_y = 0.0f + (height/2.0f);
    float block_loc_z = front_wall_z + (length/2.0f);

    for(int x=0; xpVB, 
                      block_loc_x, block_loc_y, block_loc_z, 
                      width, height, length);

                block->loc_x = block_loc_x;
                block->loc_y = block_loc_y;
                block->loc_z = block_loc_z;
                block->width = width;
                block->height = height;
                block->length = length;

                ZeroMemory( &block->material, sizeof(D3DMATERIAL8) );
                // color of block
                block->material.Diffuse.r = block->material.Ambient.r = 1.0f;//random(0.4f, 1.f);
                block->material.Diffuse.g = block->material.Ambient.g = 1.0f;//random(0.4f, 1.f);
                block->material.Diffuse.b = block->material.Ambient.b = 1.0f;//random(0.4f, 1.f);
                block->material.Diffuse.a = block->material.Ambient.a = 0.5f;

                // update the z
                block_loc_z += length+2;
            // update the y
            block_loc_y += height+2;
            // reset the z
            block_loc_z = front_wall_z + (length/2.0f);//front_wall_z;
        // update the x
        block_loc_x += width+2;
        // reset the y and z
        block_loc_y = 0.0f + (height/2.0f);//0.0f;
        block_loc_z = front_wall_z + (length/2.0f);//front_wall_z;
And my render code snippet:
    // Begin the scene
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); 
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); 
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );    
    //here i am trying to make the walls semi transparent
    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);    
    //g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE );
    //g_pd3dDevice->SetRenderState(D3DRS_ALPHAREF, 0x02 );
    //g_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
    g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
    g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
    D3DXMATRIX matWorld, matTemp, matTemp2, padScale;

    //g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
    // draw blocks(s)
    g_pd3dDevice->SetTexture( 0, tex_Target );
    for(int x=0; xSetTransform( D3DTS_WORLD, &matWorld );
                    // set the material for the block
                    g_pd3dDevice->SetMaterial( &blocks[x][y][z].material );
                    g_pd3dDevice->SetStreamSource( 0, blocks[x][y][z].pVB, sizeof(CUSTOMVERTEX) );
                    g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
	                for (int i = 0; i < 6; i++)
	                   g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, i*4, 2 );
		            D3DXMatrixIdentity( &matWorld );
    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE );
    // draw pad
    //g_pd3dDevice->SetTexture(0, tex_pad);
    // matTemp - holds the rotation around the x-axis,
    // matTemp2 - holds the rotation around the z-axis, orienting the pad look direction
	D3DXMatrixTranslation( &matWorld, pad.loc_x, pad.loc_y, pad.loc_z );

    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
    // Draw from the mesh we loaded from x file ///////////////////////////////////////

    // Meshes are divided into subsets, one for each material. Render them in
    // a loop
    for( DWORD j=0; jSetMaterial( &pad.lp_MeshMaterials[j] );
        g_pd3dDevice->SetTexture( 0, pad.lp_MeshTextures[j] );
        // Draw the mesh subset
        pad.mesh->DrawSubset( j );
    D3DXMatrixIdentity( &matWorld );

    // draw ball
	if(ball.isActive) {
        // ball texture
        g_pd3dDevice->SetTexture( 0, tex_ball );

        D3DXMatrixTranslation( &matWorld, ball.loc_x, ball.loc_y, ball.loc_z );
		g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

		g_pd3dDevice->SetMaterial( &ball.material );
		ball.lp_mesh->DrawSubset( 0 );

		D3DXMatrixIdentity( &matWorld );

    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
    D3DXMatrixIdentity( &matWorld );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
    // draw walls
    g_pd3dDevice->SetTexture( 0, tex_Wall );
    //turn the alpha off
    //g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
    g_pd3dDevice->SetStreamSource( 0, g_pCubeVB, sizeof(CUSTOMVERTEX) );
    g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
	for (int i = 0; i < 5; i++)
	   g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, i*4, 2 );

    // LASTLY, Draw the score and high score
    // End the scene

Share this post

Link to post
Share on other sites
i guess i didn''t make myself very clear:

the material is R, G, B = 1 and alpha to 0.5

The texture, which is just plain yellow, shows up pink when i render it.

I think perhaps if someone could point me to a good reference to setting the RenderState flags, that''d be great, because i think that''s where my problem is.

I hope i explained the problem clear enough.


Share this post

Link to post
Share on other sites
Alright, i just noticed that if i set the background to black then the transparency works fine. So is there something special you have to do to get transparency to work with a white background?


Share this post

Link to post
Share on other sites
the sdk explains it very well. anyhoo, you are using D3DBLEND_SRCCOLOR and D3DBLEND_INVSRCCOLOR which uses the color as the alpha value. thus INVSRCCOLOR inverts the color from the source. you want to use SRCALPHA and INVSRCALPHA. i am not sure if this will work (ie material alpha may do anything). try using vertex alpha colors, and the vertex diffuse alpha blend (search the sdk for the correct renderstate). i don know however you CANT use SRCCOLOR and INVSRCCOLOR for the effect you want.

Share this post

Link to post
Share on other sites