From b1681de107a2eaa76ae5e649cb29a0486743d11e Mon Sep 17 00:00:00 2001 From: NaifBanana <30419422+NaifBanana@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:51:32 -0600 Subject: [PATCH] Set cube scene --- CMakeLists.txt | 4 +- Draw.cpp | 112 +++++++++++++++++++++++++++++++++- funcs.cpp | 46 +++++--------- grid.cpp | 157 ------------------------------------------------ include/Draw.h | 55 ++++++++++++++++- include/funcs.h | 13 +--- include/grid.h | 52 ---------------- main.cpp | 53 +++++++++------- shaders/vert.vs | 4 +- 9 files changed, 214 insertions(+), 282 deletions(-) delete mode 100644 grid.cpp delete mode 100644 include/grid.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ce0f2e..b1d9f79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ include_directories( ../libs/NBEngine/include ../libs/glfw/include ../libs/glad/include - ../libs/glm-0.9.9.8/ + ../libs/glm-0.9.9.8/glm ./deps ./include ) @@ -39,6 +39,6 @@ set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(NBGL_BUILD_TEST ON) -add_executable(GraphicsTest main.cpp funcs.cpp Draw.cpp Shader.cpp grid.cpp Buffers.cpp ../libs/glad/src/glad.c) +add_executable(GraphicsTest main.cpp funcs.cpp Draw.cpp Shader.cpp Buffers.cpp ../libs/glad/src/glad.c) target_link_libraries(GraphicsTest NBWindow glfw OpenGL::GL) diff --git a/Draw.cpp b/Draw.cpp index cd90e7c..44dae67 100644 --- a/Draw.cpp +++ b/Draw.cpp @@ -72,7 +72,7 @@ uint8_t PrimitivesFromVertices(GLenum type, unsigned int num_verts) { } -//DrawBuffer class +// DrawBuffer class DrawBuffer::DrawBuffer(const Shader& shader, VertexAttributeList vas, GLenum prim_type) : _shader(shader), _vert_data(), _elmt_data(), _gl_primitive_type(prim_type), _VAO() { @@ -210,7 +210,7 @@ void DrawBuffer::loadVBO(const RawVec& data, unsigned int offset) { _VAO.unbind(); } -//DrawInstanceBufferClass +// DrawInstanceBufferClass DrawInstanceBuffer::DrawInstanceBuffer( const Shader& shad, VertexAttributeList vert_vas, @@ -307,4 +307,110 @@ void DrawInstanceBuffer::draw() const { _VAO.unbind(); } -} \ No newline at end of file +// Camera class +Camera::Camera(const Vec3& pos, const Vec3& tar, const Vec3& up) : _camera_type(CameraType::None) { + _pos = pos; + _tar = tar; + _world_up = glm::normalize(up); + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _proj = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); + _calcLook(); +} + +void Camera::_calcLook() { + _look = glm::lookAt(_pos, _tar, _world_up); +} + +glm::vec3 Camera::normCross(const Vec3& a, const Vec3& b) { + return glm::normalize(glm::cross(a, b)); +} + +glm::vec3 Camera::getPos() const { return _pos; } + +glm::vec3 Camera::getTarget() const { return _tar; } + +glm::vec3 Camera::getDirection() const { return _dir; } + +glm::vec3 Camera::getWorldUp() const { return _world_up; } + +glm::vec3 Camera::getUp() const { return _up; } + +glm::vec3 Camera::getRight() const { return _right; } + +glm::mat4 Camera::getLookMatrix() const { return _look; } + +glm::mat4 Camera::getProjectionMatrix() const { return _proj; } + +glm::mat4 Camera::getFlattenedMatrices() const { return _proj * _look; } + +void Camera::setProjection(const Mat4& proj) { + _proj = proj; +} + +void Camera::setPos(const Vec3& pos) { + _pos = pos; + _calcLook(); +} + +void Camera::setTarget(const Vec3& tar) { + _tar = tar; + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::setDirection(const Vec3& dir) { + setTarget(glm::normalize(dir)+_pos); +} + +void Camera::setWorldUp(const Vec3& up) { + _world_up = up; + _right = normCross(_dir, _up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::addPos(const Vec3& add) { + _pos += add; + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::panPos(const Vec3& add) { + _tar += add; + addPos(add); +} + +void Camera::addTarget(const Vec3& add) { + _tar += add; + _dir = glm::normalize(_tar-_pos); + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _calcLook(); +} + +void Camera::roll(float ang) { + +} + +void Camera::pitch(float ang) { + Mat4 rot_mat = glm::rotate(_look, ang, _right); + _dir = Vec3(rot_mat * glm::vec4(_dir, 1.0f)); + _tar = _pos + _dir; + _calcLook(); +} + +void Camera::yaw(float ang) { + Mat4 rot_mat = glm::rotate(_look, ang, _up); + _dir = Vec3(rot_mat * glm::vec4(_dir, 1.0f)); + _right = Vec3(rot_mat * glm::vec4(_right, 1.0f)); + _tar = _pos + _dir; + _calcLook(); +} + +} diff --git a/funcs.cpp b/funcs.cpp index 8cfacc4..c788e4a 100644 --- a/funcs.cpp +++ b/funcs.cpp @@ -4,42 +4,24 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } -void keypress_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { - if (key == GLFW_KEY_P && action == GLFW_PRESS) { - if (!running) { lastRefresh = glfwGetTime(); } - running ^= true; - } - if (key == GLFW_KEY_R && action == GLFW_PRESS) { - conwayGrid->setCells(start_grid); - conwayGrid->sendCells(); - lastRefresh = glfwGetTime(); - } -} - void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); } -} - -void mouseclick_callback(GLFWwindow* window, int button, int action, int mods) { - if (action == GLFW_RELEASE) { - double xpos, ypos; - int xsize, ysize; - glfwGetCursorPos(window, &xpos, &ypos); - glfwGetWindowSize(window, &xsize, &ysize); - conwayGrid->click(xpos/xsize, ypos/ysize); - conwayGrid->sendCells(); + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { + cam->yaw(0.05f); } -} - -void mousemove_callback(GLFWwindow* window, double xpos, double ypos) { - if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) { - double xpos, ypos; - int xsize, ysize; - glfwGetCursorPos(window, &xpos, &ypos); - glfwGetWindowSize(window, &xsize, &ysize); - conwayGrid->click(xpos/xsize, ypos/ysize); - conwayGrid->sendCells(); + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { + cam->yaw(-0.05f); + } + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { + cam->pitch(0.05f); + } + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { + cam->pitch(-0.05f); + } + if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) { + cam->setTarget(glm::vec3(0.0f, 0.0f, 0.0f)); + cam->setWorldUp(glm::vec3(0.0f, 1.0f, 0.0f)); } } \ No newline at end of file diff --git a/grid.cpp b/grid.cpp deleted file mode 100644 index 258e882..0000000 --- a/grid.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "grid.h" - -namespace NB{ - -ConwayGridError::ConwayGridError(const std::string& msg) : std::runtime_error(msg) {} - -ConwayGrid::ConwayGrid( - const Shader& shad, - unsigned int m, - unsigned int n, - Vec2 bl, - Vec2 tr -) : _buffer(shad, - {{2, GL_FLOAT, false}, {3, GL_FLOAT, false}}, - {{2, GL_FLOAT, false}, {1, GL_UNSIGNED_BYTE, false}} - ), _m(m), _n(n), _bl(bl), _tr(tr) -{ - if ( (_m < 2) || (_n < 2) ) { - throw ConwayGridError("Grid size must be at least 2x2."); - } - std::vector vaps(2); - unsigned int vertPosChunkDataSize = (_m+1)*(_n+1)*8; - vaps[0].divisor = 1; vaps[0].stride = 2*GLSLTypeSize(GL_FLOAT); - vaps[1].divisor = 1; vaps[1].offset = _m*_n*2*GLSLTypeSize(GL_FLOAT); vaps[1].stride = GLSLTypeSize(GL_UNSIGNED_BYTE); - _buffer.changeInstanceLayout(0, vaps[0]); - _buffer.changeInstanceLayout(1, vaps[1]); - _cell_size.x = (_tr.x-_bl.x)/float(_m); - _cell_size.y = (_tr.y-_bl.y)/float(_n); - _cell_verts = { 0.0, 0.0, 1.0, 0.0, 0.0, - _cell_size.x, 0.0, 0.0, 1.0, 0.0, - 0.0, _cell_size.y, 0.0, 1.0, 0.0, - _cell_size.x, _cell_size.y, 0.0, 0.0, 1.0 - }; - _cell_offsets = std::vector(_m*_n*2); - _cells = CellGrid(_n, std::vector(_m, Cell::Dead)); - for (int i = 0; i < _n; ++i) { - for(int j = 0; j < _m; ++j) { - _cell_offsets[(_m*i+j)*2 ] = _cell_size.x*j + _bl.x; - _cell_offsets[(_m*i+j)*2 + 1] = _cell_size.y*i + _bl.y; - } - } - _buffer.keepLocalElement(false); - _buffer.keepLocalVertex(false); - NB_GL_DEBUG(_buffer.generateEBO({0, 2, 3, 0, 3, 1})); - NB_GL_DEBUG(_buffer.generateVBO(vectorToRaw(_cell_verts))); - _buffer.generateIBO(_m*_n); - RawVec cell_offs_raw = vectorToRaw(_cell_offsets); - _buffer.loadIBO(cell_offs_raw); - sendCells(); -} - -ConwayGrid::CellGrid ConwayGrid::getCells() const { return _cells; } - -void ConwayGrid::setCells(const ConwayGrid::CellGrid& set_cells) { - if (set_cells.size() != _n) { - throw ConwayGridError("New cell grid with " + std::to_string(set_cells.size()) + - " rows does not match ConwayGrid of " + std::to_string(_n) + - " rows."); - } - for (const std::vector& row : set_cells) { - if (row.size() != _m) { - throw ConwayGridError("New cell grid with " + std::to_string(set_cells.size()) + - " columns does not match ConwayGrid of " + std::to_string(_n) + - " columns."); - } - } - _cells = set_cells; -} - -void ConwayGrid::sendCells() { - unsigned int curr_byte = vectorToRaw(_cell_offsets).size(); - for (int i = 0; i < _n; ++i) { - _buffer.loadIBO(vectorToRaw(_cells[i]), curr_byte); - curr_byte += _cells[i].size(); - } -} - -void ConwayGrid::calcNext() { - decltype(_cells) prev = _cells; - int numAlive = 0; - for (int i = 0; i < _n; ++i) { - for (int j = 0; j < _m; ++j) { - numAlive = 0; - if (j != 0) { - numAlive += prev[i][j-1]; - if (i != 0) { - numAlive += prev[i-1][j-1]; - } - if (i != _n-1) { - numAlive += prev[i+1][j-1]; - } - } - if (j != _m-1) { - numAlive += prev[i][j+1]; - if (i != 0) { - numAlive += prev[i-1][j+1]; - } - if (i != _n-1) { - numAlive += prev[i+1][j+1]; - } - } - if (i != 0) { - numAlive += prev[i-1][j]; - } - if (i != _n-1) { - numAlive += prev[i+1][j]; - } - if (_cells[i][j]) { - if ((numAlive<2) || (numAlive>3)) { - _cells[i][j] = Cell::Dead; - } - } else { - if (numAlive==3) { - _cells[i][j] = Cell::Alive; - } - } - } - } -} - -void ConwayGrid::draw() { - _buffer.draw(); -} - -Cell& ConwayGrid::at(unsigned int x, unsigned int y) { - if ((x<0) || (_n<=y) || (y<0) || (_m<=y)) { - throw ConwayGridError("Indices of x=" + std::to_string(x) + " and y=" + std::to_string(y) + " are out of bounds."); - } - return _cells[y][x]; -} - -void ConwayGrid::click(double x, double y) { - x = x*2-1; - y = y*-2+1; - if (!(_bl.x x) { - if (j) { j--; } - break; - } - } - for (; i<_n; ++i) { - if (_cell_offsets[_m*i*2+1] > y) { - if (i) { i--; } - break; - } - } - i = (i<_n) ? i : _n-1; - j = (j<_m) ? j : _m-1; - unsigned char prev = at(j, i); - if (prev) { at(j,i)=Cell::Dead; } else { at(j, i)=Cell::Alive; } -} - -} \ No newline at end of file diff --git a/include/Draw.h b/include/Draw.h index 146efef..89fb78e 100644 --- a/include/Draw.h +++ b/include/Draw.h @@ -6,7 +6,8 @@ #include #include -#include <> +#include +#include #include #include #include @@ -84,6 +85,58 @@ private: }; class Camera { +public: + typedef glm::vec3 Vec3; + typedef glm::mat4 Mat4; + + enum CameraType : unsigned char { + None, + Orthographic, + Perspective + }; + + static Vec3 normCross(const Vec3&, const Vec3&); + + Camera( + const Vec3& pos=Vec3(1.0f, 0.0f, 0.0f), + const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f), + const Vec3& up =Vec3(0.0f, 1.0f, 0.0f) + ); + + Vec3 getPos() const; + Vec3 getTarget() const; + Vec3 getDirection() const; + Vec3 getWorldUp() const; + Vec3 getUp() const; + Vec3 getRight() const; + Mat4 getLookMatrix() const; + Mat4 getProjectionMatrix() const; + Mat4 getFlattenedMatrices() const; + + void setProjection(const Mat4&); + void setPos(const Vec3&); + void setTarget(const Vec3&); + void setDirection(const Vec3&); + void setWorldUp(const Vec3&); + void addPos(const Vec3&); + void panPos(const Vec3&); + void addTarget(const Vec3&); + void roll(float); + void pitch(float); + void yaw(float); + +protected: + Vec3 _pos; + Vec3 _tar; + Vec3 _dir; + Vec3 _world_up; + Vec3 _up; + Vec3 _right; + Mat4 _look; + Mat4 _proj; + const CameraType _camera_type; + + void _calcLook(); }; diff --git a/include/funcs.h b/include/funcs.h index 0d5c9df..89db972 100644 --- a/include/funcs.h +++ b/include/funcs.h @@ -4,21 +4,12 @@ #include #include #include -#include "grid.h" +#include "Draw.h" -extern bool running; -extern float lastRefresh; -extern NB::ConwayGrid* conwayGrid; -extern NB::ConwayGrid::CellGrid start_grid; +extern NB::Camera* cam; void framebuffer_size_callback(GLFWwindow*, int, int); -void keypress_callback(GLFWwindow*, int, int, int, int); - void processInput(GLFWwindow*); -void mouseclick_callback(GLFWwindow*, int, int, int); - -void mousemove_callback(GLFWwindow*, double, double); - #endif \ No newline at end of file diff --git a/include/grid.h b/include/grid.h deleted file mode 100644 index 0879ea1..0000000 --- a/include/grid.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#ifndef _NB_GRID -#define _NB_GRID - -#include - -#include "Draw.h" - -namespace NB{ - -class ConwayGridError : std::runtime_error { -public: - ConwayGridError(const std::string&); -}; - -struct Vec2 { - float x; - float y; -}; - -enum Cell : unsigned char { - Dead = 0, - Alive = 1 -}; - -class ConwayGrid { -public: - typedef std::vector> CellGrid; - - ConwayGrid(const Shader&, unsigned int m=2, unsigned int n=2, Vec2 bl={-1, -1}, Vec2 tr={1, 1}); - - CellGrid getCells() const; - - void setCells(const CellGrid&); - Cell& at(unsigned int, unsigned int); - void calcNext(); - void sendCells(); - void draw(); - void click(double, double); - -private: - unsigned int _m, _n; - Vec2 _bl, _tr, _cell_size; - std::vector _cell_verts; - std::vector _cell_offsets; - DrawInstanceBuffer _buffer; - CellGrid _cells; -}; - -} - -#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp index e4637c5..0e4d8de 100644 --- a/main.cpp +++ b/main.cpp @@ -11,13 +11,9 @@ #include #include "Draw.h" -#include "grid.h" #include "Buffers.h" -bool running = false; -float lastRefresh = 0.0; -NB::ConwayGrid* conwayGrid; -NB::ConwayGrid::CellGrid start_grid; +NB::Camera* cam; int main() { NB::Window myWindow(800, 600, "Howdy Naif!"); @@ -27,19 +23,37 @@ int main() { auto window = myWindow.getWindow(); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetKeyCallback(window, keypress_callback); - glfwSetMouseButtonCallback(window, mouseclick_callback); - glfwSetCursorPosCallback(window, mousemove_callback); NB::Shader myShader("../shaders/vert.vs", "../shaders/frag.fs"); myShader.use(); - NB::ConwayGrid myGrid(myShader, 30, 30, {-0.9, -0.9}, {0.9, 0.9}); - conwayGrid = &myGrid; - NB_GL_DEBUG(myGrid.sendCells()); + NB::DrawBuffer myCube(myShader, {{3, GL_FLOAT}, {3, GL_FLOAT}}, GL_TRIANGLES); + std::vector vert_data = { + -.5, -.5, -.5, 0, 0, 0, + 0.5, -.5, -.5, 1, 0, 0, + -.5, 0.5, -.5, 0, 1, 0, + 0.5, 0.5, -.5, 1, 1, 0, + -.5, -.5, 0.5, 0, 0, 1, + 0.5, -.5, 0.5, 1, 0, 1, + -.5, 0.5, 0.5, 0, 1, 1, + 0.5, 0.5, 0.5, 1, 1, 1, + }; + std::vector elmt_data = { + 0, 2, 3, 0, 3, 1, + 4, 7, 6, 4, 5, 7, + 4, 6, 2, 4, 2, 0, + 1, 3, 7, 1, 7, 5, + 4, 0, 1, 4, 1, 5, + 2, 6, 7, 2, 7, 3 + }; + myCube.generateVBO(NB::vectorToRaw(vert_data)); + myCube.generateEBO(elmt_data); + + NB::Camera myCam(glm::vec3(0.0f, 0.0f, 1.0f)); + cam = &myCam; + glm::mat4 lookMat; // Window loop - start_grid = myGrid.getCells(); GLenum err; while(!glfwWindowShouldClose(window)) { NB_GL_DEBUG_THROW("nothing", "during"); @@ -48,18 +62,11 @@ int main() { // Rendering Loop myShader.use(); - if (running) { - glClearColor(0.2f, 0.4f, 0.3f, 1.0f); - } else { - glClearColor(0.4f, 0.2f, 0.3f, 1.0f); - } + lookMat = myCam.getLookMatrix(); + myShader.setMat4("look", lookMat); + glClearColor(0.2f, 0.4f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - NB_GL_DEBUG(myGrid.draw()); - if ( running && glfwGetTime()-lastRefresh > 0.2) { - myGrid.calcNext(); - myGrid.sendCells(); - lastRefresh = glfwGetTime(); - } + myCube.draw(); // Events and buffer swap // myDrawing.draw(); diff --git a/shaders/vert.vs b/shaders/vert.vs index 522c679..7d6e3eb 100644 --- a/shaders/vert.vs +++ b/shaders/vert.vs @@ -4,10 +4,12 @@ layout (location=1) in vec3 bary; layout (location=2) in vec2 iPos; layout (location=3) in uint life; +uniform mat4 look; + out vec3 vertColor; out vec3 baryPos; void main() { baryPos = bary; vertColor = vec3(1.0, 1.0, 1.0)*life; - gl_Position = vec4(iPos + vPos, 0.0, 1.0); + gl_Position = look * vec4(iPos + vPos, 0.0, 1.0); } \ No newline at end of file