OpenGL: 模板緩衝區

相信大家有些人對OpenGL的模板緩衝區不是很理解,包括我最開始也是,OpenGL的模板緩衝區其實就是採用過濾的技術來控制那些顏色可以繪製,那些不能進行繪製。這裏的過濾技術也就是我們的一個控制方法,主要體現在如下兩個函數glStencilFunc(GLenum func,GLint ref,GLuint mask)和glStencilOp(GLenum fail,GLenum zfail, GLenum zpass),其中

1.glStencilFunc中的第一個參數指的是過濾函數,(如何來進行過濾),過濾函數有如下幾種類型

   GL_NEVER 從來不能通過

   GL_ALWAYS 永遠可以通過(默認值)

   GL_LESS 小於參考值可以通過

   GL_LEQUAL 小於或者等於可以通過

   GL_EQUAL 等於通過

   GL_GEQUAL 大於等於通過

   GL_GREATER 大於通過

   GL_NOTEQUAL 不等於通過

        在這裏“通過”的意思指的是,我們在將圖元繪製到幀緩衝區的時候在片段進行測試的時候是可以完全透過去的,否則的話這個片段就無法繪製到對應的顏色幀緩衝區,那麼我們所繪製的內容也就顯示不出來。通過這種控制方法來控制顯示,其實這種操作在我們實際的生活中也是很常見的,例如給汽車噴漆,蓋章(只會顯示刻了的內容)。

2.通過模板操作glStencil()來控制模板結果值的操作,例如,如果失敗了對模板值進行加1,減1等處理。等待下一次片段處理的時候再進行新的比較,對值的過濾做新的控制。

3.在這裏我想通過這樣一個例子來說明一下:

  1. #include <math.h>  
  2. #include <iostream>  
  3. #include <assert.h>  
  4.   
  5. #include <GL/glut.h>  
  6. #pragma comment(lib, "glut32.lib")  
  7. // #include <GL/glew.h>  
  8. // #pragma comment(lib, "glew32.lib")  
  9.   
  10. void init()  
  11. {  
  12.     glClearColor(0.0, 0.0, 1.0, 0.0);  
  13.     glClearStencil(0);  
  14.     glEnable(GL_STENCIL_TEST);  
  15. }  
  16.   
  17. void display()  
  18. {  
  19.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);  
  20.   
  21.     glLoadIdentity();  
  22.     glTranslatef(0.0, 0.0, -20.0);  
  23.   
  24.     glStencilFunc(GL_ALWAYS, 0, 0x00);  
  25.     //glStencilFunc(GL_NEVER, 0x0, 0x0);  
  26.     //glStencilOp(GL_INCR, GL_INCR, GL_INCR);//  
  27.   
  28.     glColor3f(1.0f, 1.0f, 1.0f);  
  29.   
  30.     float dRadius = 5.0 * (sqrt(2.0) / 2.0);  
  31.     glBegin(GL_LINE_STRIP);  
  32.     for (float dAngel = 0; dAngel < 380.0; dAngel += 0.1)  
  33.     {  
  34.         glVertex2d(dRadius * cos(dAngel), dRadius * sin(dAngel));  
  35.         dRadius *= 1.003;  
  36.     }  
  37.     glEnd();  
  38.   
  39.     //glStencilFunc(GL_NOTEQUAL,0x1,0x1);  
  40.     //glStencilOp(GL_INCR,GL_INCR,GL_INCR);//  
  41.   
  42.     glColor3f(1.0f, 0.0f, 0.0f);  
  43.     glRectf(-5, -5, 5, 5);  
  44.   
  45.     glutSwapBuffers();  
  46. }  
  47.   
  48. void reshape(int w, int h)  
  49. {  
  50.     glViewport(0, 0, w, h);  
  51.     float aspect = (w * 1.0) / h;  
  52.   
  53.     glMatrixMode(GL_PROJECTION);  
  54.     glLoadIdentity();  
  55.     gluPerspective(60, aspect, 1, 100);  
  56.   
  57.     glMatrixMode(GL_MODELVIEW);  
  58.     glLoadIdentity();  
  59. }  
  60.   
  61. int main(int argc, char* argv[])  
  62. {  
  63.     glutInit(&argc, argv);  
  64.     glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_STENCIL);  
  65.     glutInitWindowPosition(200,200);  
  66.     glutInitWindowSize(600,600);  
  67.     glutCreateWindow(argv[0]);  
  68.   
  69. //  assert(GLEW_NO_ERROR == glewInit());  
  70.   
  71.     init();  
  72.     glutReshapeFunc(reshape);  
  73.     glutDisplayFunc(display);  
  74.     glutMainLoop();  
  75.   
  76.     return 0;  
  77. }  
#include <math.h>
#include <iostream>
#include <assert.h>

#include <GL/glut.h>
#pragma comment(lib, "glut32.lib")
// #include <GL/glew.h>
// #pragma comment(lib, "glew32.lib")

void init()
{
	glClearColor(0.0, 0.0, 1.0, 0.0);
	glClearStencil(0);
	glEnable(GL_STENCIL_TEST);
}

