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

Friday, August 5, 2022

Implementation: First Person and Orbit Cameras

Overview 
An OpenGL application uses specialized cameras navigate a terrain in 3D scenes or wade thru sections of a complex structure. Some of such implementations are First Person Shooter (FPS) Camera or Orbit Camera or ARC ball Camera.

Details
System  class diagram
New Camera classes derived from DualProjectionCamera are defined. They are FPSCamera and OrbitCamera,

A new mesh class  QuadMesh is defined for loading vertexdata of 3D objects such as walls, ceilings etc in a scene. It's used by another  Quad object for loading vertex data to vertex shader and texture data to the vertex and fragment shaders. 

FPSCamera
FPSCamera class is derived from DualProjectionCamera class. This camera captures objects from the viewpoint of a viewer. Some aspects have to be considered, like the characteristics of the camera (orbiting with the mouse and translation with keyboard keys).
The camera has the following characteristics:
Orbit: The character can look left, right, up, and down; however, if we imagine the character’s head, it can’t be tilted.
Translation: The character can move in four directions: forward, backward, left, and right, up and down. 
It process mouse and keyboard inputs and calculates forward, backward, left, and right, up and down movements. They are updated into MatrixData  objects.

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

Members
Name  Description
camera_frontcontains front of the camera which gets updated when the viewer moves forward or backward or sideways.
camera_poscontains current position based on the movements of the viewer.
camera_upcontains front of the camera which gets updated when the viewer moves up or down.
mouse_sensitivitySensitivity of the mouse to calculate finer movements of the viewer.
velocitySpeed to calculate finer movements of the viewer.

Methods
NameDescription
OnKeyThis method handles keyboard input events and updates camera_pos as below:
W,S : Viewer Move forward or backward
A,D:Viewer Move Left  or right
R,F:Viewer Move Up or Down
OnMouseMoveUpdates camera_pos based on the mouse movements.
setSenseivitySets mouse_sensitivity and velocity values
updateViewMatrixSets starting values of camera_pos, camera_front and camera_up values.

OrbitCamera
OrbitCamera class is derived from DualProjectionCamera class. 
An orbit camera moves in a circle around a central object. The camera always looks at the center of the object. The viewer moves around the object in a circular path while keeping the focus fixed on that center point.  To calculate polar coordinates and spherical coordinates are used.
A polar coordinate represents a point in a 2D space as radius and angle. The point lies on the circumference where the radius is computed from the center point and the angle between the point and  the polar axis.
As shown below, the blue line represents polar axis. r represents the radius.

A spherical coordinate system specifies a given point in three-dimensional space by using a distance and two angles as its three coordinates. 
These are radius r,  the polar angle, θ, and the azimuthal angle, φ, which is the angle of rotation of the radial line around the polar axis.
The three coordinates (r, θ, φ), provide a coordinate system on a sphere, typically called the spherical polar coordinates. 


Given sphere with center point c and [r, θ, φ], the corresponding [x, y, z] coordinates are:
x = c.x + r * cos(θ) * cos(φ)
y = c.y + r * sin(θ)
z = c.z + r * cos(θ) * sin(φ)
They are updated into MatrixData  objects.

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

Members
Name  Description
_minRadiusThe minimum value of radius set during zoom operation.
azimuthAngle_contains the value of current azimuth angle.
center_The center defaulted to 0,0,0.
polarAngle_contains the value of current polar angle.
radiusThe current value of the radius.
upVector_The up vector defaulted to 0,1,0.
zoomfactorThe increments of the zoom both ways defaulted to 0.5
mouse_sensitivitySensitivity of the mouse to calculate finer movements of the viewer.

Methods
NameDescription
OnKeyThis method handles keyboard input events and updates radius as below:
Left Arrow : Makes radius bigger
Right Arrow : Makes radius smaller
OnMouseMoveLeft Button: Rotates all the objects
Right Button: Changes Azimuth and Polar angles resulting in circular motion of the objects
Middle Button: Changes center point resulting in panning motion of the objects horizontally and vertically.
geteyeReturns current viewer position
getNormalizedViewVectorReturns normalized value of  (center_ - getEye())
getUpVectorReturns upVector_
getViewPointReturns center_
moveHorizontalPans entire scene horizontally as a result of mouse movement
moveVerticalPans entire scene vertically as a result of mouse movement
rotateAzimuthRotates entire scene horizontally as a result of mouse movement
rotatePolarRotates entire scene vertically as a result of mouse movement
updateViewMatrixSets view matrix data based on current positions of the eye, center_ and upVector_.
zoomSets fov based on keyboard input resuting in zoom out and zoom in actions.



