【directX 3D游戏开发】DirectX 中的空间坐标和灵活顶点格式使用
来源:互联网 发布:自然语言和c语言 编辑:程序博客网 时间:2024/06/05 01:14
实例工程文件如下:点击打开链接
在DirectX 中,坐标系主要分为三种,分别是:自身坐标系,世界坐标系,和摄像机坐标系
自身坐标系:一般情况下,游戏角色的自身坐标系的原点一般在两脚之间,自身坐标系的作用是用于改变角色形状的,比如你的胳膊相对于自身原点的坐标系改变,胳膊的位置长短什么的就肯定变了
世界坐标系:世界坐标系是物体相对于整个场景的坐标,他是用来确定的物体的位置的,一般物体的平移旋转都是对世界坐标的改变
摄像机坐标系:顾名思义,摄像机坐标系就是相对于摄像机的坐标,以摄像机所在的位置为原点
DirectX中,坐标系采用的是左手坐标系,就是向右为X轴的正方形,向上为Y轴的正方形,向屏幕里是Z轴的正方向,OpenGL里采用右手坐标系,这个不在我们讨论范围,所以在此不再赘述,总之,不同框架有其自己的坐标系规定,我们注意即可。
接下来是顶点,首先要弄明白的就是,顶点有哪些属性:1、基于世界坐标系的世界坐标 2、颜色、法线、贴图、纹理坐标等
下面介绍灵活顶点格式的概念:
灵活顶点格式 ( Flexible Vertex Format )FVF
我们着重介绍一下灵活顶点格式的坐标部分:
#define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
struct stVertex{D3DXVECTOR4 vPos;//为什么是4维向量,因为是X Y Z RHW各占一维DWORD dwColor;};
D3D中的顶点缓冲区,为什么有了数组还是定义顶点缓冲区?
D3D的API在绘制的时候,顶点数据是存到数组中了,但是在画的时候,还是从缓冲区中拿。因此数组只是临时存一下,存完了还是要把数据放到缓冲区中,这样显卡在画的时候才能从缓冲中拿数据、绘制
LPDIRECT3DVERTEXBUFFER9 p_dVB = NULL;
stVertex cVertices[] = {{ D3DXVECTOR4(100,100,0,1), D3DCOLOR_XRGB(255 , 0, 0) },//因为使用的是XYZRHW,D3DXVECTOR4(100,100,0,1)最后一个数字一定是1{ D3DXVECTOR4(400,100,0,1), D3DCOLOR_XRGB(0, 255, 0) },{ D3DXVECTOR4(100,400,0,1), D3DCOLOR_XRGB(0, 0, 255) },};
5.为顶点缓冲区分配空间,并将数组中的顶点数据拷贝到顶点缓冲区中
//通过设备指针来创建顶点缓冲区,CreateVertexBuffer类似new,在堆中申请的内存,因此不可以写在循环中,会造成内存泄露g_pDevice->CreateVertexBuffer(sizeof(cVertices),//顶点缓冲区的大小D3DUSAGE_WRITEONLY,//顶点缓冲区的作用D3DFVF_CUSTOMVERTEX,//通过我们已经定义好的灵活顶点模式,告知系统当前每一个顶点的格式D3DPOOL_MANAGED,//顶点缓冲区的存储空间位于哪里,D3DPOOL_MANAGED代表当前存储空间受系统管理,自动分配&p_dVB,//返回的顶点缓冲区指针NULL//Handle*一律给NULL,系统保留参数,一律给NULL即可);//前面只是分配空间,下面要拷贝数据,格式是固定的,先声明一个无类型的指针void* pVertices = NULL;//锁定顶点缓冲区,以便向其中拷贝数据【有锁定就有unlock】p_dVB->Lock(0,//锁定的偏移量,0表示不偏移sizeof(cVertices),//锁定的大小&pVertices,//锁定之后的存储空间由该指针指向0//锁定的标识,为0即可);//将cVertices中的数据拷贝到pVertices中,大小就是cVertices数组这么大memcpy(pVertices,cVertices,sizeof(cVertices));p_dVB->Unlock();
6.设置数据源、设置灵活顶点格式、绘制图元,这部分写在游戏循环里
//设置数据流的来源g_pDevice->SetStreamSource(0,//数据流管道号(d3d中可以同时支持16种管道,编号从0-15,使用的时候依次使用,从0开始)p_dVB,//数据来源,将数据从这个往管道0里面放0,//数据流的偏移量,前面p_dVB->Lock就没有偏移,这都是相对应的,因此这里也不偏移sizeof(stVertex)//每个数据的字节数大小,但是系统不知道按照何种格式解析);//告知系统数据格式,以便解析数据g_pDevice->SetFVF(D3DFVF_CUSTOMVERTEX);//绘制图元----一种画图方式,以后讲解,PT—Primitive是图元,Type是类型,三角形Triangleg_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,//三角形列0,//起始点编号(三角形中先画哪个点,等同于在数组中顶点的编号,即从数组的0号元素开始画)1//图元的数量);完整代码示例如下
//Utility.h#ifndef D3D_USEFUL_TOOLS_#define D3D_USEFUL_TOOLS_#include <Windows.h>#include <MMSystem.h>#pragma comment(lib,"Winmm.lib")#include <d3d9.h>//d3d的基础函数头文件#pragma comment(lib,"d3d9.lib")//d3d的基础函数库文件#include <d3dx9.h>//d3d的扩展函数头文件#pragma comment(lib,"d3dx9.lib")//d3d的扩展函数库文件#endif
//main.cpp#include "Utility.h"HWND g_hWnd = 0;//------改造3D窗口需要用到的内容-------LPDIRECT3D9 g_pD3D = NULL; //D3D的接口指针LPDIRECT3DDEVICE9 g_pDevice = NULL;//D3D的设备指针/*在3D窗口中绘制一个三角形的步骤为:(1)、定义灵活顶点格式(2)、根据顶点格式构建一个描述顶点的结构体(3)、声明一个顶点缓冲区指针(4)、定义一个结构体数组用来给每一个顶点赋值(5)、为顶点缓冲区分配空间并将数组中的顶点数据拷贝到顶点缓冲区中(6)、设置数据源、设置灵活顶点格式、绘制图元*///----步骤(1)、定义灵活顶点格式----//每一个顶点的格式(经过变换的屏幕坐标|顶点的颜色)#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)//----步骤(2)、根据顶点格式构建一个描述顶点的结构体----//描述一个顶点的结构体struct stVertex{D3DXVECTOR4 vPos;DWORD dwColor;};//----步骤(3)、声明一个顶点缓冲区指针----//D3D中的顶点缓冲区LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;//初始化顶点缓冲区void initVB(){//----步骤(4)、定义一个结构体数组用来给每一个顶点赋值----//数组用来存储当前程序中的顶点数据stVertex cVertices[] = {{D3DXVECTOR4(100,100,0,1),D3DCOLOR_XRGB(255,0,0)},{D3DXVECTOR4(400,100,0,1),D3DCOLOR_XRGB(0,255,0)},{D3DXVECTOR4(100,400,0,1),D3DCOLOR_XRGB(0,0,255)}};//----步骤(5)、为顶点缓冲区分配空间并将数组中的顶点数据拷贝到顶点缓冲区中----//通过设备指针来创建顶点缓冲区,用来存储顶点数据g_pDevice->CreateVertexBuffer(sizeof(cVertices),//顶点缓冲区的大小D3DUSAGE_WRITEONLY,//顶点缓冲区的作用D3DFVF_CUSTOMVERTEX,//通过我们已经定义好的灵活顶点格式告知系统当前每一个顶点的格式D3DPOOL_MANAGED,//顶点缓冲区的存储空间位于哪里,D3DPOOL_MANAGED代表当前存储空间受系统管理,自动分配&g_pVB,//返回的顶点缓冲区指针NULL//系统保留参数,为NULL即可);void * pVertices = NULL;//锁定顶点缓冲区,以便向其中拷贝数据g_pVB->Lock(0,//锁定的偏移量sizeof(cVertices),//锁定的大小&pVertices,//锁定之后的存储空间由该指针指向0//锁定的标识,为0即可);memcpy(pVertices,cVertices,sizeof(cVertices));g_pVB->Unlock();}//初始化D3D运行环境void onCreateD3D(){g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);if(!g_pD3D)return;////-----检测硬件设备能力的方法-----//D3DCAPS9 caps;//ZeroMemory(&caps,sizeof(caps));//g_pD3D->GetDeviceCaps(//D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps);D3DDISPLAYMODE d3ddm;ZeroMemory(&d3ddm,sizeof(d3ddm));g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm);D3DPRESENT_PARAMETERS d3dpp;ZeroMemory(&d3dpp,sizeof(d3dpp));d3dpp.Windowed = true;//窗口模式////-------全屏模式的写法:---------//d3dpp.Windowed = false;//d3dpp.BackBufferWidth = d3ddm.Width;//d3dpp.BackBufferHeight = d3ddm.Height;d3dpp.BackBufferFormat = d3ddm.Format;d3dpp.BackBufferCount = 1;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//是否开启自动深度模板缓冲d3dpp.EnableAutoDepthStencil = true;//当前自动深度模板缓冲的格式d3dpp.AutoDepthStencilFormat = D3DFMT_D16;g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pDevice);if(!g_pDevice)return;//设置渲染状态:设置启用深度值g_pDevice->SetRenderState(D3DRS_ZENABLE,true);}//初始化游戏内容void onInit(){onCreateD3D();/*D3DXMATRIX matView , matProj;D3DXMatrixIdentity(&matView);D3DXMatrixIdentity(&matProj);D3DXVECTOR3 vEyePos(0,3,-5);D3DXVECTOR3 vLookAt(0,0,0);D3DXVECTOR3 vUp(0,1,0);D3DXMatrixLookAtLH(&matView,&vEyePos,&vLookAt,&vUp);g_pDevice->SetTransform(D3DTS_VIEW,&matView);D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/3,4.0f/3.0f,1.0f,5000.0f);g_pDevice->SetTransform(D3DTS_PROJECTION,&matProj);*/initVB();}void onLogic(float fElapsedTime){}void onRender(float fElapsedTime){g_pDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(234,123,123),1.0f,0);g_pDevice->BeginScene();//----步骤(6)、设置数据源、设置灵活顶点格式、绘制图元----//设置数据流的来源g_pDevice->SetStreamSource(0,//数据流管道号(0-15)g_pVB,//数据的来源0,//数据流的偏移量sizeof(stVertex)//每个数据的字节数大小);//告知系统数据格式,以便解析数据g_pDevice->SetFVF(D3DFVF_CUSTOMVERTEX);//绘制图元 Primitive:图元,Type:类型,Triangle:三角形g_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,//三角形列0,//起始点编号(等同于在数组中顶点的编号)1//图元的数量);g_pDevice->EndScene();g_pDevice->Present(NULL,NULL,NULL,NULL);}//销毁游戏void onDestroy(){}LRESULT CALLBACK WndProc(HWND _hWnd,UINT _uMsg, WPARAM _wparam,LPARAM _lparam);INT WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ){WNDCLASS wc;ZeroMemory(&wc,sizeof(wc));wc.cbClsExtra = NULL;wc.cbWndExtra = NULL;wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);wc.hCursor = LoadCursor(NULL,IDC_ARROW);wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);wc.hInstance = hInstance;wc.lpfnWndProc = WndProc;wc.lpszClassName = TEXT("alibaba");wc.lpszMenuName = NULL;wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;RegisterClass(&wc);g_hWnd = CreateWindow(wc.lpszClassName,TEXT("First_3DApp"),WS_OVERLAPPEDWINDOW,100,20,800,600,NULL,NULL,hInstance,NULL);if(!g_hWnd)return 0;ShowWindow(g_hWnd,SW_SHOWNORMAL);UpdateWindow(g_hWnd);onInit();MSG msg;ZeroMemory(&msg,sizeof(msg));while (msg.message!=WM_QUIT){if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}else{static DWORD dwTime = timeGetTime();DWORD dwCurrentTime = timeGetTime();DWORD dwElapsedTime = dwCurrentTime - dwTime;float fElapsedTime = dwElapsedTime * 0.001f;//----------------------------------------onLogic(fElapsedTime);onRender(fElapsedTime);//----------------------------------------if(dwElapsedTime < 1000 / 60)Sleep(1000/60 - dwElapsedTime);dwTime = dwCurrentTime;}}onDestroy();return 0;}LRESULT CALLBACK WndProc(HWND _hWnd,UINT _uMsg, WPARAM _wparam,LPARAM _lparam){switch(_uMsg){case WM_KEYDOWN:if(_wparam == VK_ESCAPE)DestroyWindow(_hWnd);break;case WM_CLOSE:DestroyWindow(_hWnd);break;case WM_DESTROY:PostQuitMessage(0);break;}return DefWindowProc(_hWnd,_uMsg,_wparam,_lparam);}
- 【directX 3D游戏开发】DirectX 中的空间坐标和灵活顶点格式使用
- 使用GDI+模拟directx 3D渲染中的坐标变换
- DirectX 游戏编程之3D空间,顶点缓存及索引缓存
- DirectX.9.0.3D游戏开发总结
- 关于GUI设计的Directx灵活顶点格式
- DirectX 2D游戏开发
- Directx 3D - 3D视图空间和投影
- 【DirectX 3D游戏开发】DirectX 3D 窗口的创建
- 【DirectX 2D游戏开发基础】DirectX的应用实例
- DirectX游戏编程心得之:使用2-D坐标显示2-D图形的注意事项
- 【阅读笔记之五】《DIRECTX.9.0.3D游戏开发编程基础》Direct3D中的绘制
- 【阅读笔记之六】《DIRECTX.9.0.3D游戏开发编程基础》:Direct3D中的颜色
- 【阅读笔记之七】《DIRECTX.9.0.3D游戏开发编程基础》:Direct3D中的光照
- 【阅读笔记之九】《DIRECTX.9.0.3D游戏开发编程基础》:Direct3D中的融合技术
- 【阅读笔记之十】《DIRECTX.9.0.3D游戏开发编程基础》:Direc3D中的字体
- 【阅读笔记之一】《DIRECTX.9.0.3D游戏开发编程基础》:DirectX概略
- 《 DirectX 9.0 3D游戏开发编程基础》书评
- DirectX 9.0 3D 游戏开发编程基础
- linux mysql 操作命令
- WCF
- 冒泡法排序
- 沙盒存储机制
- 解决跨域问题,聊聊JSONP
- 【directX 3D游戏开发】DirectX 中的空间坐标和灵活顶点格式使用
- 微信支付---申请退款的https双向认证demo
- 函数指针与指针函数
- 关于list集合
- 测试某个类运行是否正常的方法
- Android Fragment 真正的完全解析(下)
- eclipse 设置 自动格式化代码 formatter cleanup
- Objective-C 【从文件中读写字符串(直接读写/通过NSURL读写)】
- 统计_z值