added new cmake setup, graphics, vendors, obj importer, etc.
This commit is contained in:
271
src/main.cpp
Normal file
271
src/main.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
#include <bitset>
|
||||
#include <array>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <span>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include "loaders/stb_image.h"
|
||||
|
||||
#include "gfx/geometry.h"
|
||||
#include "gfx/Texture.h"
|
||||
#include "gfx/Mesh.h"
|
||||
#include "gfx/Shader.h"
|
||||
#include "VoxelSpace.h"
|
||||
#include "SomaSolve.h"
|
||||
|
||||
struct Camera {
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj;
|
||||
glm::vec3 pos;
|
||||
glm::vec3 up;
|
||||
glm::vec3 target;
|
||||
|
||||
auto init(float aspect_ratio = 800.0f / 600.0f) -> void {
|
||||
view = glm::mat4();
|
||||
proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f);
|
||||
pos = glm::vec3(0.0f, 5.0f, 0.0f);
|
||||
up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
auto look_at(float x, float y, float z) -> void {
|
||||
target = glm::vec3(x, y, z);
|
||||
view = glm::lookAt(pos, target, up);
|
||||
}
|
||||
|
||||
auto set_up(float up_x, float up_y, float up_z) -> void {
|
||||
up = glm::vec3(up_x, up_y, up_z);
|
||||
}
|
||||
};
|
||||
|
||||
struct WindowDims {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
};
|
||||
|
||||
struct TrsSpecs {
|
||||
glm::vec3 translation;
|
||||
glm::quat rotation;
|
||||
glm::vec3 scale;
|
||||
|
||||
auto reset() -> void {
|
||||
scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
translation = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
};
|
||||
|
||||
struct Entity {
|
||||
glm::mat4 local;
|
||||
glm::mat4 world;
|
||||
TrsSpecs trs;
|
||||
Mesh* mesh;
|
||||
Texture* tex;
|
||||
|
||||
auto init() -> void {
|
||||
trs.reset();
|
||||
local = glm::mat4(1.0f);
|
||||
}
|
||||
|
||||
auto update_model_mat() -> void {
|
||||
local = glm::mat4(1.0f);
|
||||
local = glm::scale(
|
||||
glm::translate(
|
||||
local,
|
||||
trs.translation
|
||||
) * glm::toMat4(trs.rotation),
|
||||
trs.scale
|
||||
);
|
||||
world = local;
|
||||
}
|
||||
};
|
||||
|
||||
struct Polycube {
|
||||
std::vector<Entity*>* entities;
|
||||
uint8_t color;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
int x;
|
||||
int y;
|
||||
Camera* cam;
|
||||
|
||||
auto init(Camera* camera) -> void {
|
||||
camera->init((float)width / (float)height);
|
||||
cam = camera;
|
||||
}
|
||||
};
|
||||
|
||||
auto framebuffer_size_callback(GLFWwindow* window, int width, int height) -> void {
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
auto process_input(GLFWwindow *window) -> void {
|
||||
static auto wireframe = false;
|
||||
static auto last_frame_state_press = false;
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
} else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS && !last_frame_state_press) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, !wireframe ? GL_LINE : GL_FILL);
|
||||
wireframe = !wireframe;
|
||||
last_frame_state_press = true;
|
||||
} else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_RELEASE) {
|
||||
last_frame_state_press = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto init_window_and_gl(WindowDims* window_dims) -> GLFWwindow* {
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
auto window = glfwCreateWindow(window_dims->width, window_dims->height, "Somaesque", NULL, NULL);
|
||||
if (window == NULL) {
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return nullptr;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||
std::cout << "Failed to initilaize GLAD" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glViewport(0, 0, 800, 600);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
return window;
|
||||
}
|
||||
|
||||
auto gl_update_viewport(WindowDims* window_dims, Frame* frame) -> void {
|
||||
glViewport(frame->x, window_dims->height - frame->y - frame->height, frame->width, frame->height);
|
||||
}
|
||||
|
||||
auto rotate_cam_around_centre(Camera* cam, int radius) -> void {
|
||||
cam->pos.x = sin(glfwGetTime()) * radius;
|
||||
cam->pos.z = cos(glfwGetTime()) * radius;
|
||||
cam->look_at(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
auto active_shader = Shader{};
|
||||
auto cube_mesh = Mesh{};
|
||||
auto wall_tex = Texture{};
|
||||
auto entities = std::vector<Entity>();
|
||||
|
||||
auto draw_entity(Entity* entity) -> void {
|
||||
auto modelUniformLoc = glGetUniformLocation(active_shader.prog_id, "model");
|
||||
glUniformMatrix4fv(modelUniformLoc, 1, GL_FALSE, glm::value_ptr(entity->world));
|
||||
glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
|
||||
glBindVertexArray(entity->mesh->vao);
|
||||
glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
auto use_default_shader(Camera* cam) -> void {
|
||||
glUseProgram(active_shader.prog_id);
|
||||
auto viewUniformLoc = glGetUniformLocation(active_shader.prog_id, "view");
|
||||
auto projectionUniformLoc = glGetUniformLocation(active_shader.prog_id, "projection");
|
||||
glUniformMatrix4fv(projectionUniformLoc, 1, GL_FALSE, glm::value_ptr(cam->proj));
|
||||
glUniformMatrix4fv(viewUniformLoc, 1, GL_FALSE, glm::value_ptr(cam->view));
|
||||
}
|
||||
|
||||
auto print_mat(glm::mat4* matrix) -> void {
|
||||
auto mat = *matrix;
|
||||
std::cout << mat[0][0] << mat[0][1] << mat[0][2] << mat[0][3] << std::endl;
|
||||
std::cout << mat[1][0] << mat[1][1] << mat[1][2] << mat[1][3] << std::endl;
|
||||
std::cout << mat[2][0] << mat[2][1] << mat[2][2] << mat[2][3] << std::endl;
|
||||
std::cout << mat[3][0] << mat[3][1] << mat[3][2] << mat[3][3] << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
auto create_polycube_from_repr(Voxel::Space* repr) -> std::vector<Entity*> {
|
||||
auto result = std::vector<Entity*>(Voxel::size(repr->space));
|
||||
for (int x = 0; x < repr->dim_x; x++) {
|
||||
for (int y = 0; y < repr->dim_y; y++) {
|
||||
for (int z = 0; z < repr->dim_z; z++) {
|
||||
if (Voxel::filledAt(repr, x, y, z)) {
|
||||
entities.push_back({
|
||||
.mesh=&cube_mesh,
|
||||
.tex=&wall_tex,
|
||||
});
|
||||
auto polycube_segment = &entities.back();
|
||||
polycube_segment->init();
|
||||
polycube_segment->trs.translation = glm::vec3(
|
||||
-((repr->dim_z - 1)/2) + z,
|
||||
((repr->dim_x - 1)/2) - x,
|
||||
-((repr->dim_y - 1)/2) + y
|
||||
);
|
||||
result.push_back(polycube_segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
auto window_dims = WindowDims{ 800, 600 };
|
||||
auto window = init_window_and_gl(&window_dims);
|
||||
if (window == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto little_frame = Frame{ .width=80, .height=60, .x=20, .y=20 };
|
||||
auto big_frame = Frame{ .width=800, .height=600, .x=0, .y=0 };
|
||||
auto main_cam = Camera{};
|
||||
auto other_cam = Camera{};
|
||||
little_frame.init(&other_cam);
|
||||
big_frame.init(&main_cam);
|
||||
auto frames = std::vector{ &big_frame, &little_frame };
|
||||
|
||||
active_shader.init("../assets/shaders/basic.vertex.glsl", "../assets/shaders/basic.fragment.glsl");
|
||||
|
||||
cube_mesh.init("../assets/models/c000000.obj");
|
||||
wall_tex.init("../assets/textures/brick-wall.jpg");
|
||||
|
||||
auto voxel_space = Voxel::Space{
|
||||
.space=SomaSolve::STD_SOMA[0],
|
||||
.dim_x=3,
|
||||
.dim_y=3,
|
||||
.dim_z=3
|
||||
};
|
||||
Voxel::cullEmptySpace(&voxel_space);
|
||||
auto polycube1 = create_polycube_from_repr(&voxel_space);
|
||||
for (auto &entity : entities) {
|
||||
entity.update_model_mat();
|
||||
}
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
rotate_cam_around_centre(big_frame.cam, 10.0f);
|
||||
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
use_default_shader(big_frame.cam);
|
||||
gl_update_viewport(&window_dims, &big_frame);
|
||||
|
||||
for (auto &entity : entities) {
|
||||
entity.update_model_mat();
|
||||
auto scale = glm::mat4(1.0f);
|
||||
entity.world = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f) * abs((float)sin(glfwGetTime()))) * entity.world;
|
||||
draw_entity(&entity);
|
||||
}
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user