2013-05-01 133 views
1

我正在使用Qt + OpenGl进行2D渲染。 我是OpenGL的初学者,对我而言,我无法弄清楚这个宽高比问题。每当我想到我已经理解了glOrtho和gViewPort,但是下次我将他们带入另一个问题。虽然如果坐标是像-1和1之间的对称,我的代码工作,否则它不。我真的很想彻底解决这些问题。我所搜寻和应用的所有建议对我来说都毫无结果。OpenGL宽高比问题

我的问题陈述:

我绘制一个正方形和三角形,我和按键“R”它们之间进行切换。我也在放大和缩小。广场保持高宽比时,三角形不是。形状的坐标为:

正方形:(-10,-250),(500,-250),(500,-260),( - 10,-260);

三角:(250,0),(310,0),(280,30)

基本上我不能够呈现上述三角形。下面是相同的代码:

我的代码

#include <QtGui/QMouseEvent> 
#include <qdebug.h> 
#include "GLWidget.h" 
#include "stdio.h" 
#include "qgl.h" 
#include "qimage.h" 

GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) 
{ 
    setMouseTracking(true); 
} 

void GLWidget::initializeGL() 
{ 
    glDisable(GL_TEXTURE_2D); 
    glDisable(GL_DEPTH_TEST); 
    glDisable(GL_COLOR_MATERIAL); 
    glEnable(GL_BLEND); 
    glEnable(GL_POLYGON_SMOOTH); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glClearColor(1, 1, 1, 0); 
    glEnable(GL_POINT_SMOOTH); // For Circular Points 
} 

void GLWidget::resizeGL(int w, int h) 
{ 
    canvas_width = (double)w; 
    canvas_height = (double)h; 
    aspect_ratio = canvas_width/canvas_height; 

    left_plane = 250; 
    right_plane = 310; 
    bottom_plane = 0; 
    top_plane = 60; 
    z_near_plane = 1; 
    z_far_plane = -1; 

    glViewport(0, 0, w, h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    if(canvas_width > canvas_height){ 
     glOrtho(left_plane*aspect_ratio, right_plane*aspect_ratio, bottom_plane, top_plane, z_near_plane, z_far_plane); 
    }else{ 
     glOrtho(left_plane, right_plane, bottom_plane/aspect_ratio, top_plane/aspect_ratio, z_near_plane, z_far_plane); 
    } 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

void GLWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(1,0,0); // red 

    glBegin(GL_POLYGON); 
     //glVertex2f(-30,0); 
     //glVertex2f(30,0); 
     //glVertex2f(0,60); 
     glVertex2f(250,0); 
     glVertex2f(310,0); 
     glVertex2f(280,60); 
    glEnd(); 
} 

我没有看到任何黄金三角,因为left_plane * ASPECT_RATIO剪辑我的画(250是最小X,250 * 1.4> 310,310是最大X )。

我希望我已经说清楚了。

我会尝试放置图像以及(我想我将不得不上传图像到其他网站并将它们链接到这里?)。

+2

1.您至少在五个地方使用glOrtho()。除了使问题难以回答之外,不推荐这种编码风格。您应该将此重构为一个函数,它将视口的宽度和高度作为输入。你的问题很长。 :)目前还不清楚什么可行,什么不可行。我建议你备份你的源代码目录,删除所有已经工作或者不相关的问题,并发布剩下的内容。 – 2013-05-01 15:21:29

+1

我很抱歉让它看起来笨拙。我已经整理出来了。请看一看。谢谢。 – Pankaj 2013-05-01 16:13:52

+0

您正在使用已弃用的功能,就像您的信息一样。 – 2013-05-01 17:34:39

回答

1

您的问题是,边界框(分配给左/右/上/ bottom_plane的值)与视口的宽高比不同。如果您有对象的边框,则需要以正确的高宽比(w/h)查找视口坐标。视口需要以边界框中心为中心,并且要足够大以适应边界框。但视口的宽高比与边界框的大小无关。

一般来说,你有一个3D边界框(8个角点)。您可以将每个角落投影到屏幕上,然后使用min/max获取需要在屏幕上居中的矩形。然后检查该矩形的宽高比ar = wr/hr与视口a = w/r的宽高比。如果一个< AR,你需要适合W到W,否则适合小时H。

void GLWidget::resizeGL(int w, int h) 
{ 
    // First set up the projection. 
    double canvas_width = (double)w; 
    double canvas_height = (double)h; 
    double a = canvas_width/canvas_height; 

    glViewport(0, 0, w, h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(-a, +a, -1, +1, -1, +1); 

    // Now set up the view matrix. 
    double leftBoundingRectangle = 250; 
    double rightBoundingRectangle = 310; 
    double bottomBoundingRectangle = 0; 
    double topBoundingRectangle = 60; 

    double widthBoundingRectangle = rightBoundingRectangle - leftBoundingRectangle; 
    double heightBoundingRectangle = topBoundingRectangle - bottomBoundingRectangle; 

    double ar = widthBoundingRectangle/heightBoundingRectangle; 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    // Center on bounding rectangle center. 
    double tx = (leftBoundingRectangle + rightBoundingRectangle)/2.0, ty = (topBoundingRectangle + bottomBoundingRectangle)/2.0; 
    glTranslated(tx, ty, 0.0); // or is it -tx, -ty? 

    // Scale to fit bounding box. 
    double s; 
    if (ar > a) 
    { 
    s = ... // sorry, but you have to figure this one out for yourself. :) 
    } 
    else 
    { 
    s = ... 
    } 
    glScaled(s,s,s); 
} 
+0

Thx答复安德烈亚斯。我想我将不得不忘记许多事情。基本上你是说要保持宽高比,你必须改变ViewPort?虽然我一直在用glOrtho改变剪切平面,但在这种情况下显然不起作用,但对其他对称情况有效(如上述三角坐标分别为(-30,0),(30,0) ,(0,60)...改变glOrtho的作品如果你发现-30到+30之间的三角形的长宽比是1并且与250到310之间的三角形相同。哦,评论中有字符限制,我会详细说明我的怀疑你在post.Thx的回复 – Pankaj 2013-05-01 16:56:37

+0

我不认为修改ViewPort会有所帮助Viewport意味着在哪里绘制窗口虽然修改它将有助于将我的边界框居中在视口,但为了保持宽高比,我相信你必须用glOrtho修改裁剪平面。你说什么? – Pankaj 2013-05-01 17:14:28

+0

不,glViewport(0,0,w,h)很好。我的意思是你应该调用glOrtho(l,r,t,b )具有不同的值,但它们需要具有相同的纵横比:(rl)/(bt)== w/h。 – 2013-05-01 17:20:22