初学Direct X (2)


这一次要学习如何现实位图,尽管看过对双缓冲机制还有很多疑问,但是这并不阻碍我对他的入门了解

Direct3D提供了一个双重/后台缓冲区,在调用CreateDevice之时就有了。其运行机制就是,我们需要在其中一个缓冲区上绘制完所需要显示的一切,之后将这个缓冲区快速的复制到另一个缓冲区,因为后者的缓冲区被称为Front Buffer,显示器在刷新之时会直接从中取出数据以显示,而前者就称之为backbuffer

但是,还有一种buffer,是可供我们在内存中进行操作的,被称之为surface,也有离屏表面的称呼,后面的表面都指的是离屏表面

1. 使用表面的实例

初始化变量:

LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DSURFACE9 backbuffer = NULL;
// 指向内存中的表面
LPDIRECT3DSURFACE9 surface = NULL;

1.1 Game_Init()

bool Game_Init(HWND hwnd)
{
//initialize Direct3D
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (d3d == NULL)
{
MessageBox(hwnd, "Error initializing Direct3D", "Error", MB_OK);
return false;
} //set Direct3D presentation parameters
D3DPRESENT_PARAMETERS d3dpp; d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&dm); ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = dm.Width;
d3dpp.BackBufferHeight = dm.Height;
d3dpp.hDeviceWindow = hwnd; //create Direct3D device
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &d3ddev); if (!d3ddev)
{
MessageBox(hwnd, "Error creating Direct3D device", "Error", MB_OK);
return false;
} //set random number seed
// 用于Game_Run()
srand((unsigned int)time(NULL)); //clear the backbuffer to black
//注意这里并没有获取到backbuffer指针,就可以直接Clear backbuffer
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); //create pointer to the back buffer
//通常这是指向真实后台缓冲区的指针
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); //create surface
HRESULT result = d3ddev->CreateOffscreenPlainSurface(
100, //width of the surface
100, //height of the surface
D3DFMT_X8R8G8B8, //surface format
D3DPOOL_DEFAULT, //memory pool to use
&surface, //pointer to the surface
NULL); //reserved (always NULL) if (result != D3D_OK) return false; return true;
}

这样一来,就获取了backbuffer的位置,并且创造了一个离屏表面,可供我们进行绘图操作

1.2 Game_Run()

void Game_Run(HWND hwnd)
{
//make sure the Direct3D device is valid
if (!d3ddev) return; //start rendering
if (d3ddev->BeginScene())
{
//将离屏表面填色
int r = rand() % 255;
int g = rand() % 255;
int b = rand() % 255;
d3ddev->ColorFill(surface, NULL, D3DCOLOR_XRGB(r, g, b)); //把离屏表面复制到backbuffer
RECT rect;
rect.left = rand() % dm.Width;
rect.right = rect.left + rand() % (dm.Width - rect.left);
rect.top = rand() % dm.Height;
rect.bottom = rect.top + rand() % (dm.Height - rect.top);
d3ddev->StretchRect(surface, NULL, backbuffer, &rect, D3DTEXF_NONE); //stop rendering
d3ddev->EndScene(); //将backbuffer的数据显示到屏幕上
d3ddev->Present(NULL, NULL, NULL, NULL);
} //check for escape key (to exit program)
if (KEY_DOWN(VK_ESCAPE))
PostMessage(hwnd, WM_DESTROY, 0, 0);
}

1.3写到这里的时候我发现几个问题

1) 似乎无法操作front buffer?

这正是双缓冲的机制,因为直接操作front buffer会导致一些问题,想象一下,若屏幕的刷新频率很快,而此时你正在生成一个计算量巨大的数据,正在你计算之时,显示器已经来尝试取n次数据了,而这n次取出的图像都是一部分且不连贯的。故而出现了双缓冲技术,在backbuffer绘制好之后再将其显示在屏幕上

2)backbuffer和frontbuffer的是怎么运转的,好像只要调用Present就可以将backbuffer的显示在屏幕上了

2. 加载位图

需要使用d3dx,它是Direct3D Extensions 即Direct3D的扩展,需要进行如下的引用:

#include <d3dx9.h>
#pragma comment(lib,"d3dx9.lib")

有趣的就是D3DXLoadSurfaceFromFile函数了,他可以装载.bmp , .jpng, .png等一系列的位图,调用示例如下:

result = D3DXLoadSurfaceFromFile(
surface,
NULL,
NULL,
"show.png",
NULL,
D3DX_DEFAULT,
0,
NULL
);

3. 绘制表面

StretchRect函数可以将某个表面的一部分或全部位块传输到另一个表面

HRESULT StretchRect(
IDirect3DSurface9* pSourceSurface,
CONST RECT* pSourceRect,
IDirect3DSurface9* pDestSurface,
CONST RECT* pDestRect,
D3DTEXTUREFILTERTYPE Filter)

这里值得一提的是,若rect超出了pDestSurface的显示范围,函数还是可以正常运行的,下面是调用示例:

	d3ddev->StretchRect(surface, NULL, backbuffer, &rect, D3DTEXF_NONE);

