Direct3D 纹理映射



纹理映射是将2D的图片映射到一个3D物体上面,物体上漂亮图案被称为纹理贴图, 一个表面可以支持多张贴图等等,下面简单介绍下纹理贴图

纹理贴图UV: 贴图是一个个像素点组成,每一个像素点都由一个坐标最后形成一张贴图,贴图纹理坐标系UV两个轴组成, 从左上为原点。


那我们在学习下如何在Direct3D中创建一个纹理,绘制到一个正方形上面去。

设计顶点格式:

struct  CUSTOMVERTEX
{
    float x,y,z,rhw;
    float u,v;
};
//至少要一张贴图D3DFVF_TEX1
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)

创建纹理:

LPDIRECT3DTEXTURE9 g_pTexture = NULL;
//使用本地图片,创建纹理
D3DXCreateTextureFromFile(g_pd3dDevice,L"p5.jpg",&g_pTexture);

设置纹理:

g_pd3dDevice->SetTexture(0,g_pTexture);

效果图:

整体代码:

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

#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define WINDOW_TITLE L"盘子脸的程序"
#define SAFE_RELEASE(p) { if(p) { (p) -> Release();(p)=NULL;} }

struct  CUSTOMVERTEX
{
    float x,y,z,rhw;
    float u,v;
};
//至少要一张贴图D3DFVF_TEX1
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) 

//声明变量
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
ID3DXFont* g_pFont = NULL;
float g_FPS = 0.0f;
wchar_t g_strFPS[50];                                    //包含帧速率的字符
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;            //顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9 g_pIndexBuffer = NULL;            //索引缓存
LPDIRECT3DTEXTURE9 g_pTexture = NULL;

//全局函数声明部分
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
HRESULT Direct3DInit(HWND hwnd);
HRESULT ObjectsInit(HWND hwnd);
VOID Direct3DRender(HWND hwnd);
VOID Direct3DCleanUp();

//主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    //设置一个完整的窗口类,没有设置图标
    WNDCLASSEX wndClass = {0};
    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.style = CS_HREDRAW | CS_VREDRAW;            //设置窗口样式
    wndClass.lpfnWndProc = WndProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = hInstance;
    wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = L"GameDevelop";

    //注册窗口类
    if(!RegisterClassEx(&wndClass))
    {
        return -1;
    }

    //正式创建窗口
    HWND hwnd = CreateWindow(L"GameDevelop",WINDOW_TITLE,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,WINDOW_WIDTH,
        WINDOW_HEIGHT,NULL,NULL,hInstance,NULL);

    //初始化Direct3D资源
    if(!(S_OK == Direct3DInit(hwnd)))
    {
        MessageBox(hwnd,_T("初始化Direct3D失败"),_T("盘子脸的消息窗口"),0);
    }

    MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
    ShowWindow(hwnd,nShowCmd);
    UpdateWindow(hwnd);

    //消息循环过程
    MSG msg = {0};
    while(msg.message != WM_QUIT)
    {
        if(PeekMessage(&msg,0,0,0,PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }else
        {
            Direct3DRender(hwnd);
        }
    }

    //窗口类的注销
    UnregisterClass(L"GameDevelop",wndClass.hInstance);

    return 0;
}

//消息处理函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
        Direct3DRender(hwnd);
        ValidateRect(hwnd,NULL);
        break;
    case WM_KEYDOWN:
        if(wParam == VK_ESCAPE)
        {
            DestroyWindow(hwnd);
        }
        break;
    case WM_DESTROY:
        Direct3DCleanUp();                //失败Direct3D资源
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd,message,wParam,lParam);
    }

    return 0;
}

HRESULT Direct3DInit(HWND hwnd)
{
    //创建Direct3D接口对象
    LPDIRECT3D9 pD3D = NULL;
    if(NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
    {
        return E_FAIL;
    }

    //获取硬件消息
    D3DCAPS9 caps;
    int vp = 0;
    if(FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps)))
    {
        return E_FAIL;
    }

    if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
    {
        //支出硬件顶点运算
        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    }
    else
    {
        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    //填充Direct3Dpresent参数
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp,sizeof(d3dpp));
    d3dpp.BackBufferWidth = WINDOW_WIDTH;
    d3dpp.BackBufferHeight = WINDOW_HEIGHT;
    d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
    d3dpp.BackBufferCount = 1;
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality = 0;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hwnd;
    d3dpp.Windowed = true;
    d3dpp.EnableAutoDepthStencil = true;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
    d3dpp.Flags = 0;
    d3dpp.FullScreen_RefreshRateInHz = 0;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    //创建Direct3D设备接口
    if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,vp,&d3dpp,&g_pd3dDevice)))
    {
        return E_FAIL;
    }

    SAFE_RELEASE(pD3D);

    if(!(S_OK == ObjectsInit(hwnd)))
    {
        return E_FAIL;
    }

    return S_OK;
}

