纹理映射是将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);
}

Direct3D 纹理映射的更多相关文章

  1. 【转载】Direct3D纹理映射

    原文:Direct3D纹理映射 更详细的文章:DirectX中的纹理映射相关技术 (转)   创建纹理对象 1: HRESULT CreateTexture( 2:   UINT Width,//宽度 ...

  2. Direct3D 11 Tutorial 7:Texture Mapping and Constant Buffers_Direct3D 11 教程7:纹理映射和常量缓冲区

    概述 在上一个教程中,我们为项目引入了照明. 现在我们将通过向我们的立方体添加纹理来构建它. 此外,我们将介绍常量缓冲区的概念,并解释如何使用缓冲区通过最小化带宽使用来加速处理. 本教程的目的是修改中 ...

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

    本文接着上一篇文章继续记录Direct3D(简称D3D)播放视频的技术.上一篇文章中已经记录了使用Direct3D中的Surface渲染视频的技术.本文记录一种稍微复杂但是更加灵活的渲染视频的方式:使 ...

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

    ===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...

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

    概要 在之前的教程中,我们建立了一个最小的Direct3D 11的应用程序,它用来在窗口上输出一个单一颜色.在本次教程中,我们将扩展这个应用程序,在屏幕上渲染出一个单一颜色的三角形.我们将通过设置数据 ...

  6. Direct3D中 SetTextureStageState 函数

    先说明几个概念: 1, Multipass(多通道)     将一个任务划分成几个阶段,由多个pass处理不同阶段,后续pass总是处理前一个pass的结果.例如复杂的光照方程可以分成几个pass来计 ...

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

    第15章 DirectInput接口 DirectInput作为DirectX的组件之一,依然是一些COM对象的集合.DirectInput由IDirectinput8.IDirectInputDev ...

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

    一.介绍 之前学习了如何绘制物体,还画了个DX自带的茶壶,然而这个东东并不怎么好看....离我们现实的物体简直相隔千里. 仅仅能说像美术他们用来写生的模型...那么要怎么样才干让我们的东西看起来更像真 ...

  9. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制 代码工程地址: https://gi ...

随机推荐

  1. python在一个列表中查找

    # -*- coding: utf-8 -*-__author__ = 'Administrator'import bisect#简化一些操作#1:在一个列表中查找""" ...

  2. 【公告】CSDN个人空间将于2014年4月20日全新改版上线

    尊敬的用户:   你们好!           CSDN个人空间将在2014年4月20日全新改版上线!        CSDN个人空间是2008年8月推出的服务,致力于给广大用户提供在线技术分享和资料 ...

  3. Android字数限制的EditText实现方案研究

    在应用开发中,有时需要实现有字数限制的EditText,首先来分析下市面上存在的类似实现方案吧,好有个感性的认识. [方案一:腾讯微博] 每个中文字符算一个字数,每两个英文字符算一个字数,当用户输入内 ...

  4. HTML与CSS入门——第十二章  在网页中使用多媒体

    知识点: 1.如何链接多媒体文件 2.如何嵌入多媒体文件 3.使用多媒体的更多技巧 多媒体文件:音频,视频和动画,以及静态的图像和文本. 这里我就直接讲HTML5了…… 此前都是用ojbect来加载或 ...

  5. SqlBulkCopy使用心得 (大量数据导入)

    文章转载原地址:http://www.cnblogs.com/mobydick/archive/2011/08/28/2155983.html 最近做的项目由于之前的设计人员懒省事,不按照范式来,将一 ...

  6. ASP.NET网页抓取数据

    我的数据通过一个TextBox输入,这些代码是写在一个button的点击事件里的. 网页数据抓取大概分为两步,第一步是获取网页源代码: 具体注释如下: var currentUrl = TextBox ...

  7. (转)简易WCF负载均衡方案

    最近跟高老师讨论nginx跟tomcat集群做负载均衡方案.感觉很有意思.想到自己项目中服务用的WCF技术,于是就想WCF如何做负载均衡,Google了一会,发现wcf4.0的路由服务好像可以实现.不 ...

  8. FineUI上传控件

    文件上传 现在就简单多了,并且也漂亮多了,参考这个示例. 1: <ext:SimpleForm ID="SimpleForm1" BodyPadding="5px& ...

  9. 《第一行代码》学习笔记12-UI(1)

    1.程序需要注销或者退出,用一个专门的集合类对所有的活动进行管理即可. 2.可视化编辑工具不利于真正了解界面背后的实现原理,通常这种方式制作的界面都不具有很好的屏幕适配性, 而且当需要编写较为复杂的界 ...

  10. 常用SQL语句学习整理

    增 insert into table_name (column_name1,column_name2) values (value1,value2) 删 delete from table_name ...