初学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. INCLUDE COMMON FILES IN HTML USING JQUERY

    Simple example for including common files in HTML. JQuery load() function is used for including comm ...

  2. java基础学习总结——异常处理

    一.异常的概念 异常指的是运行期出现的错误,也就是当程序开始执行以后执行期出现的错误.出现错误时观察错误的名字和行号最为重要.

  3. spring-bean 版本的问题(报错:org.xml.sax.SAXParseException; lineNumber: 14; columnNumber: 75;)

    当XML中配置的xsd是4.0,而引用的包是4以下的spring-bean.jar时,当服务器能连网时没问题,不能连网时,就报以下类似错误: org.xml.sax.SAXParseException ...

  4. python的学习之路day4

    大纲 1.一些常用的内置函数 callable() chr() & ord() 随机生成验证码 map() 全局变量,局部变量 hash() & round() max() min() ...

  5. Redis缓存穿透、缓存雪崩、redis并发问题分析

    把redis作为缓存使用已经是司空见惯,但是使用redis后也可能会碰到一系列的问题,尤其是数据量很大的时候,经典的几个问题如下: (一)缓存和数据库间数据一致性问题分布式环境下(单机就不用说了)非常 ...

  6. November 02nd, 2017 Week 44th Thursday

    Knowledge is weightless, a treasure you can always carry easily. 知识没有重量,她是我们可以很容易携带的珍宝. Knowledge is ...

  7. python3: 数字日期和时间(2)

    12.基本的日期与时间转换 Q: 你需要执行简单的时间转换,比如天到秒,小时到分钟等的转换 A: 为了执行不同时间单位的转换和计算,请使用 datetime 模块. 比如,为了表示一个时间段,可以创建 ...

  8. BZOJ1458:士兵占领(有上下界最小流)

    Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...

  9. ORB SLAM2在Ubuntu 16.04上的运行配置

    http://www.mamicode.com/info-detail-1773781.html 安装依赖 安装OpenGL 1. 安装opengl Library$sudo apt-get inst ...

  10. MetaMask/provider-engine-3-test

    通过看其test的代码去好好看看它是怎么使用的 1. provider-engine/test/basic.js const test = require('tape') const Provider ...