1.顶点缓存和索引缓存

一个顶点缓存是一个包含顶点数据的连续内存空间;一个索引缓存是一个包含索引数据的连续内存空间。

顶点缓存用接口IDirect3DVertexBuffer9表示;索引缓存用接口IDirect3DIndexBuffer9表示。

1.1创建顶点缓存和索引缓存

HRESULT IDirect3DDevice9::CreateVertexBuffer(
  UINT Length,  //为缓存分配的字节数
  DWORD Usage, //指定如何使用缓存的附加属性,0表明无需附加属性
  DWORD FVF,   //存储在顶点缓存中的灵活顶点格式
  D3DPOOL Pool,  //容纳缓存的内存池
  IDirect3DVertexBuffer9** ppVertexBuffer,  //顶点缓存的指针
  HANDLE* pSharedHandle   //不使用,为0。
);
HRESULT IDirect3DDevice9::CreateIndexBuffer(
  UINT Length,  //为缓存分配的字节数
  DWORD Usage,  //指定如何使用缓存的附加属性,0表明无需附加属性
  D3DFORMAT Format, //索引的大小.D3DFMT_INDEX16(16位索引),D3DFMT_INDEX32 (32位索引)
  D3DPOOL Pool,  //容纳缓存的内存池
  IDirect3DIndexBuffer9** ppIndexBuffer,  //索引缓存的指针
  HANDLE* pSharedHandle   //不使用,为0。
);
下面例子,创建一个容纳8个Vertex类型顶点的静态顶点缓存:
IDirect3DVertexBuffer9* vb;
Device-> CreateVertexBuffer(8*sizeof(Vertex),
0,
D3DFVF_XYZ,
D3DPOOL_MANAGED,
&vb,
0);
下面是创建动态缓存的例子,可容纳36个16位索引:
IDirect3DIndexBuffer9* ib;
Device-> CreateIndexBuffer(36*sizeof(WORD),
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
& ib,
0);
1.2访问缓存内容
借助方法Lock来获取指向缓存内容的指针。对缓存访问完毕后,要进行Unlock。
HRESULT IDirect3DVertexBuffer9::Lock(
  UINT OffsetToLock,
  UINT SizeToLock,
  VOID ** ppbData,
  DWORD Flags
);
HRESULT IDirect3DIndexBuffer9::Lock (
  UINT OffsetToLock, //自缓存的起始点到开始锁定位置的偏移量,单位为字节。
  UINT SizeToLock,  //所要锁定的字节数
  VOID ** ppbData,  //指向被锁定的存储区,起始位置的指针
  DWORD Flags  //锁定的方式,可以为0.
);
注:Flags,可以是0,也可以是下列选项之一或组合。
D3DLOCK_DISCARD 仅用于动态缓存。它指示硬件将缓存丢弃,并返回一个新的缓存指针。
D3DLOCK_NOOVERWRITE仅用于动态缓存。数据以追加方式写入缓存。
D3DLOCK_NO_DIRTY_UPDATE 
D3DLOCK_NOSYSLOCK 
D3DLOCK_READONLY  对锁定的缓存只读,不能写
D3DLOCK_DONOTWAIT
下面例子说明了Lock的一般使用方式:
Vertex * v;
vb->Lock(0,0,(void **)&v,0);
v[0]=Vertex(-1.0f,0.0f,2.0f);
v[1]=Vertex(0.0f,1.0f,2.0f);
v[2]=Vertex(1.0f,0.0f,2.0f);
vb->Unlock();
1.3获取顶点缓存和索引缓存的信息
D3DVERTEXBUFFER_DESC vbDescription;
vb->GetDesc(&vbDescription);
D3DINDEXBUFFER_DESC ibDescription;
Ib->GetDesc(&ibDescription);
2.绘制状态
Direct3D封装了多种绘制状态,这些绘制状态影响了几何体的绘制方式。如果要更改默认值,用方法:
HRESULT  IDirect3DDevice9::SetRenderState
{
D3DRENDERSTATETYPE State,
 DWORD Value
}
3.绘制的准备工作
一旦我们创建了顶点缓存和索引缓存(可选),我们基本上可以对其存储内容进行绘制。在绘制前有3个步骤需完成:
3.1指定数据流输入源.实质是将几何体的信息传输的绘制流水线中。
HRESULT IDirect3DDevice9::SetStreamSource(
  UINT StreamNumber, //标示与顶点缓存建立连接的数据流
  IDirect3DVertexBuffer9 * pStreamData, //顶点缓存的指针
  UINT OffsetInBytes, //指定了将被传输至绘制流水线的顶点数据的起始位置
  UINT Stride  //顶点缓存中每个元素的大小
);
Device->SetStreamSource(0,vb,0,sizeof(Vertex));
3.2设置顶点格式
Device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE);
3.3设置索引缓存
Device->SetIndices(ib);
4.使用顶点缓存和索引缓存进行绘制
HRESULT IDirect3DDevice9::DrawPrimitive
(D3DPRIMITIVETYPE PrimitiveType,  //所要绘制的图元类型,
  UINT StartVertex,   //读取起点元素的索引
  UINT PrimitiveCount //图元数量
)
HRESULT IDirect3DDevice9::DrawIndexedPrimitive(
  D3DPRIMITIVETYPE Type,
  INT BaseVertexIndex,
  UINT MinIndex, //允许引用的最小索引值
  UINT NumVertices,//将引用的顶点总数
  UINT StartIndex, //
  UINT PrimitiveCount
);
以上的绘制函数必须位于BeginScene() 和EndScene()函数对之间。
#include "d3dUtility.h"

