DirectX SDK 2006学习笔记2——顶点缓冲

Copyright © MikeFeng  QQ: 76848502

  D3D9以一种比较易于理解的方式让程序员来组织游戏画面,这种方式就是顶点缓冲。程序员可以自己定义一组记录多边形定点颜色,纹理位置等的数组,让D3D9去自动生成多边形内部每个像素的信息。为了和以后的vertex shader相区别,我们现在谈论的都是固定功能的顶点处理( Fixed-Function )。
  上面一段话似乎有点晦涩,让我们首先来看看这些术语的定义吧:
  • 顶点缓冲Vertex Buffer:由用户定义的,包含顶点信息的数组。

  首先我们来学习一下Vertex Buffer的技术。我喜欢先看代码再讲理论,否则看了理论也找不到北。

  下面就是一个自定义的顶点缓冲的结构
struct CUSTOMVERTEX
{
    FLOAT x, y, z, rhw; // The transformed position for the vertex
    DWORD color;         // The vertex color
};
  其中,x, y, z是顶点在3维空间的最终位置,rhw是3维矩阵的倒数(不明白的话找本图形学的书研究一下),color自然就是顶点的颜色了。由于这个结构是自定义的,所以我们需要告诉D3D应该如何识别这个结构,这就需要我们定义一个常量了:
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZRHW |D3DFVF_DIFFUSE)
  这个D3DFVF_CUSTOMVERTEX就是用来告诉D3D上面那个CUSTOMVERTEX结构是如何组织的:首先是D3DFVF_XYZRHW,即顶点在3维坐标系的最终位置,D3DFVF_DIFFUSE是色彩模式,告诉D3D紧接着D3DFVF_XYZRHW信息的是顶点的色彩信息,并且这种色彩信息是漫反射模式的。类似的标志可以学习DirectX SDK文档(搜索D3DFVF),这里就不再赘述。
  上面所提到的顶点缓冲定义方式就是为大家熟知Flexible Vertex Format,简称FVF,是不是有点眼熟呢。
  下面是Direct3D游戏编程入门一书中对复杂的FVF举的一个例子,供参考
typedef struct SObjVertex
{
    FLOAT x, y, z;                   // position
    FLOAT nx, ny, nz;             // normal
    DWORD diffuse;               // diffuse color
    DWORD specular;            // specular color
    FLOAT tu, tv;                    // first pair of texture coordinates
    FLOAT tu2, tv2, tw2;        // second pair of texture coordinates
    FLOAT tu3, tv3;                // third pair of texture coordinates
    FLOAT tu4, tv4;                // fourth pair of texture coordinates
} SObjVertex;
 
const DWORD gSObjVertexFVF = ( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_NORMAL | D3DFVF_TEX4 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE3(1) |   D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE2(3) );
 
  看完了FVF顶点格式的定义,就可以看它是如何使用的。使用方法非常简单,在OnCreateDevice中添加创建和初始化代码,在OnFrameRender中添加渲染代码就可以了,具体如下:
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, constD3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
              …
