0

ステンシル バッファの使用方法を学んでいますが、これまでのところ、単純な例でさえ機能させることに成功していません。glStencilOp実際、とのパラメーターのさまざまな組み合わせを試してみましglStencilFuncたが、ステンシル バッファーが機能しているという証拠はまったく見つかりませんでした。グラフィックス ドライバ (Mac Pro、Mac OS X 10.8.5) または JOGL (2.0.2) がサポートしていないのではないかと疑い始めています... または、本当に基本的なものが欠けています。

これが私が見ているものです:

ここに画像の説明を入力

緑のひし形で切り取られた赤いひし形が見られることを期待しています。私は何を間違っていますか?

public class Test {

    public static void main(String[] args) {
        GLProfile glprofile = GLProfile.getDefault();
        final GLCapabilities glcapabilities = new GLCapabilities(glprofile);
        final GLCanvas glcanvas = new GLCanvas(glcapabilities);
        final GLU glu = new GLU();

        glcanvas.addGLEventListener(new GLEventListener() {

            @Override
            public void reshape(GLAutoDrawable glautodrawable, int x, int y, int width, int height) {}



            @Override
            public void init(GLAutoDrawable glautodrawable) {
                GL2 gl = glautodrawable.getGL().getGL2();

                glcapabilities.setStencilBits(8);

                gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
                gl.glLoadIdentity();

                glu.gluPerspective(45, 1, 1, 10000);
                glu.gluLookAt(0, 0, 100, 0, 0, 0, 0, 1, 0);

                gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
                gl.glLoadIdentity();
            }



            @Override
            public void dispose(GLAutoDrawable glautodrawable) {}



            @Override
            public void display(GLAutoDrawable glautodrawable) {
                GL2 gl = glautodrawable.getGL().getGL2();

                gl.glEnable(GL.GL_STENCIL_TEST);

                gl.glClearStencil(0x0);
                gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);

                gl.glStencilFunc(GL.GL_ALWAYS, 1, 1);
                gl.glStencilOp(GL.GL_REPLACE, GL.GL_REPLACE, GL.GL_REPLACE);
            gl.glStencilMask(0xFF);
                //gl.glColorMask(false, false, false, false);
                //gl.glDepthMask(false);

                gl.glColor3f(0, 1, 0);
                gl.glBegin(GL2.GL_QUADS);
                gl.glVertex2f(-25.0f, 0.0f);
                gl.glVertex2f(0.0f, 15.0f);
                gl.glVertex2f(25.0f, 0.0f);
                gl.glVertex2f(0.0f, -15.0f);
                gl.glEnd();

            gl.glStencilMask(0);
                gl.glStencilFunc(GL2.GL_EQUAL, 1, 1);
                gl.glStencilOp(GL2.GL_KEEP, GL2.GL_KEEP, GL2.GL_KEEP);
                //gl.glColorMask(true, true, true, true);
                //gl.glDepthMask(true);

                gl.glColor3f(1, 0, 0);
                gl.glBegin(GL2.GL_QUADS);
                gl.glVertex2f(-20.0f, 0.0f);
                gl.glVertex2f(0.0f, 20.0f);
                gl.glVertex2f(20.0f, 0.0f);
                gl.glVertex2f(0.0f, -20.0f);
                gl.glEnd();
            }
        });

        final JFrame jframe = new JFrame("One Triangle Swing GLCanvas");
        jframe.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent windowevent) {
                jframe.dispose();
                System.exit(0);
            }
        });

        jframe.getContentPane().add(glcanvas, BorderLayout.CENTER);
        jframe.setSize(640, 480);
        jframe.setVisible(true);
    }
}
4

2 に答える 2

4

Zero298 は正しい考えを持っていますが、コードで試したことが機能しない理由を説明できません。これは、フレームバッファ ピクセル フォーマットが OpenGL でどのように機能するかを理解すると、より明確になります。これについては以下で少し触れますが、最初に適切な解決策を再ハッシュするだけです。

public static void main(String[] args) {
    GLProfile      glprofile      = GLProfile.getDefault ();
    GLCapabilities glcapabilities = new GLCapabilities   (glprofile);

    // You must do this _BEFORE_ creating a render context
    glcapabilities.setStencilBits (8);

    final GLCanvas glcanvas = new GLCanvas (glcapabilities);
    final GLU      glu      = new GLU      ();

重要なことは、レンダリング コンテキスト (「キャンバス」) を作成する前にこれを行うことです。ステンシル バッファーは、必要なときにいつでも有効または無効にできるものではありません。最初に、ストレージを予約するピクセル形式を選択する必要があります。ピクセル フォーマットはレンダー コンテキストを作成した時点から固定されているため、 の前にこれを行う必要がありますnew GLCanvas (...)

実際に FBO を使用して、ステンシル バッファーを持たないレンダー コンテキストでステンシル操作を行うことができますが、これは現時点で考慮すべきよりもはるかに高度です。ただし、MSAA を実行したい場合は考慮すべき点があります。FBO は、レンダリング コンテキスト (「キャンバス」) を作成して破棄するよりも、実行時にピクセル フォーマットを変更するためのはるかに優れた方法です。

于 2013-09-27T00:58:56.003 に答える