初学Direct X(7)

——位图的旋转,缩放以及平移


本文旨在实现通过D3DXMatrixTransformation2D函数实现位图的旋转,缩放以及平移操作,但是具体的原理部分会在后面进一步的探讨。

1. 使用

下面是D3DXMatrixTransformation2D函数的定义:

D3DXMATRIX* D3DXMatrixTransformation2D(
_Inout_ D3DXMATRIX *pOut,
_In_ const D3DXVECTOR2 *pScalingCenter,
_In_ FLOAT pScalingRotation,
_In_ const D3DXVECTOR2 *pScaling,
_In_ const D3DXVECTOR2 *pRotationCenter,
_In_ FLOAT Rotation,
_In_ const D3DXVECTOR2 *pTranslation
);

各个参数的作用都简洁明了,根据参数可计算出最终的变换矩阵,并保存在pOut中,注意这是在2维中的函数,所以其中的变换参数都是二维的,我们需要提前定义这些参数,就像下面这样:

// 控制缩放比例
D3DXVECTOR2 scale(scaling, scaling);
// 控制平移
D3DXVECTOR2 trans((float)x, (float)y);
// 旋转中心
D3DXVECTOR2 scenter((float)width / 2, (float)height / 2);

最后,将其作为参数传入D3DXMatrixTransformation2D

D3DXMatrixTransformation2D(
&mat,
&scenter, /*缩放中心*/
0,
&scale /*缩放*/,
&scenter /*旋转中心*/,
rotation /*旋转度数,弧度*/,
&trans /*平移*/
);

最终可以得到一个变换矩阵,仅仅只是得到了。但是要怎么使得渲染器知道绘制时候作用这个变换矩阵呢?如下即可:

spriteobj->SetTransform(&mat);

2. 问题

在我使用的时候发现一个问题,在设置缩放中心或者旋转中心的时候,理应乘以一个放缩量,就像下面这样:

D3DXVECTOR2 center((float)(width * scaling) / 2, (float)(height*scaling) / 2);

而不是

D3DXVECTOR2 scenter((float)width / 2, (float)height / 2);

当然,若是在位图进行同比例放缩之时,使用scenter是可以的,因为只要是同比例缩放,中心点始终是不会变的。但是若放缩比例不一致比如:

D3DXVECTOR2 scale(scaling, scaling + 2);

这意味着,y方向上缩放长度是x方向的两倍,中心点也会偏移原来的位置。其实无论哪种情况,似乎使用center这样的定义方式来定义中心点始终是没有问题的。但是这里有一个问题是我百思不得其解,此问题相关描述如下:

目的:要实现位图(image)在窗口中心显示并围绕自身中心点旋转并放缩。

位图的宽高分别是widthheight,放缩值为scaling,x与y方向上平移变量分别为xy

// 控制缩放比例
D3DXVECTOR2 scale(scaling, scaling);
// 控制平移
D3DXVECTOR2 trans((float)x, (float)y);
// 旋转,缩放中心,会随放缩比例变化
D3DXVECTOR2 center((float)(width * scaling) / 2, (float)(height*scaling) / 2); D3DXMATRIX mat; D3DXMatrixTransformation2D(
&mat,
&center, /*缩放中心*/
0,
&scale /*缩放*/,
&center /*旋转中心*/,
rotation /*旋转度数*/,
&trans /*平移*/);
spriteobj->SetTransform(&mat); //获取srcRect
// ... spriteobj->Draw(image, &srcRect, NULL, NULL, color);

调用以上函数以及个参数如下,它们是在Begin()End()之间的代码:

// rotate
r = timeGetTime() / 600.0f;
// scaling
s += scale;
if (s < 0.1f || s > 1.25f)
scale *= -1;
width = height = 512;
frame = 0;
columns = 1;
color = D3DCOLOR_XRGB(255,255,255); Sprite_Transform_Draw(
sunflower, // => image
SCREENW / 2 - width / 2, // => x
SCREENH / 2 - height / 2, // => y (xy用于平移位图至屏幕窗口中心)
width, // => width
height, // => height
frame, // => ignore
columns, // => ignore
r, // => rotation
s, // => scale
color // => ignore
);

看起来似乎可以使得sunflowercenter为中心旋转并缩放,但是事实并不是这样的,我也不知道原因是什么,这使得我十分的困惑。因为实际的结果并不是以center为中心旋转并缩放的。我尝试着将缩放比例注释掉,也就是说将s设置为了1,此时位图停止了放缩,旋转的中心是center正常。 但是一旦将s设置为了递增或递减的变量(就像代码写的那样),那么此时的旋转和放缩中心就不是真正的位图中心了。

