direct3d Colorkey 应用.

很多图片没有alpha通道, 想通过指定特定的颜色为"透明色", 比如, 有一张相片的图像和一张相框的图像. 如下所示.


相框的中间部分是白色的,而这张图像又没有alpha通道,是jpg格式的,渲染的时候想让把相框中间的白色部分渲染成透明色,以便看到后面的相片.这个时候就可以使用Colorkey技术了.
下面是设置与渲染  部分的代码.

View Code
//---------------------------------------------------------------------------------
void MyDXApp::initOther()
{
    baseInitOther();

    // 创建一个墙.
    if (FAILED(m_pDevice->CreateVertexBuffer(
        4 * sizeof(App6Vertex),
        0,
        APP6_VERTEX_FVF,
        D3DPOOL_DEFAULT,
        &m_vertex_buffer,
        NULL)))
    {
        return;
    }

    App6Vertex t_vertexs[] = 
    {
        {-10, 10, 0, 0,0},
        { 10, 10, 0, 1,0},
        {-10,-10, 0, 0,1},
        { 10,-10, 0, 1,1},
    };

    void *t_pv = NULL;
    if (FAILED(m_vertex_buffer->Lock(0,
        0, &t_pv,0 )))
    {
        return;
    }
    memcpy(t_pv, t_vertexs, sizeof(t_vertexs));
    m_vertex_buffer->Unlock();

    D3DXMatrixIdentity(&m_matrix1);

    // 创建纹理
    string t_name = "";
    getResourceFullname("xiangpian.jpg", t_name);
    if (FAILED(D3DXCreateTextureFromFile(m_pDevice, t_name.c_str(), &m_txt)))
    {
        return;
    }

    getResourceFullname("xiangkuang.jpg", t_name);
    if (FAILED(D3DXCreateTextureFromFileExA(
        m_pDevice,           //device
        t_name.c_str(),    //file name
        D3DX_DEFAULT,      //width
        D3DX_DEFAULT,      //height
        D3DX_DEFAULT,      //mip levels
        NULL,              //usage
        D3DFMT_UNKNOWN,    //texture color format
        D3DPOOL_MANAGED,   //memory class
        D3DX_DEFAULT,      //filter
        D3DX_DEFAULT,      //mip filter
        0x00ffffff,        //color key -- 就是这个值. 在***.jpg这个纹理中,此函数将会把此处指定的颜色的alpha值设置成"黑色透明"的颜色,比如加载此处的"相框"图像. 白色的部分的alpha值被设置成0值(即透明), 而其它颜色部分的alpha被设置成1(即不透明).
        NULL,              //source info
        NULL,              //pallette
        &m_txt2)))           //texture object
    {
        return;
    }

    m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    m_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);            // 只测试纹理,不测试含有材质的情况,所以不要开灯.
    m_pDevice->SetFVF(VERTEXFVF);    

    m_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
    m_pDevice->SetRenderState(D3DRS_ALPHAREF, 0x00000077);

    // D3DCMP_LESS 表示画相框的时候, 如果像素颜色的alpha值小于ref的设定值就画这个像素的颜色.
    // 见"相框效果图1"

    // D3DCMP_GREATER 表示..., 如果像素颜色的alpha值大于ref的设定值就画这个像素的颜色.[即,只画相框部分,而相框的"玻璃部分"不画]
    // 见"相框效果图2"
}
//---------------------------------------------------------------------------------
void MyDXApp::my_render()
{
    m_pDevice->SetStreamSource(0, m_vertex_buffer, 0, sizeof(App6Vertex));
    m_pDevice->SetTransform(D3DTS_WORLD, &m_matrix1);

    // 使用相片纹理
    m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    m_pDevice->SetTexture(0, m_txt);
    m_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

    // 使用相框纹理
    m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
    m_pDevice->SetTexture(0, m_txt2);
    m_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
}
//---------------------------------------------------------------------------------

下面是效果图:
相框效果图1:


相框效果图2:

posted @ 2012-05-03 17:03  莫压枯枯地  阅读(596)  评论(0编辑  收藏  举报