Tuesday, July 12, 2022

Lesson02: Single Colored cube


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

Details
The purpose of  Lesson02 is to create a Window initialized with OpenGL context and draw a with fuchsia colored cube.

System  class diagram
The scene class overrides camera with an instance of 3DCamera. It has an instance of SingleColoredCube 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 ThreeDCamera class object. This camera  processes keyboard and mouse inputs as explained earlier.
  3. It calls init function on the SingleCoredCube object to populate VBO buffers and bind them. It also compiles and links shader programs.
The DrawScene method draws the cube with fuchsia color and rotates as per keyboard or mouse inputs.

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. 

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 keyboard/mouse input handler
		camera = new ThreeDCamera(m_hWnd);

		//Create cube an set color
		cube.Init(glm::vec3(1.0f,0.0f,1.0f));
		return 0;
	}

	//release resources
	void Cleanup()
	{
		cube.Cleanup();
		delete camera;
	}
	
	//draw the scene
	void DrawScene()
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		SceneCamera()->augumentModelMatrix(cube);
		cube.Draw();
		SceneCamera()->MM.Reset();
	}

	//Close the window
	LRESULT OnCloseWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		bHandled = TRUE;
		DestroyWindow();
		PostQuitMessage(0);
		return 0;
	}

	inline ThreeDCamera*  SceneCamera() 
	{ 
		static auto ret = dynamic_cast<ThreeDCamera*>(camera); 
		return ret;
	}

private:
	SingleColoredCube cube;
	

};

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

#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 - Lesson02");
	scene.ShowWindow(show);

	MSG msg;
	while (GetMessage(&msg, 0, 0, 0)) 
	{
		TranslateMessage(&msg);
		DispatchMessageA(&msg);
	}

	return 0;
}

Output
The output looks as shown in the top. The cube is rotated by 20 degrees pitch and 20 degrees yaw. The camera position at the origin looking down on -Z axis or the back face of the cube.
To rotate the cube X,Y and Z keys can be used. They rotate respectively pitch, yaw and roll the cube  by 10 degrees.

In the next post we shall create a indexed cube.

No comments:

Post a Comment