glViewPort() glOrtho()用法(學習) - 台部落

文章推薦指數: 80 %
投票人數:10人

glOrtho是創建一個正交平行的視景體。

一般用於物體不會因爲離屏幕的遠近而產生大小的變換的情況。

比如,常用的工程中的製圖等。

需要 ... 請輸入正確的登錄賬號或密碼 註冊 忘記密碼 首頁 OpenGL 正文 glViewPort()glOrtho()用法(學習) 原創 heshiyou_2009 2018-08-2510:45 好長時間沒動過OpenGL了,現在忽然醒悟,又從前面開始,一點一點重新開始理解複習。

     昨天看到gluOtho2d及glViewport,突然明白了兩個函數的作用      一、gluOtho2d()         這個函數是定義剪裁面,何謂剪裁面,我這樣理解,我們是在一個無限的空間裏繪圖,因爲座標是可以隨便指定的,隨便在哪個座標繪圖,但是我們可以通過定一個剪裁面,也就是說,有一架照相機,儘管沿途風景很多,但是鏡頭只能拍到一定的範圍,這個範圍就是我們的剪裁面,我們能顯示的就是這個剪裁面。

     二、glViewPort()         這個函數跟上面的相似,但是我們發現上面的指定一個剪裁面後,是在我們定義的窗口的整個窗口中顯示我們剪裁出來的面,而這個函數就是爲了在一部分中顯我們要顯示的剪裁面,即,我們先取景(就是用gluOrtho2D()剪出來那個),然後在我們定義的窗口中選一個區域來顯示這個取好的景。

     下面是一個例子:    #include //不顯示控制檯窗口#pragmacomment(linker,"/subsystem:/"windows/"/entry:/"mainCRTStartup/"") voiddisplay(){//glMatrixMode(GL_MODELVIEW);//glLoadIdentity();     glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,0.0,0.0);//畫分割線,分成四個視見區glViewport(0,0,400,400);glBegin(GL_LINES);     glVertex2f(-1.0,0);   glVertex2f(1.0,0);   glVertex2f(0.0,-1.0);   glVertex2f(0.0,1.0);    glEnd(); //定義在左下角的區域glColor3f(0.0,1.0,0.0);glViewport(0,0,200,200);glBegin(GL_POLYGON);   glVertex2f(-0.5,-0.5);     glVertex2f(-0.5,0.5);   glVertex2f(0.5,0.5);   glVertex2f(0.5,-0.5);glEnd(); //定義在右上角的區域glColor3f(0.0,0.0,1.0);glViewport(200,200,200,200);//一定要注意,後面這兩個參數是高度和寬度,而不是座標    glBegin(GL_POLYGON);     glVertex2f(-0.5,-0.5);     glVertex2f(-0.5,0.5);     glVertex2f(0.5,0.5);     glVertex2f(0.5,-0.5);glEnd(); //定義在左上角的區域glColor3f(1.0,0.0,1.0);glViewport(0,200,200,200);//一定要注意,後面這兩個參數是高度和寬度,而不是座標glBegin(GL_POLYGON);glVertex2f(-0.5,-0.5);glVertex2f(-0.5,0.5);glVertex2f(0.5,0.5);glVertex2f(0.5,-0.5);glEnd(); //定義在右下角glColor3f(1.0,1.0,0.0);glViewport(200,0,200,200);//一定要注意,後面這兩個參數是高度和寬度,而不是座標glBegin(GL_POLYGON);glVertex2f(-0.5,-0.5);glVertex2f(-0.5,0.5);glVertex2f(0.5,0.5);glVertex2f(0.5,-0.5);glEnd(); glFlush();} voidinit(){    glClearColor(0.0,0.0,0.0,0.0);glColor3f(1.0,1.0,1.0); glMatrixMode(GL_PROJECTION);glLoadIdentity();//定義剪裁面gluOrtho2D(-1.0,1.0,-1.0,1.0); //glViewport(0,0,200,200);//放在這裏不好使} intmain(intargc,char**argv){     glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowPosition(100,100);glutInitWindowSize(400,400);glutCreateWindow("glViewport()");glutDisplayFunc(display);     init();glutMainLoop();} 來源:http://blog.sina.com.cn/s/blog_5f539ad70100e8ml.html     在OpenGL中有兩個比較重要的投影變換函數,glViewport和glOrtho。

