Сохранение соотношения сторон и масштаба независимо от размера окна с помощью freeglut

Я давно хотел поэкспериментировать с физикой платформеров с помощью freeglut, но прежде чем я позволил себе начать, мне нужно было решить одну старую проблему.

Видите ли, я хочу написать обработчик изменения формы, который не только поддерживает масштаб и устраняет любые искажения вида, но также позволяет всем фигурам на экране сохранять свой размер, даже если окно слишком маленькое, чтобы вместить их (т.е. быть обрезанным).

Я почти решил все три части, но когда я масштабирую свое окно, круг, который я нарисовал в нем, масштабируется немного. В противном случае я получил отсечение и устранил искажение. Обновление. Я хочу создать программу, поддерживающую масштаб и соотношение сторон независимо от размера окна.

Вот мой код:

void reshape(int nwidth,int nheight)
{
    glViewport(0,0,nwidth,nheight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    //here begins the code
    double bound = 1.5;
    double aspect = double(nwidth)/nheight;

    //so far, I get the best results by normalizing the dimensions
    double norm = sqrt(bound*bound+aspect*aspect);
    double invnorm = sqrt(bound*bound+(1/aspect)*(1/aspect));

    if(nwidth <= nheight)
        glOrtho(-bound/invnorm,bound/invnorm,-bound/aspect/invnorm,bound/aspect/invnorm,-1,1);
    else
        glOrtho(-bound*aspect/norm,bound*aspect/norm,-bound/norm,bound/norm,-1,1);

    //without setting the modelview matrix to the identity form,
    //the circle becomes an oval, and does not clip when nheight > nwidth
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

Обновление: по предложению г-на Коулмана я попытался заменить одинарную точность на двойную. Проблема масштабирования по вертикальной оси улучшилась, но всякий раз, когда я перетаскиваю горизонтальную ось в любом направлении, фигура по-прежнему заметно масштабируется. Это по-прежнему одна и та же форма повсюду, но визуальный осмотр говорит мне, что форма имеет другой размер, когда окно имеет размер 150x300, и когда окно имеет размер 600x800, независимо от того, какой glOrtho выполняется.


person Chuck Rittenhouse    schedule 29.03.2014    source источник
comment
Кстати, glOrtho (...) принимает GLdouble параметров. Рассматривали ли вы возможность использования в своих расчетах двойной точности вместо одинарной?   -  person Andon M. Coleman    schedule 30.03.2014


Ответы (1)


Я понял. Вот как я изменил свой код:

//at the top of the source file, in global scope:
int init_width;//the initial width
int init_height;//the initial height
void reshape(int new_width, int new_height)
{
    //moved the glViewport call further down (it was part of an earlier idea that didn't work out)
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();//these two lines are unchanged

    double bound = 1.0; //I reduced the edge distance to make the shape larger in the window
    double scaleX = double(new_width)/init_width;
    double scaleY = double(new_height)/init_height;

    glOrtho( -bound*scaleX/2, bound*scaleX/2, //these are halved in order to un-squash the shape
        -bound*scaleY, bound*scaleY, -1,1 );

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0,0,new_width,new_height);
}

Вот так сейчас выглядит мой код. Он поддерживает масштаб и форму того, что у меня есть на экране, и позволяет ему уйти за пределы экрана, когда окно слишком маленькое, чтобы вместить всю форму.

person Chuck Rittenhouse    schedule 02.04.2014