zoukankan      html  css  js  c++  java
  • (转)纹理坐标变换

    Direct3D提供了对生成的纹理坐标进行坐标变换的功能,与顶点坐标变换相类似,可以指定一个4x4的纹理坐标变换矩阵,把它与生成的纹理坐标相乘,然后将变换之后的纹理坐标输出至Direct3D渲染流水线。使用纹理坐标变换可以对纹理坐标进行诸如平移、旋转和缩放等三维变换。纹理坐标变换对于生成一些特殊效果是非常有用的,它不用直接修改顶点的纹理坐标。例如可以通过一个简单的平移矩阵对纹理坐标进行变换,从而使物体表面上的纹理不断变换位置,产生动画效果。纹理坐标自动生成在三维图形程序中最广泛的应用是环境映射。

    可通过函数IDirect3DDevice9::SetTransform()来设置4x4的纹理坐标变换矩阵,它以D3DTS_TEXTURE0~ D3DTS_TEXTURE7作为第一个参数,表示设置纹理层0~7的纹理矩阵。下列代码对纹理层0设置了一个将纹理坐标u、v缩小到原来一半的纹理矩阵:

    D3DXMATRIX mat;
    D3DXMatrixIdentity(&mat);
    mat._11 = 0.5f;
    mat._22 = 0.5f;
    pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);

    下面的代码将原来的纹理坐标平移(1.0, 1.0, 0)个单位。

    D3DXMATRIX mat;
    D3DXMatrixIdentity(&mat);
    mat._41 = 1.0f;
    mat._42 = 1.0f;
    mat._43 = 0.0f;
    pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);

    示例程序通过下列代码对自动生成的纹理坐标进行变换:

    // texture coordinate transform

    D3DXMATRIX mat_texture, mat_scale, mat_trans;

    D3DXMatrixIdentity(&mat_texture);
    D3DXMatrixScaling(&mat_scale, 0.5f, -0.5f, 1.0f);
    D3DXMatrixTranslation(&mat_trans, 0.5f, 0.5f, 1.0f);

    mat_texture = mat_texture * mat_scale * mat_trans;
    pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat_texture);


    运行效果图:

    主程序:

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

    #pragma warning(disable : 
    4127 4995 4996)

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

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

    struct sCustomVertex
    {
        
    float x, y, z;
        D3DCOLOR color;
    };

    #define D3DFVF_CUSTOM_VERTEX    (D3DFVF_XYZ | D3DFVF_DIFFUSE)

    const D3DXCOLOR FONT_COLOR(1.0f0.5f0.25f1.0f);

    CDXUTDialogResourceManager    g_dlg_resource_manager;
    CD3DSettingsDlg                g_settings_dlg;
    CDXUTDialog                    g_button_dlg;

    IDirect3DVertexBuffer9
    *        g_vertex_buffer;
    IDirect3DTexture9
    *            g_texture;

    ID3DXFont
    *        g_font;
    ID3DXSprite
    *    g_text_sprite;
    bool            g_show_help;

    //--------------------------------------------------------------------------------------
    // 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;

        
    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, 
    180, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
                       DEFAULT_PITCH 
    | FF_DONTCARE, L"Arial"&g_font);

        V_RETURN(D3DXCreateTextureFromFile(pd3dDevice, L
    "texture.jpg"&g_texture));
        
        
    // create vertex buffer and fill data

        sCustomVertex vertices[] 
    =     
        {
            { 
    -1.0f-1.0f,  0.0f,  0xFFFFFFFF},
            { 
    -1.0f,  1.0f,  0.0f,  0xFFFFFFFF},
            {  
    1.0f-1.0f,  0.0f,  0xFFFFFFFF},
            {  
    1.0f,  1.0f,  0.0f,  0xFFFFFFFF}
        };

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

        
    void* ptr;
        g_vertex_buffer
    ->Lock(0sizeof(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 - 1700);
        g_button_dlg.SetSize(
    170170);

        
    // setup world matrix
        D3DXMATRIX mat_world;
        D3DXMatrixIdentity(
    &mat_world);
        pd3dDevice
    ->SetTransform(D3DTS_WORLD, &mat_world);

        
    // setup view matrix

        D3DXMATRIX mat_view;
        D3DXVECTOR3 eye(
    0.0f0.0f-3.0f);
        D3DXVECTOR3  at(
    0.0f0.0f,  0.0f);
        D3DXVECTOR3  up(
    0.0f1.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.0f100.0f);
        pd3dDevice
    ->SetTransform(D3DTS_PROJECTION, &mat_proj);

        pd3dDevice
    ->SetRenderState(D3DRS_LIGHTING, FALSE);

        
    // set texture color blend method, disalbe alpha blend.

        pd3dDevice
    ->SetTexture(0, g_texture);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_COLORARG1,        D3DTA_TEXTURE);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_COLORARG2,        D3DTA_DIFFUSE);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_COLOROP,            D3DTOP_MODULATE);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_ALPHAOP,            D3DTOP_DISABLE);

        
    // create texture coordinate using vertex position in camera space 
        pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,            D3DTSS_TCI_CAMERASPACEPOSITION);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,    D3DTTFF_COUNT2);

        
    // texture coordinate transform

        D3DXMATRIX mat_texture, mat_scale, mat_trans;

        D3DXMatrixIdentity(
    &mat_texture);
        D3DXMatrixScaling(
    &mat_scale, 0.5f-0.5f1.0f);
        D3DXMatrixTranslation(
    &mat_trans, 0.5f0.5f1.0f);

        mat_texture 
    = mat_texture * mat_scale * mat_trans;
        pd3dDevice
    ->SetTransform(D3DTS_TEXTURE0, &mat_texture);

        
    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);
    }

    //--------------------------------------------------------------------------------------
    // 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(55);
        text_helper.SetForegroundColor(FONT_COLOR);
        text_helper.DrawTextLine( DXUTGetFrameStats(
    true) );
        text_helper.DrawTextLine( DXUTGetDeviceStats() );

        
    // show other simple information
        
    //text_helper.SetForegroundColor( D3DXCOLOR(0.2f, 0.5f, 0.8f, 1.0f) );
        
    //text_helper.DrawTextLine(L"Texture Coordinate Transform");

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

        
    if(g_show_help)
        {
            text_helper.SetInsertionPos(
    10, surface_desc->Height - 18 * 5);
            text_helper.SetForegroundColor(FONT_COLOR);
            text_helper.DrawTextLine(L
    "Controls (F1 to hide):");
            
            text_helper.SetInsertionPos(
    40, surface_desc->Height - 18 * 4);
            text_helper.DrawTextLine(L
    "Quit: ESC");
        }
        
    else
        {
            text_helper.SetInsertionPos(
    10, surface_desc->Height - 15 * 4);
            text_helper.SetForegroundColor( D3DXCOLOR(
    1.0f1.0f1.0f1.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(0000), 1.0f0) );

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

            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 eventint 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( truetruetrue ); // Parse the command line, handle the default hotkeys, and show msgboxes
        DXUTSetCursorSettings( truetrue ); // Show the cursor and clip it when in full screen
        DXUTCreateWindow( L"Texture Coordinate Transform" );
        DXUTCreateDevice( D3DADAPTER_DEFAULT, 
    true640480, IsDeviceAcceptable, ModifyDeviceSettings );

        
    // Start the render loop
        DXUTMainLoop();

        
    // TODO: Perform any application-level cleanup here

        
    return DXUTGetExitCode();
    }
  • 相关阅读:
    2014年互联网发展趋势如何
    服务器出现阶段性错误
    用互联网思想武装自己
    杭州互联网公司汇总
    互联网牛人网址大全
    ffmpeg开发指南
    Windows下FFmpeg快速入门
    FFmpeg介绍及参数详细说明
    windows 下FFMPEG的编译方法 附2012-9-19发布的FFMPEG编译好的SDK下载
    FFMPEG视音频编解码零基础学习方法 【荐】
  • 原文地址:https://www.cnblogs.com/lancidie/p/1870028.html
Copyright © 2011-2022 走看看