OpenGL03-2深度測試和正背面剔除

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

深度測試+正背面剔除.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;
}

demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容