2013-05-11 104 views
3

調整大小時我實現以下代碼:保持縱橫比在OpenGL

void TestGlPlot::resizeGL(int width, int height) 
{ 
    setupViewport(width, height); 
} 

void TestGlPlot::setupViewport(int width, int height) 
{ 
    /* Prevent divide by zero --------------------------------------------------------------------*/ 
    if (height == 0) height = 1; 
    /* Calculate aspect ratio --------------------------------------------------------------------*/ 
    float aspectRatio = (float)width/(float)height; 

    /* Set viewport to cover the window ----------------------------------------------------------*/ 
    glViewport(0, 0, width, height); 

    /* Set aspect ratio --------------------------------------------------------------------------*/ 
    glMatrixMode(GL_PROJECTION); /* switch to projection matrix */ 
    glLoadIdentity(); 
    /* 
    if (width >= height) 
    { 
    gluOrtho2D(-0.5*aspectRatio, 0.5*aspectRatio, 0.0, 1.0); 
    } 
    else 
    { 
    gluOrtho2D(-0.5, 0.5, 0.0*aspectRatio, 1.0*aspectRatio); 
    } 
    glMatrixMode(GL_MODELVIEW); 
    */ 
    gluOrtho2D(-1, 1, 0.0, 1.0); 
    glMatrixMode(GL_MODELVIEW); 
} 

void TestGlPlot::paintEvent(QPaintEvent *event) { 
    makeCurrent(); 
    setupViewport(width(), height()); 

    glMatrixMode(GL_MODELVIEW); 

    /* Set white background ----------------------------------------------------------------------*/ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glClearColor(255,255,255,0); 

    /* Paint OpenGL events -----------------------------------------------------------------------*/ 
    glColor4f(1.0, 0.0, 0.0, 1.0); 

    /* light grey */ 
    glColor4f(0.0, 0.0, 0.0, 0.3); 
    gluPartialDisk(plainQuad, 0.1, 1, 20, 4, -60, 120); 

    /* Paint QPainter events ---------------------------------------------------------------------*/ 
    QPainter painter(this); 

    /* Draw grey border around plot --------------------------------------------------------------*/ 
    painter.setPen(QColor("#808080")); 
    painter.drawRect(0, 0, width()-1, height()-1); 

    painter.setFont(font); 

    /* Translate coordinate system to (0,0) center -----------------------------------------------*/ 
    QMatrix m; 
    m.translate(width()*0.5, height()*0.5); 
    painter.setMatrix(m); 

    /* Left side descriptions for radius ---------------------------------------------------------*/ 
    painter.drawText(-0.17*width(), 0.38*height(), tr("100m")); 
    painter.drawText(-0.27*width(), 0.28*height(), tr("200m")); 
    painter.drawText(-0.37*width(), 0.18*height(), tr("300m")); 
    painter.drawText(-0.47*width(), 0.08*height(), tr("400m")); 

    painter.drawText(0.45*width(), -0.01*height(), tr("60°")); 
    painter.drawText(0.26*width(), -0.38*height(), tr("30°")); 

    painter.drawText(-0.47*width(), -0.01*height(), tr("300°")); 
    painter.drawText(-0.28*width(), -0.38*height(), tr("330°")); 

    painter.end(); 
} 

我試圖調整大小不同的方法處理(保持partialDisk對象的形狀不拉伸的話),但每個方法失敗。我也想保持單位圓的座標處理(所以我可以對我的測量進行標準化並將它們繪製到極座標圖中)。

回答

1

爲了保持縱橫比,你在一般的幾個選項:

  1. 總是進行縮放以一個維度。例如,您只需定義您總是希望看到水平範圍[-0.5,0.5]。在這種情況下,您必須通過因子(1/aspect_viewport)來更正垂直範圍。
  2. 使用一些等效的letterboxing。所以你定義了一個你總想完全看到的「感興趣的區域」,但是你可能會看到更多的寬度或高度,這取決於窗口方面(當觀看信箱電影時,這基本上等同於黑條)。有兩種情況需要考慮:視區的方面大於您所在區域的方面,因此它更寬。在這種情況下,您應該映射完整高度,並通過(aspect_viewport/aspect_region)因子增加horitonal範圍。否則,窗口的方面比您所在區域的方面要低,所以您應該使用全寬並通過(aspect_region/aspect_viewport)來放大垂直範圍。請注意,在這兩種情況下,該因子> = 1。

在代碼中,你幾乎已經實現的方法2,但你得到了的aspectRatio < 1例錯了,應該是

if (width >= height) 
      gluOrtho2D(-0.5f*aspectRatio, 0.5f*aspectRatio, 0.0f, 1.0f); 
    else 
      gluOrtho2D(-0.5f, 0.5f, 0.0, 1.0/aspectRatio); 
+0

謝謝您的幫助。渲染後的圖像現在不能在調整大小時展開,但無法調整大小。我認爲我必須調整plainQuad for gluPartialDisk(plainQuad,0.1,1,20,4,-60,120)的比率; – omgodie 2013-05-11 16:20:38

+0

此外,如果我只是使用您的建議的改變與劃分aspectRatio分開,呈現的部分磁盤擴展在剪輯(這是邏輯的,因爲外半徑1.0f和剪輯區域在0.5f停止) – omgodie 2013-05-11 16:28:48

+0

我也想提及當我選擇: gluOrtho2D(-1.0f * aspectRatio,1.0f * aspectRatio,1.0f,1.0f);一切工作正常,但圖像較小,我只是想看到我的窗口的頂部,它應該相應地調整大小(頂部我的意思是從-1.0到+1.0 x的所有內容,y從0.0到+ 1.0) – omgodie 2013-05-11 16:48:41