Set cube scene

This commit is contained in:
NaifBanana 2024-11-20 20:51:32 -06:00
parent afed80219e
commit b1681de107
9 changed files with 214 additions and 282 deletions

View File

@ -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)

110
Draw.cpp
View File

@ -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();
}
// 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();
}
}

View File

@ -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();
}
}
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_A) == GLFW_PRESS) {
cam->yaw(0.05f);
}
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));
}
}

157
grid.cpp
View File

@ -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<VertexAttributePointer> 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<float>(_m*_n*2);
_cells = CellGrid(_n, std::vector<Cell>(_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<Cell>& 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 && x<_tr.x) || !(_bl.y<y && y<_tr.y)) {
return;
}
int i=0, j=0;
for (; j < _m; ++j) {
if (_cell_offsets[j*2] > 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; }
}
}

View File

@ -6,7 +6,8 @@
#include <exception>
#include <glm/glm.hpp>
#include <>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <map>
#include <string>
#include <vector>
@ -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();
};

View File

@ -4,21 +4,12 @@
#include <iostream>
#include <thread>
#include <GLLoad.h>
#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

View File

@ -1,52 +0,0 @@
#pragma once
#ifndef _NB_GRID
#define _NB_GRID
#include <exception>
#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<std::vector<Cell>> 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<float> _cell_verts;
std::vector<float> _cell_offsets;
DrawInstanceBuffer _buffer;
CellGrid _cells;
};
}
#endif

View File

@ -11,13 +11,9 @@
#include <Window.h>
#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<float> 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<unsigned int> 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();

View File

@ -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);
}