How z-buffer( depth buffer) for 3D object rendering.

October 4, 2008

Z buffer plays an important role to draw 3D objects. Z buffer( depth buffer) holds the depth of each pixel.

Consider two objects with different z values, and some portion of one object and some portion of one object overlap with other. When first object drawn, its corresponding z values( the distance between view point and object) are updated in z-buffer and the pixel values(RGB) are updated in color buffer of the current rendering context.

During rendering next object, before updating a pixel in color buffer, openGL will compare the distance of current pixel from view point with the z-value in z-buffer( depth buffer). OpenGL modifies color buffer and depth buffer only if z-value of current pixel is lower than the z value of corresponding location in z buffer. If the new pixel is close to the eye point, openGL places the new pixel’s color in color buffer and its depth buffer.


Installable Client Driver

October 4, 2008

Installable Client Driver

Hardware acceleration is achieved in OpenGL through ICD’s. ICD contain methods for high speed rendering( that is supported by hardware).

To increase performance, we bought new video hardware( GPU ). But openGL calls are then also routed through openGL32.dll. To achieve hardware capabilities hardware venders provides their openGL ICD’s, which are implemented by hardware vendors, and these functions are capable of calling high speed methods implemented in hardware. This way openGL32.dll achieves high speed rendering.

I think the communication between openGL32.dll and OpenGL display driver is performed through ICD and generic openGL driver. The software interface between hardware driver( display driver ) and openGL32.dll is capable of routing openGL calls to high speed methods that are implemented in hardware.


OpenGL Sample: Quad Drawing

October 4, 2008

This simple sample program draws a Rectangle on a static controls DC. It just demonstrates how to create a Rendering context from a windows device context, and to render a rectangle with OpenGL API.

 

ScreenShot of Quad Sample:

 

Source Code:

http://www.sendspace.com/file/xn08ok

http://rapidshare.com/files/150852762/Quad.zip.html

 

I learned that OpenGL is an OS independent API for high speed graphics requirements. When I first read the API for creating a rendering context (wglCreateContext( HDC )) I believed that OpenGL in Windows uses GDI for rendering high speed graphics. But soon I got the functionalites of ICD( Installable Client Driver) and hardware supplied libraries for high speed graphics.

 

In this sample program I created a reusable class( GLInterface) for initializing and drawing an OpenGL scene in a Window.

 

The methods in GLInterface are

1)      Init: Initializes an OpenGL rendering Context.

bool GLInterface::Init( CWnd* pWnd_i )

{

 

      m_pWnd_i = pWnd_i;

 

      /* 1) Getting DC of Rendering Window. */

      // Getting DC from Window.

      m_pDC = m_pWnd_i->GetDC();

 

      // Validating DC.

      ASSERT( m_pDC != 0 );

 

      /* 2) Filling PIXELFORMATDESCRIPTOR with required paramaters. */

      // Filling Pixel Format structure.

      PIXELFORMATDESCRIPTOR pfd;

      memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) );

      pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );

      pfd.nVersion = 1;

      pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW |

                              PFD_DOUBLEBUFFER;

      pfd.iPixelType = PFD_TYPE_RGBA;

      pfd.cColorBits = 24;

      pfd.cDepthBits = 24;

      pfd.iLayerType = PFD_MAIN_PLANE;

 

      /* 3) Getting Pixel format index of corresponding PIXELFORMATDESCRIPTOR structure. */

      // Getting Pixel Format index.

      int iPixelFormat = ChoosePixelFormat( m_pDC->m_hDC, &pfd );

     

      // Validating Pixel Format.

      ASSERT( iPixelFormat != 0 ) ;

 

      /* 4) Creating Rendering Context for the DC. */

      // Set Current Pixel Format.

      SetPixelFormat( m_pDC->m_hDC, iPixelFormat, &pfd );

 

      // Creating a rendering Context.

      m_hRenderingContext = wglCreateContext( m_pDC->m_hDC );

 

      /* 5) Selecting Rendering Context as the Current Rendering Context. */

 

      // Set This Rendering Context as the Active Rendering Context.

      wglMakeCurrent( m_pDC->m_hDC, m_hRenderingContext );

      return ( m_hRenderingContext != 0 );

}

 

2)      Draw: Drawing a rectangle.


bool GLInterface::Draw()

{

      /* 1) Clear the back buffer for initialising the frame. */

      glClear( GL_COLOR_BUFFER_BIT );

 

      /* 2) Specify drawing color.  */

      glColor3f( 0.0f, 1.0f, 0.f );

 

      /* 3) Specify Primitive Type.( GL_QUADS ) */

      glBegin( GL_QUADS );

 

      /* 4) Specify verices for Quad. */

      glVertex3f( -0.5f, -0.5f, 0.f ); // Left Bottom.

      glVertex3f( 0.5f, -0.5f, 0.f ); // Right bottom.

      glVertex3f( 0.5f, 0.5f, 0.f ); // Right Top.

      glVertex3f( -0.5f, 0.5f, 0 ); // Left Top

       

        glEnd();

        /* 5) Swap Back buffer content to front buffer. */

        SwapBuffers( m_pDC->m_hDC );

 

      return true;

}

 

Steps to create Sample Program.

1)      Create an MFC AppWizard EXE (Application Type: Dialog based ).

2)      Add a static control to dialog and change its size to display a rectangle.

3)      Call Init() of GLInterface from OnInitDialog() of dialog class. Get Window handle to static control and pass to Init method.

4)      Change Caption of OK button to Draw, and add message handler for that button.

Call Draw() function of GLInterface class.

 

 

Notes:

1)      ( 0,0) coordinate in OpenGL is at center of rendering Window.

2)      Whenever windows repaints a window, we need to redraw our frame. For that I modified OnPaint() of dialog class.