渲染时如何使 SDL2 0,0 定位在窗口的中心?
Posted
技术标签:
【中文标题】渲染时如何使 SDL2 0,0 定位在窗口的中心?【英文标题】:How to make SDL2 0,0 position the center of the window when rendering? 【发布时间】:2020-04-18 15:26:57 【问题描述】:我们正在“移植/更新”一个使用 SDL 进行渲染的旧项目,并且我们正在更改代码以使用矩阵变换等。
主要问题是 SDL 坐标系在左上角 (0,0),我们希望它是窗口的中心。
我们正在使用它来渲染:
const auto modelMatrix = (Matrix3::translation(tr.position) * Matrix3::rotation(Magnum::Deg(tr.rotation))) * Matrix3::scaling(tr.scale);
const auto mvpMatrix = viewProjectionMatrix * modelMatrix;
SDL_SetRenderDrawColor(renderer, 0xFF, 0x0, 0x0, 0xFF);
Magnum::Vector2i winSize;
SDL_GetWindowSize(window, &winSize.x(), &winSize.y());
SDL_RenderDrawPointF(renderer, mvpMatrix.translation().x() + (winSize.x() /2), mvpMatrix.translation().y() + (winSize.y() /2));
这是我们尝试过并且似乎“有效”的方法,因为当我们在 mvpMatrix.translation() 中获得正确的世界位置时,我们会使用 (winSize / 2) 来抵消它,让 SDL 将其渲染到屏幕的中心.
我们对这个解决方案不满意,我们不确定它是否适用于所有场景。还有另一种方法可以使它起作用吗?修改投影矩阵?
【问题讨论】:
【参考方案1】:我们结束了这个转换:
(重要提示:我们在这里也反转了 Y 轴)!
Magnum::Vector2 convertHomogenousCoordsToSDL(SDL_Window* window, const Matrix3& MVP, Magnum::Vector2 vertex)
// get vertex in homogenous coords
vertex = MVP.transformPoint(vertex);
// now convert from homogenous coords 0,0 center and y-axis up to SDL screen coords
Vector2i winSize;
SDL_GetWindowSize(window, &winSize.x(), &winSize.y());
auto winSizeHalf = Vector2(winSize) / 2.f;
auto matrixChangeCoords = Matrix3::translation(winSizeHalf) * Matrix3::scaling( winSizeHalf.x(), -winSizeHalf.y() );
vertex = matrixChangeCoords.transformPoint(vertex);
return vertex;
现在我们可以像这样将空间中的任何点转换为 SDL 窗口空间:
const auto modelMatrix = (Matrix3::translation(tr.position) * Matrix3::rotation(Magnum::Deg(tr.rotation))) * Matrix3::scaling(tr.scale);
const auto mvpMatrix = viewProjectionMatrix * modelMatrix;
SDL_SetRenderDrawColor(renderer, 0xFF, 0x0, 0x0, 0xFF);
const auto vertexPosition = helpers::convertHomogenousCoordsToSDL(window, mvpMatrix, 0,0 );
SDL_RenderDrawPointF(renderer, vertexPosition.x(), vertexPosition.y());
我不会接受这个答案,看看这里是否可以改进!
(编辑) 封装它并像@keltar在cmets中所说的那样在ProjectionMatrix中设置转换
Magnum::Vector2i framebufferSize(SDL_Window* window)
Vector2i winSize;
SDL_GetWindowSize(window, &winSize.x(), &winSize.y());
return winSize;
Magnum::Matrix3 projectionMatrixToSDLSpace(SDL_Window* window, const Vector2& cameraSize)
const Vector2 winSizeHalf = Vector2(framebufferSize(window)) / 2.f;
return Matrix3::translation(winSizeHalf) * Matrix3::scaling( winSizeHalf.x(), -winSizeHalf.y() ) * Magnum::Matrix3::projection(cameraSize);
【讨论】:
这种转换只有一个正确的公式,所以这里没有错。但是您不必为每个点应用额外的变换或生成矩阵 - 只需将此matrixChangeCoords
乘以一次投影矩阵,即可免费获得该变换。
谢谢@keltar 我在答案中添加了您的建议。以上是关于渲染时如何使 SDL2 0,0 定位在窗口的中心?的主要内容,如果未能解决你的问题,请参考以下文章