-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPolygon.cpp
More file actions
141 lines (123 loc) · 4.59 KB
/
Copy pathPolygon.cpp
File metadata and controls
141 lines (123 loc) · 4.59 KB
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "Polygon.hpp"
void Polygon::generateVertices() {
// Create vertices and indices arrays
_vertices = new GLfloat[_sides * 3];
_indices = new GLuint[(_sides - 2) * 3];
// Determines angle to spin and create new vertices
float tetha = 2 * PI / (float)_sides;
// Fills the arrays
for (int i = 0; i < _sides; i++) {
// The polygon is created with a radius of 1 by default
_vertices[3 * i] = (1.0f * sin(tetha * i));
_vertices[(3 * i) + 1] = (1.0f * cos(tetha * i));
_vertices[(3 * i) + 2] = 0.0f;
}
// Saves vertice references in order to draw all the triangles that make the full polygon
for (int i = 0; i < _sides - 2; i++) {
_indices[3 * i] = 0;
_indices[(3 * i) + 1] = i + 1;
_indices[(3 * i) + 2] = i + 2;
}
}
Polygon::Polygon(float x, float y, float radius, int sides, Camera *camera, GLFWwindow *window) {
// Gets variables ready
_camera = camera;
_x = x;
_y = y;
_radius = radius;
_sides = sides;
glfwGetFramebufferSize(window, &_width, &_height);
// Gets arrays ready
generateVertices();
// Set EBO, VAO and VBO for drawing
glGenBuffers(1, &_EBO);
glGenBuffers(1, &_VBO);
glGenVertexArrays(1, &_VAO);
glBindVertexArray(_VAO);
glBindBuffer(GL_ARRAY_BUFFER, _VBO);
glBufferData(GL_ARRAY_BUFFER, 3 * _sides * sizeof(GLfloat), _vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * (_sides - 2) * sizeof(GLuint), _indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Sets movement related variables
_speedDirection = glm::vec3(0.0f, 0.0f, 0.0f);
_speedValue = 0;
_startTime = (float)glfwGetTime();
}
float Polygon::x() {
return _x;
}
float Polygon::y() {
return _y;
}
void Polygon::setSpeed(glm::vec3 direction, float value) {
_speedDirection = glm::normalize(direction);
_speedValue = value;
}
void Polygon::setShaderProgram(GLuint *shaderProgram) {
_shaderProgram = shaderProgram;
}
void Polygon::Update() {
// The aux vector is used to apply transformations more easily
glm::vec4 aux = glm::vec4(_x, _y, 0.0f, 1.0f);
glm::mat4 transform;
// Gets the current time and applies transform based on deltaTime between updates
float currentTime = (GLfloat)glfwGetTime();
transform = glm::translate(transform, (_speedDirection * _speedValue) * (currentTime - _startTime));
// Saves the time of the current update
_startTime = currentTime;
// Applies the translation and updates current position
aux = transform * aux;
_x = aux.x;
_y = aux.y;
// Check if the object is out of bounds
if (_x + _radius < 0 || _x - _radius > _width || _y + _radius < 0 || _y - _radius > _height) {
// If the object is out of bounds, determines the location where it must respawn
do {
// Reverses speed and looks for the first position out of bounds
_x -= _speedDirection.x;
_y -= _speedDirection.y;
} while (_x + _radius >= 0 && _x - _radius <= _width && _y + _radius >= 0 && _y - _radius <= _height);
// Moves a little bit to ensure it is back inside the boundaries
_x += _speedDirection.x;
_y += _speedDirection.y;
}
}
void Polygon::Draw() {
// Sets shader program to be used
glUseProgram(*_shaderProgram);
// model transform changes from local space to world space, view changes from world to view space
// and projection changes from view space to clip space. glTransform contains the resulting transform matrix
glm::mat4 model, view, projection, gltransform;
// the translation moves the polygon to it's location in world space
model = glm::translate(model, glm::vec3(_x, _y, 0.0f));
// the scale applies the polygon radius
model = glm::scale(model, glm::vec3(_radius, _radius, 1.0f));
// gets the view matrix from camera
view = _camera->view2D;
// gets the projection matrix from camera
projection = _camera->projection2D;
// Passes the resulting transform matrix to the vertex shader
gltransform = projection * view * model;
// Applies transform to shader program
GLuint transformLoc = glGetUniformLocation(*_shaderProgram, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(gltransform));
// Draws the object
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _EBO);
glBindVertexArray(_VAO);
glDrawElements(GL_TRIANGLES, (_sides - 2) * 3, GL_UNSIGNED_INT, _indices);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
Polygon::~Polygon() {
// Frees allocated memory
glDeleteVertexArrays(1, &_VAO);
glDeleteBuffers(1, &_VBO);
glDeleteBuffers(1, &_EBO);
delete(_vertices);
delete(_indices);
}