標籤:opengl 編程指南 第七版 紅寶書 gl_line_stipple
問題1:當我照著源碼敲進去的時候發現,啟動並執行結果不對。哪裡不對?源碼中沒有glPushAttrib(GL_LINE_STIPPLE) glPopAttrib()。所以會出現每次更新點畫線時在下一次繪製時會以最後一次設定的資訊重繪而覆蓋掉之前已繪製好的點線。所以要進行狀態壓棧處理和談棧處理,這樣子在刷幀重繪才不會影響其他幀的繪製結果。(原因是什麼目前我也不清楚,估計是狀態機器的管理問題。要瞭解內部的繪製機制才行。)但是每次手動添加壓棧和彈棧太麻煩了,所以我處理C_style的宏定義形式去實現
問題2:reshape的操作屏蔽掉之後發現只要display中正確設定視窗參數,還是能正常繪製的。。問題來了,reshape不應該是我展開視窗才會觸發的嗎?但是情況如修改仍能正常顯示。百思不得其解,求指教!!
修改1源碼如下:
#include "stdafx.h"#include <GL/freeglut.h>#define drawOneLine(x1,y1,x2,y2) glBegin(GL_LINES);glVertex2f((x1),(y1));glVertex2f((x2),(y2));glEnd();void init(void){glClearColor(0.0,0.0,0.0,0.0);glShadeModel(GL_FLAT);}void display(void){//初初始化定義 視窗,我故意把這段搬出來測試reshape函數的調用,問題2:int w = 400,h =150;glViewport(0,0,static_cast<GLsizei>(w),static_cast<GLsizei>(h));glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,static_cast<GLfloat>(w),0.0,static_cast<GLfloat>(h));glMatrixMode(GL_MODELVIEW);glLoadIdentity();//int i;glClear(GL_COLOR_BUFFER_BIT);glPushMatrix();glColor3f(1.0,1.0,1.0);glEnable(GL_LINE_STIPPLE);//1st rowglPushAttrib(GL_LINE_STIPPLE);//以二進位讀取,從低位開始繪製,第一個參數為展開參數glLineStipple(1,0x0101);drawOneLine(50.0,125.0,150,125.0);glPopAttrib();glPushAttrib(GL_LINE_STIPPLE);glLineStipple(1,0x00FF);drawOneLine(150.0,125.0,250.0,125.0);glPopAttrib();glPushAttrib(GL_LINE_STIPPLE);glLineStipple(1,0x1c47);drawOneLine(250.0,125.0,350.0,125.0);glPopAttrib();//2nd rowglLineWidth(5.0);glPushAttrib(GL_LINE_STIPPLE);//以二進位讀取,從低位開始繪製,第一個參數為展開參數glLineStipple(1,0x0101);drawOneLine(50.0,100.0,150.0,100.0);glPopAttrib();glPushAttrib(GL_LINE_STIPPLE);glLineStipple(1,0x00ff);drawOneLine(150.0,100.0,250.0,100.0);glPopAttrib();glPushAttrib(GL_LINE_STIPPLE);glLineStipple(1,0x1c47);drawOneLine(250.0,100.0,350.0,100.0);glPopAttrib();glLineWidth(1.0);//3rd rowglPushAttrib(GL_LINE_STIPPLE);glLineStipple(1,0x1c47);glBegin(GL_LINE_STRIP);for (int i = 0; i < 7; i++){glVertex2f(50.0+static_cast<GLfloat>(i*50.0),75.0);}glEnd();glPopAttrib();glDisable(GL_LINE_STIPPLE);glPopMatrix();glFlush();}void reshape(int w,int h){}int _tmain(int argc, char * argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,150);glutInitWindowPosition(0,0);glutCreateWindow(argv[0]);init();glutDisplayFunc(display);glutReshapeFunc(NULL);glutMainLoop();return 0;}
正確源碼示範:
// Lines_P35.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <GL/freeglut.h>#define drawOneLine(scale,stipple,x1,y1,x2,y2) glPushAttrib(GL_LINE_STIPPLE);glLineStipple(scale,stipple);glBegin(GL_LINES);glVertex2f((x1),(y1));glVertex2f((x2),(y2));glEnd();glPopAttrib();void init(void){glClearColor(0.0,0.0,0.0,0.0);glShadeModel(GL_FLAT);}void display(void){glClear(GL_COLOR_BUFFER_BIT);glPushMatrix();glColor3f(1.0,1.0,1.0);glEnable(GL_LINE_STIPPLE);//1st row//以二進位讀取,從低位開始繪製,第一個參數為展開參數drawOneLine(1,0x0101,50.0,125.0,150,125.0);drawOneLine(1,0x00FF,150.0,125.0,250.0,125.0);drawOneLine(1,0x1c47,250.0,125.0,350.0,125.0);//2nd rowglLineWidth(5.0);//以二進位讀取,從低位開始繪製,第一個參數為展開參數drawOneLine(1,0x0101,50.0,100.0,150.0,100.0);drawOneLine(1,0x00ff,150.0,100.0,250.0,100.0);drawOneLine(1,0x1c47,250.0,100.0,350.0,100.0);glLineWidth(1.0);//3rd rowglPushAttrib(GL_LINE_STIPPLE);glLineStipple(1,0x1c47);glBegin(GL_LINE_STRIP);for (int i = 0; i < 7; i++){glVertex2f(50.0+static_cast<GLfloat>(i*50.0),75.0);}glEnd();glPopAttrib();//4thfor (int i = 0; i < 6; i++){drawOneLine(1,0x1c47,50.0+static_cast<GLfloat>(i*50.0),50.0,50.0+static_cast<GLfloat>(i+1)*50.0,50.0);}//5thdrawOneLine(5,0x1c47,50.0,25.0,350.0,25.0);glDisable(GL_LINE_STIPPLE);glPopMatrix();glFlush();}void reshape(int w,int h){glViewport(0,0,static_cast<GLsizei>(w),static_cast<GLsizei>(h));glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,static_cast<GLfloat>(w),0.0,static_cast<GLfloat>(h));glMatrixMode(GL_MODELVIEW);glLoadIdentity();}int _tmain(int argc, char * argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,150);glutInitWindowPosition(0,0);glutCreateWindow(argv[0]);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoop();return 0;}
opengl編程指南 第七版 源碼有bug Page35 lines.c 紅寶書