Friday, July 8, 2022

Modern OpenGL Library Implementation - Part 1

Source code of modern OpenGL library is located under VOGLLib folder . It's a set of header files that can be included by the client applications.  The directory structure looks as below.



CompileLink.h
This header files defines locations of the externals.  Note that include file locations and libraries locations are predefined. If your setup is different then this file needs to be edited.
       
#define WGL_WGLEXT_PROTOTYPES
#pragma include_alias( "GL/GL.h", "..\..\externals\GLExtensions\GL\GL.h" )
#pragma include_alias( "GL/wglext.h", "..\..\externals\GLExtensions\GL\wglext.h" )
#pragma include_alias( "SOIL2.h", "..\..\externals\SOIL2\src\SOIL2\SOIL2.h" )
#pragma include_alias( "glm/glm.hpp", "..\..\externals\glm\glm\glm.hpp" )
#pragma include_alias( "glm/gtc/matrix_transform.hpp", "..\..\externals\glm\glm\gtc\matrix_transform.hpp" )
#pragma include_alias( "glm/gtc/type_ptr.hpp", "..\..\externals\glm\glm\gtc\type_ptr.hpp" )

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "gdiplus.lib")
#ifdef _DEBUG 
#pragma comment(lib, "..\\..\\externals\\GLExtensions\\lib\\GLExtensions_static_x86_d.lib")
#pragma comment(lib, "..\\..\\externals\\SOIL2\\projects\\VC15\\libs\\SOIL_static_x86_d.lib")
#else
#pragma comment(lib, "..\\externals\\GLExtensions\\lib\\GLExtensions_static_x86.lib")
#pragma comment(lib, "..\\externals\\SOIL2\\projects\\VC15\\libs\\SOIL_static_x86.lib")
#endif

Geometry
This folder defines some base classes responsible for sending vertex data and also rendering  objects such as Text, Cube etc.

Camera
This folder contains classes responsible  for different type of projections of  the scene and mouse and keyboard handling for the same.

Lighting
This folder contains classes responsible lighting the objects in the scene.

Scene
This folder contains classes responsible creating OpenGL context and host window.

Creating OpenGL context
As discussed earlier, OpenGL is a drawing library that requires a context to draw upon. 
Creating OpenGL context in windows OS is not a trivial task. It's mainly because opengl32.lib supplied by windows OS supports OpenGL specification 1.1. 
The display card providers such as NVidia or intel actually implement the latest and greatest OpenGL specification, including additional functionality and supply it as OpenGL Installable Client Driver or ICD.

Following lists the steps of modern OpenGL context  creation
  1. Create a dummy window with CS_OWNDC style.
  2. Create OpenGL context  as per OpenGL 1.1 specification
  3. Load the OpenGL extensions using wglGetProcAddress API. This will setup and forward any future OpenGL API calls to OpenGL ICD from the vendor
  4. Once the extensions are loaded the the OpenGL context and dummy window should be discarded  because the pixel format  of the OpenGL specification 1.1  and 3.3 are different and cannot be changed once set.
  5. Create a new window that will render 3d Graphics with CS_OWNDC style.. 
  6. Create OpenGL context compatible with OpenGL specification 3.3


OGLAppWindow implements creating OpenGL context and the hosting window. It's located in  VOGLLib\Scene\OGLAppWindow.h

BaseScene Implements rendering, resizing, mouse and keyboard events. It's located in VOGLLib\Scene\BaseScene .h. All the scene classes should derive from BaseScene class.

Init
When the scene is created Init method is called. Note that the Init method should be overridden by all scene classes derived from  BaseScene class. Internally it calls basescene's Init method to create the hosting window and the OpenGL context.

Rendering
The scene will be rendered when WM_PAINT  message is received. The OnPaint method captures it and internally calls DrawScene to render the scene using OpenGL APIs. Note that the DrawScene method should be overridden by all scene classes derived from  BaseScene class.

Mouse/Keyboard input support
Keyboard and Mouse inputs are used for various visual operations such as panning, rotation, zoom in/out etc. BaseScene class captures' keyboard and mouse inputs and passes it to the scene's  Keyboard and mouse input handler for further processing when it's assigned. The scene's   Keyboard and mouse input handler is  implemented in BaseCameraInputHandler class. The BaseCameraInputHandler  itself can be overridden for specialization. For example, SimpleCameraInputHandler class

The following table shows Keyboard and mouse input events handled.

BaseScene class

BaseCameraInputHandler  class 

OnKeyDown

OnKey

OnMouseDown

OnMouseBtnDown

OnMouseMove

OnMouseMove

OnMouseWheel

updateFOV


Resizing 
When the window is resized, WM_SIZE event is raised. OnSize method in BaseScene class captures' this event. This method resizes the viewport, passes the input to BaseCameraInputHandler  for aspect ratio  calculations and repaints the scene.

Cleanup
When the scene is destroyed Cleanup method is called. Note that the Cleanup() should be overridden by all scene classes derived from  BaseScene class.

In the next post we will discuss creation of  Creating OpenGL Context, Rendering and Mouse/Keyboard input support.

No comments:

Post a Comment