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. 第十四节,基本数据类型,列表list

    创建列表  #!/usr/bin/env python # -*- coding:utf-8 -*- a = ['alex', 'seven', 'eric'] #或 a = list(['alex' ...

  2. assert()函数用法

    assert是定义在头文件cassert中的宏 其作用是如果他的返回值不为真则终止程序. assert(expression); if 为假,先向stderr打印一条错误信息,再用abort终止程序 ...

  3. servlet第3讲(上集)----同一用户的不同页面共享数据

    1.方法综述 2.Cookie 3.sendRedict()方法     4.隐藏表单

  4. HAProxy与varnish

    Even if HAProxy can do TCP proxying, it is often used in front of web application, exactly where we ...

  5. Nginx配置IP白名单和黑名单

    白名单设置,访问根目录 location / { allow 123.34.22.155; allow ; deny all; } 黑名单设置,访问根目录 location / { deny 123. ...

  6. C++设计模式-Visitor访问者模式

    #include <iostream> #include <string> #include <string.h> #include <memory> ...

  7. PHP开发之路之一--WAMP的安装和配置

    来到新公司,领导说后面一个web系统不用ASP.NET做了,用国外的一个Drupal进行二次开发.这个Drupal是基于PHP的一款开源CMS系统,那就必须要自学PHP咯~ 接下来说说正题吧: 一.安 ...

  8. Bill Total Value

    Bill Total Value time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  9. HTML之组件margin、padding

    1.  HTML之组件可以通过CSS里的width height进行大小控制 2.HTML之组件可以通过CSS里的margin.padding进行组件和组件间的间距 margin/padding:(u ...

  10. Number Sequence HDU 1711 KMP 模板

    题目大意:两个数组匹配,求子串首次出现的位置. 题目思路:数组长度,比较大,朴素算法的时间复杂度为 m*n超时.KMP的时间复杂度为m+n可行. #include<iostream> #i ...