初学Direct X (2)的更多相关文章

  1. 初学Direct X(7) ——位图的旋转,缩放以及平移

    初学Direct X(7) --位图的旋转,缩放以及平移 本文旨在实现通过D3DXMatrixTransformation2D函数实现位图的旋转,缩放以及平移操作,但是具体的原理部分会在后面进一步的探 ...

  2. 初学Direct X(10)—— D3D基础预备知识

    初学Direct X(10) -- D3D基础预备知识 1. 像素格式 D3DFMT_X8R8G8B8(F) X:未加使用 8:8位用于显示 B:用于显示蓝色 F:浮点像素类型 以下三个较为常用,使用 ...

  3. 初学Direct X(9) ——文字的显示

    初学Direct X(9) --文字的显示 本次学习如何使用ID3DXFont创建字体,使得我们可以在任何安装了Windows系统中TrueType字体来打印文字,不过最好使用标准字体,这样文字在每一 ...

  4. 初学Direct X(8) ——碰撞检测

    初学Direct X(8) --碰撞检测 真正让一个游戏鹤立鸡群的是程序对碰撞的响应有多好,这里介绍两种检测的方法: 1) 基于边框的碰撞检测 2) 基于距离的碰撞检测 1. 基于边框的碰撞检测 1. ...

  5. 初学Direct X(6)

    初学Direct X(6) 这一文本应和上一篇放在一起的,但是上一章写着写着发现对Draw绘制透明位图的方式有感觉了,决定就单写一篇,留作笔记了. 那这一篇是记录如何使用位图表来绘制动画帧,想象一下, ...

  6. 初学Direct X(5)

    初学Direct X(5) 前面学习了使用表面绘制屏幕,但这种方法与另一种比较起来,有着绘图速度颇慢以及缺乏对任何透明类型的支持,这就是前面的篮框以及炸弹会有黑色背景的原因,这种方法就是纹理.他可以绘 ...

  7. 初学Direct X(4)

    初学Direct X(4) 本文学着做出一个如下的小游戏 游戏方式是使用键盘控制红色的Bucket收集蓝色的炸弹 1.酝酿一下 现在我已经掌握: 将位图文件加载到内存 绘制位图到buckbuffer ...

  8. 初学Direct X(3)

    初学Direct X(3) 1.获取外设输入--键盘以及鼠标 无论是获取鼠标还是键盘的设备,首先得初始化DirectInput,不过先把必要的环境先配置好: 所要用到的头文件以及库文件是(相比于前两次 ...

  9. 初学DirectX(1)

    初学Direct X (1) Direct3D设备用于访问视频卡的帧缓冲区,以及后台缓冲区.由于IDE是vs2013,默认安装了direct 9,只需要在使用头文件(1)并像使用库文件(2)即可 #i ...

随机推荐

  1. CSS兼容性问题总结及解决方法

    css兼容问题 兼容问题 1.文字本身的大小不兼容.同样是font-size:14px的宋体文字,在不同浏览器下占的空间是不一样的,ie下实际占高16px,下留白3px,ff下实际占高17px,上留白 ...

  2. C#string byte[] base64位互相转换

    byte表示字节,byte[]则表示存放一系列字节的数组 1个字符=2个字节(byte) 1个字节=8个比特(bit) 网速上所说的1M其实是指1兆的小b,1M= 1024b/8 = 128kb 下面 ...

  3. Spring知识点小结(二)

    一.配置非自定义的Bean(数据源DataSource模型) DBCP数据源:        导入dbcp的jar包:dbcp+pool+connector                代码实现:  ...

  4. React-Reflux 基础分享

    因工作需要使用 React + Reflux 开发,最近几天都在努力学习着,特别是 Reflux,在网上查找的许多资料和 github 上的文档年代都有点久远,JavaScript 按照目前的节奏,更 ...

  5. 开发机器上利用vs2013调试远程IIS上的c#程序

    当远程IIS上的C#程序出现问题,怎么排错,一般我们通过看日志排查错误的方法,这种方法在程序异常日志都打印出来的情况下是可以解决的,但如果程序日志不详细,或者从日志看不出有用的内容的时候怎么排错? 本 ...

  6. 关于c++随机种子srand( time(NULL) )的设置问题

    设置随机种子srand( time(NULL) ) ,在程序中只需要设置一次就好,而且不能被调用多次,直接看列子. a:每次都重新设置随机种子 #include<iostream> #in ...

  7. mysql 的基本操作总结--增删改查

    本文只是总结一下mysql 的基本操作,增删改查,以便忘记的时候可以查询一下 1.创建数据库 语法:CREATE DATABASES 数据库名; 例子: CREATE DATABASES studen ...

  8. Oracle登录失败:监听程序当前无法识别连接描述符中请求的服务

    Oracle11g下载地址:https://pan.baidu.com/s/1p3RwLUTAl1Ys4yXmXJ3OVQ 安装步骤视频链接:https://pan.baidu.com/s/1c0FC ...

  9. Django忘记超级用户密码||账号

    第一步:运行django shell python3 manage.py shell 第二步:重设密码 >>> from django.contrib.auth.models imp ...

  10. 移动端利用canvas画布简单实现刮刮乐效果

    为了研究canvas一些属性简单实现的一个小效果  代码样式不太规范 随手写的 请问喷 初学者可以看下 css代码 <style> * { margin: 0; padding: 0; } ...