Thursday, April 16, 2026

Synopsis

The following discusses different topics in Modern OpenGL Tutorials.

______________________________________________________________________________________________________________________________________________________________________
Introduction
OpenGL is a graphics library that can be used to render interactive 2D and 3D graphics applications.OpenGL has wide range of applications.This tutorials attempts to teach basic to advanced concepts one at a time. The goal is to create an advanced , multifunctional library from scratch. The tutorials will be a set of C++ header (.h) files.This tutorial is primarily targeted for windows OS. Visual Studio development environment is used for writing, compiling and debugging the code.
______________________________________________________________________________________________________________________________________________________________________

Implementation - Initializing OpenGL Context
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.
______________________________________________________________________________________________________________________________________________________________________
Lesson01 : Initializing OpenGL Context
This lesson discusses  implementing the basic operations of creating a hosting window, Initializing it with OpenGL context, rendering it and handle mouse/keyboard inputs.
______________________________________________________________________________________________________________________________________________________________________
Primer: Vector
Vectors are widely used  in 3D calculations. A 3D vector is represented as [Vx, Vy,  Vz] where  Vx, Vy and Vz represent numbers in 3D cartesian space.
______________________________________________________________________________________________________________________________________________________________________
Primer: Matrices and Affine transformations
OpenGL uses matrix operations for a lot of purposes. For example, translations, scaling, rotations. Also computing of projection matrices, view matrices etc. The following discusses it in detail.
______________________________________________________________________________________________________________________________________________________________________
Implementation - BaseCamera and Camera Data
Camera is used for projections and animations. It holds camera data which is used for storing mouse and keyboard input information. Further, it stores computed transformation information such as pitch, yaw and roll angles, translation, scaleby as well as Model, View and Projection matrix information of the 3D object. 
______________________________________________________________________________________________________________________________________________________________________
Primer: Graphics Pipeline
A scene consists of  a set of  3D objects. Transformations such as translation, scaling and rotation as a result of Camera movement, mouse and keyboard input brings them into life. 
For example  the following diagram shows a multi color cube with  50 degrees pitch and 20 degrees yaw.
____________________________________________________________________________________________________________________________________________________________________
Implementation:Vertex Buffer
In this post we shall deep dive and understand mechanics behind sending vertex data to the GPU. Vertex data is obtained from mesh objects such as cubemesh which will be discussed later. The vertex data consists of Position, Color, Normal, and Texture Coordinate of each vertex. They are basically stored into VBO, EBO buffers. Later they are packaged into VAO objects.
______________________________________________________________________________________________________________________________________________________________________
Implementation: 3D Mesh
In this post we shall deep dive and understand implementing a mesh.
______________________________________________________________________________________________________________________________________________________________________
Implementation:Shader programs
The following provide an overview of shader programs and their implementation in this tutorial.
______________________________________________________________________________________________________________________________________________________________________
Implementation: Pipeline
In this post we shall deep dive and understand mechanics behind rendering 3D objects on the screen.
So far we discussed  FrameBuffers,Vertex Array Object containing VBO and EBO buffers and  Program Object containing Vertex Shader and Fragment Shaders.
______________________________________________________________________________________________________________________________________________________________________
Implementation: CubeMesh and SingleColoredCube
In this post we shall deep dive and understand implementing a mesh and geometric object for cube shape. We will try to draw a single colored cube as shown above and rotate it along the three axes. The cube looks elongated because aspect ratio is not applied. 
______________________________________________________________________________________________________________________________________________________________________
Lesson02: Single Colored cube
In the previous posts the graphics pipeline and vertex processing were explained. Also, the implementation of the CubeMesh and SingleColoredCube were covered. 
In this post we will try to draw a single colored cube as shown above. The cube looks elongated because aspect ratio is not applied.
______________________________________________________________________________________________________________________________________________________________________
Implementation: Multi Colored Cube
In SingleColoredCube we saw that VBOs were used to draw the single colored cube using Position data. In this post we  will discuss how to draw a Multi Colored cube using VBOs with Position and Color data having unique color on each face. It looks as shown at the bottom. It looks elongated because aspect ratio is not applied.
______________________________________________________________________________________________________________________________________________________________________
Lesson03: Multi-Colored Cube
In the previous posts the graphics pipeline and vertex processing were explained. Also, the implementation of the CubeMesh and SingleColoredCube were covered. 
In this post we will try to draw a single colored cube as shown above. The cube looks elongated because aspect ratio is not applied.
______________________________________________________________________________________________________________________________________________________________________
Implementation:Indexed Cube with interpolated colors
 In this post we  will discuss how to draw an IndexedCube using VBOs and EBO with interpolated colors. It looks as shown above. It looks elongated because aspect ratio is not applied.
