第1章 初始化Direct3D

chapter 1

Posted by XDong on January 28, 2022

初始化Direct3D

学习目标

  • 了解Direct3D与图形硬件的交互方式
  • 理解COM在Direct3D中扮演的角色
  • 掌握基本的图形学概念,如2D图像的存储方式、页面置换和深度缓存
  • 掌握如何初始化Direct3D
  • 熟悉本书示例所采用的通用结构

1.1 Direct3D概述

1.1

Direct3D可以视为应用程序与图形设备交互的中介

HAL:硬件抽象层,使用HAL可以不必了解设备的具体细节

1.1.1 REF设备

Direct3D某些功能不被图形设备支持,可以使用参考光栅设备,即REF设备,它能以软件运算方式完全支持Direct3D API

1.1.2 D3DDEVTYPE

HAL设备由D3DDEVTYPE_HAL来指定

REF设备由D3DDEVTYPE_REF来指定

1.2 COM(组件对象模型)

可以视为C++的类来使用

1.3 预备知识

1.3.1 表面

虽然我们可以将表面存储的数据视为一个矩阵,但像素试举实际存储在一个线性数组中

1.2

pitch用字节来度量,所以pitch实际上可能比width要宽,这要依赖于底层的硬件实现

在代码中,我们用接口IDirect3DSurface9来描述表面。该接口提供了几种直接从表面读取和写入数据的方法,以及一种获取表面相关信息的方法。最重要的方法如下:

  • LockRect
  • UnlockRect
  • GetDesc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Assume _surface is a pointer to an IDirect3DSurface9 interface.
// Assumes a 32-bit pixel format for each pixel.
// Get the surface description.
D3DSURFACE_DESC surfaceDesc;
_surface->GetDesc(&surfaceDesc);
// Get a pointer to the surface pixel data.
D3DLOCKED_RECT lockedRect;
_surface->LockRect(
&lockedRect,// pointer to receive locked data
0, // lock entire surface
0); // no lock flags specified
// Iterate through each pixel in the surface and set it to red.
DWORD* imageData = (DWORD*)lockedRect.pBits;
for(int i = 0; i < surfaceDesc.Height; i++)
{
for(int j = 0; j < surfaceDesc.Width; j++)
{
// index into texture, note we use the pitch and divide by
// four since the pitch is given in bytes and there are
// 4 bytes per DWORD.
// pitch是以字节为单位的,而DWORD为4个字节
int index=i* lockedRect.Pitch / 4 + j;
imageData[index] = 0xffff0000; // red
}
}
_surface->UnlockRect();

1.3.2 多重采样

多重采样是一项用于平滑块状图像的技术

1.3

本书的实例都没有用到多重采样技术

1.3.3 像素格式

创建表面和纹理时,需要指定像素格式。像素格式可用D3DFORMAT枚举类型的枚举变量来定义。

1.3.4 内存池

表面和其他的Direct3D资源可以放入许多类型的内存池中。

1.3.5 交换链和页面置换

交换链和页面置换技术主要用于生成更加平滑的动画

1.4

1.5

1.3.6 深度缓存

深度缓存是一个只含有特定像素的深度信息而不含图像数据的表面

深度缓存用于计算每个像素的深度值并进行深度测试

1.3.7 顶点运算

顶点是3D几何学中的基本元素,在Direct3D中,可用两种不同的方式进行顶点运算,包括软件顶点运算和硬件顶点运算

1.3.8 设备性能

Direct3D所提供的每一项性能都对应于结构D3DCAP9中的一个数据成员或某一位

1.4 Direct3D的初始化

初始化Direct3D可分解为如下步骤:

  1. 获取接口IDirect3D9的指针
  2. 检查设备性能(D3DCAPS9),判断主显卡是否支持硬件顶点运算
  3. 初始化D3DPRESENT_PARAMETER结构的一个实例
  4. 利用已初始化的D3DPRESENT_PARAMETER结构创建IDirect3DDevice9对象

1.4.1 获取接口IDirect3D9的指针

1
2
IDirect3D9* _d3d9;
_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

IDirect3D9对象主要有两个用途:

  1. 设备枚举
  2. 创建IDirect3DDevice9类型的对象

1.4.2 校验硬件顶点运算

1
2
3
4
5
HRESULT IDirect3D9::GetDeviceCaps(
UINT Adapter,
D3DDEVTYPE DeviceType,
D3DCAPS9 *pCaps
);

1.4.3 填充D3DPRESENT_PARAMETER结构

1.4.4 创建IDirect3DDevice9接口

1.5 例程:Direct3D的初始化

1.6 小结

  • Direct3D can be thought of as a mediator between the programmer and the graphics hardware. The programmer calls a Direct3D function, which in turn, indirectly, has the physical hardware perform the operation by interfacing with the device’s HAL (Hardware Abstraction Layer).
  • The REF device allows developers to test features that Direct3D exposes but are not implemented by available hardware.
  • Component Object Model (COM) is the technology that allows DirectX to be language independent and have backward compatibility. Direct3D programmers don’t need to know the details of COM and how it works; they only need to know how to acquire COM interfaces and release them.
  • Surfaces are special Direct3D interfaces used to store 2D images. A member of the D3DFORMAT enumerated type specifies the pixel format of a surface. Surfaces and other Direct3D resources can be stored in several different memory pools as is specified by a member of the D3DPOOL enumerated type. In addition, surfaces can be multisampled, which creates a smoother image.
  • The IDirect3D9 interface is used to find out information about the system’s graphics devices. For example, through this interface we can obtain the capabilities of a device. It is also used to create the IDirect3DDevice9 interface.
  • The IDirect3DDevice9 interface can be thought of as our software interface for controlling the graphics device. For instance, calling the IDirect3DDevice9::Clear method will indirectly have the graphics device clear the specified surfaces. Direct3D Initialization 57 Part II
  • The sample framework is used to provide a consistent interface that all sample applications in this book follow. The utility code provided in the d3dUtility.h/cpp files wrap initialization code that every application must implement. By wrapping this code up, we hide it, which allows the samples to be more focused on demonstrating the current topic.

总结

这一章的内容还是比较简单的,重点在于Direct3D的初始化WinMain函数的编写

Direct3D的初始化

chapter-1-0

项目代码