HRESULT ObjectsInit(HWND hwnd)
{
    //创建字体
    if(FAILED(D3DXCreateFont(g_pd3dDevice,36,0,0,1,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,DEFAULT_QUALITY,0,_T("微软雅黑"),&g_pFont)))
    {
        return E_FAIL;
    }

    //创建顶点缓存
    if(FAILED(g_pd3dDevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVertexBuffer,NULL)))
    {
        return E_FAIL;
    }

    //创建索引缓存
    if(FAILED(g_pd3dDevice->CreateIndexBuffer(6 * sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&g_pIndexBuffer,0)))
    {
        return E_FAIL;
    }

    //创建顶点数据
    CUSTOMVERTEX vertices [] =
    {
        { 100.0f, 100.0f, 0.0f, 1.0f, 0.0f,0.0f },
        { 300.0f, 100.0f, 0.0f, 1.0f, 1.0f,0.0f },
        { 300.0f, 300.0f, 0.0f, 1.0f, 1.0f,1.0f},
        { 100.0f, 300.0f, 0.0f, 1.0f, 0.0f,1.0f},
    };

    //填充顶点缓冲区
    VOID *pVertices;
    if(FAILED(g_pVertexBuffer->Lock(0,sizeof(vertices),(void**)&pVertices,0)))        //加锁
    {
        return E_FAIL;
    }

    memcpy(pVertices,vertices,sizeof(vertices));        //把顶点数据保存到顶点缓存中
    g_pVertexBuffer->Unlock();                            //解锁

    //这是索引缓存数据
    WORD * indices = 0;
    g_pIndexBuffer->Lock(0,0,(void**)&indices,0);

    //第一个三角形由0,1,3顶点组成
    indices[0] = 0;
    indices[1] = 1;
    indices[2] = 2;

    //第二个三角形由1,2,3顶点组成
    indices[3] = 0;
    indices[4] = 2;
    indices[5] = 3;

    g_pIndexBuffer->Unlock();

    //使用本地图片,创建纹理
    D3DXCreateTextureFromFile(g_pd3dDevice,L"p5.jpg",&g_pTexture);

    return S_OK;

}

void Direct3DRender(HWND hwnd)
{
    g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(245,245,245),1.0f,0);

    //定义一个矩形
    RECT formatRect;
    GetClientRect(hwnd,&formatRect);

    g_pd3dDevice->BeginScene();
    g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD);
    g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,false);
    g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,false);

    g_pd3dDevice->SetTexture(0,g_pTexture);
    //绘制图形
    g_pd3dDevice->SetStreamSource(0,g_pVertexBuffer,0,sizeof(CUSTOMVERTEX));        //设置绘制的顶点数据
    g_pd3dDevice->SetIndices(g_pIndexBuffer);                                        //设置索引缓存
    g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);                                        //设置灵活顶点格式
    g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);                //根据索引绘制图形,4代表使用4个顶点,2代表两个三角形,其他查询API了解吧

    //g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,4);

    //绘制文本信息
    g_pFont->DrawTextW(NULL,L"盘子脸",3,&formatRect,DT_TOP | DT_RIGHT , D3DCOLOR_XRGB(255,39,136));

    g_pd3dDevice->EndScene();
    g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}

void Direct3DCleanUp()
{
    SAFE_RELEASE(g_pVertexBuffer);
    SAFE_RELEASE(g_pFont);
    SAFE_RELEASE(g_pd3dDevice);
}
时间: 2024-08-07 08:36:58

Direct3D 纹理映射的相关文章

【转载】Direct3D纹理映射

