initial commit

This commit is contained in:
MrLetsplay 2022-10-07 15:48:50 +02:00
commit 118f63b910
20 changed files with 602 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build/
.vscode/

36
CMakeLists.txt Normal file
View File

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.10)
project(KekEngine VERSION 1.0)
option(BUILD_SHARED_LIBS "Build as a shared library" ON)
file(GLOB KEKENGINE_SOURCE_FILES "src/kekengine/cpp/*.cpp")
file(GLOB KEKGAME_SOURCE_FILES "src/kekgame/cpp/*.cpp")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_compile_definitions(FT_CONFIG_OPTION_ERROR_STRINGS) # Freetype error strings
add_compile_options(-Wall -g)
# libkekengine
add_library(kekengine ${KEKENGINE_SOURCE_FILES})
target_link_libraries(kekengine PUBLIC glfw GLEW GL)
target_include_directories(kekengine PRIVATE "src/kekengine/include")
target_compile_definitions(kekengine PUBLIC KEKENGINE_TARGET_LINUX)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
target_link_libraries(kekengine PUBLIC ${GTK3_LIBRARIES})
target_include_directories(kekengine PRIVATE ${GTK3_INCLUDE_DIRS})
# kekgame
add_executable(kekgame ${KEKGAME_SOURCE_FILES})
target_link_libraries(kekgame PUBLIC kekengine)
target_include_directories(kekgame PRIVATE "src/kekengine/include")

View File

@ -0,0 +1,80 @@
#include "errordialog.h"
#include <iostream>
namespace kek::ErrorDialog {
#ifndef KEK_DISABLE_ERRORDIALOG
#ifdef KEKENGINE_TARGET_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
void showInfo(std::string message) {
UINT flags = MB_TASKMODAL | MB_ICONINFORMATION | MB_OK;
MessageBox(nullptr, message.c_str(), "KekEngine Info", flags);
}
void showWarning(std::string message) {
UINT flags = MB_TASKMODAL | MB_ICONWARNING | MB_OK;
MessageBox(nullptr, message.c_str(), "KekEngine Warning", flags);
}
void showError(std::string message) {
UINT flags = MB_TASKMODAL | MB_ICONERROR | MB_OK;
MessageBox(nullptr, message.c_str(), "KekEngine Error", flags);
}
#endif
#ifdef KEKENGINE_TARGET_LINUX
#include <gtk/gtk.h>
static void show(GtkMessageType type, GtkButtonsType buttons, const char *title, const char *message) {
if(!gtk_init_check(0, nullptr)) {
std::cout << "Failed init GTK for dialogs. Dialog message: " << message << std::endl;
return;
}
GtkWidget *w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *d = gtk_message_dialog_new(GTK_WINDOW(w), GTK_DIALOG_MODAL, type, buttons, "%s", message);
gtk_window_set_title(GTK_WINDOW(w), title);
gtk_dialog_run(GTK_DIALOG(d));
gtk_widget_destroy(w);
gtk_widget_destroy(d);
while(g_main_context_iteration(nullptr, false));
}
void showInfo(std::string message) {
show(GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "KekEngine Info", message.c_str());
}
void showWarning(std::string message) {
show(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "KekEngine Warning", message.c_str());
}
void showError(std::string message) {
show(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "KekEngine Error", message.c_str());
}
#endif
#else // ifndef KEK_DISABLE_ERRORDIALOG
void showInfo(std::string message) {
std::cout << "Info: " << message << std::endl;
}
void showWarning(std::string message) {
std::cout << "Warn: " << message << std::endl;
}
void showError(std::string message) {
std::cerr << "Error: " << message << std::endl;
}
#endif
}

View File

