所以我正在尝试只使用 winapi 制作一个简单的游戏引擎。我在 Wikipedia 上找到了透视投影的公式,它在 3d 空间中取一个点并将其投影到观察平面上。
Vector2 Camera::renderPoint(Point point) {
Vector2 output;
Vector3 cameraPosition = this->getPosition();
Vector3 cameraRotation = this->getRotation();
Vector3 pointPosition = point.getCoordinates();
Vector3 deltaCameraPoint;
deltaCameraPoint.x = pointPosition.x - cameraPosition.x;
deltaCameraPoint.y = pointPosition.y - cameraPosition.y;
deltaCameraPoint.z = pointPosition.z - cameraPosition.z;
Vector3 sinRotation;
sinRotation.x = sin(cameraRotation.x);
sinRotation.y = sin(cameraRotation.y);
sinRotation.z = sin(cameraRotation.z);
Vector3 cosRotation;
cosRotation.x = cos(cameraRotation.x);
cosRotation.y = cos(cameraRotation.y);
cosRotation.z = cos(cameraRotation.z);
Vector3 tempVector;
//Complex formula (copy-pasted from Wikipedia), for further info: https://en.wikipedia.org/wiki/3D_projection
tempVector.x = cosRotation.y * (sinRotation.z * deltaCameraPoint.y + cosRotation.z * deltaCameraPoint.x) - sinRotation.y * deltaCameraPoint.z;
tempVector.y = sinRotation.x * (cosRotation.y * deltaCameraPoint.z + sinRotation.y * (sinRotation.z * deltaCameraPoint.y + cosRotation.z * deltaCameraPoint.x)) + cosRotation.x * (cosRotation.z * deltaCameraPoint.y - sinRotation.z * deltaCameraPoint.x);
tempVector.z = cosRotation.x * (cosRotation.y * deltaCameraPoint.z + sinRotation.y * (sinRotation.z * deltaCameraPoint.y + cosRotation.z * deltaCameraPoint.x)) - sinRotation.x * (cosRotation.z * deltaCameraPoint.y - sinRotation.z * deltaCameraPoint.x);
output.x = (1 / tempVector.z) * tempVector.x;
output.y = (1 / tempVector.z) * tempVector.y;
return output;
}
auto var = player.renderPoint(point);
MoveToEx(hdc, var.x, var.y, 0);
LineTo(hdc, var.x + 10, var.y);
点变量只是我放置在 (10, 1, 10) 的一个点,因此它应该出现在屏幕中心附近(相机位于 0,0,0 并且具有 0,0,0 旋转),但它出现在左上角。 MoveToEx 和 LineTo 函数只是在点所在的位置放置一条简单的线,所以我可以查看代码是否有效。
我尝试实施它,据我所知它应该有效。我还实现了一种使用 W、A、S 和 D 移动相机位置的方法,但是当我这样做时,该点不会相应移动。有人可以帮助我吗?