博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Direct3D 初涉: 颜色
阅读量:6612 次
发布时间:2019-06-24

本文共 4609 字,大约阅读时间需要 15 分钟。

1. 颜色表示

在 Direct3D 中。颜色用 RGB 三元组表示。RGB 数据可用两种不同的结构来保存。第一种是 D3DCOLOR ,它实际上与 DWORD 类型完全相同(由 typedef 定义),共有 32 位。 D3DCOLOR 类型中各位被分成 位项(section),每项存储了一种颜色分量的亮度值(Alpha,,R,G,B)。每项均占一个字节,所以每个分量的亮度值范围都在[0,255]区间内,接近 值表示最小值,接近 255 的值表示高度值。

 

Direct3D 提供了宏  帮助我们完成将颜色分量值,安插到 D3DCOLOR 类型的合适位置上。也可以使用 D3DCOLOR_XRGB 宏来代替 D3DCOLOR_ARGB,两者很相似, 不接受 Alpha 参数(将 Alpha 分量设为 0xff(255) )

 

在 Direct3D 中,存储颜色的数据的另一种结构是 。在该结构中,我们使用单精度浮点数来度量每个颜色分量的亮度值。亮度范围为(0~1)

 

我们可以利用  代替 D3DCOLORVALUE,前者不但包含了与后者相同的数据成员,而且还提供了一组有用的构造函数和重载运算符,为颜色的运算提供了便利。

 

2. 顶点颜色

图元的颜色由构成该图元的顶点的颜色所决定。所以,我们必须为顶点数据结构添加一个表示颜色的数据成员。

 

3. 着色

在光栅化过程中,需要对多边形进行着色(shading)。着色规定了如何利用顶点的颜色来计算构成图元的像素的颜色。目前,我们使用两种着色模式(shading mode)

(1) 平面着色 (flat shading)。每个图元的每个像素都被一致地赋予该图元的第一个顶点所指定的颜色。即使用平面着色时,如果第一个顶点是红色的,那么其他顶点的颜色值将被忽略。平面着色容易使物体呈现出块状,这是因为各颜色之间没有平滑地过度。

(2) Gouraud 着色 (Gouraud Shading)。图元中个像素的颜色值由各顶点的颜色线性插值得到。各个颜色之间的平滑的过度,因此Gouraud 着色也称平滑着色(smooth shading)

 

4. 例程(DrawColorTriangle)

在  的框架上添加代码。

(1) 新建头文件 GlobalColorConstant.h ,添加一些颜色全局常量:

#ifndef __GLOBALCOLOR_CONSTANT_H__ #define __GLOBALCOLOR_CONSTANT_H__ const D3DXCOLOR   WHITE  ( D3DCOLOR_XRGB(255, 255, 255) ); const D3DXCOLOR   BLACK  ( D3DCOLOR_XRGB(  0,   0,   0) ); const D3DXCOLOR   RED    ( D3DCOLOR_XRGB(255,   0,   0) ); const D3DXCOLOR   GREEN  ( D3DCOLOR_XRGB(  0, 255,   0) ); const D3DXCOLOR   BLUE   ( D3DCOLOR_XRGB(  0,   0, 255) ); const D3DXCOLOR   YELLW  ( D3DCOLOR_XRGB(255, 255,   0) ); const D3DXCOLOR   CYAN   ( D3DCOLOR_XRGB(  0, 255, 255) ); const D3DXCOLOR   MAGENTA( D3DCOLOR_XRGB(255,   0, 255) ); #endif /* __GLOBALCOLOR_CONSTANT_H__ */

 

(2) 新建头文件 ColorVertex.h 添加有色顶点的结构体定义:

#ifndef __COLORVERTEX_H__ #define __COLORVERTEX_H__ struct ColorVertex {
public: ColorVertex(float x, float y, float z, D3DCOLOR color) {
m_x = x; m_y = y; m_z = z; m_color = color; } public: static const DWORD FVF; private: float m_x; float m_y; float m_z; D3DCOLOR m_color; }; const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; #endif /* __COLORVERTEX_H__ */

 

(3)在 Direct3DFrame 类中添加代码:

D3DXMATRIX              m_worldMatrix;   // 存储所要绘制三角形的世界变换矩阵     IDirect3DVertexBuffer9* m_triangle;      // 保存三角形数据的定点缓存

