0

私の質問は、背景画像の上または上にポリゴンまたはその他のOpenGLプリミティブを描画することです。さまざまなレイヤーのペイントのように要約しますが、OpenGLにはレイヤーがないと思います。

今、私は背景画像の上に三角形と線を描くことを試みているいくつかのテストをしています。

背景を描画するには、OpenGLウィンドウサイズの正方形を使用してから、この正方形のpng画像をテクスチャとして適用します。

その後、三角形と線を違う色で塗ろうとしていますが、背景画像以外は何も見えません。

アルファチャンネルで遊んでいますが、何も見えません。

コード:

void init() 
{
    // glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);

    // The following two lines enable semi transparent
    glEnable(GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    int width, height;
    bool hasAlpha;
    char filename[] = "prueba-luz.png";
    bool success = loadPngImage(filename, width, height, hasAlpha, &textureImage);

    if (!success) 
    {
        cout << "Unable to load png file" << endl;
        return;
    }

    cout << "Image loaded " << width << " " << height << " alpha " << hasAlpha << endl;

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glTexImage2D(GL_TEXTURE_2D, 0, hasAlpha ? 4 : 3, width,
                height, 0, hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE,
                textureImage);

    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

void display(void) 
{
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Igual que GL_REPLACE pero se le puede aplicar transparencias a la textura
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glPushMatrix();

    glColor4f(1, 1, 1, 1);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_QUADS);
        glTexCoord2i(0,0); glVertex2i(10, -10);
        glTexCoord2i(1,0); glVertex2i(-10, -10);
        glTexCoord2i(1,1); glVertex2i(-10, 10);
        glTexCoord2i(0,1); glVertex2i(10, 10);
    glEnd();

    glPopMatrix();

    glDisable(GL_TEXTURE_2D);

    glBegin(GL_POLYGON);
        glColor4f(1.0, 1.0, 1.0, 0.8);
        glVertex3f(-1.0f, -3.0f, 0.0f);    // A
        glVertex3f( 1.0f, -3.5f, 0.0f);    // B
        glVertex3f( 0.0f,  0.5f, 0.0f);    // C
    glEnd();

    glBegin(GL_LINES);
        glColor4f( 1.0, 0.0, 0.0, 0.8 );
        glVertex2f(-8.0,  6.0);
        glVertex2f (5.0, -3.0);
    glEnd();

    glutSwapBuffers();
}

背景画像の上に1つの画像を描画するにはどうすればよいですか?

4

1 に答える 1

9

いくつかの発見:

  • 深度テストを無効にしてみてください。すべてをZ=0で描画しており、アプリケーションは間違いなく深度バッファーに書き込みを行っています。描画するものはすべてZ=0であるため、ここで深度テストを有効にする理由がわかりません。
  • デフォルトでは、深度テストが有効になっている場合、同じまたはそれ以上のZ値に書き込まれたすべてのフラグメントが破棄されます。glDepthFuncこれは(デフォルト値)で変更できますGL_LESS。これが、この例でジオメトリが破棄される理由である可能性があります。
  • 2Dジオメトリを描画しても、デプスバッファが影響を受けないという意味ではありません。OpenGLは、Z = 0でこのジオメトリを描画し、それを深度バッファに書き込みます。

現在、異なるz位置にジオメトリを描画しない限り、アプリケーションで深度テストを使用する理由はありません。2D図面で深度テストを使用して、各オブジェクトに異なるz値を割り当てることにより、「レイヤー」を作成できます。

z-cullingを使用した2D描画の良い方法は、最初にclosesレイヤーを描画してから、さらにレイヤーを描画することです。これにより、書き込むフラグメントが少なくなります。

例えば ​​:

  • Z = 0:不透明なオーバーレイを描画します
  • Z = -1:オーバーレイの後ろに隠されたものを描画します
  • Z = -2:背景を描画します

ただし、透過オブジェクトには特別なルールが必要です。

デプスバッファを制御する必要があります。オプションがあります:

  • glEnable/Disable(GL_DEPTH_TEST):zカリングを有効または無効にする
  • glDepthMask(GL_TRUE/GL_FALSE):デプスバッファへの書き込みを有効または無効にします
  • glDepthFuncフラグメントの破棄方法を定義するために使用できます)

ここで、最初の2つの関数は、想像以上に多くのオプションを提供することに注意してください。

  • オブジェクトを描画するときの深度カリングと深度書き込み
  • デプスカリング、ただしオブジェクトはデプスバッファに影響を与えません
  • デプスカリングはありませんが、オブジェクトはデプスバッファに書き込みます
  • デプスカリングやデプスライトはありません

最後のパスですべての透明なオブジェクトを描画する場合は、たとえば、オブジェクトがオーバーレイの上に描画されないように深度テストを有効にすることができますが、その中で複数の重複するオブジェクトを描画できるようにするため、深度書き込みを無効にします層。

あなたの創造性を使って、デプスバッファを愛することを学びましょう:D

于 2012-10-20T19:56:50.663 に答える