glOrtho是創建一個正交平行的視景體。

一般用於物體不會因爲離屏幕的遠近而產生大小的變換的情況。

比如,常用的工程中的製圖等。

需要比較精確的顯示。

而作爲它的對立情況,glFrustum則產生一個透視投影。

這是一種模擬真是生活中,人們視野觀測物體的真實情況。

例如:觀察兩條平行的火車到,在過了很遠之後,這兩條鐵軌是會相交於一處的。

還有,離眼睛近的物體看起來大一些,遠的物體看起來小一些。

glOrtho(left,right,bottom,top,near,far),left表示視景體左面的座標,right表示右面的座標,bottom表示下面的,top表示上面的。

這個函數簡單理解起來,就是一個物體擺在那裏,你怎麼去截取他。

這裏,我們先拋開glViewport函數不看。

先單獨理解glOrtho的功能。

假設有一個球體,半徑爲1,圓心在(0,0,0),那麼,我們設定glOrtho(-1.5,1.5,-1.5,1.5,-10,10);就表示用一個寬高都是3的框框把這個球體整個都裝了進來。

 如果設定glOrtho(0.0,1.5,-1.5,1.5,-10,10);就表示用一個寬是1.5,高是3的框框把整個球體的右面裝進來;如果設定glOrtho(0.0,1.5,0.0,1.5,-10,10);就表示用一個寬和高都是1.5的框框把球體的右上角裝了進來。

上述三種情況可以見圖:       從上述三種情況,我們可以大致瞭解glOrtho函數的用法。

glOrtho函數只是負責使用什麼樣的視景體來截取圖像,並不負責使用某種規則把圖像呈現在屏幕上。

glViewport主要完成這樣的功能。

它負責把視景體截取的圖像按照怎樣的高和寬顯示到屏幕上。

比如:如果我們使用glut庫建立一個窗體:glutInitWindowSize(500,500);然後使用glutReshapeFunc(reshape);reshape代碼如下: voidreshape(intwidth,intheight) {    glViewport(0,0,(GLsizei)width,(GLsizei)height);    glMatrixModel(GL_PROJECTION);    glLoadIdentity();    glOrtho(-1.5,1.5,-1.5,1.5,-10,10);    .... } 這樣是可以看到一個正常的球體的。

但是,如果我們創建窗體時glutInitWindowSize(800,500),那麼看到的圖像就是變形的。

上述情況見圖。

    因爲我們是用一個正方形截面的視景體截取的圖像,但是拉伸到屏幕上顯示的時候,就變成了glViewport(0,0,800,500);也就是顯示屏變寬了,倒是顯示的時候把一個正方形的圖像“活生生的給拉寬了”。

就會產生變形。

這樣,就需要我們調整我們的OpenGL顯示屏了。

我們可以不用800那麼寬,因爲我們是用的正方形的視景體,所以雖然窗體是800寬,但是我們只用其中的500就夠了。

修改一下程序。