Monday, August 1, 2022

Implementation: Importing WaveFront OBJ Models

Overview 
As discussed before, WaveFront OBJ and MTL files needs to be parsed to get geometry, Material information. A new mesh class and new geometry object are required for this.

Details
A new utility class  GenericObjParser is defined for loading OBJ and MTL files and generating VertexData, Material and texture information. A model can consists of 1 or more Mesh. Each mesh is associated with 1 material which in turn is associated with 0 or 1 texture. Each MeshInfo object represents a mesh which contains Vertex Data consisting of vertices.

System  class diagram
The GenericParser is an abstract class. There are derived two derived classes WFObjParser and AssetImpParser to implement parsing functionality.

A new mesh class  GenericObjMesh is defined for loading vertexdata, Material and texture data. It's used by another new class  GenericObj object for loading vertex data to vertex shader and texture data to the vertex and fragment shaders. Note that  a texture is not mandatory. A GenericObj  is created for each MeshInfo object generated by the GenericParser derivative.

MeshInfo
MeshInfo is an utility class that holds vertex data of the various meshes defined by the OBJ file.

GenericParser
GenericParser the base class for parser classes that parses OBJ file and MTL files to provide geometry  and material color information for rendering. It supplies vertices, texture coordinates, normals, Ambient, Diffuse, Specular Colors and Texture information.

WFObjParser 
WFObjParser derives from GenericParser class. It parses OBJ file and MTL files to provide geometry  and material color information for rendering. It supplies vertices, texture coordinates, normals, Ambient, Diffuse, Specular Colors and Texture information.

AssetImpParser
AssetImpParser derives from GenericParser class. It parses OBJ file and MTL files to provide geometry  and material color information for rendering. It supplies vertices, texture coordinates, normals, Ambient, Diffuse, Specular Colors and Texture information. Internally it uses AssetImport library.

GenericObjMesh
This class derives from IGeometryMesh class. It contains information about Geometry information and Material color information obtained after parsing .obj and .mtl file.
GenericObj
GenericObj derives from BaseGeometry class. It renders objects after parsing obj and mtl files.

Output

Tuesday, July 26, 2022

Implementation: DualProjectionCamera 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.


Thursday, July 21, 2022

Implementation: Drawing Text and Images

Overview 
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.

Details
In this post we shall discuss drawing text using GDI+ APIs. The plan is to  draw text and Images onto a memory based bitmap which is later loaded as a texture.
A new mesh class  TextMesh is defined for loading bitmap as texture. It's used by TextImageSketcher object for loading vertex data and texture data to the vertex and fragment shaders.
TextImageSketcher uses GDIPlus to create ARGB in memory bitmap containing text to be drawn. The size of the bitmap should be multiples of 128. i.e.,  128, 256, 512 etc.
First bitmap is filled with black color and then Text is drawn using the font and color. Note the text color needs to be non black. Font can be changed by passing LOGFONT structure, Also text color can be changed by passing COLLOREF of the color.
Fragment shader is modified for blending fragments with the background.
The client needs to first Startup() GDIPlus in the beginning of the application and Shutdown()  at the end.
Instantiate TextImageSketcher object by Init() method supply unique texture id and size.
DrawText() can be called to draw text and supply font details and text color. 
DrawImage() can be called to render images.
The TextImageSketcher object can be translated, rotated etc.  just like any 3D object.

System  class diagram
TextImageSketcher derives from BaseGeometry class. It overrides mesh with an instance of TextMesh to generate 2D geometry. It also uses TextureUtil to render text and images into the texture.


TextMesh
TextMesh derives from IGeometryMesh class. It provides 2D geometry for drawing text and images. It supplies vertices and texture coordinates.





Members
NameDescription
texturemapProvides texture map.
verticesProvides 2D vertices.

Methods
NameDescription
InitThis method generates vertex data for the GPU to render the geometrical shape. This method is called if the data is sent in  non indexed mode.
It generates position and vertex data.

TextureUtil
TextureUtil implements handling textures from image files and bitmaps. It's used by multiple purposes such as rendering 3D objects or text.
Members
NameDescription
textureIDUnique texture handle returned after creating the texture.
texunitUnique texture unit. It's value should be one of the 80 values supported by the system.

