4

背景画像 (正射投影) の上に錐台投影を使用していくつかのメッシュをレンダリングしようとしています。私が何をしても、背景画像はシーンの上にあり続けます (メッシュを隠します)。

少しテストしてみました - 同じ射影行列で両方を正しい順序でレンダリングすると、背景画像がメッシュの背後にありました。

これらは射影行列と深度バッファ初期化です:

glEnable(GL_DEPTH_TEST);
glClearDepthf( 1.0f );
glDepthFunc( GL_LEQUAL );
glDepthMask (GL_TRUE);

EGLConfig eglconfig;
EGLint const attrib_list[] = {
    EGL_DEPTH_SIZE, 16,
    EGL_NONE
};
EGLint numreturned;
CHECK(eglChooseConfig(esContext.eglDisplay, attrib_list, &eglconfig, 1, &numreturned) != EGL_FALSE);

float fieldOfView = 60.0;
float znear = 0.1f;
float zfar = 100000;
float size = (float)(znear * tanf((fieldOfView * M_PI /180.0f) / 2.0f)); 

m_orthoProjMatrix.loadOrtho(0, 
                            screenWidth, 
                            0, 
                            screenHeight, 
                            znear, 
                            zfar);

m_frustProjMatrix.loadFrustum(-size, 
                               size, 
                              -size / (screenWidth / screenHeight), 
                               size / (screenWidth / screenHeight), 
                               znear, 
                               zfar);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); でバッファーをクリーニングしています。

最後にもう 1 つ..GL_DEPTH_TEST を無効にすると、背景が最初に呼び出されるため、メッシュが背景画像の前に描画されます..

Depth-Buffer または Projection マトリックスのどちらがこの問題を引き起こしているのかわかりません.. screenWidth=960 および screenHeight = 640 のマトリックスの値:

Orthographic Proj Matrix:
0.00208 0.00000 0.00000 -1.00000
0.00000 0.00313 0.00000 -1.00000
0.00000 0.00000 0.00000 -1.00000
0.00000 0.00000 0.00000  1.00000

Frustum Proj Matrix:
1.73205 0.00000  0.00000  0.00000
0.00000 2.59808  0.00000  0.00000
0.00000 0.00000 -1.00000 -0.20000
0.00000 0.00000 -1.00000  0.00000

Camera Settings:
Vector3 pos(0,10,50);
Vector3 at(0,0,0);
Vector3 up(0,1,0);
LookAt(pos,at,up);

Scene Settings:
Vector3 BackgroundImagePosition (0,0, -430);
Vector3 SomeMesh(0,0,0);

私は何を間違っていますか?アミール。

編集:これは、正投影で画像を描画する方法です:

GLfloat verts[] = { 
image->x + image->width  , image->y                , image->z,
image->x + image->width  , image->y + image->height, image->z,
image->x                 , image->y + image->height, image->z,
image->x                 , image->y                , image->z};
Matrix4s mv(m_camera->getCameraViewMatrix());
Matrix4f proj(ResManPtr->getOrthoProjMatrix() * mv);
glUniformMatrix4fv(prog->getUniformLocation("u_projMatrix"), 1, GL_FALSE, &(*proj));
glActiveTexture(GL_TEXTURE0);
image->tex->bind();
glUniform1i(prog->getUniformLocation("s_texture"), 0);
glEnableVertexAttribArray(prog->getAttribLocation("a_position")); 
glVertexAttribPointer(prog->getAttribLocation("a_position"), 3, GL_FLOAT, GL_FALSE, 0, verts); 
glEnableVertexAttribArray(prog->getAttribLocation("a_texCoord"));
glVertexAttribPointer(prog->getAttribLocation("a_texCoord"), 2, GL_FLOAT, GL_FALSE, 0, m_texcoord);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

これは、錐台投影を使用してメッシュを描画する方法です。

Matrix4f mv(world->getCamera()->getCameraViewMatrix());
const btVector3& dir = getDirection();
Scalar xzAngle = atan2s(dir.x(), dir.z()) - (Scalar)M_PI_2;
btVector3 origin = getGhostObject()->getWorldTransform().getOrigin();
mv.applyTranslate(origin.x(), origin.y() - m_width/2, origin.z());
mv.applyRotateY(xzAngle);    
GLProgramPtr prog = ResManPtr->getProgramMap()[Consts::DEFAULT_PROGRAM_KEY];
Matrix4f proj(ResManPtr->getFrustProjMatrix() * mv);
glUniformMatrix4fv(prog->getUniformLocation("u_projMatrix"), 1, GL_FALSE, &(*proj));
glActiveTexture(GL_TEXTURE0);
m_texture->bind();  
glUniform1i(prog->getUniformLocation("s_texture") , 0);
m_model->render(frame_number);
4

1 に答える 1

6

私の理解が正しければ、次のことを個別に行いたいと考えています。

  • テクスチャを含むフルスクリーン クワッドを描画する
  • このクワッドが Z バッファで考慮されないように何かをしてください
  • その後、その上にメッシュを描画します (任意の投影、ビュー、およびモデル マトリックスを使用)。

「GL_DEPTH_TEST を無効にすると、背景が最初に呼び出されるため、メッシュが背景画像の前に描画されます..」 -> フルスクリーン クワッドとメッシュの両方を別々に描画できると思います。したがって、VBO のセットアップ、マトリックス、テクスチャなどはすべて良好です。見落としているのはポイント 2 だけです。

  • 解決策 1 :

いつものように、新しいフレームのすべてをクリアします。Zバッファはどこでも1.0になります

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

背景を描きます。カラー バッファは問題ありませんが、Z バッファにはクワッドの深さが含まれるので、0.5 としましょう。そのため、メッシュをレンダリングするときは、幸運にも新しい深度値が 0.5 未満になるようにする必要があります。そうしないと、深度テストが失敗します。しかし、私たちはそれについて何かをすることができます: 単純に z-buffer を 1.0 に再度クリアします:

glClear(GL_DEPTH_BUFFER_BIT);

次に、通常どおり他のメッシュを描画します。ModelViewProjection マトリックスは変更されましたが、OpenGL はそれを認識していません。認識しているのは、深度がどこでも 1.0 であることだけです。したがって、メッシュの深度テストは常に成功します。したがって、正しい Z 値でメッシュがあるべき場所に表示され、それ以外の場所では背景のクワッドが表示されます。

  • 解決策 2

ここでは、フルスクリーン クワッドが描画されるときに深度値が更新されないようにします。

深度バッファへの書き込みを無効にします。

glDepthMask(GL_FALSE);

背景を描きます。カラー バッファーは問題なく、数行上の glClear() で設定されているように、z-buffer にはどこでも 1.0 が含まれます。

深度バッファへの書き込みを再度有効にします。

glDepthMask(GL_TRUE);

もう一方のメッシュを描画します。以前と同様に、glClear() を呼び出した場合と同様に、z-buffer はどこでも 1.0 になるため、メッシュが円錐台にある場合 (明らかにそうである必要があります)、その z は、たとえば 0.5 になります。描画されます。

  • 解決策 3

背景をカメラから遠く離れたファー クリッピング プレーンの近くに描画するだけです。(つまり、大きな Z コンポーネントを使用)。その z コンポーネントは 0.9999 またはそのようなものになり、以前と同様に、メッシュは問題なくレンダリングされます。

私は本当に、本当に詳しく説明することはできません。まだ明確でない場合は申し訳ありませんが、各アイデアをいくつかの方法で再定式化しようとしましたが、これ以上何もできません.

于 2011-03-16T16:56:29.350 に答える