DirectX 9.0 C++ 教程 Texture 纹理映射

效果图:Directx SDK上 Texture 略微修改,它是一个旋转的空心圆柱体,我觉得用正方形比较能更好理解纹理坐标。其实用游戏引擎时,是不会关心纹理是如何具体映射的。

 

对上面这张gif图片是如何制作感兴趣?看截取视频,然后制成gif 教程

1.纹理坐标

DirectX中的纹理跟Opengl中的是类似的,可以参考这篇文章 Android 中使用OpenGL ES进行2D开发(纹理Texture使用)

DirectX 假设纹理图始终为1×1的正方形,其原点位于(0.0)处,右下角为(1,1)。如下图。

 

纹理坐标与顶点坐标之间的映射如下图:

 

// A structure for our custom vertex type. We added texture coordinates
struct CUSTOMVERTEX
{
	float x, y, z;
	unsigned long color;
    FLOAT       tu, tv;   // 纹理坐标
};
    // 构造组成物体的顶点,并为其指定纹理坐标
    CUSTOMVERTEX Vertices[] =
    {
           { -1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255),0,1 }, // x, y, z, rhw, color,tu,tv
           { -1.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255), 0,0},
           { 1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255), 1,1},
           { 1.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255), 1,0},
    };

 

2.加载纹理图片

//D3DXCreateTextureFromFile函数原型
HRESULT WINAPI D3DXCreateTextureFromFile(
  LPDIRECT3DDEVICE9 pDevice,      // 设备对象
  LPCTSTR pSrcFile,               // 图像文件名
  LPDIRECT3DTEXTURE9 * ppTexture  // 用来储存载入图片的纹理对象实例
);
//具体例子
 // 创建纹理
    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "objective-c.png", &g_pTexture ) ) )
    {
           MessageBox(NULL, "Could not find objective-c.png", "Textures.exe", MB_OK);
           return E_FAIL;   
    } 

 

3.总结一下场景添加纹理映射步骤

1.构造组成物体的顶点,并为其指定纹理坐标

2.用函数D3DXCreateTextureFromFile为LPDIRECT3DTEXTURE9 加载纹理

3.绘制物体前,用函数SetTexture来设定与该物体关联的纹理

纹理复杂起来非常复杂,本篇文章只设计到纹理坐标

4.全部源码(注意中文注释的代码)

//-----------------------------------------------------------------------------
// File: Textures.cpp
// About DirectX Texture
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#include <strsafe.h>

//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D       = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL; // Buffer to hold vertices
LPDIRECT3DTEXTURE9      g_pTexture   = NULL; // Our texture

// A structure for our custom vertex type. We added texture coordinates
struct CUSTOMVERTEX
{
	float x, y, z;
	unsigned long color;
    FLOAT       tu, tv;   // 纹理坐标
};

// 多了纹理,增加了D3DFVF_TEX1
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // Create the D3D object.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // Set up the structure used to create the D3DDevice. Since we are now
    // using more complex geometry, we will create a device with a zbuffer.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // Create the D3DDevice
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // Turn off culling
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    // Turn off D3D lighting
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

    // Turn on the zbuffer
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Create the Textures and vertex buffers
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // 创建纹理
    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "objective-c.png", &g_pTexture ) ) )
    {
           MessageBox(NULL, "Could not find objective-c.png", "Textures.exe", MB_OK);
           return E_FAIL;   
    }
	// 构造组成物体的顶点,并为其指定纹理坐标
	CUSTOMVERTEX Vertices[] =
	{
		   { -1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255),0,1 }, // x, y, z, rhw, color,tu,tv
		   { -1.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255), 0,0},
		   { 1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255), 1,1},
		   { 1.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(255,255,255), 1,0},
    };
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( sizeof(Vertices),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }    
    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof(Vertices), (void**)&pVertices, 0 ) ) )
        return E_FAIL;
	memcpy( pVertices, Vertices, sizeof(Vertices) );

    g_pVB->Unlock();

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pTexture != NULL )
        g_pTexture->Release();

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

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

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

//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    // 一定时间绕Y轴旋转
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixRotationY( &matWorld, timeGetTime()/1000.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    // 设置摄像头的位置等
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // 设置视锥体
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}

//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
    // Clear the backbuffer and the zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Setup the world, view, and projection matrices
        SetupMatrices();

        // 绘制物体前,设置物体关联的纹理
        g_pd3dDevice->SetTexture( 0, g_pTexture );

        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
		//两个三角形组成矩形
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);

        // End the scene
        g_pd3dDevice->EndScene();
    }

    // Present the backbuffer contents to the display
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }

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

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    // Register the window class
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      "D3D Tutorial", NULL };
    RegisterClassEx( &wc );

    // Create the application's window
    HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 05: Textures",
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Create the scene geometry
        if( SUCCEEDED( InitGeometry() ) )
        {
            // 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
                    Render();
            }
        }
    }

    UnregisterClass( "D3D Tutorial", wc.hInstance );
    return 0;
}

项目下载:http://download.csdn.net/detail/fox64194167/4636676 (CSDN下载,免积分)

http://www.waitingfy.com/wp-content/uploads/2012/10/Textures.rar(本站下载)

1.DirectX 9.0 C++ 教程 开发环境设定

2.DirectX 9.0 C++ 教程 第一个程序

3.DirectX 9.0 C++ 教程 绘制三角形

4.DirectX 9.0 C++ 教程 关于Perspective projection,Matrices,摄像头,旋转

5.DirectX 9.0 C++ 教程 光照

6.DirectX 9.0 C++ 教程 Texture 纹理映射

7.DirectX 9.0 C++ 教程 字体 迟到的helloworld

8. DirectX 9.0 C++ 教程 使用3ds max 创建的模型 xfile,mesh

238

2 Responses to DirectX 9.0 C++ 教程 Texture 纹理映射

  1. […] had to know some knowledge about “DirectX Texture”. If you don’t, you can see the article “DirectX 9.0 C++ tutorial Texture ” […]

  2. […] 我们来看下是如何实现的,首先你要有点知识关于“DirectX Texture(纹理)”. 如果你还没有的话,可以看下这篇文章 “DirectX 9.0 C++ tutorial Texture ”. […]

Leave a Reply

Name and Email Address are required fields.
Your email will not be published or shared with third parties.