______________________________________________________________________________________________________________________________________________________________________
Lesson04:Indexed Cube with interpolated colors
In the previous posts the graphics pipeline and vertex processing were explained. Also, the implementation of the CubeMesh and IndexedCube were covered. 
In this post we will try to draw a cube with interpolated colors as shown above. The cube looks elongated because aspect ratio is not applied.
______________________________________________________________________________________________________________________________________________________________________
Implementation: Textured Cube
In the previous discussions, we covered sending vertex data - Position and color. In this post we will try to send texture vertex data. It's implemented in TexturedCube class.
______________________________________________________________________________________________________________________________________________________________________
Lesson05: Textured Cube
In the previous posts the graphics pipeline and vertex processing were explained. Also, the implementation of the TextureUtil and TexturedCube were covered. 
In this post we will try to draw a cube with brick texture as shown above. The cube looks elongated because aspect ratio is not applied.
______________________________________________________________________________________________________________________________________________________________________
Primer:Lighting
Lighting is an important factor to consider while rendering realistic 3D shapes.  The following discusses adapting lighting conditions while rendering 3D images.
______________________________________________________________________________________________________________________________________________________________________
Implementation: LightedTexCube
In previous examples, we saw that Position, Color, Texture data were sent to draw cubes. In this post we  will discuss how to implement  Phong lighting models and other lights such as Directional, Point and Spot Lights. For this surface normals needs to be sent as VBO data.
______________________________________________________________________________________________________________________________________________________________________
Lesson06: Lighting a Textured Cube interactively
In the previous posts drawing a textured cube were explained. Also, the implementation of the LightingUtil and LightedTexCube were covered. 
In this post we will try to draw a textured cube with lighting interactively. The cube looks as shown above. The cube looks elongated because aspect ratio is not applied.
______________________________________________________________________________________________________________________________________________________________________
Implementation: Drawing Text and Images
Modern OpenGL does not support drawing text or Images so it needs to be handled independently. There many popular libraries available such as freetype to render text in a scene.
______________________________________________________________________________________________________________________________________________________________________
Lesson07: Drawing Text and Images interactively.
As discussed in the  previous article, we saw how Text can be drawn in multiple fonts, sizes and colors and images can be placed side by side.
Also, the implementation of the TextMesh , TextureUtil  and TextImageSketcher were covered. 
In this post we will try to draw  text and image interactively.
______________________________________________________________________________________________________________________________________________________________________
Lesson08: Understanding Affine Transformation interactively.
In this post we shall understand affine transformations interactively the three kinds of affine 
transformations: Scale, Translate and Rotation on X, Y and  Z axes as discussed in the previous post.
The rotation has been already demonstrated in the earlier examples. In this post we will deep dive into Translation and Scaling.
______________________________________________________________________________________________________________________________________________________________________
Primer: Importing WaveFront OBJ Models
Thus far we have worked with the cube geometric object to understand the concepts. In real world, more complex and detailed geometric objects or models are used. They are generated by sophisticated softwares such as blender that can be exported to plethora image formats.
Wavefront OBJ is one such image format.
______________________________________________________________________________________________________________________________________________________________________
Implementation: Importing WaveFront OBJ Models
In previous examples, we saw that Position, Color, Texture data were sent to draw cubes. In this post we  will discuss how to implement  Phong lighting models and other lights such as Directional, Point and Spot Lights. For this surface normals needs to be sent as VBO data.
______________________________________________________________________________________________________________________________________________________________________
Lesson 09: Importing WaveFront OBJ Models
As discussed in the  previous article, we saw how geometric objects can be imported from obj and mtl files. Also, the implementation of the WFObjMesh, WFOBJInfo and WFObj were covered. 
In this post we will try to render a model from "dolphin.obj" and "dolphin.mtl" files.
______________________________________________________________________________________________________________________________________________________________________
Primer: Understanding View space, Perspective and Orthographic Projections
So far our camera was in a fixed position and transformations happened in object space.  In this post we will  look at the larger picture.
______________________________________________________________________________________________________________________________________________________________________$$
Implementation: Perspective and Orthographic Camera
In the previous post, we understood how view matrix, perspective matrix and orthographic matrix. Two new cameras are used to provide perspective and orthographic views.
______________________________________________________________________________________________________________________________________________________________________
Lesson10: Roll Camera and Action Interactively
 In this post understand cameras space and Perspective and Orthographic  projections interactively.
