OpenGL編程 基礎篇(五)世界窗口和視口


一、基本定義

世界窗口:在世界坐標系中定義一個對齊的矩形(aligned rectangle,即矩陣的邊與坐標軸平行)的窗口,這個世界窗口外的部分被裁減並不被繪制。OpenGL會自動地做剪裁。

視口:在顯示器的屏幕窗口上定義一個對齊的矩形的視口,OpenGL會自動建立世界窗口和視口的變換(包括縮放和平移)。當世界窗口中所有對象都被繪制時,對象在世界窗

口中的部分會被自動地映射到視口中————換句話說,被映射到屏幕坐標中,即像素在顯示器上的坐標。

二、相關函數介紹

1.對於二維繪圖來說,世界窗口由函數gluOrtho2D()設定,它的原型是:
    void gluOrtho2D(GLDouble left,GLdouble right,GLdouble buttom,GLdouble top);
   對於三維的情況,有另外兩個參數需要設定,后續講述。

2.視口的設定通過glViewport()函數,它的原型是:
    void glViewport(GLint x,GLint y,GLint width,GLint ehignt);//它設置窗口的左下角,以及寬度和高度。
    注意:因為openGL通過矩陣來完成所有的變換,因此GluOrtho2D()的調用必須在glMatrixModel(GL_PROJECTION)和glLoadIdentity()這兩個函數之后。

3.將設定窗口的部分放到setWindow()函數中,增加程序的可讀性:

void setWindow(GLdouble left,GLdouble right,GLdouble buttom,GLdouble top)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(left,right,bottom,top); //eg: gluOrtho2D(0.0,640.0,0.0,480.0);
}
//為了讓setViewport()更容易使用,我們將其參數作了輕微的調整使得它和setWindow()相匹配;
//它們都是按左、右、下、上的順序做參數
void setViewport(GLint left,GLint right,GLint bottom,GLint top)
{
//right-left 等於寬度,top-bottom 等於高度
glViewport(left,bottom,right-left,top-bottom);
}

三、應用樣例——平鋪

setWindow(0,640.0,0,440.0);
for(int i = 0;i < 5;i++)
{
  for(int j = 0;j < 5;j++)
  {
    glViewport(i * 64,j * 44,64,44);
    drawPolylineFile("dino.dat");    //dino.dat為存儲繪圖數據的文件,drawPolylineFile為畫該文件數據的函數
  }
}

四、程序示例

從文件中讀取數據繪制小房子,更改setWindow和setViewport的參數改變房子的大小

dot.dat

5
5
0
0 0
0 20
10 25
20 20
20 0
4
1
11 0
11 12
16 12
16 0
4 
1
20 0
30 0
30 10
20 10
4
1
24 0
24 5
27 5
27 0
2 
1
30 10
20 16

程序

#include "stdafx.h"
#include <gl\glut.h>
#include <fstream>
using namespace std;
const int screenWidth = 640;
const int screenHeight = 480;
void myInit(){
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glColor3f(0.0f, 0.0f, 0.0f);
    glPointSize(2.0);
    //glMatrixMode(GL_PROJECTION);
    //glLoadIdentity();
    //gluOrtho2D(0.0, (GLdouble)screenWidth, 0.0, (GLdouble)screenHeight);
}
void setWindow(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(left, right, bottom, top); //eg:  gluOrtho2D(0.0,640.0,0.0,480.0);
}
void setViewport(GLint left, GLint right, GLint bottom, GLint top)
{
    //right-left 等於寬度,top-bottom 等於高度
    glViewport(left, bottom, right - left, top - bottom);
}
void myDisplay(){
    fstream inStream;
    char filename[] = "dot.dat";
    inStream.open(filename, ios::in);
    if (inStream.fail()){ printf("Fail!!!!!\n"); return; }
    glClear(GL_COLOR_BUFFER_BIT);
    GLint numpolys, numLines, way, x, y;
    inStream >> numpolys;
    for (int j = 0; j < numpolys; j++)
    {
        inStream >> numLines;
        inStream >> way;
        if (way == 0){
            glBegin(GL_LINE_LOOP);
            for (int i = 0; i < numLines; i++)
            {
                inStream >> x >> y;
                glVertex2i(x, y);
            }
            glEnd();
        }
        else{
            glBegin(GL_LINE_STRIP);
            for (int i = 0; i < numLines; i++)
            {
                inStream >> x >> y;
                glVertex2i(x, y);
            }
            glEnd();
        }
        
    }
    glFlush();
    inStream.close();
}
int main(int argc, char **argv){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(screenWidth, screenHeight);
    glutInitWindowPosition(100, 150);
    glutCreateWindow("Dot Plot of a Function");
    setWindow(0.0, 40.0, 0.0, 40.0);
    setViewport(0.0, 40.0, 0.0, 40.0);
    glutDisplayFunc(myDisplay);
    myInit();
    
    glutMainLoop();
}
View Code

運行效果:

setWindow(0.0, 40.0, 0.0, 40.0);
setViewport(0.0, 40.0, 0.0, 40.0);

 

 

setWindow(0.0, 400.0, 0.0, 240.0);
setViewport(0.0, 400.0, 0.0, 240.0);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM