I have a Windows (XP) application which needs to display a two-dimensional rectangle within a window. The rectangle must not be clipped (i.e. must always lie completely within the viewport), and must preserve its aspect ratio on resize. Currently, the method which handles layout distorts the aspect ratio of the rectangle to match the window. I want the rectangle to scale to the window and be centered in the window (again, without clipping). The method as it stands is below. lWinDist and lMaxDepth are the width and height of the rectangle to be displayed (in 48ths of an inch, if it matters):
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 ) ;
}
}
This one should scale as expected:
// 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;
}
Try this reshape function. It will preserve your aspect ratio, resize the object, and make the viewport to be centralize.
// 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() ;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With