mail

OpenGL engine project

Portfolio Page

Introduction

I worked for 8 weeks on this engine with a team of several other programmers. We made an engine that includes 3D rendering, 2D rendering, 3D physics, 2D physics, and networking. This put together by an architecture in which we had scenes and game objects. The architecture was modular, in which the engine would call the specific parts of the engine that were needed. Every part of the engine was written as a model that would be called by the main loop depending on its needs.

In the game scene you would register objects as game objects of specfic type, for example sprite. These would then put in static lists from which the engine gets the objects behind the scene and would for example render the object and apply physics on the object.

My work

I worked mainly on the 2D rendering and partly on the 2D demo game.

I used for the renderer OpenGL version 3.3 which is entirely different than the old version I used previously. This required some reading up and following articles and tutorials to figure out how to make a 2D renderer in this version.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
const std::vector<SpriteComponent*>& spriteComp = SpriteComponent::ms_SpriteRegistry;
	
m_ShaderProgram->Use();


// For every sprite component
for (unsigned int i = 0; i < spriteComp.size(); i++)
{


	// Get transform component of object
	const TransformComp* tc = dynamic_cast<GameObject*>(spriteComp[i]->GetParentObject())->GetComponent<TransformComp>();

	glm::vec3 pos = { tc->m_Position.x, tc->m_Position.y, -1.0f };
	glm::vec3 size = tc->m_Scale;
	glm::vec3 rot = tc->m_Rotation;

	//Matrics 
	glm::mat4 model;
	model = glm::translate(model, pos);
	model = glm::translate(model, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f)); 
	model = glm::rotate(model, glm::radians(0.0f) , glm::vec3(0.0f, 0.0f, 1.0f)); 
	model = glm::translate(model, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f));
	model = glm::scale(model, glm::vec3(spriteComp[i]->m_SpriteReference->GetTexture().g_Size.x * size.x,-( spriteComp[i]->m_SpriteReference->GetTexture().g_Size.y * size.y), 100.0f));

	GLuint transformLoc = glGetUniformLocation(m_ShaderProgram->g_ShaderProgram, "transform");
	glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model));

	GLuint cameraLoc = glGetUniformLocation(m_ShaderProgram->g_ShaderProgram, "projection");
	glUniformMatrix4fv(cameraLoc, 1, GL_FALSE, glm::value_ptr(projection));

	//auto bind the texture to the shader sampler2D
	glBindTexture(GL_TEXTURE_2D, spriteComp[i]->m_SpriteReference->GetTexture().g_ID);

	//Use the shaderprogram, bind the VAO, draw a trangle and unbind the VAO.

	glBindVertexArray(VAO);
	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
	glBindVertexArray(0);


}
glUseProgram(0);

Above you see the rendering sequence of the 2D renderer. This is done in the draw function of the 2D renderer which gets called by the engine update. It starts with getting the sprite objects that are registered by the engine. Then it loops through every component and draws them according to the OpenGL conventions. First, it will get the transform of the object, then it will calculate the position, rotation and scale put it in a matrix. It will then send this to the shader which will use it for the position of the object. After that it will bind the texture and draw the object.

I also made a primitive component so that the 2D physics programmer could draw lines for his calculations. There was also a text component in the engine that I made. This renders text on screen. Lastly, I helped build the 2D demo game to demonstrate the engine.