// Initialize three vertices for rendering a triangle
       CUSTOMVERTEX vertices[] =
       {
// x, y, z, rhw, color
              { 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, },
              { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
              { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
       };    
if( FAILED( pd3dDevice->CreateVertexBuffer(
3* sizeof(CUSTOMVERTEX),
              0, D3DFVF_CUSTOMVERTEX,
              D3DPOOL_MANAGED, & g_pVB, NULL ) ) )
       {
              return E_FAIL;
       }
       // Now we fill the vertex buffer. To do this, we need to Lock()
// the VB to gain access to the vertices. This mechanism is
// required becuase vertex buffers may be in device memory.
       VOID* pVertices;
       if( FAILED( g_pVB->Lock( 0, sizeof(vertices),
( void**)&pVertices, 0 ) ) )
              return E_FAIL;
       memcpy( pVertices, vertices, sizeof(vertices) );
       g_pVB-> Unlock();
}
  为了统一和强调精度,D3D采用了float作为其主要的数值类型。上面的程序调用了CreateVertexBuffer和LPDIRECT3DVERTEXBUFFER9-> Lock和 Unlock函数。另外需要在OnFrameRender中的BeginScene和EndScene中调用如下代码
pd3dDevice-> SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
pd3dDevice-> SetFVF( D3DFVF_CUSTOMVERTEX );
pd3dDevice-> DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
  其中 SetStreamSource 函数第一个参数 StreamNumber 用来设定使用哪条数据流,这个数据流的最大值根据显卡硬件的不同而不同,现在好的显卡可以支持 8 条或者 16 条数据流。 SetFVF 函数用来把我们自定义的顶点缓冲布局常量传递给 D3D DrawPrimitive 函数用来告诉 D3D 以那种图元绘制这个图形。其中图元这个概念很重要,它是 D3D 世界中最基本的单位,分为点列表,线列表,线带,三角形列表,三角形带,三角扇形六中,在 D3D 中的具体定义如下:
       typedef enum _D3DPRIMITIVETYPE
       {
              D3DPT_POINTLIST = 1,
              D3DPT_LINELIST = 2,
              D3DPT_LINESTRIP = 3,
              D3DPT_TRIANGLELIST = 4,
              D3DPT_TRIANGLESTRIP = 5,
              D3DPT_TRIANGLEFAN = 6,
              D3DPT_FORCE_DWORD = 0x7fffffff,
} D3DPRIMITIVETYPE;
  其中点列表,线列表,三角形列表很好理解,它们就是独立的点/线/三角形的集合,每个顶点缓冲中的点分别表示一个点/独立线条中的一个端点/独立三角形中的一个顶点。而线带,三角形带每个顶点缓冲中的点表示连续的线条的端点/连续三角形中的顶点。三角扇形顶点缓冲中的点表示三角扇形中的每个顶点,如图:
 
                三角形列表                                              三角形带 
 
         三角扇形                                               线列表
 
                      点列表                                                        线带
 
  在特殊情况下三角形带和三角扇形都可以组成四边形。只要将 DrawPrimitive 中的参数变换一下,适当改变顶点缓冲就可以得到 D3D 中以不同图元画出的图形。下图是三角形列表形式画出的一个三角形。
  不要忘了更改 CreateVertexBuffer 中的第一个表示顶点缓冲大小的参数,否则添加的顶点会被忽略的。最后在 OnDestroyDevice 中调用 SAFE_RELEASE( g_pVB ) 来释放资源。
 
本文详细介绍了如何利用Python语言结合MySQL数据库开发个学生管理系统。通过这过程,读者不仅能够掌握系统设计的基本思路,还能学习到如何使用Python进行数据库操作。该系统涵盖了用户界面设计、数据验证以及数据库的增删改查等多个关键环节。 Python作为种高级编程语言,以简洁易懂著称,广泛应用于数据分析、机器学习和网络爬虫等领域,同时也非常适合用于快速开发数据库管理应用。MySQL是个广泛使用的开源关系型数据库管理系统,具有轻量级、高性能、高可靠性和良好的编程语言兼容性等特点,是数据存储的理想选择。在本系统中,通过Python的pymysql库实现了与MySQL数据库的交互。 pymysql是个Python第三方库,它允许程序通过类似DB-API接口连接MySQL数据库,执行SQL语句并获取结果。在系统中,通过pymysql建立数据库连接,执行SQL语句完成数据的增删改查操作,并对结果进行处理。 系统采用命令行界面供用户操作。程序开始时,提示用户输入学生信息,如学号、姓名和各科成绩,并设计了输入验证逻辑,确保数据符合预期格式,例如学号为1至3位整数,成绩为0至100分的整数。 数据库设计方面,系统使用名为“test”的数据库和“StuSys”表,表中存储学生的学号、姓名、各科成绩及总成绩等信息。通过pymysql的cursor对象执行SQL语句,实现数据的增删改查操作。在构建SQL语句时,采用参数化查询以降低SQL注入风险。 系统在接收用户输入时进行了严格验证,包括正则表达式匹配和数字范围检查等,确保数据的准确性和安全性。同时,提供了错误处理机制,如输入不符合要求时提示用户重新输入,数据库操作出错时给出相应提示。 在数据库操作流程中,用户可以通过命令行添加学生信息或删除记录。添加时会检查学号是否重复以避免数据冲突,删除时需用户确认。通过上述分析,本文展示了从
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值