Сохранить соотношение сторон 2D-объекта при изменении размера окна - PullRequest
3 голосов
/ 02 декабря 2010

У меня есть приложение для Windows (XP), которое должно отображать двухмерный прямоугольник в окне.Прямоугольник не должен быть обрезан (т.е. всегда должен полностью находиться внутри области просмотра), и должен сохранять свое соотношение сторон при изменении размера.В настоящее время метод, который обрабатывает макет, искажает пропорции прямоугольника, чтобы соответствовать окну.Я хочу, чтобы прямоугольник масштабировался до окна и центрировался в окне (опять же, без обрезки).Метод в том виде, как он есть, ниже.lWinDist и lMaxDepth - это ширина и высота отображаемого прямоугольника (в 48-х дюймах, если это имеет значение):

void CRoRRecView::RedoLayout( long lWinDist, long lMaxDepth )
{
    CDC* pDC = GetDC() ;

    if ( pDC != NULL )
    {
        m_lWinDist = lWinDist;
        GetClientRect( m_rectClient ) ;
        int nClientWidth = m_rectClient.Width();
        int nClientHeight = m_rectClient.Height();
        glViewport( 0, 0, nClientWidth, nClientHeight );

        glMatrixMode( GL_PROJECTION);
        glLoadIdentity();

        m_fWinXDist = (float) lWinDist ;
        m_fWinYDist = lMaxDepth ;
        m_fAspectRatio = m_fWinXDist / m_fWinYDist;

        glOrtho(0.0, m_fWinXDist, 0.0, m_fWinYDist, -1, 1 ) ;

        glRotatef(180.0, 0,1,0); 
        glTranslatef( (float)(-1 * lWinDist),0,0 ); // Translate across the x axis

        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();

        ReleaseDC( pDC ) ;
    }
}

Ответы [ 4 ]

3 голосов
/ 04 декабря 2010

Это должно масштабироваться как ожидалось:

// g++ main.cpp -lglut -lGL
#include <GL/glut.h>

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    double ar = w / h;
    glOrtho( -2 * ar, 2 * ar, -2, 2, -1, 1);

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glColor3ub( 255, 0, 0 );
    glBegin( GL_QUADS );
    glVertex2i( -1, -1 );
    glVertex2i(  1, -1 );
    glVertex2i(  1,  1 );
    glVertex2i( -1,  1 );
    glEnd();

    glutSwapBuffers();
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow( "Aspect Ratio" );
    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}
1 голос
/ 09 октября 2013

Попробуйте эту функцию изменения формы. Это сохранит ваши пропорции, изменит размер объекта и сделает область просмотра централизованной.

// initial window screen size
int WIDTH = 400;
int HEIGHT = 300;

// reshape function, call with glutReshapeFunc(reshape) in yout main function
void reshape(int width, int height) {
    const float ar_origin = (float) WIDTH / (float) HEIGHT;
    const float ar_new = (float) width / (float) height;

    float scale_w = (float) width / (float) WIDTH;
    float scale_h = (float) height / (float) HEIGHT;
    if (ar_new > ar_origin) {
        scale_w = scale_h;
    } else {
        scale_h = scale_w;
    }

    float margin_x = (width - WIDTH * scale_w) / 2;
    float margin_y = (height - HEIGHT * scale_h) / 2;

    glViewport(margin_x, margin_y, WIDTH * scale_w, HEIGHT * scale_h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, WIDTH / ar_origin, 0, HEIGHT / ar_origin, 0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity() ;
}
0 голосов
/ 10 февраля 2016

Я думаю, вы должны посмотреть на это, чтобы получить правильные числа:

self.hOffset = (self.wOffset / (16.0 / 9.0));
self.xOffset = ((int)ceil((_backingWidth  / 2.0) - ((_backingWidth  + self.wOffset) / 2.0)));
self.yOffset = ((int)ceil((_backingHeight / 2.0) - ((_backingHeight + self.hOffset) / 2.0)));

glViewport(self.xOffset, self.yOffset, _backingWidth + self.wOffset, _backingHeight + self.hOffset );

В приведенном выше коде wOffset, который является шириной изображения, дает или принимает его значение, измененное с помощью ползунка.Первая строка увеличивает высоту при увеличении ширины в правильном соотношении, которое составляет 16: 9 (не получается разделить ширину на высоту, чтобы получить это соотношение; лучше указать ее явно).Следующие две строки корректируют координаты x, y изображения, так что при увеличении или уменьшении его размера оно всегда остается в центре.

Это гораздо более простой и легкий подход - и легче наGPU.Если есть причины, по которым подход мега-кодирования, который я здесь вижу, лучше, я не могу понять это.Удачи.

0 голосов
/ 02 декабря 2010

Попробуйте это:

#include <GL/glut.h>

size_t win_w = 0;
size_t win_h = 0;

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, win_w, 0, win_h, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glColor3ub(255,0,0);
    glPushMatrix();
        glTranslatef(win_w/2,win_h/2,0);
        glScalef(50,50,50);
        glBegin(GL_QUADS);
            glVertex2f(-1,-1);
            glVertex2f(1,-1);
            glVertex2f(1,1);
            glVertex2f(-1,1);
        glEnd();
    glPopMatrix();

    glFlush();
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    win_w = w;
    win_h = h;
    glViewport(0, 0, w, h);
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

    glutInitWindowSize(800,600);
    glutCreateWindow("Aspect Ratio");

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...