我有一个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 ) ;
}
}
答案 0 :(得分:3)
这个应按预期扩展:
// 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 :(得分:1)
尝试此重塑功能。它将保留您的纵横比,调整对象大小,并使视口集中。
// 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() ;
}
答案 2 :(得分:0)
试试这个:
#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;
}
答案 3 :(得分:0)
我认为你应该看看这个以获得正确的数字:
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上更轻。如果有理由为什么我在这里看到的超级编码方法更好,我无法弄明白。祝你好运。