私は OpenGL を丸 1 週間、またはそれと同等のもので遊んでいます。2Dの次は3Dに挑戦中です。http://johnnylee.net/projects/wii/の 3 番目のビデオで見られる 3D シーンを再現したいと思います。
テクスチャと深度ですべてを適切に機能させるのに苦労しました。
最近、視覚的に同じ影響を与える2つの問題が発生しました。
- 2D で見つけた手法を使用しても、3D ではうまくブレンドできないテクスチャを持つもの。
- オブジェクトが上から下に表示されるもの。ここで公開されている問題のように: OpenGL の深度バッファ
私は両方の問題を解決しましたが、特に 2 番目の点について、問題が解決したかどうかを知りたいです。
最初のものについては、私はそれを持っていると思います。ディスクの外側にアルファがある丸いターゲットの画像があります。OpenGL内で問題なくロードされます。(Z オーダーの問題により) その背後にある他のターゲットの一部は、ペイントに使用した自然に正方形の四角形の透明な領域によって隠されていました。
その理由は、深度バッファに関して、テクスチャのすべての部分が完全に不透明であると想定されているためです。glEnable(GL_ALPHA_TEST)
をテストで使用するとglAlphaFunc(GL_GREATER, 0.5f)
、テクスチャのアルファ レイヤーがピクセルごとの (ブール値) 不透明度インジケーターとして機能するため、ブレンドがまったく役に立たなくなります (私の画像にはブール値の透明度があるため)。
補足質問:ちなみに、ブレンドに使用するアルファレイヤーとは別のソースをアルファテストに指定する手段はありますか?
第二に、問題の解決策を見つけました。色と深度のバッファをクリアする前に、デフォルトの深度を 0 に設定しglClearDepth(0.0f)
、「より大きな」深度関数を使用しましglDepthFunc(GL_GREATER)
た。
私にとって奇妙に見えるのは、深さが 1.0 であり、深さ関数がGL_LESS
デフォルトで「少ない」ことです。オブジェクトが反転して表示されないように、基本的に反転しています...
私はそのようなハックをどこにも見たことがありませんが、一方、描画する順序に関係なく、オブジェクトが間違った順序で体系的に描画されるのを見たことはありません!
わかりました、ここにコードの一部があります(必要以上に削除されていないことを願っています)。これは現在、私が望むように機能しています。
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(600, 600); // Size of the OpenGL window
glutCreateWindow("OpenGL - 3D Test"); // Creates OpenGL Window
glutDisplayFunc(display);
glutReshapeFunc(reshape);
PngImage* pi = new PngImage(); // custom class that reads well PNG with transparency
pi->read_from_file("target.png");
GLuint texs[1];
glGenTextures(1, texs);
target_texture = texs[0];
glBindTexture(GL_TEXTURE_2D, target_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, pi->getGLInternalFormat(), pi->getWidth(), pi->getHeight(), 0, pi->getGLFormat(), GL_UNSIGNED_BYTE, pi->getTexels());
glutMainLoop(); // never returns!
return 0;
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1, 1, -1, 1);
gluPerspective(45.0, w/(GLdouble)h, 0.5, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display(void) {
// The stared *** lines in this function make the (ugly?) fix for my second problem
glClearColor(0, 0, 0, 1.00);
glClearDepth(0); // ***
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_FUNC); // ***
glDepthFunc(GL_GREATER); // ***
draw_scene();
glutSwapBuffers();
glutPostRedisplay();
}
void draw_scene() {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.5, 0, -3, 0, 0, 1, 0, 1, 0);
glColor4f(1.0, 1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
// The following 2 lines fix the first problem
glEnable(GL_ALPHA_TEST); // makes highly transparent parts
glAlphaFunc(GL_GREATER, 0.2f); // as not existent/not drawn
glBindTexture(GL_TEXTURE_2D, target_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Drawing a textured target
float x = 0, y = 0, z = 0, size = 0.2;
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(x-size, y-size, z);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(x+size, y-size, z);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x+size, y+size, z);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x-size, y+size, z);
glEnd();
// Drawing an textured target behind the other (but drawn after)
float x = 0, y = 0, z = 2, size = 0.2;
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(x-size, y-size, z);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(x+size, y-size, z);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x+size, y+size, z);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x-size, y+size, z);
glEnd();
}