OpenGL的glScissor示例程序
剪裁測(cè)試用于限制繪制區(qū)域。我們可以指定一個(gè)矩形的剪裁窗口,當(dāng)啟用剪裁測(cè)試后,只有在這個(gè)窗口之內(nèi)的像素才能被繪制,其它像素則會(huì)被丟棄。換句話說(shuō),無(wú)論怎么繪制,剪裁窗口以外的像素將不會(huì)被修改。有的朋友可能玩過(guò)《魔獸爭(zhēng)霸3》這款游戲。游戲時(shí)如果選中一個(gè)士兵,則畫面下方的一個(gè)方框內(nèi)就會(huì)出現(xiàn)該士兵的頭像。為了保證該頭像無(wú)論如何繪制都不會(huì)越界而覆蓋到外面的像素,就可以使用剪裁測(cè)試。可以通過(guò)下面的代碼來(lái)啟用或禁用剪裁測(cè)試:
[cpp]?view plaincopy可以通過(guò)下面的代碼來(lái)指定一個(gè)位置在(x, y),寬度為width,高度為height的剪裁窗口。glScissor(x, y, width, height);注意,glScissor窗口坐標(biāo)是以左下角為(0, 0),右上角為(width, height)的,這與Windows系統(tǒng)窗口有所不同。
Demo使用裁剪區(qū)來(lái)將矩形窗口正中間四分之一刷成紅色,正中間十六分之一刷成綠色。
// GlutScissorDemo.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//#include "stdafx.h"
#include <gl/glut.h>
#include <math.h>
//圓周率宏
#define GL_PI 3.1415f
//獲取屏幕的寬度
GLint SCREEN_WIDTH=0;
GLint SCREEN_HEIGHT=0;
//設(shè)置程序的窗口大小
GLint windowWidth=400;
GLint windowHeight=300;
//繞x軸旋轉(zhuǎn)角度
GLfloat xRotAngle=0.0f;
//繞y軸旋轉(zhuǎn)角度
GLfloat yRotAngle=0.0f;
//受支持的點(diǎn)大小范圍
GLfloat sizes[2];
//受支持的點(diǎn)大小增量
GLfloat step;
//顯示回調(diào)函數(shù)
void renderScreen(void){
? ? GLfloat x,y,z,angle;
int i;
// Clear blue window
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
? ? //把整個(gè)窗口清理為當(dāng)前清理顏色:藍(lán)色
? ? glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
? ? //將當(dāng)前Matrix狀態(tài)入棧
? ? glPushMatrix();
? ? //坐標(biāo)系繞x軸旋轉(zhuǎn)xRotAngle
? ? glRotatef(xRotAngle,1.0f,0.0f,0.0f);
? ? //坐標(biāo)系繞y軸旋轉(zhuǎn)yRotAngle
? ? glRotatef(yRotAngle,0.0f,1.0f,0.0f);
x=0.0f;
y=0.0f;
? ? z=0.0f;
//進(jìn)行平滑處理
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);
//繪制坐標(biāo)系
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();
? ? //使能裁剪區(qū)
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);
? ??
? ? //禁止裁剪區(qū)
? ? glDisable(GL_SCISSOR_TEST);
? ? //恢復(fù)壓入棧的Matrix
? ? glPopMatrix();
? ? //交換兩個(gè)緩沖區(qū)的指針
? ? glutSwapBuffers();
}
//設(shè)置Redering State?
void setupRederingState(void){
? ? //設(shè)置清理顏色為黑色
? ? glClearColor(0.0f,0.0,0.0,1.0f);
? ? //設(shè)置繪畫顏色為綠色
? ? glColor3f(0.0f,1.0f,0.0f);
//使能深度測(cè)試
glEnable(GL_DEPTH_TEST);
//獲取受支持的點(diǎn)大小范圍
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
//獲取受支持的點(diǎn)大小增量
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);
printf("point size range:%f-%f\n",sizes[0],sizes[1]);
printf("point step:%f\n",step);
}
//窗口大小變化回調(diào)函數(shù)
void changSize(GLint w,GLint h){
? ? //橫寬比率
? ? GLfloat ratio;
? ? //設(shè)置坐標(biāo)系為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;
? ? //設(shè)置視口和窗口大小一致
? ? glViewport(0,0,w,h);
? ? //對(duì)投影矩陣應(yīng)用隨后的矩陣操作
? ? glMatrixMode(GL_PROJECTION);
? ? //重置當(dāng)前指定的矩陣為單位矩陣
? ? 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);
? ? //對(duì)模型視圖矩陣堆棧應(yīng)用隨后的矩陣操作
? ? glMatrixMode(GL_MODELVIEW);
? ? //重置當(dāng)前指定的矩陣為單位矩陣
? ? glLoadIdentity();
}
//按鍵輸入處理回調(diào)函數(shù)
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);
? ? //使用雙緩沖區(qū)模式
? ? glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
? ? //獲取系統(tǒng)的寬像素
? ? SCREEN_WIDTH=glutGet(GLUT_SCREEN_WIDTH);
? ? //獲取系統(tǒng)的高像素
? ? SCREEN_HEIGHT=glutGet(GLUT_SCREEN_HEIGHT);
//創(chuàng)建窗口,窗口名字為OpenGL Scissor Demo
? ? glutCreateWindow("OpenGL Scissor Demo");
? ? //設(shè)置窗口大小
? ? glutReshapeWindow(windowWidth,windowHeight);
? ? //窗口居中顯示
? ? glutPositionWindow((SCREEN_WIDTH-windowWidth)/2,(SCREEN_HEIGHT-windowHeight)/2);
? ? //窗口大小變化時(shí)的處理函數(shù)
? ? glutReshapeFunc(changSize);
? ? //設(shè)置顯示回調(diào)函數(shù)?
? ? glutDisplayFunc(renderScreen);
? ? //設(shè)置按鍵輸入處理回調(diào)函數(shù)
? ? glutSpecialFunc(specialKey);
? ? //設(shè)置全局渲染參數(shù)
? ? setupRederingState();
? ? glutMainLoop();
? ? return 0;
}
總結(jié)
以上是生活随笔為你收集整理的OpenGL的glScissor示例程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: OPenGL模板缓冲区示例程序
- 下一篇: 编程修养(二)