added new cmake setup, graphics, vendors, obj importer, etc.

This commit is contained in:
Daniel Ledda
2022-12-29 12:57:19 +01:00
parent 783f9ee055
commit e83185f011
30 changed files with 18711 additions and 116 deletions

60
src/gfx/Mesh.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include <iostream>
#include "Mesh.h"
#include "loaders/tinyobj.h"
auto Mesh::init(const char* obj_file) -> void {
auto reader = tinyobj::ObjReader();
auto success = reader.ParseFromFile(obj_file);
std::cout << reader.Error() << std::endl;
auto attrib = reader.GetAttrib();
auto indices_t = reader.GetShapes().at(0).mesh.indices;
auto indices = std::vector<unsigned int>(indices_t.size());
for (int i = 0; i < indices_t.size(); i++) {
indices[i] = indices_t[i].vertex_index;
}
num_indices = indices.size();
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo_xyz);
glGenBuffers(1, &vbo_uv);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo_xyz);
glBufferData(GL_ARRAY_BUFFER, attrib.vertices.size() * sizeof(float), attrib.vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_uv);
glBufferData(GL_ARRAY_BUFFER, attrib.texcoords.size() * sizeof(float), attrib.texcoords.data(), GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
}
auto Mesh::init(const LeddaGeometry::Shape* shape) -> void {
num_indices = shape->indices_size;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo_xyz);
glGenBuffers(1, &vbo_uv);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo_xyz);
glBufferData(GL_ARRAY_BUFFER, shape->xyz_size * sizeof(float), shape->xyz, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_uv);
glBufferData(GL_ARRAY_BUFFER, shape->uv_size * sizeof(float), shape->uv, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, shape->indices_size * sizeof(unsigned int), shape->indices, GL_STATIC_DRAW);
}

17
src/gfx/Mesh.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef LEDDA_MESH_H
#define LEDDA_MESH_H
#include "glad/glad.h"
#include "geometry.h"
struct Mesh {
unsigned int vao;
unsigned int vbo_xyz;
unsigned int vbo_uv;
unsigned int ebo;
unsigned int num_indices;
auto init(const char* obj_file) -> void;
auto init(const LeddaGeometry::Shape* shape) -> void;
};
#endif

View File

81
src/gfx/OrbitControls.h Normal file
View File

@@ -0,0 +1,81 @@
#ifndef ORBIT_CONTROLS_H
#define ORBIT_CONTROLS_H
#include "glad/glad.h"
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "loaders/stb_image.h"
constexpr auto ROTATION_FACTOR = 1.0f / 200.0f;
struct Point {
float x;
float y;
};
class OrbitControls {
private:
bool dragging;
bool hovered;
bool scrolling;
bool flyingEnabled;
float lastX;
float lastY;
Point lastScroll1;
Point lastScroll2;
glm::vec3 y_axis;
glm::vec3 x_axis;
glm::vec3 start;
Entity* orbited_object;
OrbitControls(Entity* orbited, Camera* camera) {
camera = camera;
orbited_object = orbited;
y_axis = orbited_object.worldToLocal(camera.up);
x_axis = orbited_object.position.sub(camera.position);
x_axis /= sqrt(pow(x_axis.x) + pow(x_axis.y, 2) + pow(x_axis.z, 2));
x_axis = glm::cross(x_axis, y_axis);
start = orbited_object.rotation;
this.element.addEventListener('wheel', (ev) => this.handleScroll(ev));
this.element.addEventListener('mouseover', () => this.hovered = true);
this.element.addEventListener('mouseout', () => this.hovered = false);
this.element.addEventListener('mousedown', (ev) => this.handleMouseDown(ev));
window.addEventListener('mousemove', (ev) => this.handleMove(ev));
window.addEventListener('mouseup', () => this.dragging = false);
}
on_mouse_down(event) {
if (event.button === 1) {
this.object.setRotationFromEuler(this.start);
}
if (!this.dragging) {
this.lastX = event.x;
this.lastY = event.y;
this.dragging = true;
}
}
on_mouse_move(event) {
if (dragging) {
auto x_diff = event.movementX * ROTATION_FACTOR;
auto y_diff = event.movementY * ROTATION_FACTOR;
glm::rotate(&orbited_object, x_diff, &y_axis);
//rotate on world axis ???
glm::rotate(&orbited_object, y_diff &x_axis);
}
}
on_scroll(event) {
if (this.flyingEnabled && this.hovered) {
for (const fliable of this.fliables) {
const direction = event.deltaY / Math.abs(event.deltaY);
fliable.flyBy(direction / 10);
}
}
}
}
#endif

57
src/gfx/Shader.cpp Normal file
View File

