Showing posts with label Essentials. Show all posts
Showing posts with label Essentials. Show all posts

Saturday, July 16, 2022

Essential 3D math - Matrices

OpenGL uses matrix operations for a lot of purposes. For example, translations, scaling, rotations. Also computing of projection matrices, view matrices etc.
OpenGL uses 4x4 matrix used in homogenous coordinate system. Where each coordinate is represented as [x,y,z,w].Where w=1 for the affine transformations such as  translations, scaling, rotations. W can be any floating point number in the range -1.0 to 1.0 for projection matrices. During rasterization x, y, z coordinates are computed as  x/w, y/w and z/w. This is known as perspective divide.

OpenGL uses columnar matrix multiplication as shown below.

Identity Matrix
A special matrix having all elements along diagonal as 1 as shown below. 
It is associative, I*M = M*I = M. It's used in the computation of rotation, translation and scaling as discussed below.


Translation Matrix
Translation matrix is used for moving around 3d objects.
Example:
Let's say there is a point [1,2,3] and want to translate by [4,5,6]. It can be accomplished as below. Resulting in  [5,7,9].

Scaling Matrix
Scaling matrix is used for Shrinking or Expanding 3d objects.










Example:
Let's say there is a point [1,2, 3] and want to  scale by [2,2,2]. It can be accomplished as below. Resulting in  [2,4,6].

Rotation
In 3D, rotation happens independently  on three cardinal axes X, Y, and Z.
Pitch or Rotation on X axis
The following matrix represents rotation matrix on X axis.

Example:
Let's say there is a point [1,2, 3] and want to  rotate by 90 degrees in X axis. It can be accomplished as below. Resulting in  [1,-3,2].
Yaw or Rotation on Y axis
The following matrix represents rotation matrix on Y axis.
Example:
Let's say there is a point [1,2, 3] and want to  rotate by 90 degrees in Y axis. It can be accomplished as below. Resulting in  [3,2,-1].









Roll or Rotation on Z  axis
The following matrix represents rotation matrix on Z axis.

Example:
Let's say there is a point [1,2, 3] and want to  rotate by 90 degrees in Z axis. It can be accomplished as below. Resulting in  [-2,1,3].













Friday, July 15, 2022

Essential 3D math - Vector

Following math concepts are essential for further understanding.

A 3D vector is represented as [Vx, Vy,  Vz] where  Vx, Vy and Vz represent numbers in 3D cartesian space. Vectors are attributed with a direction represented by its head  and a magnitude computed as square root of the squared sums of its components.


Unary negation and scalar multiplication 
The  negation and multiplication is done on all the components.
For example consider a vector
v=[1,2,3] so  2*v results in [2,4,6]. Similarly -v results in [-1,-2,-3].

Addition and Subtraction
Vectors can be added or subtracted. Here the individual components are added or subtracted. 
For example consider two vectors  A[1,2,3] and B[4,5,6]. 
A+B = [(1+4), (2+5), (3+6)] = [5, 7, 9].
A-B =  [(1-4), (2-5), (3-6)] = [-3, 3, -3].
Graphically represented as below, Note that the direction has changed  when arguments are reversed.

Unary Vectors
also known as normalized vectors are represented as V^  have magnitude of 1. 

For Example V = [3,2,1]. It's normalized vector is calculated as
[2,3,1]/sqrt(4+9+1) = [3/3.74, 2/3.74, 1/3.74]=[0.8, 0.53, 0,27]


Dot Product
Dot Product of  two vectors is equal to the product of their magnitudes and the cosine of the angle between them. The notation used is a.b where a and b are vectors. It's mathematically represented as
a ·b = |a| x |b| x cos(θ).
It's graphically represented as 




To compute angle between two unit vectors, mathematically it can be represented as

The dot product may be a positive  or a negative or a zero.




Cross Product
Cross Product of  two vectors is equal to the product of their magnitudes and the sine of the angle between them. The notation used is axb where a and b are vectors.
Mathematically it's represented as

Cross product yields a vector that is perpendicular to the plane of two vectors a and b. Graphically it's represented as



The cross product of two vector is equal to area of their parallelogram.







Sunday, July 10, 2022

Primer: Graphics Pipeline

Overview
A scene consists of one or more 3D objects.  The shapes of these 3D objects are typically described using triangles as shown in the 3D wire frame of a rabbit below.
These triangles are in turn are defined by their vertices. A vertex is the corner of the triangle where two edges meet, and thus every triangle is composed of three vertices. 

Modern OpenGL supports many different primitives  such as Points(GL_POINTS), Triangle(GL_TRIANGLE)  and Line Strip (GL_LINE_STRIP) etc. as shown below.

However this tutorial focusses only on 3D shapes rendered as  triangles.

Details
In OpenGL, the Graphics pipeline is responsible for rendering 3D objects. The following gives a brief overview without over burdening with the complex  details. As you get familiar, this can be revisited to gain a deeper understanding.

FrameBuffer
The output of graphics pipeline ends up in Framebuffer. Framebuffer is piece of memory within the graphics card that maps to the display. For simplicity, you can assume that it's like a bitmap covering entire viewport. Double framebuffers are used to avoid screen tearing while rendering the scene. For example, after the first frame of a scene is written by the pipeline into framebuffer, it's drawn on the screen while the framebuffer2 is filled with the second frame of the scene. Then it's swapped with the first so that  the screen now displays the second frame while third frame is written in to the framebuffer etc.

OpenGL  Graphics pipeline
OpenGL provides a multi-stage graphics pipeline that is partially programmable using a language called GLSL (OpenGL Shading Language) as shown below. Each of these programmable units are called shaders.


To kick off this chain, the C++ application supplies vertex data consisting of  vertices. 
For a triangle primitive, each vertex maps following information:
  • X, Y, Z coordinate (mandatory)
  • Color (optional)
  • Normal vector (optional)
  • Texture coordinates (optional)
The vertex data is first fed to the vertex shader.

Vertex Shader
This stage is mandatory. A vertex shader is a graphics processing function used to add special effects to objects in a 3D environment by performing mathematical operations on the  vertex's data. Vertex Shaders don't actually change the type of data; they simply change the values of the data, so that a vertex emerges with a different color, different textures, or a different position in 3D space.

Tessellation Shader
This stage is optional and not available to OpenGL release 3.3.  After the vertex shader has processed each vertex’s associated data, the tessellation shader stage will continue processing those data, if it has been activated. Tessellation uses patches to describe an object’s shape, and allows relatively simple collections of patch geometry to be tessellated to increase the number of geometric primitives providing better-looking models. The tessellation shading stage can potentially use two shaders to manipulate the patch data and generate the final shape.

Geometry Shader
This stage is optional. Allows additional processing of individual geometric primitives, including creating new ones, before rasterization. This shading stage is also optional, but very powerful.

Rasterization
The primitive assembly stage organizes the vertices into their associated geometric primitives in preparation for clipping and rasterization. Clipping removes all pixels outside of the viewport.
After clipping, the updated primitives are sent to the rasterizer for fragment generation. Consider a fragment a candidate pixel, in that pixels have a home in the framebuffer, while a fragment still can be rejected and never update its associated pixel location. Processing of fragments occurs in the next two stages, fragment shading and per-fragment operations.

Fragment Shader
This stage is necessary for the practical reasons. Fragment shader determines the fragment’s final color , and potentially its depth value. Fragment shaders are very powerful as they often employ texture mapping to augment the colors provided by the vertex processing stages. A fragment shader may also terminate processing a fragment if it determines the fragment shouldn’t be drawn; this process is called fragment discard.

Pixel Operations
A fragment’s visibility is determined using depth testing (also commonly known as Z-buffering) and stencil testing. If a fragment successfully makes it through all of the enabled tests, it may
be written directly to the framebuffer, updating the color (and possibly depth value) of its pixel, or if blending is enabled, the fragment’s color will be combined with the pixel’s current color to generate a new color that is written into the framebuffer.

In the next post we will discuss the nitty gritty of rendering a cube.

Thursday, July 7, 2022

Introduction


Overview
OpenGL is a graphics library  that can be used to render interactive 2D and 3D graphics applications.
OpenGL has wide range of applications. OpenGL library comes in two flavors. 
  • Deprecated fixed pipeline based API or legacy OpenGL  ( releases before 3.0)
  • Shader based API  or Modern OpenGL  (release 3.0 and onwards)
Modern OpenGL uses GPU instead CPU there by increasing user experience tremendously.  legacy OpenGL is still supported for backward compatibility as of latest release 4.6.
In this tutorial  we consider shader based approach.

Details
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.
There are plenty of websites with rich documentation on different OpenGL related topics. For various topics, a short description will be provided along with a link for further details.

This tutorial is primarily targeted for windows OS. Visual Studio development environment is used for writing,  compiling and debugging the code.

Prerequisites
OpenGL programming is  different from normal programming.  Following is a check list:
  • 3D math such as vectors, planes, rays etc., 
  • Matrix arithmetic
  • Trigonometry
  • Understanding of motion related  physics
  • Intermediate C++ programming 
  • Visual studio 2015 or higher
  • GLSL concepts and programming 
Development Environment
VS2015 IDE is used for building externals and lessons in the tutorials. The steps will be slightly different in the later versions.

Tutorial Layout
The Tutorial directory structure is laid out as shown below. 

Externals
The following folders contains 3rd party libraries used by the tutorial for loading OpenGL extensions, perform vector math, matrices calculations. loading texture, object model  etc.

GLExtns
OpenGL is a widely adopted specification (API) for rendering 2D and 3D graphics that is implemented by hardware vendors. The specification, managed by the Khronos Group, defines a set of functions and behaviors that graphics card manufacturers incorporate into their drivers. 
These APIs are  defined in the OpenGL header files and implemented in OpenGL.Lib. Client applications must include these header files and link with OpenGL.Lib to interact with the hardware.
The OpenGL header file included as a part of windows SDK supports OpenGL specification 1.1. The Modern OpenGL tutorial uses  OpenGL specification 3.3. The extensions will be loaded after the context is created. This will be discussed in detail in the next post.
As the OpenGL specification 3.3 has just too many APIs, the extensions needs to be supplied by a separate library.
The both the header file and implementation of OpenGL specification 3.3 can be downloaded from Galogen web site. 
In addition, latest WGL extensions should also be included. This can be downloaded from registry.khronos.org

The header files and the implementation of both OpenGL Extensions and WGL Extensions are located in the  externals\extns folder as shown below.

The header files are 
externals\extns\GL\GL.h
externals\extns\GL\WGLExt.h

The implementation files are
externals\extns\GL.c
externals\extns\WGLExt.c

A VS2015 wrapper project uses the above files to generate static debug and release libraries, that are available as listed below.
externals\extns\Lib\GLExtensions_static_x86_d.lib
externals\extns\Lib\GLExtensions_static_x86.lib

GLM
Rendering 3D context involves lot of vector math, matrix math, trigonometry etc. 
GLM conveniently provides a math library including all these and more. In addition it also provides APIs for creation of Ortho and Perspective projection matrix, transformations such as translation, rotation and scaling, lookat matrix and much more. 
GLM can be downloaded from glm website.
GLM is implemented as set of header files. They are located in the folder.listed below:
externals\glm \glm

Simple OpenGL Image Library
SOIL2 is used for loading textures. displaying bitmaps etc. SOIL2 can be downloaded from github
The header and implementation files of SOIL2 are located under folder:
externals\SOIL2\src

A VS2015 wrapper project uses the above files to generate static debug and release libraries, that are available as listed below.
externals\SOIL2\projects\VC15\libs\SOIL_static_x86_d.lib and externals\SOIL2\projects\VC15\libs\SOIL_static_x86.lib.

In addition to the above, the tutorial also uses other facilities implicitly provided by the Windows SDK and the Compiler as discussed below. These are not listed in the diagram.

Window Creation and Management
Creating an OpenGL window requires using a platform-specific library, as OpenGL itself does not provide window or input management functionality. ATL (Activex Template Library) is used to create windows and manage them.

ATL is part of Visual Studio C++ installation and its source files are located under the folder.
C:\Program Files\Microsoft Visual Studio\2015\Professional\Common7\IDE\ItemTemplates\VC\ATL

Mouse and Keyboard Input
OpenGL itself is purely a graphics rendering API and does not have built-in functions for handling mouse and keyboard input. To manage  mouse and keyboard inputs  Win32 API  provided by the Windows SDK are used.

OpenGL Context Creation
Creating an OpenGL (GL) context is the process of setting up the necessary environment and state machine for an application to use the OpenGL API. Because OpenGL is a platform-independent specification, the actual context creation is handled by platform-specific APIs or, more commonly, by cross-platform libraries. 
For creating OpenGL context, WGL or Wiggle APIs are used.  They are included as a part of Windows SDK.

The Windows SDK is located under the folder C:\Program Files (x86)\Windows Kits\

Lessons
This folder contains source code and binaries of the applications related to the OpenGL topics and features discussed in the tutorial.

Lessonsnn
These folders contains the lessons on different topics. The lessons are named as below:
Lesson<nn> <Description>. 
Example, Lesson01 Creating OpenGL Context, Rendering
Each folder contains a VS2015 project that wraps source files related to the topic. After building , the generated executable are transferred to the bin folder.
These lessons refer to different features of OpenGL implemented in VedaOpenGLLib discussed below.

bin
This folder contains executables and other binaries of the lessons generated during the build.

Resources
This folder contains bitmaps, texture bitmaps, wireframe models used in the tutorial.

VedaOpenGLLib
This folder contains source code of the applications related to the OpenGL topics and features discussed in the tutorial. It's a set of header files that can be included by the client applications.  


The following discusses some of the aspects implemeted by VedaOpenGLLib. 
These are located under the folder VedaOpenGLLib.

Geometry
This folder defines some base classes responsible for sending vertex data and also rendering  objects such as Text, Cube etc.

Camera
This folder contains classes responsible  for different type of projections of  the scene and mouse and keyboard handling for the same.

Lighting
This folder contains classes responsible lighting the objects in the scene.

Scene
This folder contains classes responsible creating OpenGL context and host window.

CompileLink.h
This header file defines alias locations of the header files of the externals discussed above.  It also defines the location of the libraries provided by Windows SDK and the externals. 
Note that include file locations and libraries locations are predefined. If your setup is different then this file needs to be edited.
It's used by the compiler and the linker during the build. 
#pragma once
#define WGL_WGLEXT_PROTOTYPES
#pragma include_alias( "GL/GL.h", "..\..\externals\GLExtns\GL\GL.h" )
#pragma include_alias( "GL/wglext.h", "..\..\externals\GLExtns\GL\wglext.h" )
#pragma include_alias( "SOIL2.h", "..\..\externals\SOIL2\src\SOIL2\SOIL2.h" )
#pragma include_alias( "glm/glm.hpp", "..\..\externals\glm\glm\glm.hpp" )
#pragma include_alias( "glm/gtc/matrix_transform.hpp", "..\..\externals\glm\glm\gtc\matrix_transform.hpp" )
#pragma include_alias( "glm\gtx\transform.hpp", "..\..\externals\glm\glm\gtx\transform.hpp" )
#pragma include_alias( "glm/gtc/type_ptr.hpp", "..\..\externals\glm\glm\gtc\type_ptr.hpp" )
#pragma include_alias( "glm/ext/matrix_projection.hpp", "..\..\externals\glm\glm\ext\matrix_projection.hpp" )
#ifdef _DEBUG
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "..\\..\\externals\\GLExtns\\lib\\GLExtensions_static_x86_d.lib")
#pragma comment(lib, "..\\..\\externals\\SOIL2\\projects\\VC15\\libs\\SOIL_static_x86_d.lib")
#else
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "..\\..\\externals\\GLExtns\\lib\\GLExtensions_static_x86.lib")
#pragma comment(lib, "..\\..\\externals\\SOIL2\\projects\\VC15\\libs\\SOIL_static_x86.lib")
#endif

Creating tutorial lesson projects
Following steps can be used to create a empty tutorial lesson project using VS IDE

Create an Win32 project in VS IDE wizard under Lessons folder. Provide a valid name for  the project.



Select Empty Project and no SDL check


Add include directory in VC directories



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