zoukankan      html  css  js  c++  java
  • 20. 纹理混合透明度设置

    在将图像施加到表面时,并非图像的所有部分都是可见的。例如,如果有一幅叶子的图像,并且只想看到图像中实际构成叶子的那一部分内容,而不是空的场景,就需要使用名为“透明度”的技术,以帮助实现预期效果。有了透明度,就可以设置图像的一些像素可见,而另一些像素不可见。

            使用RGBA纹理图像中的Alpha成分或顶点颜色的alpha成分可以控制透明度。同样,可以将像素设为半透明,而不是可见或不可见。这意味着图像的某些部分在某种程度上是可见的,而某种程度上像玻璃一样是可以看穿的。这对于像菜单或GUI对象、窗口、X射线视觉等这样的东西而言非常有用。控制图像的alpha通道或是顶点颜色的alpha通道可以控制显示给终端用户的物体透明度。为了在Direct3D中使用透明度,只要启用混合模式渲染对象即可,这样Direct3D就会知道基于Alpha通道的混合结果。

    为了设置透明度,首先必须启动设置,为要混合的源对象设置一个参数,为正在渲染用的目的缓存设置一个参数。本例中的目的缓存是后台缓存。若要为纹理加载图像就必须有一个alpha通道,或是使用D3DCOLOR_ARGB宏而不是D3DCOLOR_XRGB,以便在顶点结构中使用alpha。

    #include<d3d9.h>
    #include
    <d3dx9.h>

    #define WINDOW_CLASS "UGPDX"
    #define WINDOW_NAME "Alpha Transparency"
    #define WINDOW_WIDTH 640
    #define WINDOW_HEIGHT 480

    // Function Prototypes...
    bool InitializeD3D(HWND hWnd, bool fullscreen);
    bool InitializeObjects();
    void RenderScene();
    void Shutdown();


    // Direct3D object and device.
    LPDIRECT3D9 g_D3D = NULL;
    LPDIRECT3DDEVICE9 g_D3DDevice
    = NULL;

    // Matrices.
    D3DXMATRIX g_projection;
    D3DXMATRIX g_ViewMatrix;

    // Vertex buffer to hold the geometry.
    LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL;

    // Holds a texture image.
    LPDIRECT3DTEXTURE9 g_Texture = NULL;

    // A structure for our custom vertex type
    struct stD3DVertex
    {
    float x, y, z;
    unsigned
    long color;
    float tu, tv;
    };

    // Our custom FVF, which describes our custom vertex structure
    #define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)


    LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    switch(msg)
    {
    case WM_DESTROY:
    PostQuitMessage(
    0);
    return 0;
    break;

    case WM_KEYUP:
    if(wParam == VK_ESCAPE) PostQuitMessage(0);
    break;
    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
    }


    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
    {
    // Register the window class
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
    GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
    WINDOW_CLASS, NULL };
    RegisterClassEx(
    &wc);

    // Create the application's window
    HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
    100, 100, WINDOW_WIDTH, WINDOW_HEIGHT,
    GetDesktopWindow(), NULL, wc.hInstance, NULL);

    // Initialize Direct3D
    if(InitializeD3D(hWnd, false))
    {
    // Show the window
    ShowWindow(hWnd, SW_SHOWDEFAULT);
    UpdateWindow(hWnd);

    // Enter the message loop
    MSG msg;
    ZeroMemory(
    &msg, sizeof(msg));

    while(msg.message != WM_QUIT)
    {
    if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
    TranslateMessage(
    &msg);
    DispatchMessage(
    &msg);
    }
    else
    RenderScene();
    }
    }

    // Release any and all resources.
    Shutdown();

    // Unregister our window.
    UnregisterClass(WINDOW_CLASS, wc.hInstance);
    return 0;
    }


    bool InitializeD3D(HWND hWnd, bool fullscreen)
    {
    D3DDISPLAYMODE displayMode;

    // Create the D3D object.
    g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
    if(g_D3D == NULL) return false;

    // Get the desktop display mode.
    if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
    return false;

    // Set up the structure used to create the D3DDevice
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(
    &d3dpp, sizeof(d3dpp));

    if(fullscreen)
    {
    d3dpp.Windowed
    = FALSE;
    d3dpp.BackBufferWidth
    = WINDOW_WIDTH;
    d3dpp.BackBufferHeight
    = WINDOW_HEIGHT;
    }
    else
    d3dpp.Windowed
    = TRUE;
    d3dpp.SwapEffect
    = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat
    = displayMode.Format;

    // Create the D3DDevice
    if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    &d3dpp, &g_D3DDevice)))
    {
    return false;
    }

    // Initialize any objects we will be displaying.
    if(!InitializeObjects()) return false;

    return true;
    }


    bool InitializeObjects()
    {
    // Fill in our structure to draw an object.
    // x, y, z, color, texture coords.
    stD3DVertex objData[] =
    {
    {
    -0.3f, -0.4f, 0.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 1.0f},
    {
    0.3f, -0.4f, 0.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 1.0f},
    {
    0.3f, 0.4f, 0.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 0.0f},

    {
    0.3f, 0.4f, 0.0f, D3DCOLOR_XRGB(255,255,255), 1.0f, 0.0f},
    {
    -0.3f, 0.4f, 0.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 0.0f},
    {
    -0.3f, -0.4f, 0.0f, D3DCOLOR_XRGB(255,255,255), 0.0f, 1.0f}
    };

    // Create the vertex buffer.
    if(FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(objData), 0,
    D3DFVF_VERTEX, D3DPOOL_DEFAULT,
    &g_VertexBuffer, NULL))) return false;

    // Fill the vertex buffer.
    void *ptr;
    if(FAILED(g_VertexBuffer->Lock(0, sizeof(objData), (void**)&ptr, 0))) return false;
    memcpy(ptr, objData,
    sizeof(objData));
    g_VertexBuffer
    ->Unlock();


    // Load the texture image from file.
    if(D3DXCreateTextureFromFile(g_D3DDevice, "decal.tga", &g_Texture) != D3D_OK)
    return false;

    // Set the image states to get a good quality image.
    g_D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    g_D3DDevice
    ->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);


    // Set default rendering states.
    g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_D3DDevice
    ->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);


    // Set the projection matrix.
    D3DXMatrixPerspectiveFovLH(&g_projection, 45.0f, WINDOW_WIDTH/WINDOW_HEIGHT,
    0.1f, 1000.0f);
    g_D3DDevice
    ->SetTransform(D3DTS_PROJECTION, &g_projection);

    // Define camera information.
    D3DXVECTOR3 cameraPos(0.0f, 0.0f, -1.0f);
    D3DXVECTOR3 lookAtPos(
    0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 upDir(
    0.0f, 1.0f, 0.0f);

    // Build view matrix.
    D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos, &lookAtPos, &upDir);

    return true;
    }


    void RenderScene()
    {
    // Clear the backbuffer.
    g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,0,0), 1.0f, 0);

    // Begin the scene. Start rendering.
    g_D3DDevice->BeginScene();

    // Apply the view (camera).
    g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);

    /*
    设置三种不同的渲染状态,设置和启用透明度功能。第一个函数设置的渲染状态是
    D3DRS_ALPHABLENDENABLE,将其设置为TRUE,从而启动Direct3D Alpha混合。
    第二个函数将正在渲染的对象的源混合操作(D3DRS_SRCBLEND)设置为源对象的Alpha通道,
    因为这里想使用图像或顶点颜色的Alpha值来控制后台中表面的混合。最后一个(D3DRS_DESTBLEND)是
    当前屏幕的内容,设置用来使用源对象的逆alpha。这意味着Direct3D会在将两个结果混合到一起时
    从Alpha成分中提取一个值。

    */
    // Set alpha transparency on for the texture image.
    g_D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    g_D3DDevice
    ->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    g_D3DDevice
    ->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    // Draw square.
    g_D3DDevice->SetTexture(0, g_Texture);
    g_D3DDevice
    ->SetStreamSource(0, g_VertexBuffer, 0, sizeof(stD3DVertex));
    g_D3DDevice
    ->SetFVF(D3DFVF_VERTEX);
    g_D3DDevice
    ->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

    // End the scene. Stop rendering.
    g_D3DDevice->EndScene();

    // Display the scene.
    g_D3DDevice->Present(NULL, NULL, NULL, NULL);
    }


    void Shutdown()
    {
    if(g_D3DDevice != NULL) g_D3DDevice->Release();
    g_D3DDevice
    = NULL;

    if(g_D3D != NULL) g_D3D->Release();
    g_D3D
    = NULL;

    if(g_VertexBuffer != NULL) g_VertexBuffer->Release();
    g_VertexBuffer
    = NULL;

    if(g_Texture != NULL) g_Texture->Release();
    g_Texture
    = NULL;
    }

      

    // Set alpha transparency on for the texture image.
    // 启用D3D Alpha混合运算
    g_D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    // 设置源混合因子
    g_D3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    // 设置目标混合因子
    g_D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

      调用三个函数,设置三种不同的渲染状态,设置和启用透明度功能。第一个函数设置的渲染状态是D3DRS_ALPHABLENDENABLE,将其设置为TRUE,从而启动Direct3D Alpha混合。第二个函数将正在渲染的对象的源混合因子(D3DRS_SRCBLEND)设置为源对象的Alpha通道,因为这里想使用图像或顶点颜色的Alpha值来控制后台中表面的混合。最后一个(D3DRS_DESTBLEND)是当前屏幕的内容,设置用来使用源对象的逆alpha。这意味着Direct3D会在将两个结果混合到一起时从Alpha成分中提取一个值。

  • 相关阅读:
    Interview with BOA
    Java Main Differences between HashMap HashTable and ConcurrentHashMap
    Java Main Differences between Java and C++
    LeetCode 33. Search in Rotated Sorted Array
    LeetCode 154. Find Minimum in Rotated Sorted Array II
    LeetCode 153. Find Minimum in Rotated Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 31. Next Permutation
    LeetCode 60. Permutation Sequence
    LeetCode 216. Combination Sum III
  • 原文地址:https://www.cnblogs.com/kex1n/p/2149594.html
Copyright © 2011-2022 走看看