Матрицы. Поверните прямоугольник с исходной точкой в ​​левом нижнем углу, как если бы исходная точка находилась в центре.

Я занимаюсь программированием OpenGL, рисую двумерные прямоугольники. Я использую OpenGL ES 2.0, поэтому я не могу использовать glTranslate/glRotate и т. д., мне нужно свернуть свою собственную матрицу. Я хочу иметь возможность установить для них значение поворота и масштаба, при этом происхождение масштаба или поворота варьируется в зависимости от «выравнивания» и «выравнивания». Этот код правильно работает для поворота (однако координаты x, y все еще кажутся немного неправильными), но как я могу заставить работать масштабирование? Кажется, он все еще хочет использовать нижний левый угол в качестве источника.

vid.xratio/vid.yratio — это отношение текущего экрана к локальной системе координат, в которую передаются x, y, ширина и высота. Так, например, если локальные координаты основаны на сетке 640x480, но ваш экран в настоящее время 1600x1200, координаты (238, 185) будут (595, 462,5).

const byte picVerts[] = {0, 0, 1, 0, 1, 1, 0, 1};
//
// DrawPictureSize
//
// Draws a picture on the 2D screen, width and height specified.
//
void DrawPictureSize(float x, float y, float width, float height, float scalex, float scaley, Vector::vector_t *upVec, byte alpha, Texture::texture_t *texture, int halignment, int valignment)
{
    if (!texture)
        return;

    float matrix[16];
    Matrix::LoadIdentity(matrix);

    width *= scalex * vid.xratio;
    height *= scaley * vid.yratio;

    float angle = U_Rad2Deg(atan2(upVec->y, upVec->x)) - 90;

    float xalign = 0;
    float yalign = 0;

    // Move into position
    if (halignment == Font::HALIGN_CENTER)
        xalign = width/2;
    else if (halignment == Font::HALIGN_RIGHT)
        xalign = width;
    if (valignment == Font::VALIGN_CENTER)
        yalign = height/2;
    else if (valignment == Font::VALIGN_TOP)
        yalign = height;

    // Move into position
    Matrix::Translate(matrix, x * vid.xratio, y * vid.yratio, 0.0f);

    // Translate to the origin before doing scaling/rotation
    Matrix::Translate(matrix, xalign, yalign, 0);
    Matrix::Rotate(matrix, angle, 0, 0, 1);
    Matrix::Translate(matrix, -xalign, -yalign, 0);

    // Expand square to image size
    Matrix::Scale(matrix, width, height, 1.0f);

person user1054922    schedule 19.11.2011    source источник


Ответы (1)


Разобрался... вот правильный код, вдруг кому поможет

Обратите внимание, что я удалил ссылки на vid.xratio и vid.yratio... что я делаю вместо этого после вызова Matrix::Ortho в матрице проекции, я делаю:

Matrix::Scale(projMatrix, vid.xratio, vid.yratio, 1.0f);

const byte picVerts[] = {0, 0, 1, 0, 1, 1, 0, 1};
//
// DrawPictureSize
//
// Draws a picture on the 2D screen, width and height specified.
//
// Note: 'Set2D' must be called before this!
//
void DrawPictureSize(float x, float y, float width, float height, float scalex, float scaley, Vector::vector_t *upVec, byte alpha, Texture::texture_t *texture, int halignment, int valignment)
{
    if (!texture)
        return;

    float matrix[16];
    Matrix::LoadIdentity(matrix);

    width *= scalex;
    height *= scaley;

    float angle = U_Rad2Deg(atan2(upVec->y, upVec->x)) - 90;

    float xalign = 0;
    float yalign = 0;

    // Move into position
    if (halignment == Font::HALIGN_CENTER)
        xalign = width/2;
    else if (halignment == Font::HALIGN_RIGHT)
        xalign = width;
    if (valignment == Font::VALIGN_CENTER)
        yalign = height/2;
    else if (valignment == Font::VALIGN_TOP)
        yalign = height;

    // Move into position
    Matrix::Translate(matrix, x - xalign, y - yalign, 0.0f);

    // Translate to the origin before doing rotation
    if (angle != 0.0f)
    {
        Matrix::Translate(matrix, xalign, yalign, 0);
        Matrix::Rotate(matrix, angle, 0, 0, 1);
        Matrix::Translate(matrix, -xalign, -yalign, 0);
    }

    // Expand square to image size
    Matrix::Scale(matrix, width, height, 1.0f);
person user1054922    schedule 19.11.2011