Overview
As discussed earlier, OpenGL is a drawing specification that requires a context contained in a hosting window to draw upon.
Creating OpenGL context in windows OS is not a trivial task. It's mainly because opengl.dll and opengl.lib supplied by Windows only 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 as extensions and supply it as OpenGL Installable Client Driver or ICD. For example, nvogl.dll, atiogl.dll, or iglicd.dll etc.
These ICDs are registered and their locations are stored in the windows registry.
The OpenGL.dll supplied with windows acts as a wrapper and forwards any OpenGL API calls made by the client to the 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 an Application Window, create OpenGL context in it, provide Window management and mouse and Keyboard Inputs.
As discussed earlier, VedaGraphicsLib uses Windows SDK and VC++ supplied libraries to implement this functionality.
The classes OGLAppWindow, BaseScene and BaseCamera implement this functionality.
System class diagram
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. As discussed earlier, OpenGL.dll works as a wrapper forwarding OpenGL API calls to the ICD. First time when it's loaded, it looks up the registry and loads the registered ICD. It directly forwards any OpenGL 1.1 related API Calls to the ICD. However for the higher specification, it patches the call thru an internal API wglGetProcAddress. This is achieved thru a "dedicated function". This function is internally implemented by the Glad\GL.h and\WGL.h header files discussed earlier. The prototype of this function looks as below.
void* GalogenGetProcAddress(const char *name) { static HMODULE opengl32module = NULL; static PROC(WINAPI *wgl_get_proc_address)(LPCSTR name) = NULL; if (!wgl_get_proc_address) { if (!opengl32module) { opengl32module = LoadLibraryA("opengl32.dll"); } wgl_get_proc_address = (PROC(WINAPI*)(LPCSTR))GetProcAddress(opengl32module, "wglGetProcAddress"); assert(wgl_get_proc_address); } void *ptr = (void *)wgl_get_proc_address(name); if(ptr == 0 || (ptr == (void*)1) || (ptr == (void*)2) || (ptr == (void*)3) || (ptr == (void*)-1) ) { if (opengl32module == NULL) { opengl32module = LoadLibraryA("opengl32.dll"); assert(opengl32module); } ptr = (void *)GetProcAddress(opengl32module, name); } return ptr; }
For example, glViewport is defined as
static void GL_APIENTRY _impl_glViewport (GLint x, GLint y, GLsizei width, GLsizei height) { _glptr_glViewport = (PFN_glViewport)GalogenGetProcAddress("glViewport"); _glptr_glViewport(x, y, width, height); }
Output
Members
| Name | Description |
|---|---|
| glrc | This stores modern OpenGL context. It's destroyed along with the hosting window. |
| GL_MAJOR_VER | Constant containing OpenGL major version. Currently it's set to 4. |
| GL_MINOR_VER | Constant containing OpenGL minor version. Currently it's set to 0. |
| WGL_MAJOR_VER | Constant containing Windows Wiggle API major version. Currently it's set to 1. |
| WGL_MINOR_VER | Constant containing Windows Wiggle API minor version. Currently it's set to 0. |
| Name | Description |
|---|---|
| init_opengl_extensions | In order to load any OpenGL context a Display context or DC is required. init_opengl_extensions method first creates a dummy window and initializes its DC with OpenGL 1.1 Context. Later LoadWGLExtensions() is called to load the OpenGL extensions. In the end, the dummy window is destroyed as it contains OpenGL 1.1 context. |
| LoadWGLExtensions | LoadWGLExtensions method loads modern OpenGL extension. It does this by internally calling gladLoaderLoadGL() and gladLoaderLoadWGL() functions. |
| init_opengl | Initializes the host window with specific modern OpenGL context as set by GL_MAJOR_VER and GL_MINOR_VER. |
| 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. | Name | Description |
|---|---|
| camera | Handles 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
| Name | Description |
|---|---|
| DestroyWindow | Called 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. | |
| OnKeyDown | This 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. |
| OnMouseBtnDown | This 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. |
| OnMouseMove | This 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. |
| OnMouseWheel | This 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
|
| OnPaint | 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. |
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