4

テクスチャの一部が描画されないように、アルファマスク付きのステンシルバッファを使用しようとしています。

初期化コード

if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
    fprintf(stderr,"%s:%d\n    SDL_Init call failed.\n",__FILE__,__LINE__);
    return false;
}

// Request use of the stencil buffer
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 1 );

if((Surf_Display = SDL_SetVideoMode(WWIDTH, WHEIGHT, 32,  SDL_GL_DOUBLEBUFFER | SDL_OPENGL | SDL_RESIZABLE)) == NULL) {
    fprintf(stderr,"%s:%d\n    SDL_SetVideoMode call failed.\n",__FILE__,__LINE__);
    return false;
}

// Init GLDebug system
GLDebug::Init();

// Init GL system
glClearColor(0, 0, 0, 1);

glClearDepth(1.0f);

glViewport(0, 0, WWIDTH, WHEIGHT);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(0, WWIDTH,  WHEIGHT, 0, 1, -1);

glMatrixMode(GL_MODELVIEW);

glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);

glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);

glLoadIdentity();

ソース

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// Enable use of textures
glEnable(GL_TEXTURE_2D);

// Disable writing to any of the color fields
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 
glStencilFunc(GL_ALWAYS, 0,0);
glEnable(GL_ALPHA_TEST);
glEnable(GL_STENCIL_TEST);

glBindTexture(GL_TEXTURE_2D,(&StencilTex)[0]);

// Draw our stencil buffer texture
glBegin(GL_POLYGON);                                   
    glTexCoord2d( 0, 0 );    glVertex2f( 50,     50 );
    glTexCoord2d( 0, 1 );    glVertex2f( 50,     50+128 );
    glTexCoord2d( 1, 1 );    glVertex2f( 50+128, 50+128 );
    glTexCoord2d( 1, 0 );    glVertex2f( 50+128, 50 );
glEnd();

glDisable(GL_ALPHA_TEST);

// Re enable drawing of colors
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glStencilFunc(GL_GREATER, 0, -1);

// Bind desired texture for drawing
glBindTexture(GL_TEXTURE_2D,(&texture)[0]);

// Draw the box with colors (this should be masked off)
glBegin(GL_QUADS);                                   
    glTexCoord2d( 0, 0 );    glVertex2f( 50,     50 );
    glTexCoord2d( 0, 1 );    glVertex2f( 50,     50+128 );
    glTexCoord2d( 1, 1 );    glVertex2f( 50+128, 50+128 );
    glTexCoord2d( 1, 0 );    glVertex2f( 50+128, 50 );
glEnd();
glDisable(GL_STENCIL_TEST);

// Swap buffers and display!
SDL_GL_SwapBuffers();

ティムによって投稿されたように、私はこの質問から参照を外します。私が持っているセットアップはピクセルの生の描画で機能しますが、A)このプロセスがどのように機能するかについて頭または尾を作成することも、B)アルファテクスチャから機能させることもできません。私が得るのは黒い画面、または完全なテクスチャだけです。

誰かがこれを誰かの合理的なステップに分割することを気にしますか?glStencilOpオプションとglStencilFuncオプションがどのように機能するかについては漠然と理解していますが、アルファテストとステンシルテストの使用との関係は私を困惑させます。アルファレイヤーをテクスチャからのみ保持することをどのように決定しますか?

レビューする:

  • シーンに描きたいテクスチャがありますが、非常に特定の領域をブロックする必要があります。
  • この効果を実現するために、実行時にオブジェクトのアルファテクスチャを変更することはできません。
  • 固定パイプラインを使用しています。後でVBOの使用方法を学習する予定です。
  • 指定されたコードでは、2番目のテクスチャが呼び出されても何も描画されません。

[編集0]

受け入れられた解決策は機能します!これが私が期待するように動作する最終的なコードです。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// // Enable use of textures
glEnable(GL_TEXTURE_2D);

// Disable writing to any of the color fields
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 

glAlphaFunc(GL_GREATER, 0.05);
glStencilFunc(GL_ALWAYS, 0,0);

glEnable(GL_STENCIL_TEST);
glEnable(GL_ALPHA_TEST);

glBindTexture(GL_TEXTURE_2D,(&StencilTex)[0]);

// Draw our blocking poly
glBegin(GL_POLYGON);                                   
    glTexCoord2d( 0, 0 );    glVertex2f( 50,     50 );
    glTexCoord2d( 0, 1 );    glVertex2f( 50,     50+128 );
    glTexCoord2d( 1, 1 );    glVertex2f( 50+128, 50+128 );
    glTexCoord2d( 1, 0 );    glVertex2f( 50+128, 50 );
glEnd();
glDisable(GL_ALPHA_TEST);


// Re enable drawing of colors
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glStencilFunc(GL_LESS, 0, -1);

// Bind desired texture for drawing
glBindTexture(GL_TEXTURE_2D,(&texture)[0]);

// Draw the box with colors
glBegin(GL_QUADS);                                   
    glTexCoord2d( 0, 0 );    glVertex2f( 50,     50 );
    glTexCoord2d( 0, 1 );    glVertex2f( 50,     50+128 );
    glTexCoord2d( 1, 1 );    glVertex2f( 50+128, 50+128 );
    glTexCoord2d( 1, 0 );    glVertex2f( 50+128, 50 );
glEnd();
glDisable(GL_STENCIL_TEST);


// Swap buffers and display!
SDL_GL_SwapBuffers();
4

1 に答える 1

4

アルファテストを有効にしましたが、アルファ関数を設定するための呼び出しが表示されません(glAlphaFunc)?

アルファ関数を設定しない場合、アルファテストは常に合格です。どのピクセルを破棄するかをステートマシンに指示する必要があります。

通常、次のように設定します。

glAlphaFunc(GL_GREATER, 0.05); //reject any pixels with alpha less than 0.05

以前の回答から明確に理解できなかった場合は申し訳ありませんが、ステンシル機能がどのように機能するかについて混乱している場合は、いつでもリファレンスページを参照できます。glStencilFunc glStencilOp

于 2012-08-15T05:57:49.207 に答える