transparency - Depth test inverted by default in OpenGL, or did I get it wrong? -


i've been playing around opengl full week or equivalent. after 2d i'm trying 3d. want reproduce 3d scene can see in third video on http://johnnylee.net/projects/wii/.
i've had hard time making work textures , depth.

i've had 2 problems have visually same impact :

  • one textures not blend in 3d using techniques i've found 2d.
  • one objects appearing bottom above top. problem exposed here: depth buffer in opengl

i've solved both problem, know if things right, especially second point.


for first one, think i've got it. have image of round target, alpha outside disc. it's loaded fine inside opengl. (due z-ordering problem) other targets behind suffered being hidden transparent regions of naturally square quad used paint it.

the reason every part of texture assumed full opaque regard depth buffer. using glenable(gl_alpha_test) test glalphafunc(gl_greater, 0.5f) makes alpha layer of texture act per pixel (boolean) opacity indicator, , makes blending quite useless (because image has boolean transparency).

supplementary question: by way, there mean of specifying different source alpha test alpha layer used blending?


second, i've found fix problem. before clearing color , depth buffer i've set default depth 0 glcleardepth(0.0f) , and i've make use of "greater" depth function gldepthfunc(gl_greater).

what looks strange me depth 1.0 , depth function "less" gl_less default. i'm inverting objects don't displayed inverted...

i've seen such hack, in other hand i've seen objects getting drawn systematically in wrong order, regardless of order draw them!


ok, here's bit of code (stripped down, not hope) now working want:

    int main(int argc, char** argv) {         glutinit(&argc, argv);         glutinitdisplaymode(glut_double | glut_rgba | glut_depth);         glutinitwindowsize(600, 600); // size of opengl window         glutcreatewindow("opengl - 3d test"); // creates opengl window         glutdisplayfunc(display);         glutreshapefunc(reshape);          pngimage* pi = new pngimage(); // custom class reads png 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) {         // stared *** lines in function make (ugly?) fix 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);         // following 2 lines fix first problem         glenable(gl_alpha_test);       // makes highly transparent parts         glalphafunc(gl_greater, 0.2f); // 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 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 textured target behind 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();     } 

normally depth clear value 1 (effectively infinity) , depth pass function less because want simulate real world see things in front of things behind them. clearing depth buffer 1, saying objects closer maximum depth should drawn. changing parameters not want unless understand doing.

with camera parameters passing glulookat , positions of objects, z=2 quad further camera z=0 object. trying accomplish such doesn't seem correct?

the standard approach achieve order-correct alpha blending render opaque objects, render transparent objects front. regular/default depth function used.

also note may weird behavior way setting perspective matrix. call gluortho or gluperspective. not both. multiply 2 different perspective matrices not want.


Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

html - Instapaper-like algorithm -

c# - How to execute a particular part of code asynchronously in a class -