void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	glLoadIdentity();
	glTranslatef(0.0, 0.0, -20.0);

	glStencilFunc(GL_ALWAYS, 0, 0x00);
	//glStencilFunc(GL_NEVER, 0x0, 0x0);
	//glStencilOp(GL_INCR, GL_INCR, GL_INCR);//

	glColor3f(1.0f, 1.0f, 1.0f);

	float dRadius = 5.0 * (sqrt(2.0) / 2.0);
	glBegin(GL_LINE_STRIP);
	for (float dAngel = 0; dAngel < 380.0; dAngel += 0.1)
	{
		glVertex2d(dRadius * cos(dAngel), dRadius * sin(dAngel));
		dRadius *= 1.003;
	}
	glEnd();

	//glStencilFunc(GL_NOTEQUAL,0x1,0x1);
	//glStencilOp(GL_INCR,GL_INCR,GL_INCR);//

	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(-5, -5, 5, 5);

	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	float aspect = (w * 1.0) / h;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60, aspect, 1, 100);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_STENCIL);
	glutInitWindowPosition(200,200);
	glutInitWindowSize(600,600);
	glutCreateWindow(argv[0]);

// 	assert(GLEW_NO_ERROR == glewInit());

	init();
	glutReshapeFunc(reshape);
	glutDisplayFunc(display);
	glutMainLoop();

	return 0;
}

加入模板控制之後的結果:

  1. #include <math.h>  
  2. #include <iostream>  
  3. #include <assert.h>  
  4.   
  5. #include <GL/glut.h>  
  6. #pragma comment(lib, "glut32.lib")  
  7. // #include <GL/glew.h>  
  8. // #pragma comment(lib, "glew32.lib")  
  9.   
  10. void init()  
  11. {  
  12.     glClearColor(0.0, 0.0, 1.0, 0.0);  
  13.     glClearStencil(0);  
  14.     glEnable(GL_STENCIL_TEST);  
  15. }  
  16.   
  17. void display()  
  18. {  
  19.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);  
  20.   
  21.     glLoadIdentity();  
  22.     glTranslatef(0.0, 0.0, -20.0);  
  23.   
  24.     //glStencilFunc(GL_ALWAYS, 0, 0x00);  
  25.     glStencilFunc(GL_NEVER, 0x0, 0x0);  
  26.     glStencilOp(GL_INCR, GL_INCR,GL_INCR);//  
  27.   
  28.     glColor3f(1.0f, 1.0f, 1.0f);  
  29.   
  30.     float dRadius = 5.0 * (sqrt(2.0) / 2.0);  
  31.     glBegin(GL_LINE_STRIP);  
  32.     for (float dAngel = 0; dAngel < 380.0; dAngel += 0.1)  
  33.     {  
  34.         glVertex2d(dRadius * cos(dAngel), dRadius * sin(dAngel));  
  35.         dRadius *= 1.003;  
  36.     }  
  37.     glEnd();  
  38.   
  39.     glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);  
  40.     glStencilOp(GL_INCR, GL_INCR, GL_INCR);//  
  41.   
  42.     glColor3f(1.0f, 0.0f, 0.0f);  
  43.     glRectf(-5.0, -5.0, 5.0, 5.0);  
  44.   
  45.     glutSwapBuffers();  
  46. }  
  47.   
  48. void reshape(int w, int h)  
  49. {  
  50.     glViewport(0, 0, w, h);  
  51.     float aspect = (w * 1.0) / h;  
  52.   
  53.     glMatrixMode(GL_PROJECTION);  
  54.     glLoadIdentity();  
  55.     gluPerspective(60.0, aspect, 1.0, 100.0);  
  56.   
  57.     glMatrixMode(GL_MODELVIEW);  
  58.     glLoadIdentity();  
  59. }  
  60.   
  61. int main(int argc, char* argv[])  
  62. {  
  63.     glutInit(&argc, argv);  
  64.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_STENCIL);  
  65.     glutInitWindowPosition(200, 200);  
  66.     glutInitWindowSize(600, 600);  
  67.     glutCreateWindow(argv[0]);  
  68.   
  69. //  assert(GLEW_NO_ERROR == glewInit());  
  70.   
  71.     init();  
  72.     glutReshapeFunc(reshape);  
  73.     glutDisplayFunc(display);  
  74.     glutMainLoop();  
  75.   
  76.     return 0;  
  77. }  
#include <math.h>
#include <iostream>
#include <assert.h>

#include <GL/glut.h>
#pragma comment(lib, "glut32.lib")
// #include <GL/glew.h>
// #pragma comment(lib, "glew32.lib")

void init()
{
	glClearColor(0.0, 0.0, 1.0, 0.0);
	glClearStencil(0);
	glEnable(GL_STENCIL_TEST);
}

void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	glLoadIdentity();
	glTranslatef(0.0, 0.0, -20.0);

	//glStencilFunc(GL_ALWAYS, 0, 0x00);
	glStencilFunc(GL_NEVER, 0x0, 0x0);
	glStencilOp(GL_INCR, GL_INCR,GL_INCR);//

	glColor3f(1.0f, 1.0f, 1.0f);

	float dRadius = 5.0 * (sqrt(2.0) / 2.0);
	glBegin(GL_LINE_STRIP);
	for (float dAngel = 0; dAngel < 380.0; dAngel += 0.1)
	{
		glVertex2d(dRadius * cos(dAngel), dRadius * sin(dAngel));
		dRadius *= 1.003;
	}
	glEnd();

	glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
	glStencilOp(GL_INCR, GL_INCR, GL_INCR);//

	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(-5.0, -5.0, 5.0, 5.0);

	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	float aspect = (w * 1.0) / h;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, aspect, 1.0, 100.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_STENCIL);
	glutInitWindowPosition(200, 200);
	glutInitWindowSize(600, 600);
	glutCreateWindow(argv[0]);

// 	assert(GLEW_NO_ERROR == glewInit());

	init();
	glutReshapeFunc(reshape);
	glutDisplayFunc(display);
	glutMainLoop();

	return 0;
}


 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章