Showing posts with label VedaLib. Show all posts
Showing posts with label VedaLib. Show all posts

Saturday, April 4, 2026

Implementation: BaseCamera and Camera Data

Overview
In this post discusses camera  and camera data that is used in projections and animations.
It holds transformation information such as pitch, yaw and roll angles, translation, scaleby as well as Model, View and Projection matrix information of the 3D object. 

Details
Coordinate System
OpenGL uses Right hand side coordinate system where +Z is pointing towards you.
An 3D object can rotate along all the three axes as shown below. 
Rotation along X Axis is called Pitch. Rotation along Y Axis is called Yaw. Rotation along Z Axis is called Roll

The following diagram shows how the positive rotation happens in Counter clockwise direction.
        Pitch(X Axis)                                    Yaw (Y Axis)                                  Roll (Z Axis)

Mouse and Keyboard input support
As discussed earlier, the BaseScene object captures all the Mouse and Keyboard activities such as key press, mouse button press, move etc. Later it's processed by BaseCamera class  or its Derivatives.
For example, in BaseCamera class,  if a key is pressed, its scan code is stored. similarly, if mouse left button is pressed and mouse is moved and then released, delta x and delta y are computed. 
The derived camera classes from BaseCamera may use this information to further compute and  store additional information  in camera data structures.

For Example, ThreeDCamera class implements keyboard and mouse handling as below:
X key  => rotate around X axis by 10 degrees.
Y key  => rotate around X axis by 10 degrees.
Z key  => rotate around Z axis by 10 degrees.
Mouse Drag using left button => Compute Delta X, and Delta Y.
Later this is shared with 3D objects in the scene to draw.


BaseCamera and CameraData
There different types of Camera Data to store different types of information. There are associated with specialized camera classes to process data differently.
The following diagram depicts relation between   BaseCamera and various Camera Data structures.  The details of these are Discussed later.



The following discusses BaseCamera class in detail. The other classes will be discussed in later posts.

BaseCamera
BaseCamera implements handlers for mouse and keyboard events. This is a base class that can be further specialized. It's located in VedaOGLLib\Scene\BaseCamera.h

Constructor
Initializes hwnd with the Window handle of the hosting window.

Members
NameDescription
windowrect
clientrect
Upon events like resize, windowrect and clientrect are updated.
windowrect stores window rectangle of the hosting window after calling GetWindowRect() method.
clientrect stores client rectangle of the hosting window after calling GetClientRect() method.
mouseX,mouseY
deltaX,deltaY
Upon mouse move event, the current X and Y coordinates are stored in mouseX and mouseY. Delta of X and Y coordinates are stored in deltaX and deltaY.
mouseLeftDown
mouseMiddleDown
mouseRightDown
Upon mouse button down event, one of these  is set to true based on the button pressed. Rest are set to false.

Methods
NameDescription
CenterCursor
This method places the cursor at the center of the screen.
OnKeyThis method handles keyboard input events.
OnMouseBtnDown
This method handle mouse button click events.
OnMouseMoveThis method handle mouse move events.
OnMouseWheelThis method handles Mouse scroll wheel inputs. 
UpdateWHThis method handles window resize events.



Monday, July 11, 2022

Implementation: Geometry and Graphics pipeline

Overview
In this post we shall deep dive and understand mechanics behind Geometry and Vertex Data.

Details
 Every 3D object such as cube derives from BaseGeometry class. The following describes this in details.

CameraData class  holds transformation information such as pitch, yaw and roll angles, translation, scaleby as well as Model, View and Projection matrix information of the 3D object. It's implemented in VOGLLib\Camera \CameraData,h file. CamaraData of a 3D object is modified by BaseCameraInputHandler object the of the scene discussed earlier.

IGeometryMesh structure defines the abstract class that every 3D object must override. It defines methods for generating vertices for the 3D object and populating VBO and EBO buffers of VAOUtil object.  It's declared in VOGLLib\Geometry\GeometryMesh.h file. 

VAOUtil  class defines a  VAO and its associated VBOs and EBO discussed in the previous post. The VertexData class stores VBO and EBO data and manages its lifetime. VaoUtil class and VertexData class are implemented  in VOGLLib\Geometry\VAOUtil.h file.  VAOUtil class defines VertexData class for Position, Color, Normal, Texture Coordinates and Indices.
In a typical usage scenario, a 3D object first loads all the vertex data such as position by calling  GenerateVerticesData method of the mesh. Then it calls SetupVBO method for all the vertex data with location number of the the vertex data. Note that the location number has to match with the location number defined in the vertex shader. First time, this will generate a VAO and bind it. VBO is created, data is loaded for GL_STATIC_DRAW, bound and associated with the location and the location is enabled.
In cases of indices, the indices are loaded by calling  GenerateIndicesData method. Later BindEBO method is called. This will  generate a EBO, data is loaded for GL_STATIC_DRAW, bound.

ShaderUtil class loads shader code such as vertex shader and fragment shader , creates program object, attaches shader code and links them to the program object. In addition shaderUtil also stores attribute locations and uniform locations. Errors in compilation are written to the errorlogs.
In usage, first the shader code is attached and linked. At the time of drawing, uniforms are updated and program is set for use. Draw method is called to draw the 3D object. finally program is reset for use. 
ShaderUtil class is implemented  in VOGLLib\Geometry\ShaderUtil.h file.

BaseGeometry class implements base class for all the 3D objects. All the 3D objects such as cube must derive from this class. BaseGeometry class defines 
Init method that loads and attach shaders to program object. 
Cleanup method that does cleanup. 
UpdateUniform updates Projection matrix uniform.
Draw method calls  OpenGL APIs such as glDrawArrays or glDrawElements are used to draw the 3D objects.
In usage, VertexShaderSource and FragmentShaderSource are overridden to supply shader code. Init, Cleanup, UpdateUniforms methods are overridden based on the customization.

Mouse and Keyboard input support


As discussed earlier, the BaseScene object captures  all the Mouse and Keyboard activities such as key press, mouse button press, move etc.  Later it's processed by BaseCameraInputHandler class. For example, If  key is pressed, it's scan code is stored. similarly,  if mouse left button is pressed and mouse is moved and then released, delta x and delta y are computed. All the data is stored in  CameraData.
Later this data is shared with all the 3D objects in the scene to redraw.

For Example, SimpleCameraInputHandler object implements keyboard and mouse handling as below:
Press X key  => rotate around X axis by 10 degrees.
Press Y key  => rotate around X axis by 10 degrees.
Press Z key  => rotate around Z axis by 10 degrees.
Mouse Left Button Down. Mouse Move, Mouse Left Button Up => Compute Delta X, and Delta Y.
Later this is shared with 3D objects in the scene to draw.


Friday, July 8, 2022

Implementation: Initializing OpenGL Context

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, VedaOpenGLLib 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. 
It's located in VedaOGLLib\Scene\OGLAppWindow.h.
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. 
It's located in VedaOGLLib\Scene\BaseScene.h


Members
NameDescription
mskbdHandles 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 mskbd 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 mskbd 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 mskbd 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 mskbd 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 mskbd 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.

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