#include "Shader.h"
#include "VertexBuffer.h"
#include "shaders/basic.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <fstream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <vector>
using namespace std;
void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message,
const void *userParam) {
(void)source;
(void)id;
(void)length;
(void)userParam;
fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type,
severity, message);
}
int main(int argc, char const *argv[]) {
GLFWwindow *window;
if (!glfwInit()) {
std::cerr << "Cannot initialize GLFW" << std::endl;
return -1;
}
window = glfwCreateWindow(600, 600, "TEST2", NULL, NULL);
if (window == nullptr) {
std::cerr << "Cannot create window!" << std::endl;
return -1;
}
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) {
std::cerr << "Cannot init glew." << std::endl;
return -1;
}
// During init, enable debug output
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(MessageCallback, 0);
/**
* Definované proměnné, které budete potřebovat
*/
VertexBuffer VBO_task1, VBO_task2;
vector<float> vertices_task1 = {
1, 0, 0.992146, 0.00049369, 0.968984, 0.00390995, 0.93169, 0.0129763, 0.882143, 0.0300422, 0.822809,
0.0569205, 0.756588, 0.0947618, 0.686637, 0.143971, 0.616172, 0.204172, 0.548277, 0.274219, 0.48571, 0.352259,
0.430737, 0.435838, 0.385, 0.522045, 0.349415, 0.607686, 0.324128, 0.689476, 0.30851, 0.764236, 0.301207,
0.829086, 0.300235, 0.881617, 0.303112, 0.920037, 0.307025, 0.943278, 0.309017, 0.951056, 0.306183, 0.943885,
0.295865, 0.923042, 0.275826, 0.890482, 0.244406, 0.848713, 0.200636, 0.800637, 0.144309, 0.749367, 0.0760078,
0.69803, -0.00292284, 0.649575, -0.0904473, 0.606582, -0.183957, 0.571107, -0.280419, 0.544557, -0.37656, 0.5276,
-0.46906, 0.520128, -0.554746, 0.521273, -0.630784, 0.52946, -0.694848, 0.542518, -0.745253, 0.557818, -0.781054,
0.572449, -0.802095, 0.583405, -0.809014, 0.587783, -0.80319, 0.582978, -0.786652, 0.566848, -0.761946, 0.537864,
-0.731969, 0.495214, -0.699778, 0.438866, -0.6684, 0.369578, -0.640633, 0.288861, -0.618869, 0.198901, -0.60494,
0.102425, -0.600003, 0.00254807, -0.604466, -0.0974135, -0.617961, -0.194139, -0.639367, -0.2845, -0.666883, -0.365743,
-0.698142, -0.435654, -0.730363, -0.492683, -0.760527, -0.536033, -0.785572, -0.565697, -0.802589, -0.582448, -0.809011,
-0.587781, -0.802778, -0.583808, -0.782474, -0.573118, -0.747425, -0.558602, -0.697744, -0.543264, -0.634339, -0.530026,
-0.558856, -0.521534, -0.473596, -0.519989, -0.381367, -0.526997, -0.285331, -0.543464, -0.188805, -0.569537, -0.0950706,
-0.604586, -0.00717491, -0.647243, 0.0722459, -0.69548, 0.141125, -0.746739, 0.19808, -0.798087, 0.242489, -0.8464,
0.274518, -0.888562, 0.295099, -0.921654, 0.305861, -0.943143, 0.309013, -0.951044, 0.307197, -0.944044, 0.30331,
-0.921587, 0.300311, -0.883918, 0.301024, -0.832065, 0.307953, -0.767787, 0.323111, -0.693463, 0.347887, -0.611955,
0.382946, -0.52643, 0.428184, -0.440173, 0.482722, -0.356388, 0.544954, -0.278003, 0.612642, -0.207501, 0.683048,
-0.146766, 0.753103, -0.0969839, 0.81959, -0.0585693, 0.879346, -0.0311567, 0.929454, -0.0136315, 0.96742, -0.00421211,
0.991333, -0.000572479};
vector<float> vertices_task2;
ShaderProgram sp(BASIC_VERTEX, BASIC_FRAGMENT);
sp.bind();
sp.setUniform4f("color", 1.0f, 1.0f, 1.0f, 1.0f);
/**
* První úloha:
* Máte definovaný vektor 2D pozic vertexů (vertices_task1).
* Použijte Vertex buffer (VBO_task1). A data vykreselete zelenou barvou. S tloušťkou čáry 2px
*/
VBO_task1.init(vertices_task1);
VBO_task1.setAttribute(0, 2, GL_FLOAT, 2 * sizeof(float), 0);
/**
* Druhá úloha
* Máte parametricky zadanou křivku těmito rovnicemi:
* x = (4 * cos(t) + cos(4 * t)) / 5.0;
* y = (4 * sin(t) - sin(4 * t)) / 5.0;
* parametr t: 0 < t < 2*pi
* Pomocí těchto rovnic vypočítejte 1000 bodů dané křivky. Pro uložení bodů můžete využít vektor (vertices_task2) a Vertex bufer VBO_task2
* Vypočítaná data vyreslete fialovou barvou. S tloušťkou čáry 1px
*/
int resolution = 1000;
for (int i = 1; i < resolution + 1; i++)
{
float t = i * ((2 * 3.14f )/ resolution);
vertices_task2.push_back((4.0*cos(t) + cos(4.0*t)) / 5.0);
vertices_task2.push_back((4.0*sin(t) - sin(4.0*t)) / 5.0);
}
VBO_task2.init(vertices_task2);
VBO_task2.setAttribute(0, 2, GL_FLOAT, 2 * sizeof(float), 0);
/**
* Třetí úloha
* Vužijte mechanizmu trnformačních matic a implementujte tyto animace.
* Objekt z první úlohy animujte tak aby se rotoval po směru hodinových ručiček s periodou rotace 5 vteřin.
*
* Objekt z druhé úlohy zmenšete na 50% původní velikosti, úmistěte jeho střed přibližně do pravé třetiny obrazu (horizontálně na střed)
* a realizujte rotaci tohoto objektu proti směru hodinových ručiček s periodou rotace 5 vteřin.
*/
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float angle = ((fmod(glfwGetTime(), 5.0f)) / 5.0f) * 360.0;
glm::mat4 proj(1.f);
glm::mat4 model(1.f);
glm::mat4 model1(1.f);
glm::mat4 view(1.f);
//1
VBO_task1.bind();
model = glm::rotate(model, glm::radians(-angle), glm::vec3(0.0f, 0.0f, 1.0f));
sp.setUniformMatrix4fv("proj", proj);
sp.setUniformMatrix4fv("model", model);
sp.setUniformMatrix4fv("view", view);
sp.setUniform4f("color", 0.0f, 1.0f, 0.0f, 1.0f);
glLineWidth((GLfloat) 2.0);
glDrawArrays(GL_LINE_LOOP, 0, vertices_task1.size() / 2);
//2
VBO_task2.bind();
model1 = glm::translate(model1, glm::vec3(0.5f, 0.0f, 0.0f));
model1 = glm::scale(model1, glm::vec3(0.5f, 0.5f, 0.5f));
model1 = glm::rotate(model1, glm::radians(angle), glm::vec3(0.0f, 0.0f, 1.0f));
sp.setUniformMatrix4fv("proj", proj);
sp.setUniformMatrix4fv("model", model1);
sp.setUniformMatrix4fv("view", view);
sp.setUniform4f("color", 0.3f, 0.0f, 0.5f, 1.0f);
glLineWidth((GLfloat)1.0);
glDrawArrays(GL_LINE_LOOP, 0, vertices_task2.size() / 2);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}