@ -0,0 +1,110 @@
#include "kekengine.h"
#include "errordialog.h"
#include "objparser.h"
#include "resource.h"
#include <iostream>
#include <cstring>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
namespace kek {
static GLFWwindow *window;
static int screenWidth = 800.0f;
static int screenHeight = 600.0f;
static void framebufferSizeCallback(GLFWwindow *window, int w, int h) {
glViewport(0, 0, w, h);
screenWidth = w;
screenHeight = h;
}
static void glDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char *message, const void *userParam) {
//if(id == 0x20071) return;
if(severity == GL_DEBUG_SEVERITY_NOTIFICATION) return;
std::cout << "OpenGL Debug (" << id << "): " << message << std::endl;
}
int init() {
// Init GLFW
if (glfwInit() != GL_TRUE) {
const char *errorMsg;
int code = glfwGetError(&errorMsg);
if(code != GLFW_NO_ERROR) {
ErrorDialog::showError("Failed to initialize GLFW: " + std::string(errorMsg) + std::string(" (") + std::to_string(code) + std::string(")"));
}else {
ErrorDialog::showError("Failed to initialize GLFW: Unknown error");
}
return KEK_ERROR;
}
std::cout << "Initialized GLFW" << std::endl;
// Create a rendering window with OpenGL 3.3 context
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_MAXIMIZED, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
/*window = glfwCreateWindow(screenWidth, screenHeight, "MrLetsplay's weird OpenGL stuff", NULL, NULL);
if(window == NULL) {
const char *errorMsg;
int code = glfwGetError(&errorMsg);
if(code != GLFW_NO_ERROR) {
ErrorDialog::showError("Failed to create window: " + std::string(errorMsg) + " (" + std::to_string(code) + ")");
}else {
ErrorDialog::showError("Failed to create window: Unknown error");
}
glfwTerminate();
return KEK_ERROR;
}
glfwMakeContextCurrent(window);
std::cout << "Initialized window" << std::endl;
// Init GLEW
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
ErrorDialog::showError("Failed to initialize GLEW");
glfwTerminate();
return KEK_ERROR;
}
std::cout << "Initialized GLEW" << std::endl;
int flags;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) {
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(glDebugOutput, NULL);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
}
glViewport(0, 0, screenWidth, screenHeight);
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);*/
//char *file = (char *) "# Blender 3.3.0\n# www.blender.org\nmtllib Cube.mtl\no Cube\nv 1.000000 1.000000 -1.000000\nv 1.000000 -1.000000 -1.000000\nv 1.000000 1.000000 1.000000\nv 1.000000 -1.000000 1.000000\nv -1.000000 1.000000 -1.000000\nv -1.000000 -1.000000 -1.000000\nv -1.000000 1.000000 1.000000\nv -1.000000 -1.000000 1.000000\nvn -0.0000 1.0000 -0.0000\nvn -0.0000 -0.0000 1.0000\nvn -1.0000 -0.0000 -0.0000\nvn -0.0000 -1.0000 -0.0000\nvn 1.0000 -0.0000 -0.0000\nvn -0.0000 -0.0000 -1.0000\nvt 0.625000 0.500000\nvt 0.375000 0.500000\nvt 0.625000 0.750000\nvt 0.375000 0.750000\nvt 0.875000 0.500000\nvt 0.625000 0.250000\nvt 0.125000 0.500000\nvt 0.375000 0.250000\nvt 0.875000 0.750000\nvt 0.625000 1.000000\nvt 0.625000 0.000000\nvt 0.375000 1.000000\nvt 0.375000 0.000000\nvt 0.125000 0.750000\ns 0\nusemtl Material\nf 1/1/1 5/5/1 7/9/1 3/3/1\nf 4/4/2 3/3/2 7/10/2 8/12/2\nf 8/13/3 7/11/3 5/6/3 6/8/3\nf 6/7/4 2/2/4 4/4/4 8/14/4\nf 2/2/5 1/1/5 3/3/5 4/4/5\nf 6/8/6 5/6/6 1/1/6 2/2/6";
//MemoryBuffer *fileBuf = new MemoryBuffer(file, strlen(file));
//Mesh *mesh = ObjParser::parse(fileBuf);
MemoryBuffer *buf = kek::Resource::loadResource("../src/res/shader/mesh/fragment.glsl");
if(buf) {
std::cout << buf << std::endl;
delete buf;
}
return KEK_SUCCESS;
}
}

View File