Methods
NameDescription
CleanupReleases resources.
InitAssigns unique texture unit to texunit.
LoadTextTextureUsed to render text. It generates texture from GDI bitmap.
LoadTextTextureImageUsed to render text. It wraps 2D image from GDI bitmap.
LoadTextureLoads texture from an image file.
MakeActiveMakes the texture active.

TextImageSketcher
TextImageSketcher derives from BaseGeometry class. It renders text and images. The utility class TextureUtil is used for loading text and images onto the texture.



Members
NameDescription
wd
ht
Specifies the dimensions of the bitmap. 
texutlAn instance of TextureUtil. It helps with loading text and images onto the texture.

Methods
NameDescription
InitThis method overrides the base class Init method to load texture.  Generates the vertices data consisting of surface normals in non indexed mode and later sets them up in VBO buffer.  It also prepares the bitmap for rendering text and images on it. It also initializes the texutl object with texture id for loading textures.
UpdateUniformsThis method overrides the base class UpdateUniforms method. First it updates  "cameraposition" uniform. It also updates "tex" uniform to pass texture object.
vertexShaderSourceThis method overrides the base class vertexShaderSource method. It returns the vertex shader code to render the texture object.
fragmentShaderSourceThis method overrides the base class fragmentShaderSource method. It returns the fragment shader code to render the  texture object.
CleanupThis method overrides the base class Cleanup method. It releases the resources used by the host object.
Init()
Shutdown()
These methods are called by the client during start up and shutdown to initialize GDI Plus environment.
ClearCanvasThis method clears the bitmap for fresh renderings of text and images.
DrawtextThis method renders input text string based on the input such as font, color and string formats.
DrawimageThis method reenders the image in the file name and resizesto fir based on the clipping width and height inputs
DrawCanvasThis method loads the bitmap onto the texture.

Output







Saturday, July 16, 2022

Implementation: LightedTexCube

Overview 
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. They look as shown at the bottom. They look elongated because aspect ratio is not applied.

Details
System  class diagram
LightedTexCube derives from TexturedCube class. It overrides mesh with an instance of CubeMesh to generate geometry. 
LightedTexCube
LightedTexCube is derived from TexturedCube class. It illuminates the textured cube as per settings done in the light parameter. Utility class gLightingUtil is used for lighting related settings.

Members
NameDescription
lightAn instance of LightingUtil. It contains settings for illumination.

Methods
NameDescription
InitThis method overrides the base class Init method to load texture.  Generates the vertices data consisting of surface normals in non indexed mode and later sets them up in VBO buffer.  It also passes an input to use BlinnPhong or Phong illumination and also type of light source as defined by LightSource enum.
UpdateUniformsThis method overrides the base class UpdateUniforms method. Firs t it updates  "cameraposition" uniform. Next it updates lighting related uniforms by calling Updateshader method on light. Finally it c alls base class UpdateUniforms method to send rest.
vertexShaderSourceThis method overrides the base class vertexShaderSource method. It returns the vertex shader code to render the cube object.
fragmentShaderSourceThis method overrides the base class fragmentShaderSource method. It returns the fragment shader code to render the cube object based on light source type.


MaterialInfo
This class contains information about a single Material obtained after parsing a mtl file. This information includes  Ambient, Diffuse, Specular Colors and Texture information etc.  Note that a mtl file can have multiple Materials applicable to a range of meshes.
These are stored in LightingUtil object discussed below.
Members
NameDescription
nameName of the material.
ambientColorContains ambient color
diffuseColorContains Diffuse color
specularColorContains Specular color
ShininessContains shininess value

LightSrcInfo
This class contains information about the light source and viewer position for lighting calculations.
These are stored in GenericObj object discussed below. 
Members
NameDescription
srcContains light source type information. It has to be one of LightSourceType
nameName of the light source.
ambientCoefficient
ambientColor
Contains Ambient Coefficient and color
diffuseCoefficient
diffuseColor
Contains Diffuse Coefficient and color
specularColor
specularCoefficient
Contains Specular Coefficient and color
blinnContains boolean value to indicate to render blinn-phong(true) or phong(false)  lighting.
positionContains light position  information required for basic, point and spot lighting.
directionContains direction information required for directional lighting.
attconstant
attlinear
attquadratic
Contains light attenuation information required for point and spot lighting.
spotlightinner
spotlightouter
Contains light angle information required for spot lighting.

LightingUtil
It defines illumination properties of the light source and reflection properties of the material in the light and material members.
Members
NameDescription
materialAn instance of Material class. It contains settings of the material property for reflection.
lightAn instance of LightSrcInfo class. It contains settings for illumination.