______________________________________________________________________________________________________________________________________________________________________















Monday, August 29, 2022

Sunday, August 28, 2022

Saturday, July 30, 2022

Lesson10: Roll Camera and Action Interactively

Overview 
 In this post understand cameras space and Perspective and Orthographic  projections interactively.

Details
A multi colored cube is rendered interactively after applying inputs for LookAt, Perspective or Ortho projections from an Input dialog. The cube can be rotated using x, y and z keys. The The camera space can be changed by checking LookAt checkbox and supplying  varying input for Position, Target and Up vectors. 
Similarly, Perspective Projection can be changed by checking Perspective checkbox and supplying  varying input for FOV, Near  Plane and Far Plane.  The FOV can be changed by typing page up and down keys or mouse wheel.
Orthographic Projection can be changed by checking Orthographic checkbox and supplying  varying input for X minmax, y minmax and Z minmax values. 


System class diagram
The scene class overrides camera with an instance of DualProjectionCamera. It has an instance of MultiColoredCube called cube derived from BaseGeometry class.
cube overrides mesh with an instance of CubeMesh to generate geometry.

Implementation
Scene

The functionality is implemented in the Scene class derived from BaseScene class.

The three methods Init,DrawScene and Cleanup are overridden as below:
The Init method calls 
  1. BaseScene::Init to create hosting window and OpenGL Context. 
  2. It also attaches camera to a DualProjectionCamera class object. This camera  processes keyboard and mouse inputs as explained earlier.
  3. It calls init function on the MultiColoredCube object to populate VBO buffers and bind them. It also compiles and links shader programs.
The DrawScene method draws the multi colored cube and rotates as per keyboard or mouse inputs and Input dialog settings.

The Cleanup method releases the resources related to VBO and shader programs.

Finally the WM_CLOSE  event is  handled in OnCloseWindow function and the window is destroyed and  application is shutdown when the window is closed or Escape key is pressed. 

Application
Scene class is hosted main.cpp. which creates the scene object and displays it. Message pump is added to process windows messages.

Input dialog
The input dialog as shown below can be used to change settings and understand lighting.


Output
The output looks as shown in the top. 




Tuesday, July 26, 2022

Implementation: Perspective and Orthographic Camera

Overview
In the previous post, we understood how view matrix, perspective matrix and orthographic matrix. Two new cameras are used to provide perspective and orthographic views.

Details
This post discusses camera  and camera data that are used in projections and animations.
The Camera data 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. 

Camera and CameraData
There are many specialized camera classes that are associated with different types of camera data.
The class  diagram below shows their association, The light blue classes are camera data and the others are camera classes. 
The details will be provided in the next posts.
ViewMatrixData
ViewMatrixData class contains Model to World transformation information such as camera position, object position in the world, and the World up vector. They are used by DualProjectionCamera class for calling lookAt function to generate view matrix.
Members
NameDescription
Position
Camera position in world Coordinates.
TargetPosition of the object in world Coordinates.
UpWorlds Up vector.
VContains view Matrix

Methods
NameDescription
getViewMatrixReturns latest View matrix.
setViewMatrixStores inputs such as positions, Target and up. Computes view matrix by internally calling lookAt function. Stores the result in V

PerspectiveProjectionMatrixData
PerspectiveProjectionMatrixData class contains perspective view frustum information such as near plane, far plane and fov angle. Also the aspect ratio. They are used by by DualProjectionCamera class to redraw.
Members
NameDescription
AspectRatioAn aspect ratio is the proportional relationship between the width and height of a shape, image, or screen, expressed as width:height (e.g., 16:9). It defines an object's proportions rather than its physical size, ensuring visuals scale cleanly without distortion.
FOVField of view (FOV) is the angular extent of the observable world that can be seen or captured at any given moment. It dictates how wide or narrow your view is.
NearPlaneA near plane (often called the clipping or projection plane) is the imaginary flat boundary closest to the camera in a 3D perspective view. It acts as a "window" that captures the scene. Everything closer to the camera than this plane is invisible to prevent visual clipping and rendering errors.
FarPlaneA far plane (or far clipping plane) is a boundary defining the maximum distance a virtual camera can "see". Any object or geometry beyond this plane is clipped, meaning it is excluded from the rendered image
PContains latest Perspective Projection Matrix.