IDirect3DDevice9* Device = ; 

const int Width  = ;
const int Height = ; IDirect3DVertexBuffer9* Triangle = ; struct Vertex
{
Vertex(){} Vertex(float x, float y, float z)
{
_x = x; _y = y; _z = z;
} float _x, _y, _z; static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZ; //
// Framework Functions
//
bool Setup()
{
Device->CreateVertexBuffer(
* sizeof(Vertex), // size in bytes
D3DUSAGE_WRITEONLY, // flags
Vertex::FVF, // vertex format
D3DPOOL_MANAGED, // managed memory pool
&Triangle, // return create vertex buffer
); // not used - set to 0 //
// Fill the buffers with the triangle data.
// Vertex* vertices;
Triangle->Lock(, , (void**)&vertices, ); vertices[] = Vertex(-1.0f, 0.0f, 2.0f);
vertices[] = Vertex( 0.0f, 1.0f, 2.0f);
vertices[] = Vertex( 1.0f, 0.0f, 2.0f); Triangle->Unlock(); //
// Set the projection matrix.
// D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj, // result
D3DX_PI * 0.5f, // 90 - degrees
(float)Width / (float)Height, // aspect ratio
1.0f, // near plane
1000.0f); // far plane
Device->SetTransform(D3DTS_PROJECTION, &proj); //
// Set wireframe mode render state.
// Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); return true;
}
void Cleanup()
{
d3d::Release<IDirect3DVertexBuffer9*>(Triangle);
} bool Display(float timeDelta)
{
if( Device )
{
Device->Clear(, , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, );
Device->BeginScene(); Device->SetStreamSource(, Triangle, , sizeof(Vertex));
Device->SetFVF(Vertex::FVF); // Draw one triangle.
Device->DrawPrimitive(D3DPT_TRIANGLELIST, , ); Device->EndScene();
Device->Present(, , , );
}
return true;
} //
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
::PostQuitMessage();
break; case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
} //
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
Width, Height, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(, "InitD3D() - FAILED", , );
return ;
} if(!Setup())
{
::MessageBox(, "Setup() - FAILED", , );
return ;
} d3d::EnterMsgLoop( Display ); Cleanup(); Device->Release(); return ;
}

main.cpp