Methods
NameDescription
UpdateShaderUpdates the uniforms that contains copies of the information stored in light and material members.

Output
The output looks as shown below.

Thursday, July 14, 2022

Implementation: Textured Cube

Overview 
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.
It looks as shown at the bottom. It looks elongated because aspect ratio is not applied.

Details
A Texture is 2D image that can be wrapped around a 3D object like a gift wrapper. For example, resources\textures\bricks2.jpg is a 2D Texture file. 
Unlike cartesian coordinates, Texture follow UV  System as shown below.

TextureUtil Class is used for loading textures. 

Loading Texture
OpenGL supports up to 80 Textures and each with its own identifier. Loading textures is implemented in LoadTexture method in TextureUtil class. It calls the following SOIL library method. Refer to SOIL  documentation for further info.

Syntax
unsigned int
SOIL_load_OGL_texture
(
    const char *filename,
    int force_channels,
    unsigned int reuse_texture_ID,
    unsigned int flags
)

NameDescription
filename The name of the file to upload as a texture
force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
flags  flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT | SOIL_FLAG_NTSC_SAFE_RGB  |  SOIL_FLAG_CoCg_Y  | SOIL_FLAG_TEXTURE_RECTANGLE | SOIL_FLAG_PVR_LOAD_DIRECT | SOIL_FLAG_ETC1_LOAD_DIRECT | SOIL_FLAG_GL_MIPMAPS   | SOIL_FLAG_SRGB_COLOR_SPACE
return value0-failed, otherwise returns the OpenGL texture handle

MIPMAP
Mipmapping is a technique where a high-resolution texture is downscaled and filtered so that each subsequent mip level is a quarter of the area of the previous level. This means that the texture and all of its generated mips requires no more than 1.5 times the original texture size. An example is shown below.


Inversion of Y Axis
After loading the image needs to be inverted since the V axis of the texture and Y axis of OpenGL  have opposite polarity.

Wrapping
As shown below, the wrapping mode determines how the texture is wrapped.

Texture Filtering
Texture filtering is a method that is used to improve the texture quality in a scene. Without texture filtering, artifacts like aliasing generally look worse. Texture filtering makes textures look better and less blocky.

Applying Texture
As discussed previously, Texture coordinates are passed during rendering. The following mapping in relation to the UxV axes is used as texture coordinates for the vertices consecutively.

//First Triangle
{ 0.0f, 1.0f },
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
//Second Triangle
{ 1.0f, 0.0f },
{ 1.0f, 1.0f },
{ 0.0f, 1.0f }

System  class diagram
Every 3D object such as IndexedCube  derives from BaseGeometry class. It overrides mesh with an instance of CubeMesh to generate geometry. It uses a helper class texutl to help render texture.
TextureUtil
TextureUtil implements handling textures from image files and bitmaps. It's used by multiple purposes such as rendering 3D objects or text.
Members
NameDescription
textureIDUnique texture handle returned after creating the texture.
texunitUnique texture unit. It's value should be one of the 80 values supported by the system.

Methods
NameDescription
CleanupReleases resources.
InitAssigns unique texture unit to texunit.
LoadTextTextureUsed to render text. It generates texture from GDI bitmap.
LoadTextTextureImageUsed to render text. It wraps 2D image from GDI bitmap.
LoadTextureLoads texture from an image file.
MakeActiveMakes the texture active.

TexturedCube
TexturedCube is derived from BaseGeometry class. It assembles vertex data generated by mesh in VBO and EBO buffers. Later  sent to GPU using shader programs.
Members
NameDescription
filenameFile name of the image file containing the texture.
texutlTexture utility to aid rendering texture.

Methods
NameDescription
InitThis method overrides the base class Init method. It creates the mesh object. Generates the vertices and texture data in non indexed mode and later sets them up in VBO buffers of the GPU. It later loads the texture from the image file.
UpdateUniformsThis method overrides the base class UpdateUniforms method. The base class method updates the "transform" matrix uniform by calling GetTransformationMatrix method. It updates the uniform "tex" containing the texture coordinates from to the loaded texture.
vertexShaderSourceThis method overrides the base class vertexShaderSource method. It returns the vertex shader code to render the cube object.
fragmentShaderSourceThis method overrides the base class fragmentShaderSource method. It returns the fragment shader code to render the cube object.
CleanupReleases resources. Calls base class method and the texutl.

Output