diff --git a/.vscode/launch.json b/.vscode/launch.json index 10efcb2..b73002c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,9 +8,9 @@ "type": "lldb", "request": "launch", "name": "Debug", - "program": "${workspaceFolder}/", + "program": "${workspaceFolder}/build/TimeCoil", "args": [], - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder}/build" } ] } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 9095e13..534c72e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ SET(PROJECT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp src/glad.c ${CMAKE_CURRENT_SOURCE_DIR}/src/coil/coil.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/coil/segment.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/utils.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/camera/camera.cpp ) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src diff --git a/build.sh b/build.sh index 099a2f1..76de782 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,6 @@ #!/usr/bin/env bash -mkdir -p build && cd build && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_FLAGS="-g -v -da -Q -O0" .. && make && ./TimeCoil # > ../points.csv && python ../tools/build_3d.py ../points.csv +mkdir -p build && \ +cd build && \ +cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_FLAGS="-g -v -da -Q -O0" .. && \ +make && \ +./TimeCoil # > ../points.csv && python ../tools/build_3d.py ../points.csv diff --git a/src/camera/camera.cpp b/src/camera/camera.cpp new file mode 100644 index 0000000..0932e91 --- /dev/null +++ b/src/camera/camera.cpp @@ -0,0 +1,82 @@ +#include +#include +#include + +Camera::Camera(glm::vec3 pos, glm::vec3 up, float yaw, float pitch, float speed, + float sensitivity, CameraType type) + : pos(pos), worldUp(up), yaw(yaw), pitch(pitch), speed(speed), sensitivity(sensitivity), type(type) { + updateCameraVectors(); +} + +glm::mat4 Camera::getViewMatrix() { return glm::lookAt(pos, pos + front, up); } + +void Camera::processKeyboardInput(CameraMovement direction) { + if (lastTime == -1) { + lastTime = glfwGetTime(); + } + float deltaTime = glfwGetTime() - lastTime; + float velocity = speed * deltaTime; + + switch (type) { + case CameraType::FREE: { + switch (direction) { + case CameraMovement::FORWARD: + pos += front * velocity; + break; + case CameraMovement::BACKWARD: + pos -= front * velocity; + break; + case CameraMovement::LEFT: + pos -= right * velocity; + break; + case CameraMovement::RIGHT: + pos += right * velocity; + break; + } + break; + } + case CameraType::SPINNING: { + + } + } + + lastTime = glfwGetTime(); +} + +void Camera::processMouseInput(GLFWwindow *window, double mouseX, double mouseY) { + switch (type) { + case CameraType::FREE: { + float dX = 0, dY = 0; + if (prevX == -1 && prevY == -1) { + prevX = mouseX; + prevY = mouseY; + } + dX = sensitivity * (mouseX - prevX); + dY = -sensitivity * (mouseY - prevY); + + yaw += dX; + pitch += dY; + + pitch = glm::clamp(pitch, (float)-89., (float)89.); + prevX = mouseX; + prevY = mouseY; + } + case CameraType::SPINNING: { + + } + } + updateCameraVectors(); + +} + +void Camera::updateCameraVectors() { + glm::vec3 front; + front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); + front.y = sin(glm::radians(pitch)); + front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); + // front = glm::vec3(0, 0, 10); + this->front = glm::normalize(front); + + right = glm::normalize(glm::cross(front, worldUp)); + up = glm::normalize(glm::cross(right, front)); +} \ No newline at end of file diff --git a/src/camera/camera.hpp b/src/camera/camera.hpp new file mode 100644 index 0000000..f552005 --- /dev/null +++ b/src/camera/camera.hpp @@ -0,0 +1,36 @@ +#ifndef COIL_CAMERA_HPP +#define COIL_CAMERA_HPP + +#include +#include + +enum CameraType { FREE, SPINNING }; + +enum CameraMovement { + FORWARD, + BACKWARD, + LEFT, + RIGHT +}; + +class Camera { + float pitch, yaw; + float prevX = -1, prevY = -1; + glm::vec3 pos, front, up, right, worldUp; + CameraType type; + float lastTime = -1; + + float speed, sensitivity; + + public: + Camera(glm::vec3 pos, glm::vec3 up, float yaw, float pitch, float speed, float sensitivity, CameraType type); + + glm::mat4 getViewMatrix(); + void processKeyboardInput(CameraMovement direction); + void processMouseInput(GLFWwindow *window, double offsetX, double offsetY); + + private: + void updateCameraVectors(); +}; + +#endif // COIL_CAMERA_HPP \ No newline at end of file diff --git a/src/coil/coil.cpp b/src/coil/coil.cpp index c57988a..7df6f4f 100644 --- a/src/coil/coil.cpp +++ b/src/coil/coil.cpp @@ -1,32 +1,28 @@ -#include -#include -#include -#include - #include + +#include + #include +#include +#include +#include +#include #include -Coil::Coil(uint32_t currentYear, uint32_t amountOfSegments, uint32_t sliceDetalization, float radius, float width) - : radius(radius), width(width), currentYear(currentYear) { +Coil::Coil(uint32_t currentYear, uint32_t amountOfSegments, float segmentHeight, uint32_t sliceDetalization, float radius, float width) + : radius(radius), width(width), segmentHeight(segmentHeight), currentYear(currentYear) { for (short i = amountOfSegments / -2.; i < amountOfSegments / 2.; i++) { uint32_t year = this->currentYear + i; - segments.push_back(CoilSegment(this, year, segmentHeight, i, sliceDetalization,false)); + segments.push_back(CoilSegment(this, year, segmentHeight, i, sliceDetalization)); } }; -std::vector &Coil::getSegments() { - return segments; -} +std::vector &Coil::getSegments() { return segments; } -float Coil::getWidth() { - return width; -} +float Coil::getWidth() { return width; } -float Coil::getRadius() { - return radius; -} +float Coil::getRadius() { return radius; } void Coil::initGLBuffers() { @@ -39,12 +35,14 @@ void Coil::initGLBuffers() { glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - // glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + // glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, + // GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*) (3 * sizeof(float))); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), + (void *)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(0); @@ -52,15 +50,93 @@ void Coil::initGLBuffers() { void Coil::render() { glBindVertexArray(VAO); - std::cout << "Rendering a coil." << std::endl; - for (CoilSegment segment : segments) { - std::cout << "Rendering " << segment.getYear() << std::endl; - segment.fillVBO(); - uint64_t indicesCount = segment.fillEBO(EBO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - // glDrawArrays(GL_POINTS, 0, segment.getVerticesLength()); - glDrawElements(GL_TRIANGLES_ADJACENCY, sizeof(unsigned int)*indicesCount, GL_UNSIGNED_INT, 0); + uint64_t verticesLength = 0; + for (CoilSegment &segment : segments) { + verticesLength += segment.getVerticesLength(); } + + float *vertices = (float *) malloc(verticesLength * sizeof(float)); + if (vertices == NULL) { + std::cerr << "Couldn't allocate memory for vertices." << std::endl; + } + fillVBO(vertices); + uint32_t indicesAmount = fillEBO(); + + glDrawElements(GL_TRIANGLES, indicesAmount, + GL_UNSIGNED_INT, 0); glBindVertexArray(0); + + free(vertices); +} +void Coil::fillVBO(float *vertices) { + uint64_t verticesSize = 0; + for (CoilSegment &segment : segments) { + float *segmentVertices = segment.getVertices(); + uint32_t segmentVerticesLength = segment.getVerticesLength(); + uint32_t segmentVerticesSize = segmentVerticesLength * sizeof(float); + + memcpy(&vertices[verticesSize], segmentVertices, segmentVerticesSize); + verticesSize += segmentVerticesLength; + } + + glBufferData(GL_ARRAY_BUFFER, verticesSize * sizeof(float), vertices, GL_STATIC_DRAW); +} +uint32_t Coil::fillEBO() { + uint32_t indicesLength = 0; + + for (CoilSegment &segment : segments) { + indicesLength += segment.getDaysAmount() * segment.getSlicePointsAmount() * 6; + } + uint32_t *indices = (uint32_t *)malloc(indicesLength * sizeof(uint32_t)); + + uint32_t currentIndex = 0; + + uint32_t yearOffset = 0; + + for (uint32_t segmentNumber = 0; segmentNumber < segments.size(); segmentNumber++) { + CoilSegment &segment = segments[segmentNumber]; + uint32_t slicePointsAmount = segment.getSlicePointsAmount(); + + for (uint32_t day = 0; day < segment.getDaysAmount(); day++) { + for (uint32_t pointOfSlice = 0; pointOfSlice < slicePointsAmount; pointOfSlice++) { + uint32_t dayOffset = day * slicePointsAmount; + uint32_t currentPointIndex = yearOffset + dayOffset + pointOfSlice - 1; + // First triangle + indices[currentIndex] = currentPointIndex; + currentIndex++; + indices[currentIndex] = currentPointIndex + slicePointsAmount; + currentIndex++; + indices[currentIndex] = currentPointIndex + 1; + currentIndex++; + // Second triangle + //if (pointOfSlice % (sliceDetalization+1) == 0 && pointOfSlice != 0) { + if (pointOfSlice == segment.getSliceDetailization() - 1 && + pointOfSlice != 0) { + indices[currentIndex] = currentPointIndex - (slicePointsAmount - 1); + currentIndex++; + indices[currentIndex] = currentPointIndex + 1; + currentIndex++; + indices[currentIndex] = currentPointIndex; + } else { + indices[currentIndex] = currentPointIndex + 1; + currentIndex++; + indices[currentIndex] = currentPointIndex + slicePointsAmount + 1; + currentIndex++; + indices[currentIndex] = currentPointIndex + slicePointsAmount; + } + currentIndex++; + } + } + yearOffset += segment.getVerticesAmount(); + } + if (currentIndex != indicesLength) { + std::cerr << "currentIndex == indicesLength assertion failed" << std::endl; + std::cerr << currentIndex << " " << indicesLength << std::endl; + } + + // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * indicesLength, indices, GL_STATIC_DRAW); + + free(indices); + return indicesLength; } \ No newline at end of file diff --git a/src/coil/coil.hpp b/src/coil/coil.hpp index c06eb5e..6916141 100644 --- a/src/coil/coil.hpp +++ b/src/coil/coil.hpp @@ -5,6 +5,7 @@ #ifndef COIL_HPP #define COIL_HPP + // Coil segment is a one turn of a coil // Coil slice is a set of points that define slice of coil @@ -20,11 +21,14 @@ class Coil { GLuint VBO, VAO, EBO; public: - Coil(uint32_t currentYear, uint32_t amountOfSegments, uint32_t sliceDetalization, float radius, float width); + Coil(uint32_t currentYear, uint32_t amountOfSegments, float segmentHeight, uint32_t sliceDetalization, float radius, float width); std::vector &getSegments(); float getWidth(); float getRadius(); + void render(); + void fillVBO(float *vertices); + uint32_t fillEBO(); void initGLBuffers(); }; diff --git a/src/coil/segment.cpp b/src/coil/segment.cpp index 1f2267b..a85c4cc 100644 --- a/src/coil/segment.cpp +++ b/src/coil/segment.cpp @@ -12,10 +12,6 @@ #include #include -// x, y, z, r, g, b -#define FIELDS_IN_POINT 6 -#define DAYS_IN_YEAR (isLeap? 366.0f : 365.0f) - using glm::vec4; using glm::vec3; using glm::mat4; @@ -30,260 +26,239 @@ using std::cout; using std::cerr; CoilSegment::CoilSegment( - Coil* coil, - uint16_t year, - uint16_t height, - int shift, - uint32_t sliceDetalization, - bool isLeap - ) : - coil(coil), year(year), - height(height), shift(shift), - sliceDetalization(sliceDetalization), isLeap(isLeap) { - init(); - calculate(); - } + Coil* coil, + uint16_t year, + uint16_t height, + int shift, + uint32_t sliceDetailization + ): + coil(coil), year(year), + height(height), shift(shift), + sliceDetailization(sliceDetailization), + slicePointsAmount(sliceDetailization + 2), + //evil shit + leap(year % 4 == 0? year % 100 == 0? year % 400 == 0 : true : false) { + init(); + // calculate(); + } void CoilSegment::init () { - verticesLength = DAYS_IN_YEAR * FIELDS_IN_POINT * (sliceDetalization+2); - vertices = (float *) calloc(verticesLength, sizeof(float)); - if (vertices == NULL) { - cerr << "Allocation failed" << endl; - exit(-1); - } - calculate(); - // cout << "Initialized CoilSegment" - // << "(year: " << year - // << ", height: " << height - // << ", shift: " << shift - // << ", isLeap: " << isLeap <<")" << endl; + verticesLength = getDaysAmount() * slicePointsAmount * FIELDS_IN_POINT; + vertices = (float *) malloc(verticesLength * sizeof(float)); + if (vertices == NULL) { + cerr << "Allocation failed" << endl; + exit(-1); + } + calculate(); } void CoilSegment::printVertices() { - for (uint16_t day = 0; day < DAYS_IN_YEAR; day ++) { - cout << "Day " << day << ", " << - "x: " << vertices[FIELDS_IN_POINT * day + 0] << ", " << - "y: " << vertices[FIELDS_IN_POINT * day + 1] << ", " << - "z: " << vertices[FIELDS_IN_POINT * day + 2] << ", " << - "r: " << vertices[FIELDS_IN_POINT * day + 3] << ", " << - "g: " << vertices[FIELDS_IN_POINT * day + 4] << ", " << - "b: " << vertices[FIELDS_IN_POINT * day + 5] << endl; - } + for (uint16_t day = 0; day < getDaysAmount(); day ++) { + cout << "Day " << day << ", " << + "x: " << vertices[FIELDS_IN_POINT * day + 0] << ", " << + "y: " << vertices[FIELDS_IN_POINT * day + 1] << ", " << + "z: " << vertices[FIELDS_IN_POINT * day + 2] << ", " << + "r: " << vertices[FIELDS_IN_POINT * day + 3] << ", " << + "g: " << vertices[FIELDS_IN_POINT * day + 4] << ", " << + "b: " << vertices[FIELDS_IN_POINT * day + 5] << endl; + } } float *CoilSegment::calculateSlice() { - uint32_t size = (/*start and end of a slize*/2 + sliceDetalization) * FIELDS_IN_POINT * sizeof(float); - float *slice = (float *)malloc(size); - mat4 transform = mat4(1.); - transform = glm::scale( - transform, - vec3( - coil->getWidth(), - 10, - 1 - ) - ); - vec3 point = vec3(cos(0), sin(0), 0); - // Start of a slice - slice[0] = cos(0); - slice[1] = sin(0); - slice[2] = 0; - slice[3] = 1; - slice[4] = 1; - slice[5] = 1; + uint32_t size = slicePointsAmount * 3 * sizeof(float); + float *slice = (float *)malloc(size); + mat4 transform = mat4(1.); + transform = glm::scale( + transform, + vec3( + coil->getWidth(), + 10, + 1 + ) + ); + // Start of a slice + slice[0] = cos(0); + slice[1] = sin(0); + slice[2] = 0; - float degreeByPoint = -180. / (sliceDetalization + 1); + float degreeByPoint = -180. / (sliceDetailization + 1); - for (uint32_t i = 1; i <= sliceDetalization; i ++) { - uint32_t offset = FIELDS_IN_POINT * i; - - slice[offset + 0] = round_to_presicion(cos(radians(degreeByPoint * i)), 5); - slice[offset + 1] = round_to_presicion(sin(radians(degreeByPoint * i)), 5); - slice[offset + 2] = 0; - slice[offset + 3] = 1; - slice[offset + 4] = 1; - slice[offset + 5] = 1; - } + for (uint32_t i = 1; i <= sliceDetailization; i ++) { + uint32_t offset = FIELDS_IN_POINT * i; - // End of a slice - uint32_t endIndex = (size / sizeof(float) - FIELDS_IN_POINT); - slice[endIndex + 0] = round_to_presicion(cos(radians(180.)), 5); - slice[endIndex + 1] = round_to_presicion(sin(radians(180.)), 5); - slice[endIndex + 2] = 0; - slice[endIndex + 3] = 1; - slice[endIndex + 4] = 1; - slice[endIndex + 5] = 1; + slice[offset + 0] = round_to_precision(cos(radians(degreeByPoint * i)), 5); + slice[offset + 1] = round_to_precision(sin(radians(degreeByPoint * i)), 5); + slice[offset + 2] = 0; + } - return slice; + // End of a slice + uint32_t endIndex = (size / sizeof(float) - FIELDS_IN_POINT); + slice[endIndex + 0] = round_to_precision(cos(radians(180.)), 5); + slice[endIndex + 1] = round_to_precision(sin(radians(180.)), 5); + slice[endIndex + 2] = 0; + + return slice; } void CoilSegment::constructSegment(float *slice) { - float degreesPerDay = 360.f / DAYS_IN_YEAR; + float degreesPerDay = 360.f / getDaysAmount(); - for (uint32_t day = 0; day < DAYS_IN_YEAR; day ++) { - float daysDegree = day * degreesPerDay; - vec3 daysPosition = vec3( - cos(radians(daysDegree)) * coil->getRadius(), - 10* daysDegree/360., - sin(radians(daysDegree)) * coil->getRadius() - ); + for (uint32_t day = 0; day < getDaysAmount(); day ++) { + float daysDegree = day * degreesPerDay; + vec3 daysPosition = vec3( + cos(radians(daysDegree)) * coil->getRadius(), + height * daysDegree/360. + shift * height, + sin(radians(daysDegree)) * coil->getRadius() + ); - mat4 transform = mat4(1.); + mat4 transform = mat4(1.); - transform = translate( - transform, - daysPosition - ); + transform = translate( + transform, + daysPosition + ); - transform = rotate( - transform, - -radians(daysDegree), - vec3( - 0.0, - 1.0, - 0.0 - ) - ); + transform = rotate( + transform, + -radians(daysDegree), + vec3( + 0.0, + 1.0, + 0.0 + ) + ); - for (uint32_t slicePoint = 0; slicePoint < (2 + sliceDetalization); slicePoint ++) { - uint32_t slicePointOffset = FIELDS_IN_POINT * slicePoint; - vec4 point( - slice[slicePointOffset + 0], - slice[slicePointOffset + 1], - slice[slicePointOffset + 2], - 1 - ); - - point = transform * point; - uint64_t currentPointOffset = day * (2+sliceDetalization) * FIELDS_IN_POINT + slicePointOffset; - vertices[currentPointOffset + 0] = point.x; - vertices[currentPointOffset + 1] = point.y; - vertices[currentPointOffset + 2] = point.z; + for (uint32_t slicePoint = 0; slicePoint < slicePointsAmount; slicePoint ++) { + uint32_t slicePointOffset = 3 * slicePoint; + vec4 point( + slice[slicePointOffset + 0], + slice[slicePointOffset + 1], + slice[slicePointOffset + 2], + 1 + ); - vertices[currentPointOffset + 3] = 0.5; - vertices[currentPointOffset + 4] = 0.5; - vertices[currentPointOffset + 5] = 0.5; - - // memcpy( - // vertices + currentPointOffset + 3, - // slice + slicePointOffset + 3, - // 3 - // ); - } - } -} -void CoilSegment::fillVBO() { - // printVertices(); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * verticesLength, vertices, GL_STATIC_DRAW); + point = transform * point; + uint64_t currentPointOffset = day * slicePointsAmount * FIELDS_IN_POINT + slicePointOffset*2; + vertices[currentPointOffset + 0] = point.x; + vertices[currentPointOffset + 1] = point.y; + vertices[currentPointOffset + 2] = point.z; + + vertices[currentPointOffset + 3] = (float)slicePoint / slicePointsAmount; + vertices[currentPointOffset + 4] = 0; + vertices[currentPointOffset + 5] = 0; + } + } + free(slice); } uint64_t CoilSegment::fillEBO(uint64_t EBO) { - uint64_t indicesLength = 6 * (sliceDetalization+2) * DAYS_IN_YEAR; - uint64_t currentIndex = 0; - uint64_t* indices = (uint64_t*) calloc(indicesLength, sizeof(uint64_t)); - for (uint64_t day = 0; day < DAYS_IN_YEAR; day ++) { - for (uint64_t pointOfSlice = 0; pointOfSlice < (sliceDetalization+2); pointOfSlice ++) { - // cout << currentIndex << endl; - uint64_t dayOffset = day * (sliceDetalization+2); - uint64_t offset = dayOffset + pointOfSlice; - //First triangle - indices[currentIndex] = offset; - currentIndex ++; - indices[currentIndex] = offset + (sliceDetalization+2); - currentIndex ++; - indices[currentIndex] = offset + 1; - currentIndex++; - //Second triangle - - if (pointOfSlice % (sliceDetalization+1) == 0 && pointOfSlice != 0) { - indices[currentIndex] = offset - (sliceDetalization+2); - currentIndex++; - indices[currentIndex] = offset + 1; - currentIndex++; - indices[currentIndex] = offset; - } else { - indices[currentIndex] = offset + 1; - currentIndex++; - indices[currentIndex] = offset + (sliceDetalization+3); - currentIndex ++; - indices[currentIndex] = offset + (sliceDetalization+2); - } - currentIndex ++; - } - } + uint64_t indicesLength = 6 * slicePointsAmount * getDaysAmount(); + uint64_t currentIndex = 0; + uint64_t* indices = (uint64_t*) calloc(indicesLength, sizeof(uint64_t)); + for (uint64_t day = 0; day < getDaysAmount() - 1; day ++) { + for (uint64_t pointOfSlice = 0; pointOfSlice < slicePointsAmount; pointOfSlice ++) { + // cout << currentIndex << endl; + uint64_t dayOffset = day * slicePointsAmount; + uint64_t currentPointIndex = dayOffset + pointOfSlice; - // for (uint64_t i = 0; i < indicesLength; i ++) { - // cout << indices[i] << ","; - // } - // cout << endl; - // cout << indicesLength << endl; + //First triangle + indices[currentIndex] = currentPointIndex; + currentIndex ++; + indices[currentIndex] = currentPointIndex + slicePointsAmount; + currentIndex ++; + indices[currentIndex] = currentPointIndex + 1; + currentIndex++; + //Second triangle + // if (pointOfSlice % (sliceDetalization+1) == 0 && pointOfSlice != 0) { + if (pointOfSlice == sliceDetailization+1) { + indices[currentIndex] = currentPointIndex - (slicePointsAmount - 1); + currentIndex++; + indices[currentIndex] = currentPointIndex + 1; + currentIndex++; + indices[currentIndex] = currentPointIndex; + } else { + indices[currentIndex] = currentPointIndex + 1; + currentIndex++; + indices[currentIndex] = currentPointIndex + slicePointsAmount + 1; + currentIndex ++; + indices[currentIndex] = currentPointIndex + slicePointsAmount; + } + currentIndex ++; + } + } - if (currentIndex != indicesLength) { - cerr << "currentIndex == indicesLength assertion failed" << endl; - cerr << currentIndex << " " << indicesLength << endl; - } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned long) * indicesLength, indices, GL_STATIC_DRAW); - free(indices); - return indicesLength; + // for (uint64_t i = 0; i < indicesLength; i ++) { + // cout << indices[i] << ","; + // } + // cout << endl; + // cout << indicesLength << endl; + + if (currentIndex != indicesLength) { + cerr << "currentIndex == indicesLength assertion failed" << endl; + cerr << currentIndex << " " << indicesLength << endl; + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned long) * indicesLength, indices, GL_STATIC_DRAW); + free(indices); + return indicesLength; } -// void testEBO(uint64_t *EBO, uint64_t length) { -// for (uint64_t i = 0; i < length; i ++) { - -// } -// } // Sample layout of 2 slices with 3 points. // |x |y |z |r |g |b | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | // 0 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 -// | point | point | point | point | point | point | +// | point | point | point | point | point | point | // | slice | slice | -// +// void CoilSegment::calculate() { - float *slice = calculateSlice(); - - constructSegment(slice); - exportSegmentToCsv(); + float *slice = calculateSlice(); + constructSegment(slice); } float *CoilSegment::getVertices() { return vertices; } uint64_t CoilSegment::getVerticesLength() { return verticesLength; } +uint64_t CoilSegment::getVerticesAmount() { return verticesLength / FIELDS_IN_POINT; } + uint16_t CoilSegment::getYear() { return year; } -void CoilSegment::render() { - -} void CoilSegment::exportSliceToCSV(float *slice) { - cout << "Exporting slice to csv" << endl; - std::ofstream outFile("./slice_export.csv"); + cout << "Exporting slice to csv" << endl; + std::ofstream outFile("./slice_export.csv"); - outFile << "x,y,z" << endl; - - for (uint32_t i = 0; i < sliceDetalization+2; i ++) { - uint32_t offset = FIELDS_IN_POINT * i; - outFile - << slice[offset + 0] << "," - << slice[offset + 1] << ",0" << endl; - } + outFile << "x,y,z" << endl; + + for (uint32_t i = 0; i < slicePointsAmount; i ++) { + uint32_t offset = FIELDS_IN_POINT * i; + outFile + << slice[offset + 0] << "," + << slice[offset + 1] << ",0" << endl; + } } void CoilSegment::exportSegmentToCsv() { - cout << "Exporting segment to csv" << endl; - std::ofstream outFile("./segment_export.csv"); + cout << "Exporting segment to csv" << endl; + std::ofstream outFile("./segment_export.csv"); - outFile << "x,y,z" << endl; + outFile << "x,y,z" << endl; - for (uint16_t day = 0; day < DAYS_IN_YEAR; day ++) { - uint64_t dayOffset = day * (2+sliceDetalization) * FIELDS_IN_POINT; + for (uint16_t day = 0; day < getDaysAmount(); day ++) { + uint64_t dayOffset = day * slicePointsAmount * FIELDS_IN_POINT; - for (uint32_t point_in_slice = 0; point_in_slice < (2+sliceDetalization); point_in_slice ++) { - uint32_t sliceOffset = point_in_slice * FIELDS_IN_POINT; - outFile << vertices[dayOffset + sliceOffset + 0] << "," - << vertices[dayOffset + sliceOffset + 1] << "," - << vertices[dayOffset + sliceOffset + 2] << endl; - } - } -} \ No newline at end of file + for (uint32_t point_in_slice = 0; point_in_slice < slicePointsAmount; point_in_slice ++) { + uint32_t sliceOffset = point_in_slice * FIELDS_IN_POINT; + outFile << vertices[dayOffset + sliceOffset + 0] << "," + << vertices[dayOffset + sliceOffset + 1] << "," + << vertices[dayOffset + sliceOffset + 2] << endl; + } + } +} + +uint16_t CoilSegment::getDaysAmount() { return leap? 366 : 365; } + +bool const CoilSegment::isLeap() { return leap; } + +uint32_t CoilSegment::getSliceDetailization() { return sliceDetailization; } + +uint32_t CoilSegment::getSlicePointsAmount() { return sliceDetailization + 2; } \ No newline at end of file diff --git a/src/coil/segment.hpp b/src/coil/segment.hpp index 2f4f5cd..2e0e443 100644 --- a/src/coil/segment.hpp +++ b/src/coil/segment.hpp @@ -3,6 +3,9 @@ #include +// x, y, z, r, g, b +#define FIELDS_IN_POINT 6 + class Coil; class CoilSegment { @@ -11,8 +14,9 @@ class CoilSegment { uint16_t height; // Number of a segments, counting from the central (which is 0) int shift; - uint32_t sliceDetalization; - bool isLeap; + uint32_t sliceDetailization; + uint32_t slicePointsAmount; + bool leap; float *vertices; uint64_t verticesLength; @@ -21,18 +25,22 @@ class CoilSegment { void constructSegment(float *slice); public: - CoilSegment(Coil* coil, uint16_t year, uint16_t height, int shift, uint32_t sliceDetalization, bool isLeap); + CoilSegment(Coil* coil, uint16_t year, uint16_t height, int shift, uint32_t sliceDetalization); void calculate(); void printVertices(); float *getVertices(); uint64_t getVerticesLength(); + uint64_t getVerticesAmount(); void printSlice(float *slice); void exportSliceToCSV(float *slice); void exportSegmentToCsv(); - void render(); - void fillVBO(); uint64_t fillEBO(uint64_t EBO); uint16_t getYear(); + + uint16_t getDaysAmount(); + bool const isLeap(); + uint32_t getSliceDetailization(); + uint32_t getSlicePointsAmount(); }; #endif // COIL_SEGMENT_HPP \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a7b5a76..d4a27da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,9 +9,14 @@ #include #include + + #include #include #include +#include + + using std::cerr; using std::cout; @@ -23,18 +28,36 @@ using std::endl; void framebufferSizeCallback(GLFWwindow *window, int width, int height) { glViewport(10, 10, width-10, height-10); -} +} + +Camera cam = Camera(glm::vec3(0., 0., 0), glm::vec3(0., 1.,0.),-89, 0, 20, 0.1, CameraType::FREE); + void processInput(GLFWwindow *window) { if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); - } + return; + } + + CameraMovement dir; + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) + dir = CameraMovement::FORWARD; + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) + dir = CameraMovement::BACKWARD; + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + dir = CameraMovement::LEFT; + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + dir = CameraMovement::RIGHT; + + cam.processKeyboardInput(dir); } +void processMousePosCallback(GLFWwindow *window, double deltaX, double deltaY) { + cam.processMouseInput(window, deltaX, deltaY); +} int main () { - - Coil c = Coil(2025, 1, 5, 50, 10); + Coil coil = Coil(2025, 3, 10, 2, 50, 10); srand(time(0)); glfwInit(); @@ -53,6 +76,8 @@ int main () { glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebufferSizeCallback); + glfwSetCursorPosCallback(window, processMousePosCallback); + // glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { cerr << "Failed to initialize GLAD." << endl; @@ -68,159 +93,30 @@ int main () { unsigned int projectionLoc = glGetUniformLocation(shaderProgram, "projection"); glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); - - c.initGLBuffers(); - - // float vertices[] = { - // // positions // texture coords - // 05.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right - // 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right - // -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left - // -0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left - // }; - // unsigned int indices[] = { - // 0, 1, 3, // first triangle - // 1, 2, 3 // second triangle - // }; - // unsigned int VBO, VAO, EBO; - // glGenVertexArrays(1, &VAO); - // glGenBuffers(1, &VBO); - // glGenBuffers(1, &EBO); - - // glBindVertexArray(VAO); - - // glBindBuffer(GL_ARRAY_BUFFER, VBO); - // glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - // glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - - // // position attribute - // glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); - // glEnableVertexAttribArray(0); - // // texture coord attribute - // glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); - // glEnableVertexAttribArray(1); - + // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + coil.initGLBuffers(); + glEnable(GL_DEPTH_TEST); while(!glfwWindowShouldClose(window)) { processInput(window); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 model = glm::mat4(1.0f); glm::mat4 view = glm::mat4(1.0f); model = glm::rotate(model, glm::radians(5.0f), glm::vec3(1.0f, 0.0f, 0.0f)); - view = glm::translate(view, glm::vec3(0.0f, 0.0f, -89.0f)); - + view = cam.getViewMatrix(); unsigned int modelLoc = glGetUniformLocation(shaderProgram, "model"); unsigned int viewLoc = glGetUniformLocation(shaderProgram, "view"); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - c.render(); - // glBindVertexArray(VAO); - // glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + coil.render(); glfwSwapBuffers(window); glfwPollEvents(); } - // CoilSegment cs = CoilSegment(10, 0, false); - // for (auto segment : c.getSegments()) { - // // segment.printVertices(); - // } - // cs.printVertices(); gracefulExit(0); -// srand(time(0)); -// glfwInit(); -// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); -// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); -// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -// #ifdef __APPLE__ -// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -// #endif - -// GLFWwindow *window = glfwCreateWindow(800, 600, "TimeCoil", NULL, NULL); -// if (window == NULL) { -// std::cerr << "Failed to create GLFW window." << std::endl; -// gracefulExit(-1); -// } - -// glfwMakeContextCurrent(window); -// glfwSetFramebufferSizeCallback(window, framebufferSizeCallback); - -// if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { -// std::cerr << "Failed to initialize GLAD." << std::endl; -// return -1; -// } - -// unsigned int shaderProgram = prepareShaders(); - -// float *vertices = cs.getVertices(); -// unsigned int amountOfVerticies = cs.getVerticesLength(); -// std::cout << amountOfVerticies << std::endl; -// // float vertices[] = { -// // -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // upper left -// // -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left -// // 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // upper right -// // 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f // bottom right -// // }; -// // unsigned int indices[] = { -// // 1, 2, 3, -// // 1, 2, 0 -// // }; -// unsigned int VBO, VAO, EBO; -// glGenVertexArrays(1, &VAO); -// glGenBuffers(1, &VBO); -// // glGenBuffers(1, &EBO); - -// glBindVertexArray(VAO); - -// glBindBuffer(GL_ARRAY_BUFFER, VBO); -// // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - -// glBufferData(GL_ARRAY_BUFFER, amountOfVerticies, vertices, GL_STATIC_DRAW); -// // glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - -// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); -// glEnableVertexAttribArray(0); - -// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*) (3 * sizeof(float))); -// glEnableVertexAttribArray(1); - -// glBindVertexArray(0); - -// while(!glfwWindowShouldClose(window)) { -// processInput(window); - -// glClearColor(0.2f, 0.3f, 0.3f, 1.0f); -// glClear(GL_COLOR_BUFFER_BIT); - -// glUseProgram(shaderProgram); - -// // float time = glfwGetTime(); -// // float greenValue = sin(time); - - -// // int vertexColorLocation = glGetUniformLocation(shaderProgram, "MyColor"); -// // glUniform4f(vertexColorLocation, 0, greenValue, 0, 1); -// glBindVertexArray(VAO); - -// // updateVertices(vertices); -// glBufferData(GL_ARRAY_BUFFER, amountOfVerticies, vertices, GL_DYNAMIC_DRAW); -// // glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); -// glDrawArrays(GL_LINE_STRIP_ADJACENCY, -30, amountOfVerticies); - - -// glBindVertexArray(0); -// glfwSwapBuffers(window); -// glfwPollEvents(); -// } - -// glDeleteVertexArrays(1, &VAO); -// glDeleteBuffers(1, &VBO); -// glDeleteProgram(shaderProgram); -// gracefulExit(0); } diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index a6df396..4b701c3 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -5,7 +5,7 @@ #include #include -float round_to_presicion( float value, int precision ) { +float round_to_precision( float value, int precision ) { const int adjustment = pow(10,precision); return floor( value*(adjustment) + 0.5 )/adjustment; } diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index ffdbe53..fd35dea 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -3,7 +3,7 @@ #include #include -float round_to_presicion( float value, int precision ); +float round_to_precision( float value, int precision ); std::string readFile(std::string path);