View File

@ -0,0 +1,83 @@
#include "objparser.h"
#include <iostream>
#include <string>
#include <sstream>
#include <glm/glm.hpp>
#include "types.h"
namespace kek::ObjParser {
static bool readFaceVertex(std::istringstream &stream, uint32_t *outVertex, uint32_t *outTexture, uint32_t *outNormal) {
std::string face;
stream >> face;
size_t first = face.find('/');
if(first == std::string::npos) return false;
size_t second = face.find('/', first + 1);
if(second == std::string::npos) return false;
*outVertex = std::stoi(face.substr(0, first));
*outTexture = std::stoi(face.substr(first + 1, second));
*outNormal = std::stoi(face.substr(second + 1, face.length()));
return true;
}
Mesh *parse(MemoryBuffer *buf) {
std::vector<glm::vec3> vertexPositions;
std::vector<glm::vec3> vertexNormals;
std::vector<glm::vec2> vertexTexCoords;
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
std::istream stream(buf);
std::string line;
while(std::getline(stream, line)) {
std::istringstream str(line);
std::string cmd;
str >> cmd;
if(cmd == "#") continue;
if(cmd == "v") {
float x, y, z;
str >> x >> y >> z;
vertexPositions.push_back(glm::vec3(x, y, z));
}else if(cmd == "vn") {
float x, y, z;
str >> x >> y >> z;
vertexNormals.push_back(glm::normalize(glm::vec3(x, y, z)));
}else if(cmd == "vt") {
float u, v = 1.0f;
str >> u >> v;
vertexTexCoords.push_back(glm::vec2(u, v));
}else if(cmd == "f") {
uint32_t v1, v1T, v1N;
readFaceVertex(str, &v1, &v1T, &v1N);
uint32_t v2, v2T, v2N;
readFaceVertex(str, &v2, &v2T, &v2N);
uint32_t v3, v3T, v3N;
readFaceVertex(str, &v3, &v3T, &v3N);
vertices.push_back(Vertex(vertexPositions[v1], vertexNormals[v1N], vertexTexCoords[v1T]));
indices.push_back(indices.size());
vertices.push_back(Vertex(vertexPositions[v2], vertexNormals[v2N], vertexTexCoords[v2T]));
indices.push_back(indices.size());
vertices.push_back(Vertex(vertexPositions[v3], vertexNormals[v3N], vertexTexCoords[v3T]));
indices.push_back(indices.size());
}else {
std::cout << "Ignoring unknown OBJ command: " << cmd << std::endl;
}
}
for(glm::vec3 v : vertexNormals) {
std::cout << v.x << " " << v.y << " " << v.z << std::endl;
}
return new Mesh(vertices, indices);
}
}

View File

@ -0,0 +1,17 @@
#include "resource.h"
namespace kek::Resource {
MemoryBuffer *loadResource(std::string path) {
std::ifstream in = std::ifstream(path, std::ios::binary);
if(!in.good()) return nullptr;
in.ignore(std::numeric_limits<std::streamsize>::max());
std::streamsize size = in.gcount();
in.clear();
in.seekg(0, std::ios_base::beg);
char *data = (char *) malloc(size);
in.read(data, size);
return new MemoryBuffer(data, size);
}
}

View File