Methods
NameDescription
getProjectionMatrixreturns latest Perspective Projection Matrix stored in P
setProjectionMatrixStores inputs such as near plane and far plane and computes Perspective Projection Matrix. Stores the result in P
setFOVStores FOV angle after clipping the input is lower or higher than tolerance.  Later computes Perspective Projection Matrix. Stores the result in P
setAspectRatioIf the input is a float, aspect ratio is stored from the input parameter.
If the input is an integer, the current FOV is doubled and sign is applied. typically used for zooming in or out.
Later computes Perspective Projection Matrix. Stores the result in P

OrthographicProjectionMatrixData
OrthographicProjectionMatrixData class contains orthographic view frustum information such as xmin, xmax, ymin, ymax, zmin, zmax. They are used by by DualProjectionCamera class to redraw.
Members
NameDescription
XMinMaxxmin and xmax define the left and right clipping planes (boundaries) of the 3D viewing volume in an orthographic projection.
YMinMaxymin and ymax define the left and right clipping planes (boundaries) of the 3D viewing volume in an orthographic projection.
ZMinMaxzmin and zmax define the nearest and farthest clipping planes (boundaries) of the 3D viewing volume in an orthographic projection.
PContains latest projection matrix.

Methods
NameDescription
getProjectionMatrixreturns latest Orthographic Projection Matrix stored in P
setProjectionMatrixStores inputs such as X,Y, Z min and max distance and computes Orthographic Projection Matrix. Stores the result in P

DualProjectionCamera
DualProjectionCamera class is derived from ThreeDCamera class. It process mouse and keyboard inputs and calculates zoom factor, view matrix, perspective and orthographic projection matrices. They are updated into ViewMatrixData, PerspectiveProjectionMatrixData, OrthographicProjectionMatrixData object.


Constructor
Initializes hwnd with the Window handle of the hosting window. Internally calls ThreeDCamera constructor.

Members
Name  Description
VMcontains 3D transformation information such as camera position, object position in the world, and the World up vector. . They are updated by based on mouse and keyboard inputs and are shared with 3D objects based on BaseGeometry class  to redraw.
PPM          contains perspective view frustum information such as near plane, far plane and fov angle. Also the aspect ratio. They are updated by based on mouse and keyboard inputs and are shared with 3D objects based on BaseGeometry class  to redraw Perspective projection.
OPMcontains orthographic view frustum information such as xmin, xmax, ymin, ymax, zmin, zmax.  They are updated by based on mouse and keyboard inputs and are shared with 3D objects based on BaseGeometry class  to redraw Orthographic projection.

Methods
NameDescription
CopyToClipboardCopies Unproject() information to clipboard.
OnKeyThis method handles keyboard input events as below:
P  => Captures x,y,z coordinates at current mouse position  in the world space  and copies to clipboard.
PageUp  => doubles current FOV resulting in Zooms Out effect or items on the screen becomes smaller.  This affects only Perspective projection.
PageUp  => current FOV is halved resulting in Zooms in effect or items on the screen becomes bigger.  This affects only Perspective projection.
OnMouseWheelThis simulates ZoomOut when scroll wheel is moved up and ZoomIn when scroll wheel is moved down.
setOrthographicProjectionMatrixApplies latest Orthographic Projection Matrix stored in OPM to the geometry object.
setPerspectiveProjectionMatrixApplies latest Perspective Projection Matrix stored in PPM to the geometry object.
setViewMatrixApplies latest View Matrix stored in VM to the geometry object.
UnprojectInternally called by keyboard handler to capture  x,y,z coordinates at the mouse cursor
UpdateWHCalls BaseCamera's method to reset window sizes and sets aspect ratio.





Monday, July 25, 2022

Primer: Understanding View space, Perspective and Orthographic Projections

Overview
So far our camera was in a fixed position and transformations happened in object space.  In this post we will  look at the larger picture.

Details
As shown in the diagram below, a 3D object in a scene starts off from object space. Model transformation places it in the world space using a model matrix.  Based on the camera position the entire world is transformed into Camera space or view space. This is called view transform. This is done using viewing matrix. It is later moved to screen space using Projection matrix.


