以下位移、旋转、缩放仅是补充,又或着是说个人笔记(?),阅读这篇单纯的看算式结果就可以知道,为什麽他的矩阵是长这样了。
把这两个放在一起讲是因为真的没有甚麽要多补充的,只是单纯少了一轴-Z而已,并且看起来更简单了。
/*
Translate:
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
*/
Mat4 Mat4Translate(Mat4 origin, float x, float y) {
Mat4 translate = MAT4_IDENTITY;
translate.ary2d[3][0] = x;
translate.ary2d[3][1] = y;
return Mat4MulMat4(origin, translate);
}
/*
Scale:
x 0 0 0
0 y 0 0
0 0 z 0
0 0 0 1
*/
Mat4 Mat4Scale(Mat4 origin, float x, float y) {
Mat4 scale = MAT4_IDENTITY;
scale.ary2d[0][0] = x;
scale.ary2d[1][1] = y;
return Mat4MulMat4(origin, scale);
}
好在是2D,要旋转的话,我们只需要Z轴
/*
Rotate:
s = sin(angle), c = cos(angle)
c -s 0 0
s c 0 0
0 0 1 0
0 0 0 1
*/
Mat4 Mat4EulerRotate(Mat4 origin, float angle) {
Mat4 rotate = MAT4_IDENTITY;
float rad = DegToRad(angle);
float s = sinf(rad), c = cosf(rad);
rotate.ary2d[0][0] = c;
rotate.ary2d[0][1] = s;
rotate.ary2d[1][0] = -s;
rotate.ary2d[1][1] = c;
return Mat4MulMat4(origin, rotate);
}
单独拿出来讲是这里,使用的尤拉角(Eular Angle)的旋转,每个轴的旋转都是分开算的,如果是3D的话,每个轴都要可以转360的话,会出现**万向锁(Gimbal Lock)**(这个连结会到YT)。这时就会需要另一种旋转的表示方式,四元数了。这边没有要继续讲四元数,因为我不是特别理解四元数是怎麽运作的,可能会在之後再来补充 :(。
昨天提过一件事
矩阵运算是从右到左
原因是矩阵的的顺序调换会影响结果。
所以模型矩阵(Model Matrix) x 透视矩阵(Projection Matrix)事实上会是
// Mat4MulMat4是我制作的矩阵相乘的function
MVP = Mat4MulMat4(Projection, Model);
那...模型矩阵,是要先位移呢?还是缩放?还是旋转,这个蛮有趣的,我个人试过的结果会是:**位移
旋转 > 缩放**这个顺序,才会看起来比较正常。
如果自由地缩放视窗会发现,里头的矩形没有随着视窗的大小变化进行缩放,这是因为我们缩放了视窗大小,但没有缩放OpenGL的视窗大小,需要使用法宝:
glViewport(int x, int y, int width, int height)
然後glfw
也有提供「当视窗大小有变化时」的Callback,一样在CreateWindow
加上新的处理
// framebuffer size callback
void FramebufferSizeCallback(GLFWwindow* window, int w, int h) {
glViewport(0, 0, w, h);
}
// in `CreateWindow`
glfwSetFramebufferSizeCallback(WINDOW.wnd, FramebufferSizeCallback);
就这样,我们的矩形跟贴图就会跟着视窗大小变化了。
昨天我们已经按照时间去新增我们的资料了,也得到列表啦,那麽我们今天就要来建立点击事件,因为如果只有...
Kernel里面除了前述几种物件之外,我们以下介绍其他几种比较重要的物件,首先我们来看所谓的pipe...
Annotation 很常写 Java 或是 Kotlin 的朋友对 annotation 大概不陌...
▉适用性声明书范例(适用或不适用都要提出说明) └这个是老师给的范例…我记得不适用也是要写啦。 ▉估...
使用Matplotlib绘制图表 安装matplotlib套件的命令列指令 pip install ...