got movement and tile placing working
This commit is contained in:
parent
4e3ab6460b
commit
799fd1c7dc
|
@ -17,6 +17,7 @@ void main() {
|
|||
mat4 mat_mv = u_view * u_model;
|
||||
vout.pos = mat_mv * vec4(v_pos, 1);
|
||||
vout.colour = v_colour;
|
||||
gl_Position = u_projection * vout.pos;
|
||||
vec4 p = u_projection * vout.pos;
|
||||
gl_Position = vec4(p.xy, 2 / (p.z + 2) - 1, p.w);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,49 @@
|
|||
|
||||
#include "context.hpp"
|
||||
#include "gl/uniform.hpp"
|
||||
#include "window.hpp"
|
||||
#include <GL/glew.h>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include <glm/ext/matrix_float4x4.hpp>
|
||||
#include <glm/trigonometric.hpp>
|
||||
|
||||
using Graphics::Context;
|
||||
|
||||
Context::Context(unsigned int program) {
|
||||
Context::Context(GLFWwindow* window, unsigned int program) {
|
||||
glUseProgram(program);
|
||||
m_u_model = glGetUniformLocation(program, "u_model");
|
||||
m_u_view = glGetUniformLocation(program, "u_view");
|
||||
m_u_projection = glGetUniformLocation(program, "u_projection");
|
||||
m_u_colour = glGetUniformLocation(program, "u_colour");
|
||||
m_program = program;
|
||||
m_window = window;
|
||||
}
|
||||
|
||||
void Context::set_model_matrix(glm::mat4 mat) {
|
||||
void Context::set_model_matrix(glm::mat4 mat) const {
|
||||
GL::Uniform::set_mat4(m_u_model, false, mat);
|
||||
}
|
||||
|
||||
void Context::set_view_matrix(glm::mat4 mat) {
|
||||
GL::Uniform::set_mat4(m_u_view, false, mat);
|
||||
m_view = mat;
|
||||
}
|
||||
void Context::set_projection_matrix(glm::mat4 mat) {
|
||||
GL::Uniform::set_mat4(m_u_projection, false, mat);
|
||||
}
|
||||
void Context::set_colour_matrix(glm::mat4 mat) {
|
||||
|
||||
void Context::set_colour_matrix(glm::mat4 mat) const {
|
||||
GL::Uniform::set_mat4(m_u_colour, false, mat);
|
||||
}
|
||||
|
||||
void Context::set_projection_matrix(glm::mat4 mat) {
|
||||
GL::Uniform::set_mat4(m_u_projection, false, mat);
|
||||
m_projection = mat;
|
||||
}
|
||||
|
||||
void Context::set_player(const World::Player& player) {
|
||||
set_projection_matrix(glm::perspective(glm::radians(90.0f), Graphics::Window::get_aspect(), 0.01f, 10.f));
|
||||
set_view_matrix(player.get_view_matrix());
|
||||
m_transform = player.m_pos;
|
||||
}
|
||||
|
||||
glm::mat4 Context::get_vp() const {
|
||||
return m_projection * m_view;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,21 +2,31 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/ext/matrix_float4x4.hpp>
|
||||
#include <glm/ext/vector_float4.hpp>
|
||||
#include <glm/matrix.hpp>
|
||||
#include "../world/player.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
namespace Graphics {
|
||||
struct Context {
|
||||
GLFWwindow* m_window;
|
||||
unsigned int m_program;
|
||||
unsigned int m_u_model;
|
||||
unsigned int m_u_view;
|
||||
unsigned int m_u_projection;
|
||||
unsigned int m_u_colour;
|
||||
glm::vec<2, double> m_transform;
|
||||
glm::mat4 m_view;
|
||||
glm::mat4 m_projection;
|
||||
|
||||
Context(unsigned int program);
|
||||
Context(GLFWwindow* window, unsigned int program);
|
||||
|
||||
void set_model_matrix(glm::mat4 mat);
|
||||
void set_model_matrix(glm::mat4 mat) const;
|
||||
void set_view_matrix(glm::mat4 mat);
|
||||
void set_projection_matrix(glm::mat4 mat);
|
||||
void set_colour_matrix(glm::mat4 mat);
|
||||
void set_colour_matrix(glm::mat4 mat) const;
|
||||
void set_player(const World::Player& player);
|
||||
|
||||
glm::mat4 get_vp() const;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
#include <iostream>
|
||||
#include "model.hpp"
|
||||
#include "../../util/stream/vector.hpp"
|
||||
|
||||
using Graphics::GL::Model;
|
||||
|
||||
|
@ -10,16 +8,6 @@ void Model::set(const Mesh& mesh, int usage) {
|
|||
glBufferData(GL_ARRAY_BUFFER, mesh.m_vertices.size() * sizeof(mesh.m_vertices[0]), mesh.m_vertices.data(), usage);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.m_indices.size() * sizeof(mesh.m_indices[0]), mesh.m_indices.data(), usage);
|
||||
m_size = mesh.m_indices.size();
|
||||
|
||||
std::cout << "Indices: ";
|
||||
for(int i : mesh.m_indices) {
|
||||
std::cout << i << ", ";
|
||||
}
|
||||
std::cout << "\nVertices:\n";
|
||||
for(const Vertex& v : mesh.m_vertices) {
|
||||
std::cout << Util::Stream::Vector(v.m_pos) << ", ";
|
||||
std::cout << Util::Stream::Vector(v.m_colour) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void Model::bind() const {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include "pipeline.hpp"
|
||||
#include "context.hpp"
|
||||
#include "gl/shader.hpp"
|
||||
#include "shader/compile.hpp"
|
||||
#include "shader/link.hpp"
|
||||
|
||||
using Graphics::Pipeline;
|
||||
|
||||
Pipeline::Pipeline() {
|
||||
Graphics::GL::Shader model_vert(GL_VERTEX_SHADER);
|
||||
Graphics::GL::Shader model_frag(GL_FRAGMENT_SHADER);
|
||||
Graphics::Shader::compile(model_vert, "../assets/shader/model.vert");
|
||||
Graphics::Shader::compile(model_frag, "../assets/shader/model.frag");
|
||||
Graphics::Shader::link(m_program_model, {model_vert, model_frag});
|
||||
}
|
||||
|
||||
bool Pipeline::should_close() const {
|
||||
return m_window.should_close();
|
||||
}
|
||||
|
||||
void Pipeline::update() const {
|
||||
m_window.update();
|
||||
}
|
||||
|
||||
void Pipeline::render(const World::State& state, const Context& ctx) const {
|
||||
|
||||
glUseProgram(m_program_model);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.1, 0.1, 0.12, 1);
|
||||
|
||||
state.render(ctx);
|
||||
m_window.swap_buffers();
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "context.hpp"
|
||||
#include "gl/program.hpp"
|
||||
#include "window.hpp"
|
||||
#include "../world/state.hpp"
|
||||
|
||||
namespace Graphics {
|
||||
struct Pipeline {
|
||||
Window m_window;
|
||||
GL::Program m_program_model;
|
||||
|
||||
Pipeline();
|
||||
void update() const;
|
||||
void render(const World::State& state, const Context& ctx) const;
|
||||
bool should_close() const;
|
||||
|
||||
operator unsigned int() const;
|
||||
};
|
||||
};
|
||||
|
|
@ -13,7 +13,7 @@ namespace Graphics {
|
|||
constexpr Primitive with_colour(glm::vec4 colour) const {
|
||||
Primitive p = *this;
|
||||
for(Vertex& v : p.m_vertices) {
|
||||
v.m_colour = colour;
|
||||
v.m_colour *= colour;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -105,9 +105,8 @@ static bool parse(std::vector<char>& source, const std::filesystem::path& path)
|
|||
return true;
|
||||
}
|
||||
|
||||
Graphics::GL::Shader Graphics::Shader::compile(int type, const std::filesystem::path& path) {
|
||||
void Graphics::Shader::compile(unsigned int shader, const std::filesystem::path& path) {
|
||||
std::vector<char> source;
|
||||
GL::Shader shader(type);
|
||||
|
||||
if(!parse(source, path)) {
|
||||
throw std::runtime_error(std::format("File '{}' not found", path.string()));
|
||||
|
@ -140,7 +139,5 @@ Graphics::GL::Shader Graphics::Shader::compile(int type, const std::filesystem::
|
|||
|
||||
throw std::runtime_error(std::format("OpenGL shader compilation error\n{}\nIn expanded source file '{}'\n{}", source_processed.str(), path.string(), info_log));
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../gl/shader.hpp"
|
||||
#include <filesystem>
|
||||
|
||||
namespace Graphics::Shader {
|
||||
GL::Shader compile(int type, const std::filesystem::path& path);
|
||||
void compile(unsigned int shader, const std::filesystem::path& path);
|
||||
};
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include <format>
|
||||
#include <stdexcept>
|
||||
|
||||
Graphics::GL::Program Graphics::Shader::link(const std::vector<unsigned int>& shaders) {
|
||||
GL::Program program;
|
||||
void Graphics::Shader::link(unsigned int program, const std::vector<unsigned int>& shaders) {
|
||||
int success;
|
||||
|
||||
for(unsigned int shader : shaders) {
|
||||
|
@ -20,7 +19,5 @@ Graphics::GL::Program Graphics::Shader::link(const std::vector<unsigned int>& sh
|
|||
glGetProgramInfoLog(program, sizeof(buff), nullptr, buff);
|
||||
throw std::runtime_error(std::format("OpenGL link error: {}", buff));
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../gl/program.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Graphics::Shader {
|
||||
GL::Program link(const std::vector<unsigned int>& shaders);
|
||||
void link(unsigned int program, const std::vector<unsigned int>& shaders);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/matrix.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include "window.hpp"
|
||||
#include "init.hpp"
|
||||
|
||||
using Graphics::Window;
|
||||
|
||||
static void GLAPIENTRY cb_debug_message(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) {
|
||||
if(severity == GL_DEBUG_SEVERITY_HIGH) {
|
||||
throw std::runtime_error(message);
|
||||
|
@ -16,11 +19,54 @@ static void GLAPIENTRY cb_debug_message(GLenum source, GLenum type, GLuint id, G
|
|||
}
|
||||
}
|
||||
|
||||
Graphics::Window::Window() {
|
||||
static void cb_framebuffer_size(GLFWwindow* win, int w, int h) {
|
||||
Window::size = {w, h};
|
||||
}
|
||||
|
||||
static void cb_keypress(GLFWwindow* win, int key, int sc, int action, int mods) {
|
||||
if(action == GLFW_PRESS && key == GLFW_KEY_ESCAPE) {
|
||||
if(Window::mouse_locked) {
|
||||
Window::mouse_locked = false;
|
||||
glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
} else {
|
||||
Window::mouse_locked = true;
|
||||
glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool clicked_from_cb = false;
|
||||
|
||||
void cb_mouse_button(GLFWwindow* win, int button, int action, int mods) {
|
||||
if(button == GLFW_MOUSE_BUTTON_RIGHT) {
|
||||
if(action == GLFW_PRESS) {
|
||||
Window::mouse_locked = true;
|
||||
glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
else if(action == GLFW_RELEASE) {
|
||||
Window::mouse_locked = false;
|
||||
glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
}
|
||||
if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
|
||||
clicked_from_cb = true;
|
||||
}
|
||||
}
|
||||
|
||||
float Window::get_aspect() {
|
||||
return (float)Window::size.x / (float)Window::size.y;
|
||||
}
|
||||
|
||||
Window::Window() {
|
||||
init();
|
||||
|
||||
Window::size = {800, 600};
|
||||
m_handle = glfwCreateWindow(800, 600, "Window", nullptr, nullptr);
|
||||
glfwMakeContextCurrent(m_handle);
|
||||
glfwSetInputMode(m_handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
glfwSetFramebufferSizeCallback(m_handle, cb_framebuffer_size);
|
||||
glfwSetMouseButtonCallback(m_handle, cb_mouse_button);
|
||||
glfwSetKeyCallback(m_handle, cb_keypress);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
assert(glewInit() == GLEW_OK);
|
||||
|
@ -32,30 +78,42 @@ Graphics::Window::Window() {
|
|||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
Graphics::Window::Window(Window&& o) {
|
||||
Window::Window(Window&& o) {
|
||||
m_handle = o.m_handle;
|
||||
o.m_handle = nullptr;
|
||||
}
|
||||
|
||||
Graphics::Window::~Window() {
|
||||
Window::~Window() {
|
||||
if(m_handle) {
|
||||
glfwDestroyWindow(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::Window::poll_events() {
|
||||
void Window::update() const {
|
||||
glfwPollEvents();
|
||||
glViewport(0, 0, Window::size.x, Window::size.y);
|
||||
|
||||
if(clicked_from_cb) {
|
||||
Window::clicked = true;
|
||||
clicked_from_cb = false;
|
||||
} else {
|
||||
Window::clicked = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::Window::swap_buffers() {
|
||||
void Window::swap_buffers() const {
|
||||
glfwSwapBuffers(m_handle);
|
||||
}
|
||||
|
||||
bool Graphics::Window::should_close() {
|
||||
bool Window::should_close() const {
|
||||
return glfwWindowShouldClose(m_handle);
|
||||
}
|
||||
|
||||
void Graphics::Window::make_current() {
|
||||
void Window::make_current() const {
|
||||
glfwMakeContextCurrent(m_handle);
|
||||
}
|
||||
|
||||
Window::operator GLFWwindow*() const {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <glm/matrix.hpp>
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
namespace Graphics {
|
||||
struct Window {
|
||||
|
||||
inline static glm::vec<2, int> size;
|
||||
inline static bool mouse_locked = false;
|
||||
inline static bool clicked = false;
|
||||
|
||||
GLFWwindow* m_handle;
|
||||
|
||||
Window();
|
||||
|
@ -10,10 +19,14 @@ namespace Graphics {
|
|||
Window(Window&& o);
|
||||
~Window();
|
||||
|
||||
void make_current();
|
||||
bool should_close();
|
||||
void swap_buffers();
|
||||
void poll_events();
|
||||
void make_current() const;
|
||||
bool should_close() const;
|
||||
void swap_buffers() const;
|
||||
void update() const;
|
||||
|
||||
static float get_aspect();
|
||||
|
||||
operator GLFWwindow*() const;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
64
src/main.cpp
64
src/main.cpp
|
@ -1,62 +1,20 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include <glm/ext/matrix_float2x3.hpp>
|
||||
#include <glm/ext/matrix_projection.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <memory>
|
||||
#include "graphics/context.hpp"
|
||||
#include "graphics/gl/program.hpp"
|
||||
#include "graphics/gl/shader.hpp"
|
||||
#include "graphics/shader/compile.hpp"
|
||||
#include "graphics/shader/link.hpp"
|
||||
#include "graphics/window.hpp"
|
||||
#include "world/map.hpp"
|
||||
#include "world/player.hpp"
|
||||
#include "world/tile/empty.hpp"
|
||||
#include "graphics/pipeline.hpp"
|
||||
#include "world/state.hpp"
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
|
||||
int main() {
|
||||
Graphics::Window window;
|
||||
Graphics::GL::Shader model_vert = Graphics::Shader::compile(GL_VERTEX_SHADER, "../assets/shader/model.vert");
|
||||
Graphics::GL::Shader model_frag = Graphics::Shader::compile(GL_FRAGMENT_SHADER, "../assets/shader/model.frag");
|
||||
Graphics::GL::Program model_p = Graphics::Shader::link({model_vert, model_frag});
|
||||
Graphics::Context context(model_p);
|
||||
World::Player player;
|
||||
World::Map map;
|
||||
Graphics::Pipeline pipeline;
|
||||
World::State state;
|
||||
|
||||
map.set_tile({0, 0}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({1, 0}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({2, 1}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({2, 2}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({3, 2}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-1, -1}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-1, -2}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-2, -3}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-1, 0}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-3, 0}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-4, 0}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-5, 0}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-4, 1}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({-4, -1}, std::make_unique<World::Tile::Empty>());
|
||||
map.set_tile({0, -1}, std::make_unique<World::Tile::Empty>());
|
||||
while(!pipeline.should_close()) {
|
||||
Graphics::Context ctx(pipeline.m_window, pipeline.m_program_model);
|
||||
ctx.set_player(state.m_player);
|
||||
|
||||
glUseProgram(model_p);
|
||||
|
||||
context.set_projection_matrix(glm::perspective(glm::radians(90.0), 800.0 / 600.0, 0.1, 100.0));
|
||||
context.set_view_matrix(player.get_view_matrix());
|
||||
|
||||
while(!window.should_close()) {
|
||||
map.update();
|
||||
window.poll_events();
|
||||
|
||||
glUseProgram(model_p);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.1, 0.1, 0.12, 1);
|
||||
|
||||
map.render(context);
|
||||
window.swap_buffers();
|
||||
pipeline.update();
|
||||
state.update(ctx);
|
||||
pipeline.render(state, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
#include "builder.hpp"
|
||||
#include "../graphics/window.hpp"
|
||||
#include "chunk.hpp"
|
||||
#include "map.hpp"
|
||||
#include "tile/empty.hpp"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/common.hpp>
|
||||
#include <glm/ext/matrix_projection.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <memory>
|
||||
|
||||
using World::Builder;
|
||||
|
||||
Builder::Builder() {
|
||||
Graphics::Mesh mesh;
|
||||
mesh.add_primitive(Chunk::PRIMITIVE_0);
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
mesh.add_primitive(Chunk::PRIMITIVE_S[i]);
|
||||
}
|
||||
|
||||
m_model.bind();
|
||||
m_model.set(mesh, GL_STATIC_DRAW);
|
||||
Graphics::Vertex::set_vertex_attribs();
|
||||
}
|
||||
|
||||
void Builder::update(Map& map, const Graphics::Context& ctx) {
|
||||
m_has_intersect = false;
|
||||
if(Graphics::Window::mouse_locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
glm::vec<2, double> mpos;
|
||||
glfwGetCursorPos(ctx.m_window, &mpos.x, &mpos.y);
|
||||
mpos.y = Graphics::Window::size.y - mpos.y;
|
||||
glm::vec<3, double> near = glm::unProject<float>(glm::vec3(mpos, -1), ctx.m_view, ctx.m_projection, glm::vec4(0, 0, Graphics::Window::size));
|
||||
glm::vec<3, double> far = glm::unProject<float>(glm::vec3(mpos, 1), ctx.m_view, ctx.m_projection, glm::vec4(0, 0, Graphics::Window::size));
|
||||
glm::vec<3, double> direction = far - near;
|
||||
|
||||
if(direction.z >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_intersect = glm::round(glm::vec<2, double>(near - direction / direction.z * near.z) + ctx.m_transform);
|
||||
|
||||
if(map.get_tile(m_intersect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const glm::vec<2, double> CHECK_TILES[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
|
||||
bool found = false;
|
||||
|
||||
for(const glm::vec<2, double>& off : CHECK_TILES) {
|
||||
if(map.get_tile(m_intersect + off)) {
|
||||
m_has_intersect = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!m_has_intersect) {
|
||||
return;
|
||||
}
|
||||
if(Graphics::Window::clicked) {
|
||||
map.set_tile(m_intersect, std::make_unique<Tile::Empty>());
|
||||
}
|
||||
}
|
||||
|
||||
void Builder::render(const Graphics::Context& ctx) const {
|
||||
if(!m_has_intersect) {
|
||||
return;
|
||||
}
|
||||
|
||||
glm::vec<2, double> pos = glm::round(m_intersect);
|
||||
ctx.set_model_matrix(glm::translate(glm::mat4(1), {pos - ctx.m_transform, 0}));
|
||||
ctx.set_colour_matrix({
|
||||
0.5, 0.5, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0.5, 0.5, 0,
|
||||
0, 0, 0, 1,
|
||||
});
|
||||
m_model.bind();
|
||||
m_model.render(GL_TRIANGLES);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../graphics/context.hpp"
|
||||
#include "../graphics/gl/model.hpp"
|
||||
#include "map.hpp"
|
||||
|
||||
namespace World {
|
||||
struct Builder {
|
||||
Graphics::GL::Model m_model;
|
||||
glm::vec<2, double> m_intersect;
|
||||
bool m_has_intersect = false;
|
||||
|
||||
Builder();
|
||||
|
||||
void update(Map& map, const Graphics::Context& ctx);
|
||||
void render(const Graphics::Context& ctx) const;
|
||||
};
|
||||
};
|
||||
|
|
@ -13,44 +13,14 @@
|
|||
using World::Chunk;
|
||||
using World::Tile::TileBase;
|
||||
|
||||
constexpr Graphics::Primitive<4, 6> PRIMITIVE_B = {
|
||||
.m_vertices = {
|
||||
{.m_pos = {-0.5, -0.5, 0, 1}, .m_colour = {1, 0, 0, 1}},
|
||||
{.m_pos = {-0.5, +0.5, 0, 1}, .m_colour = {1, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, -0.5, 0, 1}, .m_colour = {0, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, +0.5, 0, 1}, .m_colour = {0, 0, 1, 1}},
|
||||
},
|
||||
.m_indices = {
|
||||
0, 2, 3,
|
||||
0, 3, 1,
|
||||
},
|
||||
};
|
||||
constexpr Graphics::Primitive<4, 6> PRIMITIVE_0 = {
|
||||
.m_vertices = {
|
||||
{.m_pos = {-0.5, -0.5, 0.5, 1}, .m_colour = {1, 0, 0, 1}},
|
||||
{.m_pos = {-0.5, -0.5, 0, 1}, .m_colour = {1, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, -0.5, 0.5, 1}, .m_colour = {0, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, -0.5, 0, 1}, .m_colour = {0, 0, 1, 1}},
|
||||
},
|
||||
.m_indices = {
|
||||
0, 2, 3,
|
||||
0, 3, 1,
|
||||
},
|
||||
};
|
||||
|
||||
static const Graphics::Primitive<4, 6> PRIMITIVE_S[4] = {
|
||||
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 0.5f, {0, 0, 1})),
|
||||
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 1.0f, {0, 0, 1})),
|
||||
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 1.5f, {0, 0, 1})),
|
||||
PRIMITIVE_0,
|
||||
};
|
||||
|
||||
constexpr glm::vec<2, int> get_pos_mod(glm::vec<2, int> pos) {
|
||||
return (pos % Chunk::N + Chunk::N) % Chunk::N;
|
||||
}
|
||||
|
||||
Chunk::Chunk(glm::vec<2, int> pos) {
|
||||
m_pos = pos;
|
||||
m_model.bind();
|
||||
Graphics::Vertex::set_vertex_attribs();
|
||||
}
|
||||
|
||||
TileBase* Chunk::get(glm::vec<2, int> p) {
|
||||
|
@ -96,15 +66,15 @@ void Chunk::update(Map& map) {
|
|||
|
||||
for(int x = 0; x < N; x++) {
|
||||
for(int y = 0; y < N; y++) {
|
||||
if(!get({x, y})) {
|
||||
glm::vec<2, int> t_off(x, y);
|
||||
if(!get(t_off)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
glm::vec<2, int> t_off(m_pos.x + x, m_pos.y + y);
|
||||
mesh.add_primitive(PRIMITIVE_B.with_translation({t_off, 0}));
|
||||
|
||||
for(int i = 0; i < std::size(neighbours); i++) {
|
||||
glm::vec<2, int> n_off = neighbours[i] + glm::vec<2, int>(x, y);
|
||||
glm::vec<2, int> n_off = neighbours[i] + t_off;
|
||||
const Chunk* chunk_check = this;
|
||||
if(n_off.x == N) {
|
||||
chunk_check = chunks[0];
|
||||
|
@ -123,11 +93,12 @@ void Chunk::update(Map& map) {
|
|||
}
|
||||
m_model.bind();
|
||||
m_model.set(mesh, GL_DYNAMIC_DRAW);
|
||||
Graphics::Vertex::set_vertex_attribs();
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
void Chunk::render(Graphics::Context& ctx) const {
|
||||
void Chunk::render(const Graphics::Context& ctx) const {
|
||||
ctx.set_model_matrix(glm::translate(glm::mat4(1), {glm::vec<2, double>(m_pos) - ctx.m_transform, 0}));
|
||||
ctx.set_colour_matrix(glm::mat4(1));
|
||||
m_model.bind();
|
||||
m_model.render(GL_TRIANGLES);
|
||||
for(auto& tile : m_tiles) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
namespace World {
|
||||
struct Chunk;
|
||||
};
|
||||
|
@ -16,6 +17,38 @@ namespace World {
|
|||
struct Chunk {
|
||||
static constexpr int N = 16;
|
||||
|
||||
static constexpr Graphics::Primitive<4, 6> PRIMITIVE_B = {
|
||||
.m_vertices = {
|
||||
{.m_pos = {-0.5, -0.5, 0, 1}, .m_colour = {1, 0, 0, 1}},
|
||||
{.m_pos = {-0.5, +0.5, 0, 1}, .m_colour = {1, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, -0.5, 0, 1}, .m_colour = {0, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, +0.5, 0, 1}, .m_colour = {0, 0, 1, 1}},
|
||||
},
|
||||
.m_indices = {
|
||||
0, 2, 3,
|
||||
0, 3, 1,
|
||||
},
|
||||
};
|
||||
static constexpr Graphics::Primitive<4, 6> PRIMITIVE_0 = {
|
||||
.m_vertices = {
|
||||
{.m_pos = {-0.5, -0.5, 0.5, 1}, .m_colour = {1, 0, 0, 1}},
|
||||
{.m_pos = {-0.5, -0.5, 0, 1}, .m_colour = {1, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, -0.5, 0.5, 1}, .m_colour = {0, 1, 0, 1}},
|
||||
{.m_pos = {+0.5, -0.5, 0, 1}, .m_colour = {0, 0, 1, 1}},
|
||||
},
|
||||
.m_indices = {
|
||||
0, 2, 3,
|
||||
0, 3, 1,
|
||||
},
|
||||
};
|
||||
|
||||
static const inline Graphics::Primitive<4, 6> PRIMITIVE_S[4] = {
|
||||
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 0.5f, {0, 0, 1})),
|
||||
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 1.0f, {0, 0, 1})),
|
||||
PRIMITIVE_0.with_matrix(glm::rotate(glm::mat4(1), glm::pi<float>() * 1.5f, {0, 0, 1})),
|
||||
PRIMITIVE_0,
|
||||
};
|
||||
|
||||
std::unique_ptr<Tile::TileBase> m_tiles[N*N];
|
||||
Graphics::GL::Model m_model;
|
||||
glm::vec<2, int> m_pos;
|
||||
|
@ -24,7 +57,7 @@ namespace World {
|
|||
Chunk(glm::vec<2, int> pos);
|
||||
|
||||
void update(Map& map);
|
||||
void render(Graphics::Context& ctx) const;
|
||||
void render(const Graphics::Context& ctx) const;
|
||||
Tile::TileBase* get(glm::vec<2, int> p);
|
||||
const Tile::TileBase* get(glm::vec<2, int> p) const;
|
||||
Tile::TileBase* set(glm::vec<2, int> p, std::unique_ptr<Tile::TileBase> v);
|
||||
|
|
|
@ -70,7 +70,7 @@ void Map::update() {
|
|||
}
|
||||
}
|
||||
|
||||
void Map::render(Graphics::Context& ctx) const {
|
||||
void Map::render(const Graphics::Context& ctx) const {
|
||||
for(auto& [cid, chunk] : m_chunks) {
|
||||
chunk.render(ctx);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace World {
|
|||
Tile::TileBase* set_tile(glm::vec<2, int> pos, std::unique_ptr<Tile::TileBase> tile);
|
||||
|
||||
void update();
|
||||
void render(Graphics::Context& ctx) const;
|
||||
void render(const Graphics::Context& ctx) const;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,20 +1,72 @@
|
|||
|
||||
#include "player.hpp"
|
||||
#include "../graphics/window.hpp"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/detail/qualifier.hpp>
|
||||
#include <glm/detail/type_quat.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/ext/quaternion_transform.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <glm/geometric.hpp>
|
||||
|
||||
using World::Player;
|
||||
|
||||
Player::Player() {
|
||||
GLFWwindow* ctx = glfwGetCurrentContext();
|
||||
glfwGetCursorPos(ctx, &m_cursor_last.x, &m_cursor_last.y);
|
||||
}
|
||||
|
||||
void Player::update() {
|
||||
GLFWwindow* ctx = glfwGetCurrentContext();
|
||||
glm::vec<2, double> move = {0, 0};
|
||||
glm::vec<2, double> cursor;
|
||||
|
||||
// keyboard input
|
||||
|
||||
if(glfwGetKey(ctx, GLFW_KEY_W) == GLFW_PRESS) {
|
||||
move.y += 1;
|
||||
}
|
||||
if(glfwGetKey(ctx, GLFW_KEY_S) == GLFW_PRESS) {
|
||||
move.y -= 1;
|
||||
}
|
||||
if(glfwGetKey(ctx, GLFW_KEY_A) == GLFW_PRESS) {
|
||||
move.x -= 1;
|
||||
}
|
||||
if(glfwGetKey(ctx, GLFW_KEY_D) == GLFW_PRESS) {
|
||||
move.x += 1;
|
||||
}
|
||||
if(move.x != 0 || move.y != 0) {
|
||||
glm::mat<2, 2, double> mat = {
|
||||
std::cos(m_pitch), std::sin(m_pitch),
|
||||
-std::sin(m_pitch), std::cos(m_pitch)
|
||||
};
|
||||
move = glm::normalize(move);
|
||||
if(glfwGetKey(ctx, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
|
||||
move *= 2;
|
||||
}
|
||||
m_accel += move * 0.0025 * mat;
|
||||
}
|
||||
|
||||
// mouse input
|
||||
|
||||
glfwGetCursorPos(ctx, &cursor.x, &cursor.y);
|
||||
glm::vec<2, double> cursor_diff = cursor - m_cursor_last;
|
||||
m_cursor_last = cursor;
|
||||
|
||||
if(Graphics::Window::mouse_locked) {
|
||||
m_pitch += cursor_diff.x * 0.0025;
|
||||
}
|
||||
|
||||
m_vel += m_accel;
|
||||
m_pos += m_vel;
|
||||
m_accel -= m_vel * 0.01;
|
||||
m_accel = -m_vel * 0.125;
|
||||
}
|
||||
|
||||
glm::mat4 Player::get_view_matrix() const {
|
||||
glm::mat4 mat(1);
|
||||
mat = glm::translate(mat, {0, 0, -m_distance});
|
||||
// mat = glm::rotate(mat, (float)m_pitch, {0, 0, 1});
|
||||
mat = glm::rotate(mat, (float)m_yaw, {-1, 0, 0});
|
||||
mat = glm::rotate(mat, (float)m_pitch, {0, 0, 1});
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,15 @@
|
|||
|
||||
namespace World {
|
||||
struct Player {
|
||||
glm::vec<2, double> m_pos;
|
||||
glm::vec<2, double> m_vel;
|
||||
glm::vec<2, double> m_accel;
|
||||
double m_distance = 4;
|
||||
glm::vec<2, double> m_pos = {0, 0};
|
||||
glm::vec<2, double> m_vel = {0.01, 0};
|
||||
glm::vec<2, double> m_accel = {0, 0};
|
||||
glm::vec<2, double> m_cursor_last;
|
||||
double m_distance = 2;
|
||||
double m_pitch = 0;
|
||||
double m_yaw = glm::pi<double>() * 0.25;
|
||||
double m_yaw = glm::pi<double>() * 5.0 / 16.0;
|
||||
|
||||
Player();
|
||||
void update();
|
||||
glm::mat4 get_view_matrix() const;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
#include "state.hpp"
|
||||
#include "tile/empty.hpp"
|
||||
#include <memory>
|
||||
|
||||
using World::State;
|
||||
|
||||
State::State() {
|
||||
m_map.set_tile({0, 0}, std::make_unique<Tile::Empty>());
|
||||
}
|
||||
|
||||
void State::update(const Graphics::Context& ctx) {
|
||||
m_builder.update(m_map, ctx);
|
||||
m_player.update();
|
||||
m_map.update();
|
||||
}
|
||||
|
||||
void State::render(const Graphics::Context& ctx) const {
|
||||
m_map.render(ctx);
|
||||
m_builder.render(ctx);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../graphics/context.hpp"
|
||||
#include "builder.hpp"
|
||||
#include "player.hpp"
|
||||
#include "map.hpp"
|
||||
|
||||
namespace World {
|
||||
struct State {
|
||||
Builder m_builder;
|
||||
Player m_player;
|
||||
Map m_map;
|
||||
|
||||
State();
|
||||
|
||||
void update(const Graphics::Context& ctx);
|
||||
void render(const Graphics::Context& ctx) const;
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue