Learn Modern OpenGL for Windows OS from scratch and its use in areas such as clinical imaging.
Sunday, August 28, 2022
Saturday, August 6, 2022
Wednesday, August 3, 2022
Lesson 08: Start Camera and Roll
In this post understand cameras space and Perspective and Orthographic projections interactively.
Orthographic Projection can be changed by checking Orthographic checkbox and supplying varying input for X minmax, y minmax and Z minmax values.
Monday, July 25, 2022
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.
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. 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.
Tuesday, July 19, 2022
Lesson 07:Drawing Text interactively.
As discussed in the previous article, Text can be drawn in multiple fonts, sizes and colors. Also can be moved around. It's implemented in Lessons\Lesson07 project.
Monday, July 18, 2022
Drawing Text
Sunday, July 17, 2022
Lesson06:Understanding Affine Transformation interactively.
- Scale
- Rotate by Z,X,Y
- Translate
M = mat4(1);
M = translate(M, translateby);
M = rotate(M, radians((float)(yaw)), vec3(0.0f, 1.0f, 0.0f));
M = rotate(M, radians((float)(pitch)), vec3(1.0f, 0.0f, 0.0f));
M = rotate(M, radians((float)(roll)), vec3(0.0f, 0.0f, 1.0f));
M = scale(M, scaleby);
Saturday, July 16, 2022
Essential 3D math - Matrices
Friday, July 15, 2022
Essential 3D math - Vector
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.
Lesson05: Multi-Colored Cube
//Implements multi colored cube
class MultiColoredCube :public BaseGeometry
{
public:
//OpenGL initialization
void Init()
{
//initialize opengl context
BaseGeometry::Init(new CubeMesh());
//generate vbo data
kount = mesh->GenerateVerticesData(false, VAOUtil::POS | VAOUtil::CLR, vaoutl);
//setup vertices
vaoutl.SetupVBO(0, VAOUtil::POS);
vaoutl.SetupVBO(1, VAOUtil::CLR);
vaoutl.unbindVAO();
}
//override
virtual string vertexShaderSource()
{
return R"(
#version 330 core
layout (location = 0) in vec3 vVertex;
layout (location = 1) in vec3 vColor;
out vec3 fcolor;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(vVertex, 1.0);
fcolor = vColor;
};
)";
}
//override
virtual string fragmentShaderSource()
{
return R"(
#version 330 core
in vec3 fcolor;
out vec4 FragColor;
void main()
{
FragColor = vec4(fcolor,1.0);
};
)";
}
};
#include "Scene\BaseScene.h"
#include "Geometry\Cube\MultiColoredCube.h"
class Scene:public BaseScene
{
public:
//message handler
BEGIN_MSG_MAP(Scene0)
MESSAGE_HANDLER(WM_CLOSE, OnCloseWindow)
CHAIN_MSG_MAP(BaseScene)
END_MSG_MAP()
//override
int Init(RECT rect, WCHAR *windowname)
{
//create host window and context
BaseScene::Init(rect, windowname);
//attach mouse keyboard input handler
mskbd = new BaseCameraInputHandler(m_hWnd);
//Create multicolor cube
cube.Init();
return 0;
}
//release resources
void Cleanup()
{
cube.Cleanup();
delete mskbd;
}
//draw the scene
void DrawScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//get model view projection matrix.
//only model is modified
//view and projection will be identity matrix
mskbd->fetchCameraData(&cube.camera);
cube.Draw();
}
//Close the window
LRESULT OnCloseWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = TRUE;
DestroyWindow();
PostQuitMessage(0);
return 0;
}
private:
MultiColoredCube cube;
};
#include "Scene.h"
Scene scene;
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd_line, int show)
{
scene.Init(RECT{ 100, 100, 780, 500 }, L"Modern OpenGL-Tutorial - Lesson05");
scene.ShowWindow(show);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
return 0;
}
Thursday, July 14, 2022
Lesson04:Textured Cube
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.
SOIL_load_OGL_texture(filename.c_str(), SOIL_LOAD_AUTO, 0, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
//first triangle
{ 0.0, 1.0, 0.0 },
{ -1.0, 0.0, 0.0 },
{ 0.0, -1.0, 0.0 },
//second triangle
{ 1.0, 0.0, 0.0 },
{ 0.0, 0.0, -1.0 },
{ 0.0, 0.0, 1.0 },
#pragma once
#include "..\BaseGeometry.h"
#include "..\TextureUtil.h"
#include "CubeMesh.h"
//implements texturedcube
class TexturedCube:public BaseGeometry
{
public:
//initialize
void Init(GLushort texunit, const string& filename)
{
//create mesh and the window
BaseGeometry::Init(new CubeMesh());
//generate VBOs for position and Texture coordinates
kount = mesh->GenerateVerticesData(false, VAOUtil::POS | VAOUtil::TEX, vaoutl);
//setup vertices
vaoutl.SetupVBO(0, VAOUtil::POS);
vaoutl.SetupVBO(1, VAOUtil::TEX);
vaoutl.unbindVAO();
this->filename = filename;
//Load Texture from the file
texutl.Init(texunit);
texutl.LoadTexture(filename);
}
//update uniforms
void UpdateUniforms()
{
//pass builtin texture to the fragment shader
texutl.MakeActive(shader.GetUniformLocation("tex"));
BaseGeometry::UpdateUniforms();
}
//release resources
void Cleanup()
{
BaseGeometry::Cleanup();
texutl.Cleanup();
}
//override
virtual string vertexShaderSource()
{
return R"(
#version 330 core
layout (location = 0) in vec3 vVertex;
layout (location = 1) in vec2 vTexCrd;
uniform mat4 transform;
out vec2 FragTexCrd;
void main()
{
gl_Position = transform * vec4(vVertex, 1.0);
FragTexCrd=vTexCrd;
};
)";
}
//override
virtual string fragmentShaderSource()
{
return R"(
#version 330 core
in vec2 FragTexCrd;
out vec4 FragColor;
uniform sampler2D tex;
void main()
{
FragColor = texture(tex, FragTexCrd);
};
)";
}
private:
TextureUtil texutl;
std::string filename;
};
#include "Scene\BaseScene.h"
#include "Geometry\Cube\TexturedCube.h"
class Scene:public BaseScene
{
public:
//message handler
BEGIN_MSG_MAP(Scene0)
MESSAGE_HANDLER(WM_CLOSE, OnCloseWindow)
CHAIN_MSG_MAP(BaseScene)
END_MSG_MAP()
//override
int Init(RECT rect, WCHAR *windowname)
{
//create host window and context
BaseScene::Init(rect, windowname);
//attach mouse keyboard input handler
mskbd = new BaseCameraInputHandler(m_hWnd);
//Create cube an set texture filename
cube.Init(0, R"(..\..\resources\textures\bricks2.jpg)");
return 0;
}
//release resources
void Cleanup()
{
cube.Cleanup();
delete mskbd;
}
//draw the scene
void DrawScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//get model view projection matrix.
//only model is modified
//view and projection will be identity matrix
mskbd->fetchCameraData(&cube.camera);
cube.Draw();
}
//Close the window
LRESULT OnCloseWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = TRUE;
DestroyWindow();
PostQuitMessage(0);
return 0;
}
private:
TexturedCube cube;
};
#include "Scene.h"
Scene scene;
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd_line, int show)
{
scene.Init(RECT{ 100, 100, 780, 500 }, L"Modern OpenGL-Tutorial - Lesson04");
scene.ShowWindow(show);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
return 0;
}