Как заставить SDL2 0,0 позиционировать центр окна при рендеринге? - PullRequest
1 голос
/ 18 апреля 2020

Мы «портируем / обновляем» старый проект, который использует SDL для рендеринга, и мы меняем код для использования матричных преобразований и т. Д. c ..

Основная проблема заключается в том, что система координат SDL находится на вершине -left (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 отрисовать ее в центре экрана.

Мы не довольны с этим решением, и мы не уверены, будет ли оно работать во всех сценариях ios. Есть ли другой способ заставить это работать? Изменение матрицы проекции?

1 Ответ

0 голосов
/ 18 апреля 2020

Мы закончили делать это преобразование:

(ВАЖНО: здесь мы также инвертировали ось 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());

Я не приму этот ответ, чтобы посмотреть, можно ли здесь что-то улучшить!

(РЕДАКТИРОВАТЬ). комментарии

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);
}
...