@@ -0,0 +1,57 @@
#include "glad/glad.h"
#include <array>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include "Shader.h"
enum ShaderType {
fragment=GL_FRAGMENT_SHADER,
vertex=GL_VERTEX_SHADER,
};
auto create_shader(const char* file_path, ShaderType shader_type, char* info_log) -> unsigned int {
std::stringstream shader_stream;
std::ifstream shader_file;
shader_file.open(file_path);
shader_stream << shader_file.rdbuf();
shader_file.close();
auto shader_string = shader_stream.str();
const auto shader_code = shader_string.c_str();
auto vertex_shader = glCreateShader(shader_type);
glShaderSource(vertex_shader, 1, &shader_code, NULL);
glCompileShader(vertex_shader);
int success;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
auto shader_type_name = shader_type == ShaderType::fragment ? "FRAGMENT" : "VERTEX";
std::cout << "ERROR::SHADER::" << shader_type_name << "::COMPILATION_FAILED\n" << info_log << std::endl;
}
return vertex_shader;
}
auto Shader::init(const char* vertex_path, const char* fragment_path) -> void {
auto info_log = std::array<char, 512>();
auto vertex_shader = create_shader(vertex_path, ShaderType::vertex, info_log.data());
auto fragment_shader = create_shader(fragment_path, ShaderType::fragment, info_log.data());
prog_id = glCreateProgram();
glAttachShader(prog_id, vertex_shader);
glAttachShader(prog_id, fragment_shader);
glLinkProgram(prog_id);
int success;
glGetProgramiv(prog_id, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(prog_id, 512, NULL, info_log.data());
std::cout << "ERROR::SHADER::PROGRAM::LINK_FAILED\n" << info_log.data() << std::endl;
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
}

9
src/gfx/Shader.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef LEDDA_SHADER_H
#define LEDDA_SHADER_H
struct Shader {
unsigned int prog_id;
auto init(const char* vertex_path, const char* fragment_path) -> void;
};
#endif

23
src/gfx/Texture.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include "Texture.h"
#include <iostream>
#include "loaders/stb_image.h"
#include "glad/glad.h"
auto Texture::init(const char* source_path) -> void {
glGenTextures(1, &tex_id);
glBindTexture(GL_TEXTURE_2D, tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int nr_channels;
auto data = stbi_load(source_path, &width, &height, &nr_channels, 0);
if (data) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
} else {
std::cout << "Failed to load texture." << std::endl;
}
stbi_image_free(data);
}

11
src/gfx/Texture.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef LEDDA_TEXTURE_H
#define LEDDA_TEXTURE_H
struct Texture {
unsigned int tex_id;
int width;
int height;
auto init(const char* source_path) -> void;
};
#endif

112
src/gfx/geometry.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include <array>
#include "geometry.h"
// Buffer layout:
// X, Y, Z, U, V
auto triangle_vertices = std::to_array<float>({
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.5f, 0.5f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f,
});
auto triangle_indices = std::to_array<unsigned int>({
0, 1, 2
});
auto cube_vertices = std::to_array<float>({
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
});
auto cube_indices = std::to_array<unsigned int>({
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
});
auto square_xyz = std::to_array<float>({
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
});
auto square_uv = std::to_array<float>({
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
});
auto square_indices = std::to_array<unsigned int>({
0, 1, 3,
1, 2, 3,
});
namespace LeddaGeometry {
const Shape TRIANGLE = {
.indices = triangle_indices.data(),
.indices_size = sizeof(triangle_indices),
.uv = triangle_vertices.data(),
.uv_size = sizeof(triangle_vertices),
.xyz = triangle_vertices.data(),
.xyz_size = sizeof(triangle_vertices),
};
const Shape SQUARE = {
.indices = square_indices.data(),
.indices_size = square_indices.size(),
.uv = square_uv.data(),
.uv_size = square_uv.size(),
.xyz = square_xyz.data(),
.xyz_size = square_xyz.size(),
};
const Shape CUBE = {
.indices = cube_indices.data(),
.indices_size = cube_indices.size(),
.uv = triangle_vertices.data(),
.uv_size = triangle_vertices.size(),
.xyz = triangle_vertices.data(),
.xyz_size = triangle_vertices.size(),
};
}

20
src/gfx/geometry.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef LEDDA_GEOMETRY_H
#define LEDDA_GEOMETRY_H
#include <cstddef>
namespace LeddaGeometry {
struct Shape {
unsigned int* indices;
size_t indices_size;
float* uv;
size_t uv_size;
float* xyz;
size_t xyz_size;
};
extern const Shape TRIANGLE;
extern const Shape SQUARE;
extern const Shape CUBE;
}
#endif