VS2012下基於Glut OpenGL glScissor示例程式:
阿新 • • 發佈:2019-01-22
剪裁測試用於限制繪製區域。我們可以指定一個矩形的剪裁視窗,當啟用剪裁測試後,只有在這個視窗之內的畫素才能被繪製,其它畫素則會被丟棄。換句話說,無論怎麼繪製,剪裁視窗以外的畫素將不會被修改。有的朋友可能玩過《魔獸爭霸3》這款遊戲。遊戲時如果選中一個士兵,則畫面下方的一個方框內就會出現該士兵的頭像。為了保證該頭像無論如何繪製都不會越界而覆蓋到外面的畫素,就可以使用剪裁測試。可以通過下面的程式碼來啟用或禁用剪裁測試:
glEnable(GL_SCISSOR_TEST); // 啟用剪裁測試
glDisable(GL_SCISSOR_TEST); // 禁用剪裁測試
可以通過下面的程式碼來指定一個位置在(x, y),寬度為width,高度為height的剪裁視窗。glScissor(x, y, width, height);注意,glScissor視窗座標是以左下角為(0, 0),右上角為(width, height)的,這與Windows系統視窗有所不同。
Demo使用裁剪區來將矩形視窗正中間四分之一刷成紅色,正中間十六分之一刷成綠色。
原始碼:
// GlutScissorDemo.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <gl/glut.h> #include <math.h> //圓周率巨集 #define GL_PI 3.1415f //獲取螢幕的寬度 GLint SCREEN_WIDTH=0; GLint SCREEN_HEIGHT=0; //設定程式的視窗大小 GLint windowWidth=400; GLint windowHeight=300; //繞x軸旋轉角度 GLfloat xRotAngle=0.0f; //繞y軸旋轉角度 GLfloat yRotAngle=0.0f; //受支援的點大小範圍 GLfloat sizes[2]; //受支援的點大小增量 GLfloat step; //顯示回撥函式 void renderScreen(void){ GLfloat x,y,z,angle; int i; // Clear blue window glClearColor(0.0f, 0.0f, 1.0f, 0.0f); //把整個視窗清理為當前清理顏色:藍色 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //將當前Matrix狀態入棧 glPushMatrix(); //座標系繞x軸旋轉xRotAngle glRotatef(xRotAngle,1.0f,0.0f,0.0f); //座標系繞y軸旋轉yRotAngle glRotatef(yRotAngle,0.0f,1.0f,0.0f); x=0.0f; y=0.0f; z=0.0f; //進行平滑處理 glEnable(GL_POINT_SMOOTH); glHint(GL_POINT_SMOOTH,GL_NICEST); glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH,GL_NICEST); glEnable(GL_POLYGON_SMOOTH); glHint(GL_POLYGON_SMOOTH,GL_NICEST); //繪製座標系 glColor3f(1.0f,1.0f,1.0f); glBegin(GL_LINES); glVertex3f(-80.0f,0.0f,0.0f); glVertex3f(80.0f,0.0f,0.0f); glVertex3f(0.0f,-80.0f,0.0f); glVertex3f(0.0f,80.0f,0.0f); glVertex3f(0.0f,0.0f,-80.0f); glVertex3f(0.0f,0.0f,80.0f); glEnd(); glPushMatrix(); glTranslatef(80.0f,0.0f,0.0f); glRotatef(90.0f,0.0f,1.0f,0.0f); glutWireCone(3,6,10,10); glPopMatrix(); glPushMatrix(); glTranslatef(0.0f,80.0f,0.0f); glRotatef(-90.0f,1.0f,0.0f,0.0f); glutWireCone(3,6,10,10); glPopMatrix(); glPushMatrix(); glTranslatef(0.0f,0.0f,80.0f); glRotatef(90.0f,0.0f,0.0f,1.0f); glutWireCone(3,6,10,10); glPopMatrix(); //使能裁剪區 glEnable(GL_SCISSOR_TEST); //將視窗中間的四分之一面積清空為紅色 glClearColor(1.0f, 0.0f, 0.0f, 0.0f); glScissor(windowWidth/4,windowHeight/4, windowWidth/2,windowHeight/2); glClear(GL_COLOR_BUFFER_BIT); //將視窗中間的十六分之一面積清空為綠色 glClearColor(0.0f, 1.0f, 0.0f, 0.0f); glScissor(windowWidth*3/8,windowHeight*3/8, windowWidth/4,windowHeight/4); glClear(GL_COLOR_BUFFER_BIT); //禁止裁剪區 glDisable(GL_SCISSOR_TEST); //恢復壓入棧的Matrix glPopMatrix(); //交換兩個緩衝區的指標 glutSwapBuffers(); } //設定Redering State void setupRederingState(void){ //設定清理顏色為黑色 glClearColor(0.0f,0.0,0.0,1.0f); //設定繪畫顏色為綠色 glColor3f(0.0f,1.0f,0.0f); //使能深度測試 glEnable(GL_DEPTH_TEST); //獲取受支援的點大小範圍 glGetFloatv(GL_POINT_SIZE_RANGE,sizes); //獲取受支援的點大小增量 glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step); printf("point size range:%f-%f\n",sizes[0],sizes[1]); printf("point step:%f\n",step); } //視窗大小變化回撥函式 void changSize(GLint w,GLint h){ //橫寬比率 GLfloat ratio; //設定座標系為x(-100.0f,100.0f)、y(-100.0f,100.0f)、z(-100.0f,100.0f) GLfloat coordinatesize=100.0f; //視窗寬高為零直接返回 if((w==0)||(h==0)) return; //設定視口和視窗大小一致 glViewport(0,0,w,h); //對投影矩陣應用隨後的矩陣操作 glMatrixMode(GL_PROJECTION); //重置當前指定的矩陣為單位矩陣 glLoadIdentity(); ratio=(GLfloat)w/(GLfloat)h; //正交投影 if(w<h) glOrtho(-coordinatesize,coordinatesize,-coordinatesize/ratio,coordinatesize/ratio,-coordinatesize,coordinatesize); else glOrtho(-coordinatesize*ratio,coordinatesize*ratio,-coordinatesize,coordinatesize,-coordinatesize,coordinatesize); //對模型檢視矩陣堆疊應用隨後的矩陣操作 glMatrixMode(GL_MODELVIEW); //重置當前指定的矩陣為單位矩陣 glLoadIdentity(); } //按鍵輸入處理回撥函式 void specialKey(int key,int x,int y){ if(key==GLUT_KEY_UP){ xRotAngle-=5.0f; } else if(key==GLUT_KEY_DOWN){ xRotAngle+=5.0f; } else if(key==GLUT_KEY_LEFT){ yRotAngle-=5.0f; } else if(key==GLUT_KEY_RIGHT){ yRotAngle+=5.0f; } //重新繪製 glutPostRedisplay(); } int main(int argc, char* argv[]) { int nModeMenu; int nEdgeMenu; int nDepthMask; int nMainMenu; //初始化glut glutInit(&argc,argv); //使用雙緩衝區模式 glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH); //獲取系統的寬畫素 SCREEN_WIDTH=glutGet(GLUT_SCREEN_WIDTH); //獲取系統的高畫素 SCREEN_HEIGHT=glutGet(GLUT_SCREEN_HEIGHT); //建立視窗,視窗名字為OpenGL Scissor Demo glutCreateWindow("OpenGL Scissor Demo"); //設定視窗大小 glutReshapeWindow(windowWidth,windowHeight); //視窗居中顯示 glutPositionWindow((SCREEN_WIDTH-windowWidth)/2,(SCREEN_HEIGHT-windowHeight)/2); //視窗大小變化時的處理函式 glutReshapeFunc(changSize); //設定顯示回撥函式 glutDisplayFunc(renderScreen); //設定按鍵輸入處理回撥函式 glutSpecialFunc(specialKey); //設定全域性渲染引數 setupRederingState(); glutMainLoop(); return 0; }