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

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.





Saturday, July 23, 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 mesh class  WFObjMesh is defined for loading OBJ and MTL files. It's used by another new class  WFObj object for loading vertex data and texture data to the vertex and fragment shaders. Note that  a texture is not mandatory.

System  class diagram
WFObj derives from BaseGeometry class. It overrides mesh with an instance of WFObjMesh to generate geometry and material color information.
MaterialInfo
This class contains information about a single Material obtained after parsing a mtl file. This information includes  range of vertices, Ambient, Diffuse, Specular Colors and Texture information etc.  Note that a mtl file can have multiple Materials applicable to a range of vertices.
These are stored in WFObjMesh object discussed below.

Members
NameDescription
ambientclrContains ambient color
diffuseclrContains material information. It contains name of the material, mapped to the MatrialInfo structure.
diffusetxtfilenameContains material file name associated with the obj file
emissiveclrContains normals
rangeContains texture info
shininessContains vertex info
specularclrContains Specular color

WFObjMesh 
WFObjMesh derives from IGeometryMesh 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.
Members
NameDescription
facesContains vertex/texture coordinate/Normal information for each of the vertices of the geometry triangle.
matinfomapContains material information. It contains name of the material, mapped to the MatrialInfo structure.
mtlfilenameContains material file name associated with the obj file
normalsContains normals
texturemapContains texture info
verticesContains vertex info

Constructor
Parses obj and mtl files to generate geometry and color information.

Methods
NameDescription
GenerateVerticesDataThis 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.
normals_countThis method returns number of normals.
texture_countThis method returns number of texture coordinates.
vertex_countThis method returns number of vertices.
readfileThis method reads obj file and mtl file and stores contents in text member
parsegeometrydataThis method generates geometry data from the obj file
parsematerialdataThis method generates material data from the mtl file

Light
This class contains light properties such as ambient Coefficient, light position, and light color.
These are stored in WFObjInfo object discussed below.

Members
NameDescription
ambientCoefficientContains ambient Coefficient. This is multiplied with ambient color of the material.
PositionContains light position. Used in lighting calculations.
ColorContains light color. Used in lighting calculations.

WFOBJInfo
This class contains information about Geometry information and Material color information obtained after parsing .obj and .mtl file.
These are stored in WFObj object discussed below.

Constructors
Creates a fully populated WFOBJInfo from the input parameters.

Members
NameDescription
objfilenameContains name of the obj file
mtlfilenameContains name of the mtl file
viewerposContains texture info if a diffuse texture is available.
lightContains an instance of Light object describing properties of the lighting.
texturemapContains texture info
verticesContains vertex info

WFObj
WFObj derives from BaseGeometry class. It renders objects after parsing obj and mtl files.

Members
NameDescription
hastextureContains true if the object has a diffuse texture file
shapeinfContains an instance of WFOBJInfo
texutlContains an instance of TextureUtil containing texture information if available.

Methods
NameDescription
InitThis method overrides the base class Init method to loads the WFOBJInfo object. It parses obj and mtl files to generate geometric and material information. Generates the vertices data and material data consisting of surface normals in non indexed mode and later sets them up in VBO buffer.  It also sets up initializes texutl to load texture if available.
UpdateUniformsThis method overrides the base class UpdateUniforms method. First it updates  "cameraposition" uniform. It updates "tex" uniform to pass texture object. Also Light and Material properties are passed to the shaders.
vertexShaderSourceThis method overrides the base class vertexShaderSource method. It returns the vertex shader code to render the geometric object.
fragmentShaderSourceThis method overrides the base class fragmentShaderSource method. It returns the fragment shader code to render the  geometric object.
UpdateUniformsLightMatThis method is called by UpdateUniforms() to update light and material properties to the shader.

Output











 

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
cameraPositionSpecifies the location of the light source for diffuse and specular illumination. 
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.

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 sub class. It contains settings of the material property for reflection.
lightAn instance of Light sub 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