@ -0,0 +1,89 @@
#include "shader.h"
#include "types.h"
#include "resource.h"
#include <GL/glew.h>
namespace kek {
static GLuint compileShader(GLenum type, std::string path) {
MemoryBuffer *buf = Resource::loadResource(path);
if(!buf) {
std::cout << "Couldn't load shader: " << path << std::endl;
throw std::exception();
}
std::ostringstream stream;
stream << buf;
std::string code = stream.str();
delete buf;
const char *src = code.c_str();
GLint success;
GLuint vertex = glCreateShader(type);
glShaderSource(vertex, 1, &src, NULL);
glCompileShader(vertex);
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if(!success) {
char log[512];
glGetShaderInfoLog(vertex, 512, NULL, log);
std::cout << "Failed to compile vertex shader \"" << path << "\":\n" << log << std::endl;
}
return vertex;
}
static GLuint compileProgram(unsigned int n, GLenum *types, std::string *paths) {
// Compile shaders
GLuint shaderIds[n];
for(unsigned int i = 0; i < n; i++) {
shaderIds[i] = compileShader(types[i], paths[i]);
}
GLuint id = glCreateProgram();
// Attach shaders
for(unsigned int i = 0; i < n; i++) {
glAttachShader(id, shaderIds[i]);
}
glLinkProgram(id);
GLint success;
glGetProgramiv(id, GL_LINK_STATUS, &success);
if(!success) {
char log[512];
glGetProgramInfoLog(id, 512, NULL, log);
std::cout << "Failed to link program:\n" << log << std::endl;
}
// Delete shaders
for(unsigned int i = 0; i < n; i++) {
glDeleteShader(shaderIds[i]);
}
return id;
}
Shader::Shader(std::string vertexPath, std::string fragmentPath) {
}
Shader::Shader(std::string vertexPath, std::string geometryPath, std::string fragmentPath) {
}
Shader::~Shader() {
}
void Shader::use() {
}
}

View File

@ -0,0 +1,4 @@
#pragma once
#define KEK_SUCCESS 0
#define KEK_ERROR 1

View File

@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace kek::ErrorDialog {
void showInfo(std::string message);
void showWarning(std::string message);
void showError(std::string message);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "constants.h"
namespace kek {
int init();
}

View File

@ -0,0 +1,37 @@
#pragma once
#include <glm/glm.hpp>
#include <vector>
#include <cstdint>
#include <iostream>
namespace kek {
struct Vertex {
glm::vec3 pos;
glm::vec3 normal;
glm::vec2 texCoords;
Vertex(glm::vec3 pos, glm::vec3 normal, glm::vec2 texCoords) {
this->pos = pos;
this->normal = normal;
this->texCoords = texCoords;
}
};
class Mesh {
public:
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices) {
this->vertices = vertices;
this->indices = indices;
}
~Mesh();
};
}

View File

@ -0,0 +1 @@
#pragma once

View File

@ -0,0 +1,12 @@
#pragma once
#include <vector>
#include "types.h"
#include "mesh.h"
namespace kek::ObjParser {
Mesh *parse(MemoryBuffer *buf);
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "types.h"
#include <fstream>
#include <sstream>
namespace kek::Resource {
MemoryBuffer *loadResource(std::string path);
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <string>
namespace kek {
class Shader {
public:
unsigned int id;
Shader(std::string vertexPath, std::string fragmentPath);
Shader(std::string vertexPath, std::string geometryPath, std::string fragmentPath);
~Shader();
void use();
};
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <glm/glm.hpp>
#include <vector>
#include <cstdint>
#include <iostream>
namespace kek {
class MemoryBuffer: public std::streambuf {
public:
char *buffer;
size_t length;
MemoryBuffer(char *buffer, size_t length) {
this->buffer = buffer;
this->length = length;
this->setg(buffer, buffer, buffer + length);
}
~MemoryBuffer() {
free(buffer);
}
};
}

View File

@ -0,0 +1,7 @@
#include <iostream>
#include "kekengine.h"
int main(int argc, char **argv) {
kek::init();
}

View File

@ -0,0 +1,17 @@
#version 330 core
in VS_OUT {
vec2 textureCoordinate;
vec3 normal;
vec3 fragmentPosition;
} fs_in;
uniform vec3 cameraPos;
out vec4 color;
void main() {
vec3 norm = normalize(fs_in.normal);
vec3 viewDir = normalize(cameraPos - fs_in.fragmentPosition);
color = vec4(1.0);
}

View File

@ -0,0 +1,23 @@
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out VS_OUT {
vec3 fragmentPosition;
vec2 textureCoordinate;
vec3 normal;
} vs_out;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
vs_out.fragmentPosition = vec3(model * vec4(position, 1.0));
vs_out.textureCoordinate = texCoord;
vs_out.normal = mat3(transpose(inverse(model))) * normal;
}