初学Direct X (2)
初学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)的更多相关文章
- 初学Direct X(7) ——位图的旋转,缩放以及平移
		初学Direct X(7) --位图的旋转,缩放以及平移 本文旨在实现通过D3DXMatrixTransformation2D函数实现位图的旋转,缩放以及平移操作,但是具体的原理部分会在后面进一步的探 ... 
- 初学Direct X(10)—— D3D基础预备知识
		初学Direct X(10) -- D3D基础预备知识 1. 像素格式 D3DFMT_X8R8G8B8(F) X:未加使用 8:8位用于显示 B:用于显示蓝色 F:浮点像素类型 以下三个较为常用,使用 ... 
- 初学Direct X(9) ——文字的显示
		初学Direct X(9) --文字的显示 本次学习如何使用ID3DXFont创建字体,使得我们可以在任何安装了Windows系统中TrueType字体来打印文字,不过最好使用标准字体,这样文字在每一 ... 
- 初学Direct X(8) ——碰撞检测
		初学Direct X(8) --碰撞检测 真正让一个游戏鹤立鸡群的是程序对碰撞的响应有多好,这里介绍两种检测的方法: 1) 基于边框的碰撞检测 2) 基于距离的碰撞检测 1. 基于边框的碰撞检测 1. ... 
- 初学Direct X(6)
		初学Direct X(6) 这一文本应和上一篇放在一起的,但是上一章写着写着发现对Draw绘制透明位图的方式有感觉了,决定就单写一篇,留作笔记了. 那这一篇是记录如何使用位图表来绘制动画帧,想象一下, ... 
- 初学Direct X(5)
		初学Direct X(5) 前面学习了使用表面绘制屏幕,但这种方法与另一种比较起来,有着绘图速度颇慢以及缺乏对任何透明类型的支持,这就是前面的篮框以及炸弹会有黑色背景的原因,这种方法就是纹理.他可以绘 ... 
- 初学Direct X(4)
		初学Direct X(4) 本文学着做出一个如下的小游戏 游戏方式是使用键盘控制红色的Bucket收集蓝色的炸弹 1.酝酿一下 现在我已经掌握: 将位图文件加载到内存 绘制位图到buckbuffer ... 
- 初学Direct X(3)
		初学Direct X(3) 1.获取外设输入--键盘以及鼠标 无论是获取鼠标还是键盘的设备,首先得初始化DirectInput,不过先把必要的环境先配置好: 所要用到的头文件以及库文件是(相比于前两次 ... 
- 初学DirectX(1)
		初学Direct X (1) Direct3D设备用于访问视频卡的帧缓冲区,以及后台缓冲区.由于IDE是vs2013,默认安装了direct 9,只需要在使用头文件(1)并像使用库文件(2)即可 #i ... 
随机推荐
- mongo数据库基础语法
			http://www.runoob.com/mongodb/mongodb-create-collection.html 很详细 
- 管理Django1.9静态文件static
			管理Django1.9静态文件static 网站通常需要增加图片.JavaScript.或者CSS等文件提供服务.在Django中,我们把这些文件称为“静态文件”(static files).Djan ... 
- 【最新】LuaJIT 32/64 位字节码,从编译到使用全纪录
			网上关于 LuaJIT 的讨论,已经显得有些陈旧.如果你对 LuaJIT 编译 Lua 源文件为具体的 32位或64位字节码,极其具体使用感兴趣的话,不妨快速读一下这篇文章.此文章针对尝试在 iOS ... 
- chromium之compiler_specific
			直接上代码,将一些编译警告定义成宏 #if defined(COMPILER_MSVC) // Macros for suppressing and disabling warnings on MSV ... 
- MySQL 开启事件 使用定时器调用存储过程
			mysql定时器是系统给提供了event,而oracle里面的定时器是系统给提供的job.废话少说,下面创建表:create table mytable (id int auto_incremen ... 
- Linux中将端口(80)重定向
			在Linux中直接指定命令: iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 其中80为要访问的端 ... 
- java中反射的基本使用
			fanShe.java package example5;class fanShe{ /*1.应用在一些通用性比较高的代码中. *2.后面学的框架,大多数都是应用框架来实现的. ... 
- ORALCE表的约束条件
			一.主键:(PRIMARY KEY) 主键是表中的一列或多列.为表定义主键有如下几个作用: 1.主键包含的列不能输入重复的值,以此来保证一个表的所有行的唯一性: 2.主键也不允许定义此约束的列为NUL ... 
- ie 8在打印网页的时候打印预览是空白的
			win 7专业版系统中的ie 8在打印网页的时候打印预览是空白的,打印出来也是空白的,但是用别的浏览器打印没有问题 根据您的描述,该问题主要是由于保护模式下%Temp%\Low不正常工作引起的. 建议 ... 
- mysql 库和表占用空间查询
			1. 查看该数据库实例下所有库大小,得到的结果是以MB为单位 as sum from information_schema.tables; 2.查看该实例下各个库大小 as total_mb, as ... 