voidreshape(intwidth,intheight) {    intdis=width #include #include voidinit(void) {    GLfloatmat_specular[]={1.0,1.0,1.0,1.0};    GLfloatmat_shininess[]={50.0};    GLfloatlight_position[]={1.0,1.0f,1.0,0.0};    GLfloatwhite_light[]={1.0,1.0,1.0,1.0};    GLfloatlmodel_ambient[]={0.1,0.1,0.1,1.0};    glClearColor(0.0,0.0,0.0,0.0);    glShadeModel(GL_SMOOTH);    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);    glLightfv(GL_LIGHT0,GL_POSITION,light_position);    glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light);    glLightfv(GL_LIGHT0,GL_SPECULAR,white_light);    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);    glEnable(GL_LIGHTING);    glEnable(GL_LIGHT0);    glEnable(GL_DEPTH_TEST);   } voiddisplay(void) {    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);    glutSolidSphere(1.0,20,16);    glFlush(); } voidreshape(intw,inth) {    glViewport(0,0,(GLsizei)w,(GLsizei)h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    if(w<=h)        glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);    else        glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity(); } intmain(intargc,char**argv) {    glutInit(&argc,argv);    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);    glutInitWindowSize(500,500);    glutInitWindowPosition(100,100);    glutCreateWindow(argv[0]);    init();    glutDisplayFunc(display);    glutReshapeFunc(reshape);    glutMainLoop();    return0; } /*CMakeLists.txt*/ PROJECT(s5) CMAKE_MINIMUM_REQUIRED(VERSION2.6) ADD_EXECUTABLE(s5main.cpp) FIND_PACKAGE(OpenGL) FIND_PACKAGE(GLUT) IF(OPENGL_FOUND)  INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})  TARGET_LINK_LIBRARIES(${PROJECT_NAME}${OPENGL_LIBRARIES}) ELSE(OPENGL_FOUND)  MESSAGE(FATAL_ERROR"OpenGLnotfound") ENDIF(OPENGL_FOUND) IF(GLUT_FOUND)  INCLUDE_DIRECTORIES(${GLUT_INCLUDE_DIR})  TARGET_LINK_LIBRARIES(${PROJECT_NAME}${GLUT_LIBRARIES}) ELSE(GLUT_FOUND) ENDIF(GLUT_FOUND) 參考:OpenGL編程指南(原書第6版) 來源:http://xustgao.blog.163.com/blog/static/1406027932010212468231/       發表評論 登录 所有評論 還沒有人評論,想成為第一個評論的人麼?請在上方評論欄輸入並且點擊發布. 相關文章 OpenGL圖形管線和座標變換 guchongshimao2 2018-08-2718:06:13 TimeShift3d引擎.1.0版本(附帶引擎Demo)(放出.) Spiritring 2018-08-2718:01:04 在VS2010裏MFC對話框中使用OpenGL繪圖,添加的控件不顯示的一種解決方法 main_3k10 2018-08-2718:00:45 用CMake創建OpenGLES的測試工程 sinat_15734507 2018-08-2715:36:06 利用OpenGL模板緩衝,從正方形中摳出一個圓形邊框 sinat_15734507 2018-08-2715:36:06 在Ubuntu上安裝和鏈接GLES的庫 sinat_15734507 2018-08-2715:36:05 OpenGL模版測試 黑旋风包子 2018-08-2714:38:53 gluLookAt和變換 黑旋风包子 2018-08-2714:38:53 區分glFrustum和gluPerspective 黑旋风包子 2018-08-2714:38:53 QOpenGLWidget類講解 苦茶Fighting 2018-08-2714:26:59 QT5.11.1+OpenGL第一篇(OpenGL在Qt中幾個版本) 苦茶Fighting 2018-08-2714:26:59 OpenGL中的glLoadIdentity、glTranslatef、glRotatef原理【轉帖】 loop_k 2018-08-2714:20:37 GLEW+GLFW配置OpenGL開發環境 TwinkleStar0121 2018-08-2713:44:23 今天OpenGL問題 YellowBug 2018-08-2713:39:29 在Lua腳本中使用OpenGL函數 YellowBug 2018-08-2713:39:28 H heshiyou_2009 24小時熱門文章 最新文章 glViewPort()glOrtho()用法(學習) 搭建OpenGL在Eclipse底下的開發環境 最新評論文章 加賴043821爆乳小淫女:165.G.22.47kg想嘗試不同的大屌外貌協會沒有抽菸苗條大奶皮膚 大台灣橘子小妖精加賴:kk2384學生處女奶水爆乳無套肛交約妹看片www.fb742.com [2022]TopRatedCheckPoint156-315.80ExamQuestions QualifiedWritingServiceinAustraliacanallowstudentstoachievebettergrades



請為這篇文章評分?