Search code examples
c++openglcross-platformwxwidgetsmodels

opengl models do not overlap correctly cross platform


edit: I have added a few new lines of code to the beginning for depth buffering with no luck. See code..

edit 2: I am constructing the model builder on a wxglcanvas via wxwidgets. I have initialized WX_GL_DEPTH_SIZE of 16 and WX_GL_DOUBLEBUFFER on top of enabling depthbuffering and glClear(GL_DEPTH_BUFFER_BIT) with no luck. One thing that might be useful to note is that when I draw a cone, it seems to be drawing the cone as if I am looking at the inside of it rather than the outside portion, so it looks as if it's concaved in.

I have an odd problem where my openGL models do not overlap correctly. I am building a model builder so that the user can create and rotate a model on a canvas.

For example: If I have a circle within a box and I rotate the model around, I can still see the circle within the box as if the box is transparent. How I picture this is that if the circle is in the box, I should not be able to see it. Does anyone have any guesses to what causes this type of problem? I have not implemented any type of transparency, so I'm not really sure what is causing this. I am still very new to openGL so a lot of my efforts have just been trying lines of code I find on the forums and hoping it works. Also, parts of this code are inherited from other programs.

This problem seems to only occur in Ubuntu and not under Win 7 when I test my program after adding two lines of code (shown below).

Here are some lines of code for drawing the models...

//Newly Added code
      glEnable(GL_DEPTH_TEST);
      glDepthFunc(GL_GEQUAL);
      glClearDepth(1.0f);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//End newly added code  

glGetIntegerv(GL_MATRIX_MODE, &mm);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(identity);
       GrGetInfo();

glViewport(0,0,gw->gc.width,gw->gc.height);
       GrGetInfo();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set some predefined parameters

glOrtho ((GLdouble)tmpOtherAxis.minval, (GLdouble)tmpOtherAxis.maxval, 
               (GLdouble)tmpRangeAxis.minval, (GLdouble)tmpRangeAxis.maxval,  
               -range_dist, range_dist);
glMatrixMode(mm);

//ADDED THESE TWO LINES AND MODEL DISPLAYED
//CORRECTLY IN WIN7 BUT NOT UBUNTU
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();
//Draw model here
glPopMatrix();

Any help would be greatly appreciated, and feel free to ask me whatever questions you need regarding this.


Solution

  • Sounds to me like your z-buffer isn't enabled. Without a z-buffer, the geometry is simply drawn in the order of the issued OpenGL commands. Effectivly, there is no "behind".

    To get the z-buffer to function properly, you'll need to:

    1. Request a z-buffer for your rendering window. This is platform specific.
    2. Call glEnable( GL_DEPTH_TEST ).
    3. Use glClear( ... | GL_DEPTH_BUFFER_BIT );

    Two possible explanations why your code is behaving different on different platforms, is (a) the z-buffer not being allocated (properly) on one of the platforms, or (b) the default state of GL_DEPTH_TEST being ON for one of the platforms, OFF for the other.

    Edit

    In a windows application, you'll be using a ChoosePixelFormat/SetPixelFormat pair on your HDC somewhere, right before you use wglCreateContext(). That is where you specify your depth buffer.

                HDC hdc = GetDC(hwnd);
    
                PIXELFORMATDESCRIPTOR pfd;
                memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
                pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
                pfd.nVersion = 1;
                pfd.cColorBits = 16;
                pfd.cDepthBits = 16;  // <---- !!! Depth buffer !!!
                pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
                pfd.iPixelType = PFD_TYPE_RGBA;
    
                int format;
                if ((format = ChoosePixelFormat(hdc, &pfd)) != 0)
                        SetPixelFormat(hdc, format, &pfd);
    
                HGLRC hrc = wglCreateContext(hdc);