tes-tiger/main.cpp

282 lines
10 KiB
C++
Raw Normal View History

2018-06-14 19:41:30 +00:00
#include <string>
#include <cmath>
#include <vector>
#define GLEW_STATIC
2018-06-15 13:15:28 +00:00
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
2018-06-14 19:41:30 +00:00
2018-06-15 13:15:28 +00:00
#include "utilities.h"
2018-06-14 19:41:30 +00:00
2018-06-15 13:15:28 +00:00
const float pi = 3.14159f;
2018-06-14 19:41:30 +00:00
const float radius = 8.0f;
const float step = 100.0f;
const float angle = pi / 6.0f;
const size_t threadsCount = 3;
const size_t verticesCount = 6;
void bufferVertices(
std::vector<GLfloat>& verticesBuffer,
const glm::vec3& start,
const glm::vec3& end,
const glm::vec3& color
) {
auto direction = glm::normalize(end - start);
size_t iterationsCount = glm::length(end - start) / step;
if(iterationsCount == 0) {
iterationsCount = 1;
}
auto adjustedStep = glm::length(end - start) / iterationsCount;
auto e = findPlaneBasis(direction);
std::vector<glm::vec3> threadCenters;
std::vector<std::vector<glm::vec4>> threads;
for(size_t i = 0; i < threadsCount; i++) {
const auto iPhase = i * 2 * pi / threadsCount;
const glm::vec3 threadCenter = radius * (e.first * cosf(iPhase) + e.second * sinf(iPhase));
std::vector<glm::vec4> vertices;
for(size_t j = 0; j < verticesCount; j++) {
const auto jPhase = j * 2 * pi / verticesCount;
const glm::vec3 vertex = threadCenter + radius * (e.first * cosf(jPhase) + e.second * sinf(jPhase));
vertices.emplace_back(glm::vec4(vertex.x, vertex.y, vertex.z, 1.0f));
}
threadCenters.emplace_back(threadCenter);
threads.emplace_back(vertices);
}
auto transform = glm::mat4(1.0f);
transform = glm::rotate(transform, angle, direction);
transform = glm::translate(transform, adjustedStep * direction);
auto p = [&verticesBuffer] (const GLfloat& value) mutable {verticesBuffer.push_back(value);};
auto v = [&p] (const glm::vec3& vector) mutable {p(vector.x); p(vector.y); p(vector.z);};
auto st = [&p] (const GLfloat& s, const GLfloat& t) mutable {p(s); p(t);};
auto n = v;
auto c = v;
for(size_t i = 0; i < iterationsCount; i++) {
std::vector<std::vector<glm::vec4>> newThreads;
for(size_t j = 0; j < threadsCount; j++) {
auto vertices = threads[j];
std::vector<glm::vec4> newVertices;
for(size_t k = 0; k < verticesCount; k++) {
newVertices.push_back(transform * vertices[k]);
}
newThreads.push_back(newVertices);
auto threadCenter = threadCenters[j];
auto threadCenter4 = glm::vec4(threadCenter.x, threadCenter.y, threadCenter.z, 1.0f);
auto newThreadCenter4 = transform * threadCenter4;
auto newThreadCenter = glm::vec3(newThreadCenter4.x, newThreadCenter4.y, newThreadCenter4.z);
threadCenters[j] = newThreadCenter;
for(size_t k = 0; k < verticesCount; k++) {
size_t k1 = (k + 1) % verticesCount;
auto vk = glm::vec3(vertices[k].x, vertices[k].y, vertices[k].z);
auto vk1 = glm::vec3(vertices[k1].x, vertices[k1].y, vertices[k1].z);
auto nvk = glm::vec3(newVertices[k].x, newVertices[k].y, newVertices[k].z);
auto nvk1 = glm::vec3(newVertices[k1].x, newVertices[k1].y, newVertices[k1].z);
v(start + vk); n(vk - threadCenter); st(0.1f, 0.1f); c(color);
v(start + vk1); n(vk1 - threadCenter); st(0.2f, 0.1f); c(color);
v(start + nvk); n(nvk - newThreadCenter); st(0.1f, 0.2f); c(color);
v(start + vk1); n(vk1 - threadCenter); st(0.2f, 0.1f); c(color);
v(start + nvk1); n(nvk1 - newThreadCenter); st(0.2f, 0.2f); c(color);
v(start + nvk); n(nvk - newThreadCenter); st(0.1f, 0.2f); c(color);
}
}
threads = newThreads;
}
};
int main() {
2018-06-15 13:15:28 +00:00
setUp();
2018-06-14 19:41:30 +00:00
auto shaderProgram = linkShaderProgram({
{GL_VERTEX_SHADER, "../resources/shader.vertex"},
{GL_FRAGMENT_SHADER, "../resources/shader.fragment"}
});
auto texture = loadTexture("../resources/wooden-container.jpg");
GLfloat vertices[] = {
// position, texture coordinates
-2048.0f, -2048.0f, 0.0f, 0.0f, 0.0f,
2048.0f, -2048.0f, 0.0f, 1.0f, 0.0f,
2048.0f, 2048.0f, 0.0f, 1.0f, 1.0f,
2048.0f, 2048.0f, 0.0f, 1.0f, 1.0f,
-2048.0f, 2048.0f, 0.0f, 0.0f, 1.0f,
-2048.0f, -2048.0f, 0.0f, 0.0f, 0.0f
};
GLuint vertexArrayObject;
glGenVertexArrays(1, &vertexArrayObject);
GLuint vertexBufferObject;
glGenBuffers(1, &vertexBufferObject);
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(0 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
// threads
auto threadShaderProgram = linkShaderProgram({
{GL_VERTEX_SHADER, "../resources/thread.vertex"},
{GL_FRAGMENT_SHADER, "../resources/thread.fragment"}
});
auto threadTexture = loadTexture("../resources/fabric.jpg");
2018-06-15 13:15:28 +00:00
setWindowTitle("parsing lines.json");
2018-06-14 19:41:30 +00:00
boost::property_tree::ptree root;
2018-06-15 13:15:28 +00:00
boost::property_tree::read_json("../resources/line.json", root);
2018-06-14 19:41:30 +00:00
size_t linesCount = 0;
for(const auto& line: root.get_child("lines")) {
linesCount++;
}
std::vector<GLfloat> verticesBuffer;
size_t lineIndex = 0;
for(const auto& line: root.get_child("lines")) {
std::vector<int> startPosition;
std::vector<int> endPosition;
std::vector<float> color;
for(const auto& value: line.second.get_child("start")) {
startPosition.push_back(value.second.get_value<int>());
}
for(const auto& value: line.second.get_child("end")) {
endPosition.push_back(value.second.get_value<int>());
}
for(const auto& value: line.second.get_child("color")) {
color.push_back(value.second.get_value<float>());
}
if(startPosition[0] != endPosition[0] || startPosition[1] != endPosition[1]) {
bufferVertices(
verticesBuffer,
glm::vec3(
static_cast<float>(startPosition[0]) / 2.0f,
static_cast<float>(startPosition[1]) / 2.0f,
lineIndex * 0.0025f
),
glm::vec3(
static_cast<float>(endPosition[0]) / 2.0f,
static_cast<float>(endPosition[1]) / 2.0f,
lineIndex * 0.0025f
),
glm::vec3(color[0], color[1], color[2])
);
}
lineIndex++;
std::stringstream progressString;
progressString << "loading " << lineIndex << "/" << linesCount;
2018-06-15 13:15:28 +00:00
setWindowTitle(progressString.str().c_str());
2018-06-14 19:41:30 +00:00
}
GLuint threadVAO;
glGenVertexArrays(1, &threadVAO);
GLuint threadVBO;
glGenBuffers(1, &threadVBO);
glBindVertexArray(threadVAO);
glBindBuffer(GL_ARRAY_BUFFER, threadVBO);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer.size() * sizeof(GLfloat), verticesBuffer.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat), (GLvoid*)(0 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat), (GLvoid*)(8 * sizeof(GLfloat)));
glEnableVertexAttribArray(3);
glBindVertexArray(0);
2018-06-15 13:15:28 +00:00
auto threadModelTransform = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 100.0f));
2018-06-14 19:41:30 +00:00
glEnable(GL_DEPTH_TEST);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2018-06-15 13:15:28 +00:00
renderCycle([
shaderProgram,
texture,
vertexArrayObject,
threadShaderProgram,
threadTexture,
threadModelTransform,
threadVAO,
verticesBuffer
] () {
2018-06-14 19:41:30 +00:00
glClearColor(0.5f, 0.5f, 1.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
glUniformMatrix4fv(
glGetUniformLocation(shaderProgram, "modelTransform"),
1,
GL_FALSE,
glm::value_ptr(glm::mat4(1.0f))
);
glUniformMatrix4fv(
glGetUniformLocation(shaderProgram, "viewTransform"),
1,
GL_FALSE,
2018-06-15 13:15:28 +00:00
glm::value_ptr(getViewTransform())
2018-06-14 19:41:30 +00:00
);
glUniformMatrix4fv(
glGetUniformLocation(shaderProgram, "projectionTransform"),
1,
GL_FALSE,
2018-06-15 13:15:28 +00:00
glm::value_ptr(getProjectionTransform())
2018-06-14 19:41:30 +00:00
);
glBindVertexArray(vertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glUseProgram(threadShaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, threadTexture);
glUniform1i(glGetUniformLocation(threadShaderProgram, "sampler"), 0);
glUniformMatrix4fv(
glGetUniformLocation(threadShaderProgram, "modelTransform"),
1,
GL_FALSE,
glm::value_ptr(threadModelTransform)
);
glUniformMatrix4fv(
glGetUniformLocation(threadShaderProgram, "viewTransform"),
1,
GL_FALSE,
2018-06-15 13:15:28 +00:00
glm::value_ptr(getViewTransform())
2018-06-14 19:41:30 +00:00
);
glUniformMatrix4fv(
glGetUniformLocation(threadShaderProgram, "projectionTransform"),
1,
GL_FALSE,
2018-06-15 13:15:28 +00:00
glm::value_ptr(getProjectionTransform())
2018-06-14 19:41:30 +00:00
);
glBindVertexArray(threadVAO);
glDrawArrays(GL_TRIANGLES, 0, verticesBuffer.size());
glBindVertexArray(0);
2018-06-15 13:15:28 +00:00
});
2018-06-14 19:41:30 +00:00
2018-06-15 13:15:28 +00:00
tearDown();
2018-06-14 19:41:30 +00:00
return 0;
}