Direct3D中的绘制的更多相关文章

  1. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)

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

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

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

  3. 【转载】OLE控件在Direct3D中的渲染方法

    原文:OLE控件在Direct3D中的渲染方法 Windows上的图形绘制是基于GDI的, 而Direct3D并不是, 所以, 要在3D窗口中显示一些Windows中的控件会有很多问题 那么, 有什么 ...

  4. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记5——Direct3D中的顶点缓存和索引缓存

    第12章 Direct3D绘制基础 1. 顶点缓存 计算机所描绘的3D图形是通过多边形网格来构成的,网网格勾勒出轮廓,然后在网格轮廓的表面上贴上相应的图片,这样就构成了一个3D模型.三角形网格是构建物 ...

  5. Android中View绘制流程以及invalidate()等相关方法分析

    [原文]http://blog.csdn.net/qinjuning 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简 ...

  6. Android中View绘制优化之三---- 优化View

    本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning 译三: 优化视图 关于如何设计自定义View以及响应触摸时间等,请看Android developer : 地 ...

  7. OpengGL中图形绘制先后问题

    OpengGL中图形绘制先后问题 在opengl中,场景绘制总有个先后的顺序,也有个程序先后的问题,图形程序在前在后,对最终的图形的影响如何? (1)设置图中的点(蓝色)与线条(浅蓝)z分量都是0,如 ...

  8. QtCharts模块在QtWideget中图表绘制(非QML)

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QtCharts模块在QtWideget中图表绘制(非QML)     本文地址:http:/ ...

  9. JBPM4入门——2.在eclipse中安装绘制jbpm流程图的插件

    本博文只是简要对JBPM4进行介绍,如需更详细内容请自行google 链接: JBPM入门系列文章: JBPM4入门——1.jbpm简要介绍 JBPM4入门——2.在eclipse中安装绘制jbpm流 ...

随机推荐

  1. jenkins与rebotframework搭配

    一.下载Jenkins 下载地址:http://mirrors.jenkins-ci.org/ 贫道比较推荐下载war包的,进入上面的地址,页面里有war的链接,各种类型各种版本的release,大家 ...

  2. c# office转换成pdf

    下载地址 [url]http://www.microsoft.com/downloads/details.aspx?FamilyId=4D951911-3E7E-4AE6-B059-A2E79ED87 ...

  3. MFC下对串口的操作以及定时器的调用

    最近研究了一下MFC下对串口的操作,测试了一下对设备的读写. 1.打开串口 GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(FALSE); m_hComm = ...

  4. android--屏幕旋转方法总结

    在介绍之前,我们需要先了解默认情况下android屏幕旋转的机制: 默认情况下,当用户手机的重力感应器打开后,旋转屏幕方向,会导致当前activity发生onDestroy-> onCreate ...

  5. 笨方法学python--第一个程序

    该章主要知识点有: 1 print 打印,有双引号,单引号 2 分析报错信息,积累经验 3 # -*- coding:utf-8 -*-,可以输出汉字 4 井号,# ,注释, 英文名 octothor ...

  6. 从今日起,我会把OpenGL红宝书上的例子用完整的代码形式写在我的博客中,

    1.使用教程:OpenGL红宝书第8版 2.使用的库工具:GLEW和GLFW 3.使用的IDE:vs2012 4.说说目的:完整的看一遍OpenGL,加深印象并且熟练掌握运用OpenGL 5.欢迎有相 ...

  7. swool安装

    swoole安装 安装完PHP后,即可安装swoole扩展. swoole扩展下载地址:https://github.com/swoole/swoole-src/releases 尽量选择stable ...

  8. springmvc+mybatis下载项目自带模板

    1.首先如果要获取javaweb项目中的文件在哪,用到的代码:request.getSession().getServletContext().getRealPath("/WEB-INF/d ...

  9. OpenGL-------状态机

    状态机就是一种存在于理论中的机器,它具有以下的特点: 1. 它有记忆的能力,能够记住自己当前的状态. 2. 它可以接收输入,根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出. 3. 当它进 ...

  10. zzuli 1919 数列划分

    题面: Description 晴天想把一个包含n个整数的序列a分成连续的若干段,且和最大的一段的值最小,但他有强迫症,分的段数不能超过m段,然后他就不会分了...他想问你这个分出来的和最大的一段的和 ...