這篇文章主要介紹深度測試和正背面剔除,主要代碼就是以下幾行。

深度測試+正背面剔除.gif
核心代碼:
glEnable(GL_CULL_FACE); //開啟剔除
glFrontFace(GL_CCW); //設(shè)置逆時針為正面
glCullFace(GL_BACK); //剔除背面
glDisable(GL_CULL_FACE); //關(guān)閉剔除
glEnable(GL_DEPTH_TEST); //開啟深度測試
glDisable(GL_DEPTH_TEST); //關(guān)閉深度測試
一. 設(shè)置成員變量
////設(shè)置角色幀,作為相機(jī)
GLFrame viewFrame;
//使用GLFrustum類來設(shè)置透視投影
GLFrustum viewFrustum;
GLTriangleBatch torusBatch;
GLMatrixStack modelViewMatix;
GLMatrixStack projectionMatrix;
GLGeometryTransform transformPipeline;
GLShaderManager shaderManager;
//標(biāo)記:背面剔除、深度測試
int iCull = 0;
int iDepth = 0;
一. 右鍵菜單欄選項
void ProcessMenu(int value)
{
switch(value)
{
case 1:
iDepth = !iDepth;
break;
case 2:
iCull = !iCull;
break;
case 3:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
case 4:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
break;
case 5:
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
break;
}
glutPostRedisplay();
}
二. 召喚場景
void RenderScene(void)
{
//清除窗口和深度緩沖區(qū)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//根據(jù)設(shè)置iCull標(biāo)記來判斷是否開啟背面剔除
if(iCull)
{
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
}
else
glDisable(GL_CULL_FACE);
//根據(jù)設(shè)置iDepth標(biāo)記來判斷是否開啟深度測試
if(iDepth)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
//把攝像機(jī)矩陣壓入模型矩陣中
modelViewMatix.PushMatrix(viewFrame);
GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
//使用平面著色器
//參數(shù)1:平面著色器
//參數(shù)2:模型視圖投影矩陣
//參數(shù)3:顏色
//shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vRed);
//使用默認(rèn)光源著色器
//通過光源、陰影效果跟提現(xiàn)立體效果
//參數(shù)1:GLT_SHADER_DEFAULT_LIGHT 默認(rèn)光源著色器
//參數(shù)2:模型視圖矩陣
//參數(shù)3:投影矩陣
//參數(shù)4:基本顏色值
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vRed);
//繪制
torusBatch.Draw();
//出棧
modelViewMatix.PopMatrix();
glutSwapBuffers();
}
三. context. 圖像上下文
void SetupRC()
{
// 設(shè)置背景顏色
glClearColor(0.3f, 0.3f, 0.3f, 1.0f );
//初始化著色器管理器
shaderManager.InitializeStockShaders();
//將相機(jī)向后移動7個單元:肉眼到物體之間的距離
viewFrame.MoveForward(7.0);
//創(chuàng)建一個甜甜圈
//void gltMakeTorus(GLTriangleBatch& torusBatch, GLfloat majorRadius, GLfloat minorRadius, GLint numMajor, GLint numMinor);
//參數(shù)1:GLTriangleBatch 容器幫助類
//參數(shù)2:外邊緣半徑
//參數(shù)3:內(nèi)邊緣半徑
//參數(shù)4、5:主半徑和從半徑的細(xì)分單元數(shù)量
gltMakeTorus(torusBatch, 1.0f, 0.3f, 52, 26);
//點的大小
glPointSize(4.0f);
}
四. 鍵位設(shè)置,通過不同的鍵位對其進(jìn)行設(shè)置,控制Camera的移動,從而改變視口
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
viewFrame.RotateWorld(m3dDegToRad(-5.0), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_DOWN)
viewFrame.RotateWorld(m3dDegToRad(5.0), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_LEFT)
viewFrame.RotateWorld(m3dDegToRad(-5.0), 0.0f, 1.0f, 0.0f);
if(key == GLUT_KEY_RIGHT)
viewFrame.RotateWorld(m3dDegToRad(5.0), 0.0f, 1.0f, 0.0f);
//重新刷新window
glutPostRedisplay();
}
五. 修改窗口大小
void ChangeSize(int w, int h)
{
//防止h變?yōu)?
if(h == 0)
h = 1;
//設(shè)置視口窗口尺寸
glViewport(0, 0, w, h);
//setPerspective函數(shù)的參數(shù)是一個從頂點方向看去的視場角度(用角度值表示)
// 設(shè)置透視模式,初始化其透視矩陣
viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 100.0f);
//把透視矩陣加載到透視矩陣對陣中
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
// 初始化渲染管線
transformPipeline.SetMatrixStacks(modelViewMatix, projectionMatrix);
}
六. 初始化
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("Geometry Test Program");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
// Create the Menu
glutCreateMenu(ProcessMenu);
glutAddMenuEntry("Toggle depth test",1);
glutAddMenuEntry("Toggle cull backface",2);
glutAddMenuEntry("Set Fill Mode", 3);
glutAddMenuEntry("Set Line Mode", 4);
glutAddMenuEntry("Set Point Mode", 5);
glutAttachMenu(GLUT_RIGHT_BUTTON);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
return 0;
}