原文:Direct3D纹理映射 创建纹理对象 1: HRESULT CreateTexture( 2:   UINT Width,//宽度 3:   UINT Height,//高度 4:   UINT Levels,//多级渐进纹理序列级数 5:   DWORD Usage,//用途 6:   D3DFORMAT Format,//像素格式 7:   D3DPOOL Pool,//内存池类型 8:   IDirect3DTexture9** ppTexture,//创建的纹理对象指针 9:  

Direct3D 纹理使用

关于纹理使用 1 纹理的创建 2 纹理的寻址方式 3 纹理的过滤方式 1 纹理的创建 <1> D3DXCreateTexture函数 创建一个空的纹理. HRESULT  D3DXCreateTexture( __in   LPDIRECT3DDEVICE9 pDevice, __in   UINT Width, __in   UINT Height, __in   UINT MipLevels, __in   DWORD Usage, __in   D3DFORMAT Format, __i

《逐梦旅程 WINDOWS游戏编程之从零开始》笔记7——DirectInput&amp;纹理映射

第15章 DirectInput接口 DirectInput作为DirectX的组件之一,依然是一些COM对象的集合.DirectInput由IDirectinput8.IDirectInputDevice8和IDirectInputEffect这3个接口组成.其中IDirectInput8作为DirectInput API中最主要的接口,用于初始化系统以及创建输入设备接口,DirectInput中其他所有接口都需要依赖于我们的IDirectInput8之上,都是通过这个接口进行查询的.而Dir

Direct3D中 SetTextureStageState 函数

先说明几个概念: 1, Multipass(多通道)     将一个任务划分成几个阶段,由多个pass处理不同阶段,后续pass总是处理前一个pass的结果.例如复杂的光照方程可以分成几个pass来计算.     用不同的纹理通过多个pass来多次渲染一个图元,这样可以实现许多很酷的特效.例如LightMap,它就是用不同的纹理来表示复杂的光.影效果.         2, Multitexture(多纹理)     很显然,pass越多,效率越低.为了降低pass的数量,有些硬件加速卡支持在一

最简单的视音频播放演示样例4:Direct3D播放RGB(通过Texture)

===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频播放演示样例2:GDI播放YUV, RGB 最简单的视音频播放演示样例3:Direct3D播放YUV,RGB(通过Surface) 最简单的视音频播放演示样例4:Direct3D播放RGB(通过Texture) 最简单的视音频播放演示样例5:OpenGL播放RGB/YUV 最简单的视音频播放演示样例

最简单的视音频播放示例4:Direct3D播放RGB(通过Texture)

本文接着上一篇文章继续记录Direct3D(简称D3D)播放视频的技术.上一篇文章中已经记录了使用Direct3D中的Surface渲染视频的技术.本文记录一种稍微复杂但是更加灵活的渲染视频的方式:使用Direct3D中的Texture(纹理)渲染视频. 纹理有关的基础知识 在记录使用Direct3D的Texture渲染视频的技术之前,首先记录一下有关纹理的基础知识.我自己归纳总结了以下几点知识. 1. 渲染(Render),纹理(Texture) 刚开始学习Direct3D显示视频技术的人一定

Direct-X学习笔记--纹理映射

一.介绍 之前学习了如何绘制物体,还画了个DX自带的茶壶,然而这个东东并不怎么好看....离我们现实的物体简直相隔千里. 仅仅能说像美术他们用来写生的模型...那么要怎么样才干让我们的东西看起来更像真实的物体呢?这个就要用到今天学习的纹理映射技术了... 纹理映射(Texture Mapping),又称纹理贴图.是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程.简单来说.就是把一幅图像贴到三维物体的表面上来增强真实感,能够和光照计算.图像混合等技术结合起来形成很多很美丽的效果. 总之.纹理映

【DirectX11】第六篇 纹理映射

本系列文章主要翻译和参考自<Real-Time 3D Rendering with DirectX and HLSL>一书(感谢原书作者),同时会加上一点个人理解和拓展,文章中如有错误,欢迎指正. 这里是书中的代码和资源. 纹理映射主要是指将贴图添加到3D模型表面的过程.这有点类似礼物包装,而你的包装纸就是一张2D的贴图.纹理映射是现代实时渲染技术的基础,并且可以用来实现很多很有意思的图形效果. 很多书或者文章中可能会把texture翻译成材质,在这里,我将保持unity Game Engin

Direct3D 11 Tutorial 2: Rendering a Triangle_Direct3D 11 教程2:渲染一个三角形

概要 在之前的教程中,我们建立了一个最小的Direct3D 11的应用程序,它用来在窗口上输出一个单一颜色.在本次教程中,我们将扩展这个应用程序,在屏幕上渲染出一个单一颜色的三角形.我们将通过设置数据机构的过程关联到三角形. 这个教程的输出结果是在窗口中央渲染出一个三角形. 资源目录 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial02 Github-LearnDirectX-DX3D11 tutorial02 (源码已上传至Github)