Friday, July 8, 2022

Implementation: BaseScene

Overview
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 or AMD actually implement the latest and greatest OpenGL specification, including additional functionality and supply it as OpenGL Installable Client Driver or ICD.
This post discusses creating Hosting Window, initializing OpenGL context and handling Keyboard/Mouse events.

Details
There are many third party utilities such as FreeGLUT or GLFW to create Application Window, create OpenGL context and provide mouse and Keyboard Inputs. As discussed earlier, VedaLib uses Windows SDK and VS suppled libraries to implement this functionality.

The classes OGLAppWindow, BaseScene and BaseCamera  implement this functionality. 

OGLAppWindow
OGLAppWindow is derived from CWindowImpl class. It creates a hosting window and loads OpenGL context. It's an abstract class. BaseScene is derived from this class. 
Methods
NameDescription
init_opengl_extensions


This method creates a dummy window and initializes it with OpenGL 1.1  Context. Later LoadWGLExtensions() is called to load the OpenGL extensions. 
In the end, the dummy window is destroyed.
init_openglInitializes the host window with OpenGL 3.3 context.
DestroyWindow
Deletes the OpenGL context and then destroys the hosting window

BaseScene  
BaseScene  is derived from OGLAppWindow class. BaseScene Implements rendering, resizing, mouse and keyboard events. The BaseScene class is abstract. All the scene classes should derive from BaseScene class and must override DrawScene and Cleanup methods. 
Members
NameDescription
cameraHandles Mouse and Keyboard inputs. This is a pointer to an instance of BaseCamera class or its derivative. It can be a nullptr meaning, Mouse and Keyboard inputs except Escape key press are ignored.

Methods
NameDescription
DestroyWindowCalled when the application window is closed. This internally calls Cleanup() and OGLAppWindow::DestroyWindow().
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 camera for further processing when it's assigned. The scene's  Keyboard and mouse input handler is  implemented in BaseCamera class. The BaseCamera class itself can be overridden for further specialization.
OnKeyDownThis method handles Keyboard input. It's called in response to WM_KEYDOWN. Delegates to camera if assigned. By default, closes application window if Escape key is pressed.
OnMouseBtnDownThis method handles Mouse button clicks. It's called in response to WM_LBUTTONDOWN and WM_RBUTTONDOWN. Delegates to camera if assigned. The parameter button represents the left, right or middle button. x and y represents the coordinates of the mouse.
OnMouseMoveThis method handles Mouse moves. It's called in response to WM_MOUSEMOVE. Delegates to camera if assigned. The parameter button represents the left, right or middle button. x and y represents the coordinates of the mouse.
OnMouseWheelThis method handles Mouse scroll wheel inputs. It's called in response to WM_MOUSEWHEEL.Mouse scroll wheel handler. Delegates to camera  if assigned. This method updates FOV.
HandleResize
When the window is resized, WM_SIZE event is raised. OnSize method in BaseScene class captures' this event. This method resizes the viewport,and internally calls this method.
This passes the input to BaseCamera::UpdateWH()  for aspect ratio  calculations and repaints the scene.
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 OGLAppWindow Init methods to create the hosting window and the OpenGL context.
Following lists the steps 
  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.
OnPaintThe 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.

The BaseCamera class will be discussed in an upcoming post.
In the next post we will discuss creation of  the host window and initializing it with OpenGL Context.

No comments:

Post a Comment