So far in our examples, camera is located at the origin and view and projection matrixes are not computed; instead identity matrix is used.  Next we will try to move around the camera and understand different type of projections.

Model Matrix
Model Matrix is responsible for moving 3D objects  from object space to world space. The affine transformation discussed in Lesson 08 are applied.

View Matrix
When the hypothetical camera position is changed, the whole world is transformed around it using view matrix. The internals is as described below (courtesy : learnopengl.com).
 


1. Camera position
The camera position or eye at (0,0,2) is a vector in world space.

2. Camera direction vector
The  Camera direction vector is the direction at which the camera is pointing at. This is computed from the scene's origin or center in this case it's  (0,0,0). Subtracting the camera position vector from the scene's origin vector thus results in the direction vector. This must always point to +Z axis by RHS convention.
Therefore normalize((0,0,2) - (0,0,0)) = (0,0,1)

3. World up vector
The up vector (0,1,0) points to worlds Y axis. This may not be always the case.

4. Right axis vector
The right axis vector represents the positive x-axis of the camera space. This is obtained by doing a cross product on the up vector and the camera direction vector from step 2. 
Therefore cross((0,1,0) -  (0,0,1)) = (1,0,0)

5. Up axis vector
The Up axis vector points to camera's positive y-axis. It's computed by the cross product of the right and direction vector.
Therefore cross((0,0,1) - (1,0,0)) = (0,1,0)

The view matrix is computed as below from glm as below.
mat4 lookAt(vec3 const& eye, vec3 const& center, vec3 const& up)

NameDescription
eyeThe 3D coordinates defining exactly where the camera is located in world space.
centerThe 3D coordinates representing the point in the world that the camera is looking at.
up  A directional hint (usually ([0, 1, 0])) indicating which way is "up" in the world, ensuring the camera doesn't roll or tilt improperly.

Example
In the example below, the camera position or eye vector is placed in front of the cube at (0,0,5). Center is located at (0,0,0) and up vector is (0,1,0).



As mentioned earlier, the World up vector need not be always (0,1,0).
For example,  if  the camera is moved on top of the cube say (0, 5, 0), we will be looking at the  top of the cube.  The eye is (0,5,0), center is (0,0.0) and up is (1, 0, 0) not (0,1,0).



Projections
The final matrix is projection matrix. There are two types of projections
Orthographic and Perspective. The traits are as below.


The following shows another view with the view frustum. A view frustum is a rectangular box that confines the image rendered to be shown on the screen. 


The volume or the frustum is defined by the left, right, top, bottom, near and far plane values. 

perspective
The perspective projection is computed in glm as below. In Perspective projection, the frustum appears as a truncated pyramid. 
perspective(float fovy, float aspect, float zNear, float zFar)

NameDescription
fovy Field of View (FOV) or zoom factor 
aspect Aspect ratio of the viewport. i.e., width/height.
ZNear  Distance from the camera to the near plane
ZFar Distance from the camera to the far plane

Example:
perspective(45.0, 1.84, 1.0, 100.0)
The screenshot below shows the perspective projection of the colored cube rotated 20 degree pitch and 20 degree yaw.


ortho
The orthographic projection is computed in glm as below. In orthographic projection, the frustum appears as a cube. 
ortho(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax)

NameDescription
xminleft of the view frustum
xmax right of the view frustum
ymintop of the view frustum
ymax bottom of the view frustum
ZMin distance from the camera to the near plane
ZMax distance from the camera to the far plane

Example:
ortho(-1.84, 1.84, -1.0, 1.0, 1.0, 100.0); 
Note that the aspect ratio is 1.84.
The screenshot below shows the orthographic  projection of the colored cube rotated 20 degree pitch and 20 degree yaw.

Unproject
Sometimes it's useful to capture x,y,z coordinates in the object space based on the mouse cursor position. UnProject() accomplishes this.  The X,Y coordinates from the mouse cursor position and Z value from the depth buffer is used to compute the window coordinates. Later this is passed to glm unProject() along with Model, View and Projection Matrix, to get the co ordinates in world space.

wstring Unproject(const mat4& ProjectionMat)

NameDescription
ProjectionMatThe current Projection matrix of the mouse coordinate.

Example:
In the below, the red dot in the cube represents mouse cursor position  
x = 353 y = 168 and depth buffer Z = 0.79


Using  Model, View, and Perspective Projection matrices, the world space coordinate is calculated as
0.22, 0.12, 0.43.