OpenGL学習ノート(十五)テンプレートテスト

2616 ワード

クリップシェーダがクリップを処理すると、テンプレートテスト(Stencil Test)が開始され、深度テストと同様にクリップが破棄されることもあります.次に、保持されたクリップは深さテストに入り、より多くのクリップを破棄する可能性があります.テンプレートテストは、テンプレートバッファ(Stencil Buffer)と呼ばれ、レンダリング時に更新して興味深い効果を得ることができます.
1つのテンプレートバッファでは、(通常)各テンプレート値(Stencil Value)は8ビットです.したがって、各ピクセル/クリップには256種類の異なるテンプレート値があります.これらのテンプレート値を目的の値に設定し、クリップにテンプレート値がある場合は、クリップを破棄するか、保持するかを選択できます.
// 
glEnable(GL_STENCIL_TEST);
// 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

構成テンプレートテスト:glStencilFuncとglStencilOp
glStencilFunc(GLenum func,GLint ref,GLuint mask)には、3つのパラメータがあります.
  • func:テンプレートテスト関数(Stencil Test Function)を設定します.このテスト関数は、保存されたテンプレート値とglStencilFunc関数のref値に適用されます.使用可能なオプションは、GL_です.NEVER、GL_LESS、GL_LEQUAL、GL_GREATER、GL_GEQUAL、GL_EQUAL、GL_NOTEQUALとGL_ALWAYS.それらの意味は深さバッファの関数と似ています.
  • ref:テンプレートテストの参照値(Reference Value)が設定されています.テンプレートバッファの内容はこの値と比較されます.
  • mask:参照値と格納されたテンプレート値とテスト比較する前に(AND)演算を行うマスクを設定します.初期の場合、すべてのビットは1です.

  • glStencilOp(GLenum sfail,GLenum dpfail,GLenum dppass)には3つのオプションがあり、各オプションが取るべき動作を設定できます.
  • sfail:テンプレートテストに失敗したときの動作.
  • dpfail:テンプレートテストに合格したが、深さテストに失敗した場合の動作.
  • dppass:テンプレートテストと深さテストが合格したときの動作.

  • 動作
    説明
    GL_KEEP
    現在保存されているテンプレートの値を保持
    GL_ZERO
    テンプレート値を0に設定
    GL_REPLACE
    テンプレート値をglStencilFunc関数設定のref値に設定
    GL_INCR
    テンプレート値が最大値より小さい場合は、テンプレート値に1を加算します.
    GL_INCR_WRAP
    GL_とINCRは同じですが、テンプレート値が最大値を超えるとゼロになります
    GL_DECR
    テンプレートの値が最小値より大きい場合は、テンプレートの値を1に減らします.
    GL_DECR_WRAP
    GL_とDECRは同じですが、テンプレートの値が0未満の場合は最大値に設定します.
    GL_INVERT
    現在のテンプレートバッファ値をビット単位で反転
    オブジェクトプロファイルはテンプレートバッファで実現可能
  • (輪郭を追加する必要がある)物体を描画する前に、テンプレート関数をGL_に設定します.ALWAYSは、オブジェクトのクリップがレンダリングされるたびにテンプレートバッファを1に更新します.
  • は、オブジェクトをレンダリングします.
  • テンプレート書き込みおよび深さテストを無効にします.
  • は、各物体を少しずつスケールします.
  • 異なるクリップシェーダを使用して、個別の(枠線)色を出力します.
  • は、オブジェクトを再び描画しますが、クリップのテンプレート値が1に等しくない場合にのみ描画します.
  • テンプレート書き込みおよび深さテストを再度有効にします.
  • glEnable(GL_DEPTH_TEST);
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);  
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
    
    glStencilMask(0x00); //  
    normalShader.use();
    DrawFloor()  
    
    glStencilFunc(GL_ALWAYS, 1, 0xFF); 
    glStencilMask(0xFF); 
    DrawTwoContainers();
    
    glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
    glStencilMask(0x00); 
    glDisable(GL_DEPTH_TEST);
    shaderSingleColor.use(); 
    DrawTwoScaledUpContainers();
    glStencilMask(0xFF);
    glEnable(GL_DEPTH_TEST);