这里remark一下,我还会继续学下去,看看会不会找到这个问题的答案。

初学Direct X(7) ——位图的旋转,缩放以及平移的更多相关文章

  1. 初学Direct X(5)

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

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

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

  3. 初学Direct X(6)

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

  4. 初学Direct X(4)

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

  5. 初学Direct X (2)

    初学Direct X (2) 这一次要学习如何现实位图,尽管看过对双缓冲机制还有很多疑问,但是这并不阻碍我对他的入门了解 Direct3D提供了一个双重/后台缓冲区,在调用CreateDevice之时 ...

  6. Android 学习笔记之Bitmap位图的旋转

    位图的旋转也可以借助Matrix或者Canvas来实现. 通过postRotate方法设置旋转角度,然后用createBitmap方法创建一个经过旋转处理的Bitmap对象,最后用drawBitmap ...

  7. Android学习笔记之Bitmap位图的旋转

    位图的旋转也可以借助Matrix或者Canvas来实现. 通过postRotate方法设置旋转角度,然后用createBitmap方法创建一个经过旋转处理的Bitmap对象,最后用drawBitmap ...

  8. osg矩阵变换节点-----平移旋转缩放

    osg矩阵变换节点-----平移旋转缩放 转自:http://www.cnblogs.com/ylwn817/articles/1973396.html 平移旋转缩放这个三个是osg矩阵操作中,最常见 ...

  9. osg中使用MatrixTransform来实现模型的平移/旋转/缩放

    osg中使用MatrixTransform来实现模型的平移/旋转/缩放 转自:http://www.cnblogs.com/kekec/archive/2011/08/15/2139893.html# ...

随机推荐

  1. orcl 复杂查询

    测试环境: create table bqh6 (xm varchar2(10),bmbh number(2),bmmc varchar2(15),gz int);insert into bqh6 v ...

  2. Python实例---爬取下载喜马拉雅音频文件

    PyCharm下python爬虫准备 打开pycharm 点击设置 点击项目解释器,再点击右边+号 搜索相关库并添加,例如:requests 喜马拉雅全网递归下载 打开谷歌/火狐浏览器,按F12打开开 ...

  3. 软件架构方面基础-ESB \SOA \GEO-ESB

    学习初稿 软件架构演变历史 SOA  (Service-Oriented Architecture)面向服务的体系结构 它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起 ...

  4. SDN2017 期末作业验收

    GIT仓库:GITHUB 负载均衡程序 拓扑如图 目的 实现一个负载均衡的北向程序: 服务器host 2 ,host 3,host 4上各自有不同的服务,host 1是客户端 当host 2,host ...

  5. 阿里八八Alpha阶段Scrum(12/12)

    今日进度 俞鋆: 和前端对接,完成了注册接口的对接写了一部分数据同步接口. 李嘉群: 完成了注册界面与服务器的对接 黄梅玲: json数据解析并在listview中显示(还未完成) 王国超: 今天开始 ...

  6. [BUG] python实例化N次类,调用类函数log会输出N遍的bug 解决办法

    最近再写DOU用例时,采用的是 unittest测试框架,就涉及到将其它所有模块需要全部在一个 .py文件中进行实例化,然后再运行时发现在控制台中同一个日志信息会打印多次(实例化几次,同一消息就会打印 ...

  7. JVM各垃圾收集器对比

    本随笔是<深入理解Java虚拟机 JVM高级特性与最佳实践>读书笔记. 1.JDK1.7之后的HotSpot虚拟机所包含的所有收集器如下: 解读: 1. 总共有7种垃圾收集器 2.Seri ...

  8. [SDOI2008]洞穴勘测

    嘟嘟嘟 写完lct的板儿后觉得这就是一道大水题. 连pushup都不用. 不过还是因为一个zz的错误debug了一小会儿(Link的时候连出自环--) 还有一件事就是Cut的时候判断条件还得加上,因为 ...

  9. 【转】默认网关有什么用?我应当怎么填写默认网关和DNS呢

    默认网关有什么用?我应当怎么填写默认网关和DNS呢? 目前使用的是pppoe方式上网,无猫,只是将一根入户的网线插在无线路由上面,然后在路由中设置ppoe方式上网,输入帐号密码.一般电脑和手机全设成了 ...

  10. 【题解】[HNOI2008]神奇的国度—BZOJ1006。

    之前说顺着打BZOJ结果又被自己给鸽了qwq. ------------------------------------ 言归正传这道题应该怎么做. 先给大家普及一下弦图(连接环上俩个不相邻节点的边称 ...