In the previous post the graphics pipeline and vertex processing were explained. 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.
Consider a cube with 8 vertices (0,1,2,3,4,5,6,7) and 6 faces (top, bottom, right, left, back, front) with it's center at the origin (0,0,0).
vertices 0,1,5,4 will have -X whereas vertices 3,2,6,7 will have +X.
vertices 0,4,7,3 will have -Y whereas vertices 1,5,6,2 will have +Y.
vertices 0,1,2,3 will have -Z whereas vertices 4,5,6,7 will have +Z.
top face is made of two triangles made from vertices 0,4,7 and 7,3,0.
left face is made of two triangles made from vertices 0,1,5 and 5,4,0.
bottom face is made of two triangles made from vertices 1,5,6 and 6,2,1.
right face is made of two triangles made from vertices 6,7,3 and 3,2,6.
back face is made of two triangles made from vertices 0,1,2 and 2,3,0.
front face is made of two triangles made from vertices 4,5,6 and 6,7,4.
Implementation
CubeMesh class is implemented to generate vertices for the 6 faces as discussed above. It's located in VOGLLib\Geometry\Cube\CubeMesh.h
SingleColoredCube class is implemented as below to draw the single colored cube.
It's located in VOGLLib\Geometry\Cube\SingleColoredCube.h.
//Implements singled colored cube
class SingleColoredCube:public BaseGeometry
{
public:
//Initialize
void Init(glm::vec3 color)
{
//setup with a cube and Compile and link shaders
BaseGeometry::Init(new CubeMesh());
//assign the color
this->color = color;
//Generate VBO data
kount = mesh->GenerateVerticesData(FALSE,VAOUtil::POS, vaoutl);
//Enable single vertex
vaoutl.SetupVBO(0, VAOUtil::POS);
vaoutl.unbindVAO();
}
//Override to supply color of the cube
void UpdateUniforms()
{
BaseGeometry::UpdateUniforms();
glUniform3fv(shader.GetUniformLocation("color"), 1, glm::value_ptr(color));
}
private:
//override
string vertexShaderSource()
{
return R"(
#version 330 core
layout (location = 0) in vec3 vVertex;
uniform mat4 transform;
uniform vec3 color;
out vec3 cubecolor;
void main()
{
gl_Position = transform * vec4(vVertex, 1.0);
cubecolor = color;
};
)";
}
//override
string fragmentShaderSource()
{
return R"(
#version 330 core
in vec3 cubecolor;
out vec4 FragColor;
void main()
{
FragColor = vec4(cubecolor,1);
};
)";
}
glm::vec3 color;
};
Lesson02 Project
This purpose of this Lesson02 project is to create a Window initialized with OpenGL context and draw a SingleColoredCube with fuchsia color.
As discussed in introduction create tutorial lesson project Lesson02 under Lessons folder.
Add a header file Scene.h as shown below. The class itself is self explanatory.
The WM_CLOSE event is handled in OnCloseWindow function and the window is destroyed and application is shutdown.
The Init method calls BaseScene's Init to create hosting window and OpenGL Context. It also attaches BaseCameraInputHandler to rotate the cube either by keyboard or mouse inputs.
The DrawScene method draws the cube with fuchsia color and rotates as per keyboard or mouse inputs.
The Cleanup method release the resources.
The Scene class is implemented as below. It's located in Lessons\Lesson02\Scene.h file.
#include "Scene\BaseScene.h"
#include "Geometry\Cube\SingleColoredCube.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 keyboard/mouse input handler
mskbd = new BaseCameraInputHandler(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 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:
SingleColoredCube cube;
};
The main.cpp is located in Lessons\Lesson02\main.cpp file. It creates the scene object and calls its init method.
#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;
}
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