(4) Setup 方法创建了一个顶点缓存,并用所要绘制的三角形中带有颜色信息的顶点对该缓存进行填充。该三角形第 个顶点的颜色为红色,第 个顶点的颜色为绿色,第 个顶点为蓝色。在本例的最后,将光照禁用。

 

bool Direct3DFrame::Setup() {
// Create the vertex buffer. m_device->CreateVertexBuffer( 3*sizeof(ColorVertex), D3DUSAGE_WRITEONLY, ColorVertex::FVF, D3DPOOL_MANAGED, &m_triangle, 0); // Fill the buffer with the triangle data. ColorVertex* v; m_triangle->Lock(0, 0, (void**)&v, 0); v[0] = ColorVertex(-1.0f, 0.0f, 2.0f, RED); v[1] = ColorVertex( 0.0f, 1.0f, 2.0f, GREEN); v[2] = ColorVertex( 1.0f, 0.0f, 2.0f, BLUE); m_triangle->Unlock(); // Set the projection matrix. D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI * 0.5f, (float)m_width / (float)m_height, 1.0f, 1000.0f); m_device->SetTransform(D3DTS_PROJECTION, &proj); // Turn off lighting. m_device->SetRenderState(D3DRS_LIGHTING, false); return true; }

(5) Display 函数在两个不同的位置以两种不同的着色模式分别绘制 Triangle。每个三角形位置由世界变换矩阵 World 来控制。

 

bool Direct3DFrame::Display(float timeDelta) {
if (m_device) { m_device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); m_device->BeginScene(); m_device->SetFVF(ColorVertex::FVF); m_device->SetStreamSource(0, m_triangle, 0, sizeof(ColorVertex)); // draw the triangle to the left with flat shading D3DXMatrixTranslation(&m_worldMatrix, -1.25f, 0.0f, 0.0f); m_device->SetTransform(D3DTS_WORLD, &m_worldMatrix); m_device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); // draw the triangle to the right with gouraud shading D3DXMatrixTranslation(&m_worldMatrix, 1.25f, 0.0f, 0.0f); m_device->SetTransform(D3DTS_WORLD, &m_worldMatrix); m_device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); m_device->EndScene(); m_device->Present(0, 0, 0, 0); } return true; }

 

(6) 在 Cleanup 中释放资源

void Direct3DFrame::Cleanup() {
m_device->Release(); m_triangle->Release(); }

运行后截图:

 

/*******************************************************/ 

** 本文由  原创,转载请注明博客链接,谢谢!

** 小弟初学 Direct3D,文章中如果存在错误,烦请指证,不胜感激!

** 参考书籍:《DirectX 9.0 3D 游戏开发编程基础》 

** 时间:2011.11.21

/*******************************************************/

 

 

转载于:https://www.cnblogs.com/chinazhangjie/archive/2011/11/21/2257705.html

你可能感兴趣的文章
Shell脚本 常用命令总结 二
查看>>
JS模拟select下拉菜单
查看>>
vmware workstation14永久激活密钥分享
查看>>
iOS 多线程 之 GCD(大中枢派发)(一)
查看>>
Myeclipse中打开接口实现类的快捷键
查看>>
删除sql dump中的AUTO_INCREMENT
查看>>
使用JdbcTemplate和JdbcDaoSupport
查看>>
C博客作业--指针
查看>>
版本12.2.0.1.0数据库,复制种子数据库快速创建租户数据库PDB
查看>>
Glibc 和 uClibc
查看>>
vs2012中自带IIS如何让其他电脑访问
查看>>
Redux:异步操作
查看>>
Mysql学习第三课-分析二进制日志进行增量备份和还原
查看>>
POJ1961 Period [KMP应用]
查看>>
如何在 Android 手机上安装 Ubuntu 13.04
查看>>
HDU 6073 - Matching In Multiplication | 2017 Multi-University Training Contest 4
查看>>
C语言 scanf()和gets()函数的区别
查看>>
如何检测域名是否被微信屏蔽 微信域名检测接口API是如何实现
查看>>
POJ1611-The Suspects
查看>>
Linux下安装Python-3.3.2【转】
查看>>