逐梦旅程学习笔记 DirectX开发入门02:旋转的彩色立方体
2014-12-02 18:46
555 查看
本文是 系列笔记DirectX部分的第2篇,上一篇参见
逐梦旅程学习笔记 DirectX开发入门01:应用程序基本框架
这个示例增加了一些实际的内容,首先是绘制一个颜色随机变幻的彩色立方体,其二是显示FPS
我录制了一段运行时刻的视频如下(若无法显示请点此跳转)
如果不能播放视频,请参考以下截图
因为GIF动态图片只能播放第一帧,所以就分别截取了几个时刻的静态帧图片
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/14/18384a9abe3cb372a4e1712bc6de6828)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/14/d2480d698ba4a16cfa0b18334774ba09)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/14/25207fa6adcc100ca7d37e8a31754a6a)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/14/9b6562d99fbcdc99238419a6fa9fd8ce)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/14/d7189547eed6556cbaff4ec26fe3ce94)
以上都是颜色填充模式,按下数字键‘1’后切换到线框模式
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/14/73f571890cf2a8c558c9b520f2d78c13)
按下数字键‘2’切换回颜色填充模式。这个示例比较简单,没有涉及到高级的内容,如果能够理解01篇的话,这个示例应当不算太难。
我们来看看,原始的App类现在改成什么样了
关于FVF(灵活顶点格式)可以参考这篇文章
3D游戏编程入门(十一)D3D基础之FVF格式
比较上述代码可以发现,App类增加了一些成员变量和3个新的方法。
ID3DXFont* pFont; //将用作文字输出
char szFPS[32]; //存储用于输出的字符串
余下变量意义正如其名,例如
LPDIRECT3DVERTEXBUFFER9
pVertexBuffer = NULL;//顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9
pIndexBuffer = NULL;//索引缓存对象
现在主要关注InitObjects(), Rotate(), GetFPS() 这3个函数
InitObjects用来初始化将要绘制的内容(立方体),具体内容如下
基本上是直接复制浅墨《逐梦旅程》一书中的代码,小作修改
Rotate()是旋转操作,稍后再详细讲解
GetFPS()是获取当前帧率(frame per second)
以下frameCount,tickCurrent,tickLast,fps都是App类的成员变量
因为GetFPS()函数在每一次执行Render()即绘制操作时都被调用,因此调用GetFPS()的次数就是绘制的次数
这样,如果我们记录调用GetFPS()的时刻和帧数frameCount
当时间间隔达到1秒的时候,这时候计算出这一秒间隔内绘制的frameCount就能得到帧率fps
接下来看看Render()函数的内容
首先是device->Clear()对画面进行刷新
然后是device->BegineScene()准备绘制流水
接着Rotate()执行旋转操作
期间按照渲染步骤(渲染管线/流水线)进行设置,DX会自动进行后台计算处理
再接着device->EndScene()结束绘制流水
最后device->Present()呈现(根据交换链中当前帧进行填充)
本文原创,部分代码参考了浅墨《逐梦旅程》中的示例
完整代码参见
https://github.com/fengyhack/DirectGame/tree/CubeDemo
博文原始地址
http://blog.csdn.net/fengyhack/article/details/41682143
逐梦旅程学习笔记 DirectX开发入门01:应用程序基本框架
这个示例增加了一些实际的内容,首先是绘制一个颜色随机变幻的彩色立方体,其二是显示FPS
我录制了一段运行时刻的视频如下(若无法显示请点此跳转)
如果不能播放视频,请参考以下截图
因为GIF动态图片只能播放第一帧,所以就分别截取了几个时刻的静态帧图片
以上都是颜色填充模式,按下数字键‘1’后切换到线框模式
按下数字键‘2’切换回颜色填充模式。这个示例比较简单,没有涉及到高级的内容,如果能够理解01篇的话,这个示例应当不算太难。
我们来看看,原始的App类现在改成什么样了
#include <d3d9.h> #include <d3dx9.h> #include <Windows.h> struct CUSTOMVERTEX { FLOAT x, y, z; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE) class App { public: App(); ~App(); public: void Create(HWND hwnd); void Render(void); void CleanUp(void); void InitObjects(void); void Rotate(void); double GetFPS(); private: D3DPRESENT_PARAMETERS d3dpp; LPDIRECT3DDEVICE9 device; ID3DXFont* pFont; char szFPS[32]; LPDIRECT3DVERTEXBUFFER9 pVertexBuffer = NULL; //顶点缓冲区对象 LPDIRECT3DINDEXBUFFER9 pIndexBuffer = NULL; // 索引缓存对象 RECT rect; RECT clientRect; int width, height; double fps; int frameCount; DWORD tickCurrent; DWORD tickLast; };
关于FVF(灵活顶点格式)可以参考这篇文章
3D游戏编程入门(十一)D3D基础之FVF格式
比较上述代码可以发现,App类增加了一些成员变量和3个新的方法。
ID3DXFont* pFont; //将用作文字输出
char szFPS[32]; //存储用于输出的字符串
余下变量意义正如其名,例如
LPDIRECT3DVERTEXBUFFER9
pVertexBuffer = NULL;//顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9
pIndexBuffer = NULL;//索引缓存对象
现在主要关注InitObjects(), Rotate(), GetFPS() 这3个函数
InitObjects用来初始化将要绘制的内容(立方体),具体内容如下
基本上是直接复制浅墨《逐梦旅程》一书中的代码,小作修改
void App::InitObjects() { //创建顶点缓存 device->CreateVertexBuffer(8 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT, &pVertexBuffer, NULL); // 创建索引缓存 device->CreateIndexBuffer(36 * sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIndexBuffer, NULL); CUSTOMVERTEX Vertices[] = { { -20.0f, 20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { -20.0f, 20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, 20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, 20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { -20.0f, -20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { -20.0f, -20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, -20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, -20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, }; //填充顶点缓存 VOID* pVertices; pVertexBuffer->Lock(0, sizeof(Vertices), (void**)&pVertices, 0); memcpy(pVertices, Vertices, sizeof(Vertices)); pVertexBuffer->Unlock(); // 填充索引数据 WORD *pIndices = NULL; pIndexBuffer->Lock(0, 0, (void**)&pIndices, 0); // 顶面 pIndices[0] = 0, pIndices[1] = 1, pIndices[2] = 2; pIndices[3] = 0, pIndices[4] = 2, pIndices[5] = 3; // 正面 pIndices[6] = 0, pIndices[7] = 3, pIndices[8] = 7; pIndices[9] = 0, pIndices[10] = 7, pIndices[11] = 4; // 左侧面 pIndices[12] = 0, pIndices[13] = 4, pIndices[14] = 5; pIndices[15] = 0, pIndices[16] = 5, pIndices[17] = 1; // 右侧面 pIndices[18] = 2, pIndices[19] = 6, pIndices[20] = 7; pIndices[21] = 2, pIndices[22] = 7, pIndices[23] = 3; // 背面 pIndices[24] = 2, pIndices[25] = 5, pIndices[26] = 6; pIndices[27] = 2, pIndices[28] = 1, pIndices[29] = 5; // 底面 pIndices[30] = 4, pIndices[31] = 6, pIndices[32] = 5; pIndices[33] = 4, pIndices[34] = 7, pIndices[35] = 6; pIndexBuffer->Unlock(); device->SetRenderState(D3DRS_LIGHTING, FALSE); //关闭光照 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); //开启背面消隐 }
Rotate()是旋转操作,稍后再详细讲解
GetFPS()是获取当前帧率(frame per second)
以下frameCount,tickCurrent,tickLast,fps都是App类的成员变量
double App::GetFPS() { ++frameCount; tickCurrent = GetTickCount(); double delta = ((double)(tickCurrent - tickLast)) / 1000.0; if (delta > 1.0) { fps = ((double)frameCount) / delta; tickLast = tickCurrent; frameCount = 0; } return fps; }
因为GetFPS()函数在每一次执行Render()即绘制操作时都被调用,因此调用GetFPS()的次数就是绘制的次数
这样,如果我们记录调用GetFPS()的时刻和帧数frameCount
当时间间隔达到1秒的时候,这时候计算出这一秒间隔内绘制的frameCount就能得到帧率fps
接下来看看Render()函数的内容
void App::Render() { device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 128), 1.0f, 0); device->BeginScene(); Rotate(); if (::GetAsyncKeyState(0x31) & 0x8000f) // 若数字键1被按下,进行线框填充 device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); if (::GetAsyncKeyState(0x32) & 0x8000f) // 若数字键2被按下,进行实体填充 device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); device->SetStreamSource(0, pVertexBuffer, 0, sizeof(CUSTOMVERTEX));//把包含的几何体信息的顶点缓存和渲染流水线相关联 device->SetFVF(D3DFVF_CUSTOMVERTEX);//指定我们使用的灵活顶点格式的宏名称 device->SetIndices(pIndexBuffer);//设置索引缓存 device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);//利用索引缓存配合顶点缓存绘制图形 int ct=sprintf_s(szFPS, 32, "FPS:%08.3f", GetFPS()); pFont->DrawText(NULL, szFPS, ct, &clientRect, DT_TOP|DT_RIGHT , D3DCOLOR_XRGB(255, 0, 255)); device->EndScene(); device->Present(NULL, NULL, NULL, NULL); }
首先是device->Clear()对画面进行刷新
然后是device->BegineScene()准备绘制流水
接着Rotate()执行旋转操作
期间按照渲染步骤(渲染管线/流水线)进行设置,DX会自动进行后台计算处理
再接着device->EndScene()结束绘制流水
最后device->Present()呈现(根据交换链中当前帧进行填充)
本文原创,部分代码参考了浅墨《逐梦旅程》中的示例
完整代码参见
https://github.com/fengyhack/DirectGame/tree/CubeDemo
博文原始地址
http://blog.csdn.net/fengyhack/article/details/41682143
相关文章推荐
- 逐梦旅程学习笔记 DirectX开发入门01:应用程序基本框架
- 逐梦旅程学习笔记 DirectX开发入门03:旋转的彩色立方体进阶版
- 逐梦旅程学习笔记 Windows/GDI 示例02:双缓冲贴图/绘制自由线条
- [Kotlin&Anko开发Android入门学习笔记]-02Kotlin如何使用Android第三方库
- 第一章 jquery开发入门 学习笔记
- 【学习笔记】零基础C#窗口程序开发入门
- Windows 8 Directx 开发学习笔记(六)添加水模型
- Android开发入门学习笔记之三
- Windows 8 Directx 开发学习笔记(十)纹理贴图实现旋转的木箱
- Windows 8 Directx开发学习笔记(一)应用基本框架
- Windows 8 Directx 开发学习笔记(五)山峰河谷模型的简单实现
- Google.Android开发入门与实践-学习笔记1
- Google.Android开发入门与实践-学习笔记2
- Windows 8 Directx 开发学习笔记(八)要有光
- Windows 8 Directx 开发学习笔记(十一)地形纹理贴图
- Windows 8 Directx 开发学习笔记(四)示例程序小结
- spring学习笔记整理--02(搭建与测试Spring的开发环境)
- Adroid学习笔记-入门资料以及V2.3系统开发环境搭建
- DirectX终极开发指南学习笔记(一)
- Android 学习笔记 Android的王国\开发入门蓝图