新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → 高级纹理映射技术(1) 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 11774 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 高级纹理映射技术(1) 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 高级纹理映射技术(1)

    纹理映射在三维图形程序设计中具有非常重要的作用,三维场景中的许多特殊效果都是通过纹理映射来实现的。例如通过纹理映射模拟复杂的光照效果,物体表面对周围环境的反射效果等。

    多层纹理映射

    Direct3D最多支持8层纹理,也就是说,在一个三维物体的表面可以同时拥有1~8张不同的纹理贴图。Direct3D能够在一个渲染过程中把这些纹理颜色依次混合,渲染到同一个物体的表面。每一个纹理层对应0~7的索引序号,多层纹理映射能够模拟更为真实的三维世界。例如,要显示具有周围景物倒影的光滑大理石地板,可以把大理石地板贴图设置为纹理层0,把具有周围景物倒影的贴图设置为纹理层1,然后通过设置Direct3D多层纹理混合操作,把纹理层0和纹理层1相混合,这时绘制出的三维物体就同时具有大理石地板和景物倒影的纹理颜色。利用Direct3D多达8层的纹理混合,可以在图形显示系统中显示丰富多彩的图像。Direct3D多层纹理混合过程如下图所示:

    按此在新窗口浏览图片

    从上图可以看出8层纹理是逐层混合然后输出的,也就是说,最对需要8个阶段完成纹理映射,而且每一阶段都是独立进行的,针对每一阶段都需要设置相应的颜色和alpha混合方法。所以一个纹理层就相当于一个纹理阶段,多层纹理映射有时也称为多阶段纹理混合。其中,是否应用纹理层0~7,即是否进行0~7纹理阶段的操作,可由应用程序指定,但它们的选择必须是顺序的。也就是说,在没有使用第n层的情况下,第n+1层不能使用。

    默认情况下,第一个纹理阶段操作(阶段0)的默认操作是D3DTOP_MODULATE,其他纹理操作阶段的默认操作是D3DTOP_DISABLE。即默认情况下Direct3D使用单层纹理映射绘制图形,除纹理层0外,纹理层1~7都是禁用的。

    在使用多层纹理映射之前,应先查询当前设备是否支持纹理混合,以及最多能支持几层纹理混合:

    // check whether device support multi textures render
    if(pCaps->MaxTextureBlendStages <= 1)
        return false;

    MaxTextureBlendStages
    Maximum number of texture-blending stages supported in the fixed function pipeline. This value is the number of blenders available. In the programmable pixel pipeline, this corresponds to the number of unique texture registers used by pixel shader instructions.
    为了将多层纹理映射到物体表面,需要为每层纹理指定使用的纹理坐标,各层纹理可以使用相同的纹理坐标,也可以使用不同的纹理坐标。纹理坐标包含在顶点数据中,如果需要使用不同的纹理坐标,那么在顶点数据中就需要包括多组纹理坐标,然后通过索引为每层纹理指定使用哪组纹理坐标:

    pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
    pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

    D3DTSS_TEXCOORDINDEX
    Index of the texture coordinate set to use with this texture stage. You can specify up to eight sets of texture coordinates per vertex. If a vertex does not include a set of texture coordinates at the specified index, the system defaults to the u and v coordinates (0,0).
    When rendering using vertex shaders, each stage's texture coordinate index must be set to its default value. The default index for each stage is equal to the stage index. Set this state to the zero-based index of the coordinate set for each vertex that this texture stage uses.

    Additionally, applications can include, as logical OR with the index being set, one of the constants to request that Direct3D automatically generate the input texture coordinates for a texture transformation. For a list of all the constants, see D3DTSS_TCI.

    With the exception of D3DTSS_TCI_PASSTHRU, which resolves to zero, if any of the following values is included with the index being set, the system uses the index strictly to determine texture wrapping mode. These flags are most useful when performing environment mapping.

    这里指定了两组纹理坐标:

    struct sCustomVertex{ float x, y, z; DWORD color; float u0, v0; float u1, v1;};
    #define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2)
    sCustomVertex vertices[] =  {    { -3.0f, -3.0f,  0.0f,  0xffffffff, 0.0f, 1.0f, 0.0f, 1.0f},    { -3.0f,  3.0f,  0.0f,  0xffffffff, 0.0f, 0.0f, 0.0f, 0.0f},    {  3.0f, -3.0f,  0.0f,  0xffffffff, 1.0f, 1.0f, 1.0f, 1.0f},    {  3.0f,  3.0f,  0.0f,  0xffffffff, 1.0f, 0.0f, 1.0f, 0.0f}};
    这里指定的两组纹理坐标值完全相同,你可以改变其中任何一组坐标,使两层纹理使用不同的纹理坐标。

    设置纹理层混合方法的代码如下:

    // set color blend operation and texture coordinate index for texture stage 0
    pd3dDevice->SetTexture(0, g_texture_0);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
    pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

    // set color blend operation and texture coordinate index for texture stage 1
    pd3dDevice->SetTexture(1, g_texture_1);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
    pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
    pd3dDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    pd3dDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

    这里先将物体的漫反射颜色和纹理层0的纹理颜色相乘,得到的结果再与纹理层1的纹理颜色相加后输出。

    该示例将物体纹理和光照纹理相混合后输出:

    按此在新窗口浏览图片
    物体纹理
    按此在新窗口浏览图片
    光照纹理

    运行效果图如下:

    按此在新窗口浏览图片

    我们可以修改顶点的纹理坐标为:

    sCustomVertex vertices[] =  {    { -3.0f, -3.0f,  0.0f,  0xffffffff, 0.0f, 1.0f, 1.0f, 0.0f},    { -3.0f,  3.0f,  0.0f,  0xffffffff, 0.0f, 0.0f, 1.0f, 1.0f},    {  3.0f, -3.0f,  0.0f,  0xffffffff, 1.0f, 1.0f, 0.0f, 0.0f},    {  3.0f,  3.0f,  0.0f,  0xffffffff, 1.0f, 0.0f, 0.0f, 1.0f}};
    这时的运行效果图如下:

    按此在新窗口浏览图片


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/2 10:10:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    主程序:


    #include "dxstdafx.h"
    #include "resource.h"

    #pragma warning(disable : 4127)

    #define IDC_TOGGLE_FULLSCREEN        1
    #define IDC_TOGGLE_REF                2
    #define IDC_CHANGE_DEVICE            3

    #define release_com(p)    do { if(p) { (p)->Release(); (p) = NULL; } } while(0)

    struct sCustomVertex
    {
        float x, y, z;
        DWORD color;
        float u0, v0;
        float u1, v1;
    };

    #define D3DFVF_CUSTOM_VERTEX    (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2)

    ID3DXFont*        g_font;
    ID3DXSprite*    g_text_sprite;
    bool            g_show_help = true;

    CDXUTDialogResourceManager    g_dlg_resource_manager;
    CD3DSettingsDlg                g_settings_dlg;
    CDXUTDialog                    g_button_dlg;

    IDirect3DVertexBuffer9*        g_vertex_buffer;
    IDirect3DTexture9*            g_texture_0;
    IDirect3DTexture9*            g_texture_1;

    //--------------------------------------------------------------------------------------
    // Rejects any devices that aren't acceptable by returning false
    //--------------------------------------------------------------------------------------
    bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
                                      D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
    {
        // Typically want to skip backbuffer formats that don't support alpha blending

        IDirect3D9* pD3D = DXUTGetD3DObject();

        if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat,
                        D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
            return false;

        // check whether device support multi textures render
        if(pCaps->MaxTextureBlendStages <= 1)
            return false;

        return true;
    }


    //--------------------------------------------------------------------------------------
    // Before a device is created, modify the device settings as needed.
    //--------------------------------------------------------------------------------------
    bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
    {
        // If video card does not support hardware vertex processing, then uses sofaware vertex processing.
        if((pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
            pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

        static bool is_first_time = true;

        if(is_first_time)
        {
            is_first_time = false;

            // if using reference device, then pop a warning message box.
            if(pDeviceSettings->DeviceType == D3DDEVTYPE_REF)
                DXUTDisplaySwitchingToREFWarning();
        }

        return true;
    }


    //--------------------------------------------------------------------------------------
    // Create any D3DPOOL_MANAGED resources here
    //--------------------------------------------------------------------------------------
    HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice,
                                     const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
                                     void* pUserContext )
    {
        HRESULT    hr;

        V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice));
        V_RETURN(g_settings_dlg.OnCreateDevice(pd3dDevice));

        D3DXCreateFont(pd3dDevice, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
                       DEFAULT_PITCH | FF_DONTCARE, L"Arial", &g_font);

        V_RETURN(D3DXCreateTextureFromFile(pd3dDevice, L"Wall.bmp",  &g_texture_0));
        V_RETURN(D3DXCreateTextureFromFile(pd3dDevice, L"light.jpg", &g_texture_1));

        // create vertex buffer and fill data

        sCustomVertex vertices[] =     
        {
            { -3.0f, -3.0f,  0.0f,  0xffffffff, 0.0f, 1.0f, 0.0f, 1.0f},
            { -3.0f,  3.0f,  0.0f,  0xffffffff, 0.0f, 0.0f, 0.0f, 0.0f},
            {  3.0f, -3.0f,  0.0f,  0xffffffff, 1.0f, 1.0f, 1.0f, 1.0f},
            {  3.0f,  3.0f,  0.0f,  0xffffffff, 1.0f, 0.0f, 1.0f, 0.0f}
            
            /*
            { -3.0f, -3.0f,  0.0f,  0xffffffff, 0.0f, 1.0f, 1.0f, 0.0f},
            { -3.0f,  3.0f,  0.0f,  0xffffffff, 0.0f, 0.0f, 1.0f, 1.0f},
            {  3.0f, -3.0f,  0.0f,  0xffffffff, 1.0f, 1.0f, 0.0f, 0.0f},
            {  3.0f,  3.0f,  0.0f,  0xffffffff, 1.0f, 0.0f, 0.0f, 1.0f}
            */
        };

        pd3dDevice->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_MANAGED, &g_vertex_buffer, NULL);

        void* ptr;
        g_vertex_buffer->Lock(0, sizeof(vertices), (void**)&ptr, 0);
        memcpy(ptr, vertices, sizeof(vertices));
        g_vertex_buffer->Unlock();

        return S_OK;
    }


    //--------------------------------------------------------------------------------------
    // Create any D3DPOOL_DEFAULT resources here
    //--------------------------------------------------------------------------------------
    HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
                                    const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
                                    void* pUserContext )
    {
        HRESULT hr;

        V_RETURN(g_dlg_resource_manager.OnResetDevice());
        V_RETURN(g_settings_dlg.OnResetDevice());
        V_RETURN(g_font->OnResetDevice());
        V_RETURN(D3DXCreateSprite(pd3dDevice, &g_text_sprite));

        // set dialog position and size

        g_button_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, 0);
        g_button_dlg.SetSize(170, 170);

        // setup view matrix

        D3DXMATRIX mat_view;
        D3DXVECTOR3 eye(0.0f, 0.0f, -8.0f);
        D3DXVECTOR3  at(0.0f, 0.0f,  0.0f);
        D3DXVECTOR3  up(0.0f, 1.0f,  0.0f);

        D3DXMatrixLookAtLH(&mat_view, &eye, &at, &up);
        pd3dDevice->SetTransform(D3DTS_VIEW, &mat_view);

        // set projection matrix
        D3DXMATRIX mat_proj;
        float aspect = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
        D3DXMatrixPerspectiveFovLH(&mat_proj, D3DX_PI/4, aspect, 1.0f, 100.0f);
        pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_proj);

        // set color blend operation and texture coordinate index for texture stage 0
        pd3dDevice->SetTexture(0, g_texture_0);
        pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,        D3DTOP_MODULATE);
        pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,    D3DTA_TEXTURE);
        pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2,    D3DTA_DIFFUSE);
        pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,        D3DTOP_DISABLE);
        pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,    0);
        pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
        pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

        // set color blend operation and texture coordinate index for texture stage 1
        pd3dDevice->SetTexture(1, g_texture_1);
        pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP,        D3DTOP_ADD);
        pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1,    D3DTA_TEXTURE);
        pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2,    D3DTA_CURRENT);
        pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP,        D3DTOP_DISABLE);
        pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX,    1);
        pd3dDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
        pd3dDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

        pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

        return S_OK;
    }

    //--------------------------------------------------------------------------------------
    // Release resources created in the OnResetDevice callback here
    //--------------------------------------------------------------------------------------
    void CALLBACK OnLostDevice( void* pUserContext )
    {
        g_dlg_resource_manager.OnLostDevice();
        g_settings_dlg.OnLostDevice();
        g_font->OnLostDevice();

        release_com(g_text_sprite);
    }


    //--------------------------------------------------------------------------------------
    // Release resources created in the OnCreateDevice callback here
    //--------------------------------------------------------------------------------------
    void CALLBACK OnDestroyDevice( void* pUserContext )
    {
        g_dlg_resource_manager.OnDestroyDevice();
        g_settings_dlg.OnDestroyDevice();    

        release_com(g_font);
        release_com(g_vertex_buffer);
        release_com(g_texture_0);
        release_com(g_texture_1);
    }

    //--------------------------------------------------------------------------------------
    // Handle updates to the scene
    //--------------------------------------------------------------------------------------
    void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
    {
    }

    //--------------------------------------------------------------------------------------
    // Render the helper information
    //--------------------------------------------------------------------------------------
    void RenderText()
    {
        CDXUTTextHelper text_helper(g_font, g_text_sprite, 20);
        
        text_helper.Begin();

        // show frame and device states
        text_helper.SetInsertionPos(5, 5);
        text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 0.475f, 0.0f, 1.0f) );
        text_helper.DrawTextLine( DXUTGetFrameStats(true) );
        text_helper.DrawTextLine( DXUTGetDeviceStats() );

        // show other simple information
        text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f) );
        text_helper.DrawTextLine(L"Multi Texture Blending");

        // show helper information
        
        const D3DSURFACE_DESC* surface_desc = DXUTGetBackBufferSurfaceDesc();

        if(g_show_help)
        {
            text_helper.SetInsertionPos(10, surface_desc->Height - 15 * 6);
            text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 0.475f, 0.0f, 1.0f) );
            text_helper.DrawTextLine(L"Controls (F1 to hide):");
            
            text_helper.SetInsertionPos(40, surface_desc->Height - 15 * 4);
            text_helper.DrawTextLine(L"Quir: ESC");
        }
        else
        {
            text_helper.SetInsertionPos(10, surface_desc->Height - 15 * 4);
            text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f) );
            text_helper.DrawTextLine(L"Press F1 for help");
        }

        text_helper.End();
    }

    //--------------------------------------------------------------------------------------
    // Render the scene
    //--------------------------------------------------------------------------------------
    void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
    {
        HRESULT hr;

        if(g_settings_dlg.IsActive())
        {
            g_settings_dlg.OnRender(fElapsedTime);
            return;
        }

        // Clear the render target and the zbuffer
        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) );

        // Render the scene
        if( SUCCEEDED( pd3dDevice->BeginScene() ) )
        {
            pd3dDevice->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex));
            pd3dDevice->SetFVF(D3DFVF_CUSTOM_VERTEX);
            pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

            RenderText();

            V(g_button_dlg.OnRender(fElapsedTime));

            V( pd3dDevice->EndScene() );
        }
    }


    //--------------------------------------------------------------------------------------
    // Handle messages to the application
    //--------------------------------------------------------------------------------------
    LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
                              bool* pbNoFurtherProcessing, void* pUserContext )
    {
        *pbNoFurtherProcessing = g_dlg_resource_manager.MsgProc(hWnd, uMsg, wParam, lParam);
        if(*pbNoFurtherProcessing)
            return 0;

        if(g_settings_dlg.IsActive())
        {
            g_settings_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
            return 0;
        }

        *pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
        if(*pbNoFurtherProcessing)
            return 0;

        return 0;
    }


    //--------------------------------------------------------------------------------------
    // Handle keybaord event
    //--------------------------------------------------------------------------------------
    void CALLBACK OnKeyboardProc(UINT charater, bool is_key_down, bool is_alt_down, void* user_context)
    {
        if(is_key_down)
        {
            switch(charater)
            {
            case VK_F1:
                g_show_help = !g_show_help;
                break;
            }
        }
    }

    //--------------------------------------------------------------------------------------
    // Handle events for controls
    //--------------------------------------------------------------------------------------
    void CALLBACK OnGUIEvent(UINT event, int control_id, CDXUTControl* control, void* user_context)
    {
        switch(control_id)
        {
        case IDC_TOGGLE_FULLSCREEN:
            DXUTToggleFullScreen();
            break;

        case IDC_TOGGLE_REF:
            DXUTToggleREF();
            break;

        case IDC_CHANGE_DEVICE:
            g_settings_dlg.SetActive(true);
            break;
        }
    }

    //--------------------------------------------------------------------------------------
    // Initialize dialogs
    //--------------------------------------------------------------------------------------
    void InitDialogs()
    {
        g_settings_dlg.Init(&g_dlg_resource_manager);
        g_button_dlg.Init(&g_dlg_resource_manager);

        g_button_dlg.SetCallback(OnGUIEvent);

        int x = 35, y = 10, width = 125, height = 22;

        g_button_dlg.AddButton(IDC_TOGGLE_FULLSCREEN, L"Toggle full screen", x, y,         width, height);
        g_button_dlg.AddButton(IDC_TOGGLE_REF,          L"Toggle REF (F3)",     x, y += 24, width, height);
        g_button_dlg.AddButton(IDC_CHANGE_DEVICE,      L"Change device (F2)", x, y += 24, width, height, VK_F2);    
    }

    //--------------------------------------------------------------------------------------
    // Initialize everything and go into a render loop
    //--------------------------------------------------------------------------------------
    INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
    {
        // Enable run-time memory check for debug builds.
    #if defined(DEBUG) | defined(_DEBUG)
        _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    #endif

        // Set the callback functions
        DXUTSetCallbackDeviceCreated( OnCreateDevice );
        DXUTSetCallbackDeviceReset( OnResetDevice );
        DXUTSetCallbackDeviceLost( OnLostDevice );
        DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
        DXUTSetCallbackMsgProc( MsgProc );
        DXUTSetCallbackFrameRender( OnFrameRender );
        DXUTSetCallbackFrameMove( OnFrameMove );
        DXUTSetCallbackKeyboard(OnKeyboardProc);
       
        // TODO: Perform any application-level initialization here
        InitDialogs();

        // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
        DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
        DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
        DXUTCreateWindow( L"AddControl" );
        DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );

        // Start the render loop
        DXUTMainLoop();

        // TODO: Perform any application-level cleanup here

        return DXUTGetExitCode();
    }

    在DirectX 6.0引入多纹理单元时,其中最有趣的一项特征便是它可以通过多次渲染将多张纹理映射到同一个多边形上,因为这是通过多次渲染不同的纹理来实现的,所以该技术称为多通道渲染(multipass rendering)。这里讲的是多重纹理渲染,是指将多张纹理在一次渲染中映射到同一个多边形上,而多通道渲染是指分多次将多张纹理映射到同一个多边形上,前者更快,多通道渲染技术目前已经很少使用了。

    [B][URL=http://www.cppblog.com/Files/changingnow/MultiTexture.rar]下载示例工程[/URL][/B]

    [此贴子已经被作者于2008-12-3 8:23:49编辑过]

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/2 10:11:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客3
    发贴心情 
    高级纹理映射技术(2)
    纹理阶段混合操作

    纹理映射本质上就是从纹理中获取颜色值,然后应用到物体的表面,多层纹理映射本质上就是混合多层纹理的颜色,然后应用到物体表面。为了处理上的方便,Direct3D将颜色的RGB通道和alpha通道分别进行处理,具体的操作方法通过纹理阶段状态进行设置。

    设置纹理颜色混合操作的代码大致如下:

    // i表示纹理阶段序号
    pd3dDevice->SetTextureStageState(i, D3DTSS_COLORARG1, arg1);
    pd3dDevice->SetTextureStageState(i, D3DTSS_COLORARG2, arg2);
    pd3dDevice->SetTextureStageState(i, D3DTSS_COLOROP, op);

    一般的,用D3DTSS_COLORARG1指定当前纹理层的颜色,用D3DTSS_COLORARG2指定已经过颜色混合处理后的前面所有纹理层的颜色,用D3DTSS_COLOROP指定混合方式。Direct3D使用下面的方式进行纹理混合:

    Colorstage = D3DTSS_COLOROP(D3DTSS_COLORARG1, D3DTSS_COLORARG2)

    渲染状态D3DTSS_COLOROP用来指定纹理RGB通道混合方式,它们是属于枚举类型D3DTEXTUREOP的常量,D3DTEXTUREOP定义如下:

    Defines per-stage texture-blending operations.

    typedef enum D3DTEXTUREOP{    D3DTOP_DISABLE = 1,    D3DTOP_SELECTARG1 = 2,    D3DTOP_SELECTARG2 = 3,    D3DTOP_MODULATE = 4,    D3DTOP_MODULATE2X = 5,    D3DTOP_MODULATE4X = 6,    D3DTOP_ADD = 7,    D3DTOP_ADDSIGNED = 8,    D3DTOP_ADDSIGNED2X = 9,    D3DTOP_SUBTRACT = 10,    D3DTOP_ADDSMOOTH = 11,    D3DTOP_BLENDDIFFUSEALPHA = 12,    D3DTOP_BLENDTEXTUREALPHA = 13,    D3DTOP_BLENDFACTORALPHA = 14,    D3DTOP_BLENDTEXTUREALPHAPM = 15,    D3DTOP_BLENDCURRENTALPHA = 16,    D3DTOP_PREMODULATE = 17,    D3DTOP_MODULATEALPHA_ADDCOLOR = 18,    D3DTOP_MODULATECOLOR_ADDALPHA = 19,    D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,    D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,    D3DTOP_BUMPENVMAP = 22,    D3DTOP_BUMPENVMAPLUMINANCE = 23,    D3DTOP_DOTPRODUCT3 = 24,    D3DTOP_MULTIPLYADD = 25,    D3DTOP_LERP = 26,    D3DTOP_FORCE_DWORD = 0x7fffffff,} D3DTEXTUREOP, *LPD3DTEXTUREOP;
    Constants
    D3DTOP_DISABLE
    Disables output from this texture stage and all stages with a higher index. To disable texture mapping, set this as the color operation for the first texture stage (stage 0). Alpha operations cannot be disabled when color operations are enabled. Setting the alpha operation to D3DTOP_DISABLE when color blending is enabled causes undefined behavior.

    D3DTOP_SELECTARG1
    Use this texture stage's first color or alpha argument, unmodified, as the output. This operation affects the color argument when used with the D3DTSS_COLOROP texture-stage state, and the alpha argument when used with D3DTSS_ALPHAOP.
    SRGBA = Arg1
      

    D3DTOP_SELECTARG2
    Use this texture stage's second color or alpha argument, unmodified, as the output. This operation affects the color argument when used with the D3DTSS_COLOROP texture stage state, and the alpha argument when used with D3DTSS_ALPHAOP.
    SRGBA = Arg2
      

    D3DTOP_MODULATE
    Multiply the components of the arguments.
    SRGBA = Arg1 x Arg2
      

    D3DTOP_MODULATE2X
    Multiply the components of the arguments, and shift the products to the left 1 bit (effectively multiplying them by 2) for brightening.
    SRGBA = (Arg1 x Arg2) << 1
      

    D3DTOP_MODULATE4X
    Multiply the components of the arguments, and shift the products to the left 2 bits (effectively multiplying them by 4) for brightening.
    SRGBA = (Arg1 x Arg2) << 2
      

    D3DTOP_ADD
    Add the components of the arguments.
    SRGBA = Arg1 + Arg2
      

    D3DTOP_ADDSIGNED
    Add the components of the arguments with a - 0.5 bias, making the effective range of values from - 0.5 through 0.5.
    SRGBA = Arg1 + Arg2 - 0.5
      

    D3DTOP_ADDSIGNED2X
    Add the components of the arguments with a - 0.5 bias, and shift the products to the left 1 bit.
    SRGBA = (Arg1 + Arg2 - 0.5) << 1
      

    D3DTOP_SUBTRACT
    Subtract the components of the second argument from those of the first argument.
    SRGBA = Arg1 - Arg2
      

    D3DTOP_ADDSMOOTH
    Add the first and second arguments; then subtract their product from the sum.
    SRGBA = Arg1 + Arg2 - Arg1 x Arg2 = Arg1 + Arg2 x (1 - Arg1)

    D3DTA
    Texture argument constants are used as values for the following members of the D3DTEXTURESTAGESTATETYPE enumerated type:

    D3DTSS_ALPHAARG0
    D3DTSS_ALPHAARG1
    D3DTSS_ALPHAARG2
    D3DTSS_COLORARG0
    D3DTSS_COLORARG1
    D3DTSS_COLORARG2
    D3DTSS_RESULTARG
    Set and retrieve texture arguments by calling the IDirect3DDevice9::SetTextureStageState and IDirect3DDevice9::GetTextureStageState methods.

    Argument flags

    You can combine an argument flag with a modifier, but two argument flags cannot be combined.

    #define Description
    D3DTA_CONSTANT Select a constant from a texture stage. The default value is 0xffffffff.
    D3DTA_CURRENT The texture argument is the result of the previous blending stage. In the first texture stage (stage 0), this argument is equivalent to D3DTA_DIFFUSE. If the previous blending stage uses a bump-map texture (the D3DTOP_BUMPENVMAP operation), the system chooses the texture from the stage before the bump-map texture. If s represents the current texture stage and s - 1 contains a bump-map texture, this argument becomes the result output by texture stage s - 2. Permissions are read/write.
    D3DTA_DIFFUSE The texture argument is the diffuse color interpolated from vertex components during Gouraud shading. If the vertex does not contain a diffuse color, the default color is 0xffffffff. Permissions are read-only.
    D3DTA_SELECTMASK Mask value for all arguments; not used when setting texture arguments.
    D3DTA_SPECULAR The texture argument is the specular color interpolated from vertex components during Gouraud shading. If the vertex does not contain a specular color, the default color is 0xffffffff. Permissions are read-only.
    D3DTA_TEMP The texture argument is a temporary register color for read or write. D3DTA_TEMP is supported if the D3DPMISCCAPS_TSSARGTEMP device capability is present. The default value for the register is (0.0, 0.0, 0.0, 0.0). Permissions are read/write.
    D3DTA_TEXTURE The texture argument is the texture color for this texture stage. Permissions are read-only.
    D3DTA_TFACTOR The texture argument is the texture factor set in a previous call to the IDirect3DDevice9::SetRenderState with the D3DRS_TEXTUREFACTOR render-state value. Permissions are read-only.

    Modifier flags

    An argument flag may be combined with one of the following modifier flags.

    #define Description
    D3DTA_ALPHAREPLICATE Replicate the alpha information to all color channels before the operation completes. This is a read modifier.
    D3DTA_COMPLEMENT Take the complement of the argument x, (1.0 - x). This is a read modifier.

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/3 8:24:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客4
    发贴心情 
    黑暗映射

    在Direct3D的坐标变换和光照流水线中,光照效果是基于所谓的"逐顶点(per-vertex)"方式计算的,也就是说,参与实际数计算的是三角形的每个顶点,而不是针对每个像素进行。有时这会造成一些较为明显的视觉错误,例如,有一个很大的三角形,其表面近处有一个光源,当光源靠近该三角形的一个顶点时,就会看到这个三角形的受光效果;当光源向三角形的重心靠近时,三角形的受光效果便会逐渐消失。最坏的情况是,当光源位于三角形的中央时,整个三角形只受非常少的光照,而在三角形的中央会有一个亮点。由此可见,如果顶点未受光照,则无法计算出正确的三角形面的颜色。为了解决这个问题,可以采用基于像素的光照计算,但是基于像素的光照计算其计算量比较大,通常采用纹理贴图的方式模拟基于逐像素光照效果,其中纹理贴图的内容正式所期望的类型光源照射在一张漆黑表面上的结果。

    通过纹理映射来模拟逐像素光照效果,通常是将第一层纹理设置为物体原来的表面纹理,将第二层纹理设置为光照纹理,然后将两张纹理的颜色相乘,所以有时将两张纹理的颜色相乘称为光照映射(light mapping)。由于这种技术经常被用于使一张纹理变暗,有时也称为黑暗映射(dark mapping)。示例代码如下:

    pd3dDevice->SetTexture(0, g_base_texture);
    pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);

    pd3dDevice->SetTexture(1, g_dark_texture);
    pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

    按此在新窗口浏览图片
    物体纹理
    按此在新窗口浏览图片
    光照纹理

    黑暗映射的效果:

    按此在新窗口浏览图片

    这种类型的多层纹理之所以称为"黑暗映射",是因为最终结果中未受到"光照"的纹理元素比原图中的纹理元素更暗。

    黑暗映射通常有三种调制操作:D3DTOP_MODULATE,D3DTOP_MODULATE2X,D3DTOP_MODULATE4X。

    当应用程序选择了一张纹理作为当前纹理,也就是指示Direct3D将该纹理应用于此后所有将要渲染的图元,直到再次改变当前纹理为止。如果一个三维场景中的每个图元都有各自不同的纹理,则必须在渲染每个图元之前先设置相应的纹理。

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/3 8:25:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客5
    发贴心情 
    高级纹理映射技术(3)
    黑暗贴图动画

    可以通过黑暗贴图三种调制操作的切换来创建一个动画示例,代码如下所示:

    pd3dDevice->SetTexture(0, g_base_texture);pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,  D3DTA_TEXTURE);pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,  D3DTOP_SELECTARG1);
    pd3dDevice->SetTexture(1, g_dark_texture);pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1,  D3DTA_TEXTURE);pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2,  D3DTA_CURRENT);
    static double last_time = 0.0f;double interval = fTime - last_time;
    if(interval < 0.5f) pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);else if(interval > 0.5f && interval < 1.0f) pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X);else if(interval > 1.0f && interval < 1.5f) pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE4X);else if(interval > 1.5f) last_time = fTime;
    效果如下:

    按此在新窗口浏览图片

    混合纹理与顶点漫反射颜色

    当很强的阳光照射在物体表面上时,会使它表面的颜色变得更加明亮,这可以通过将纹理与顶点的漫反射颜色相混合来模拟这种效果。当一个白色材质反射一个方向光时,反射量越多,就意味着纹理颜色在最终显示结果中所占的成分越少。因此,那些被光直接照射到表面会呈现出白色。示例代码如下:

    // setup light

    ZeroMemory(&g_light, sizeof(D3DLIGHT9));

    g_light.Type = D3DLIGHT_DIRECTIONAL;
    g_light.Diffuse.r = 0.5f;
    g_light.Diffuse.g = 0.5f;
    g_light.Diffuse.b = 0.5f;

    D3DXVECTOR3 light_dir(0, 0, 10);
    D3DXVec3Normalize((D3DXVECTOR3*) &g_light.Direction, &light_dir);

    // setup material

    ZeroMemory(&g_material, sizeof(D3DMATERIAL9));

    g_material.Ambient.r = 1.0f;
    g_material.Ambient.g = 1.0f;
    g_material.Ambient.b = 1.0f;
    g_material.Ambient.a = 1.0f;
    g_material.Diffuse.r = 0.7f;
    g_material.Diffuse.g = 0.7f;
    g_material.Diffuse.b = 0.7f;
    g_material.Diffuse.a = 0.5f;

    pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00808080);
    pd3dDevice->SetLight(0, &g_light);
    pd3dDevice->LightEnable(0, TRUE);
    pd3dDevice->SetMaterial(&g_material);

    pd3dDevice->SetTexture(0, g_base_texture);
    pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);

    运行效果:

    按此在新窗口浏览图片

    这个效果只需一次渲染,因此这里没有多重纹理的代码,对这段代码的简单描述就是"基础贴图 + 漫反射插值"。

    在固定函数流水线中有三种获取漫反射颜色的途径(在可编程流水线中则有更多的途径):材质、漫反射顶点颜色、镜面反射顶点颜色。从何处获取漫反射颜色取决于渲染状态D3DRS_DIFFUSEMATERIALSOURCE的设定。例如,如果调用:

    pd3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);

    D3DRS_DIFFUSEMATERIALSOURCE
    Diffuse color source for lighting calculations. Valid values are members of the D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_COLOR1. The value for this render state is used only if the D3DRS_COLORVERTEX render state is set to TRUE.
    D3DMATERIALCOLORSOURCE
    Defines the location at which a color or color component must be accessed for lighting calculations.

    typedef enum D3DMATERIALCOLORSOURCE{    D3DMCS_MATERIAL = 0,    D3DMCS_COLOR1 = 1,    D3DMCS_COLOR2 = 2,    D3DMCS_FORCE_DWORD = 0x7fffffff,} D3DMATERIALCOLORSOURCE, *LPD3DMATERIALCOLORSOURCE;
    Constants
    D3DMCS_MATERIAL
    Use the color from the current material.
    D3DMCS_COLOR1
    Use the diffuse vertex color.
    D3DMCS_COLOR2
    Use the specular vertex color.
    D3DMCS_FORCE_DWORD
    Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.
    Remarks
    These flags are used to set the value of the following render states in the D3DRENDERSTATETYPE enumerated type.

    D3DRS_AMBIENTMATERIALSOURCE
    D3DRS_DIFFUSEMATERIALSOURCE
    D3DRS_EMISSIVEMATERIALSOURCE
    D3DRS_SPECULARMATERIALSOURCE

    混合黑暗贴图与顶点漫反射颜色

    试想,当你站在一间伸手不见五指的房间内,无法看清周围的任何颜色。于是你打开灯光,突然之间物体的颜色便呈现了出来,就好像是被火焰点燃了一样。对于这种效果,可以通过黑暗贴图和顶点漫反射颜色的混合来模拟。

    先将一张纹理与一个顶点的漫反射颜色相混合,再将这个结果与黑暗贴图相混合:

    pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x0080FFFF);
    pd3dDevice->SetLight(0, &g_light);
    pd3dDevice->LightEnable(0, TRUE);
    pd3dDevice->SetMaterial(&g_material);

    pd3dDevice->SetTexture(0, g_base_texture);
    pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

    pd3dDevice->SetTexture(1, g_dark_texture);
    pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
    pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

    运行效果:

    按此在新窗口浏览图片

    如果没有光照,则纹理颜色会乘以0,因此就看不到墙壁纹理了,在这种情况下将只能看到第二张纹理。如果第一张纹理是不可见的,则第一阶段的颜色值0与第二阶段的颜色相乘的结果仍将为0(黑色)。当没有光照在物体的某个表面上时,该面的第一张纹理颜色会减弱为黑色。当你身处一个真正漆黑的地方时,由于光照微弱,你是无法看到周围物体的颜色的,因此上面这段代码对于模拟这种情况非常有效。

    这个过程可以描述为"(基础贴图 x 顶点的漫反射颜色) x 黑暗贴图"

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/3 8:26:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/24 20:34:25

    本主题贴数5,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    156.250ms