OpenGL3.3-2D和3D坐标转换问题

3D->2D

(模型变换)

模型坐标是(-1,1)
原坐标 * model矩阵 = 世界坐标 (此时齐次坐标不知道有没有发生改变)

(视变换)

世界坐标 * view矩阵 = 视坐标(以摄像机为原点的坐标)
view矩阵实际上就是摄像机在世界坐标系中位置的逆矩阵
OpenGL3.3-2D和3D坐标转换问题_第1张图片
在这里插入图片描述
图中因为是二维的 所以y轴是与世界坐标系相反的 而x轴是与世界坐标系相同的方向 三维中xy坐标系是相同的 z轴坐标系是不同的
在这里插入图片描述
在这里插入图片描述
用视矩阵逆矩阵 * 世界坐标 = 世界坐标相对于摄像机的的位置 也就是视坐标

(投影变换)

视坐标 * projection矩阵 = 裁剪坐标 此时就是x,y,z在(-1,1)

(透视除法)

裁剪坐标/w值 = NDC坐标 GPU自动执行 NDC坐标是x,y,z在(-1,1)

(视口变换)

NDC坐标->屏幕坐标 将x,y变换到w,h 对z变换,从[-1,1]变换到[0,1]

2D->3D

获取鼠标坐标

1.通过glfwGetCursorPos获取鼠标点击的位置lm->x,lm->y
(我们也可以通过lm->x,lm->y获取到鼠标点击的像素)

转化为NDC

2.将屏幕上获取的鼠标点击位置转化为NDC坐标(标准设备坐标)(-1,1)

	/*将屏幕坐标转换为NDC坐标 也就是(-1,1)*/
	float NDCx = (scrPos.x - (scrWei/2.0)) / (scrWei / 2.0);
	float NDCy = ((scrHig / 2.0) - scrPos.y) / (scrHig / 2.0);
glReadPixels(scrPos.x, scrHig - scrPos.y - 1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);//获取点击像素的深度值depth 此时是(0,1)
//注意:获取深度的时候一定要在绘制完场景之后 要不然可能获取的深度值一直就是1.0
depth = (depth - 0.5) * 2;//再将深度值变为(-1,1)之间

转化为世界坐标

3.将NDC坐标和深度坐标通过逆矩阵转化为世界坐标

glm::mat4 view1 = camera.GetViewMatrix();//获取视矩阵
glm::mat4 projection1 = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);//获取投影矩阵
glm::vec4 world = glm::inverse(projection1 * view1) * glm::vec4(NDCx, NDCy, depth, 1.0);//逆矩阵的位置应该不会错
 world = world / world.w;//这个很容易漏掉 透视除法

坐标从键盘输入到屏幕显示的过程

OpenGL3.3-2D和3D坐标转换问题_第2张图片
OpenGL3.3-2D和3D坐标转换问题_第3张图片

你可能感兴趣的:(opengl)