Code restructuring, Input (WIP)

This commit is contained in:
MrLetsplay 2022-10-08 23:04:35 +02:00
parent a168893acc
commit 6bc5f4656e
18 changed files with 377 additions and 63 deletions

View File

@ -1,7 +1,4 @@
#include "kekengine.h"
#include "errordialog.h"
#include "objparser.h"
#include "resource.h"
#include "engine.h"
#include <iostream>
#include <cstring>
@ -10,18 +7,23 @@
#include <GLFW/glfw3.h>
#include <glm/gtc/type_ptr.hpp>
namespace kek {
#include "internal.h"
#include "errordialog.h"
#include "objparser.h"
#include "resource.h"
#include "camera.h"
#include "constants.h"
#include "gameobject.h"
#include "scene.h"
static GLFWwindow *window;
static Camera *cam;
kek::KekData kek::kekData;
static int screenWidth = 800.0f;
static int screenHeight = 600.0f;
namespace kek::Engine {
static void framebufferSizeCallback(GLFWwindow *window, int w, int h) {
glViewport(0, 0, w, h);
screenWidth = w;
screenHeight = h;
kekData.screenWidth = w;
kekData.screenHeight = h;
}
static void glDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char *message, const void *userParam) {
@ -47,8 +49,8 @@ void onCursorPosCallback(GLFWwindow *window, double x, double y) {
xoff *= 0.1f;
yoff *= 0.1f;
cam->rotateYaw(xoff);
cam->rotatePitch(yoff);
kekData.activeCamera->rotateYaw(xoff);
kekData.activeCamera->rotatePitch(yoff);
}
int init() {
@ -76,8 +78,10 @@ int init() {
glfwWindowHint(GLFW_MAXIMIZED, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
window = glfwCreateWindow(screenWidth, screenHeight, "KekEngine", NULL, NULL);
if(window == NULL) {
kekData.screenWidth = 800.0f;
kekData.screenHeight = 600.0f;
kekData.window = glfwCreateWindow(kekData.screenWidth, kekData.screenHeight, "KekEngine", NULL, NULL);
if(!kekData.window) {
const char *errorMsg;
int code = glfwGetError(&errorMsg);
if(code != GLFW_NO_ERROR) {
@ -90,7 +94,7 @@ int init() {
return KEK_ERROR;
}
glfwMakeContextCurrent(window);
glfwMakeContextCurrent(kekData.window);
std::cout << "Initialized window" << std::endl;
@ -113,9 +117,9 @@ int init() {
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
}
glViewport(0, 0, screenWidth, screenHeight);
glViewport(0, 0, kekData.screenWidth, kekData.screenHeight);
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
glfwSetFramebufferSizeCallback(kekData.window, framebufferSizeCallback);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
@ -127,74 +131,84 @@ int init() {
return KEK_ERROR;
}
glfwSetCursorPosCallback(window, onCursorPosCallback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetCursorPosCallback(kekData.window, onCursorPosCallback);
glfwSetInputMode(kekData.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glClearColor(0.1f, 0.3f, 0.1f, 0.0f);
cam = new Camera();
kekData.activeCamera = new Camera();
kekData.shader = new Shader("shader/mesh/vertex.glsl", "shader/mesh/fragment.glsl");
MemoryBuffer *buf = Resource::loadResource("object/sphere/Sphere.obj");
Mesh *mesh = ObjParser::parse(buf);
Shader *shader = new Shader("shader/mesh/vertex.glsl", "shader/mesh/fragment.glsl");
while(1) {
return KEK_SUCCESS;
}
int start() {
while(!glfwWindowShouldClose(kekData.window)) {
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, screenWidth, screenHeight);
glViewport(0, 0, kekData.screenWidth, kekData.screenHeight);
if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
cam->translate(cam->direction * 0.1f);
for(std::pair<InputListener, PeriodicCallback> cb : kekData.periodicCallbacks) {
cb.second(kekData.window);
}
if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
cam->translate(cam->direction * -0.1f);
if(glfwGetKey(kekData.window, GLFW_KEY_W) == GLFW_PRESS) {
kekData.activeCamera->translate(kekData.activeCamera->direction * 0.1f);
}
if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
glm::vec3 camRight = glm::normalize(glm::cross(cam->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
cam->translate(-camRight * 0.1f);
if(glfwGetKey(kekData.window, GLFW_KEY_S) == GLFW_PRESS) {
kekData.activeCamera->translate(kekData.activeCamera->direction * -0.1f);
}
if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
glm::vec3 camRight = glm::normalize(glm::cross(cam->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
cam->translate(camRight * 0.1f);
if(glfwGetKey(kekData.window, GLFW_KEY_A) == GLFW_PRESS) {
glm::vec3 camRight = glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
kekData.activeCamera->translate(-camRight * 0.1f);
}
if(glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
cam->translateY(0.1f);
if(glfwGetKey(kekData.window, GLFW_KEY_D) == GLFW_PRESS) {
glm::vec3 camRight = glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
kekData.activeCamera->translate(camRight * 0.1f);
}
if(glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) {
cam->translateY(-0.1f);
if(glfwGetKey(kekData.window, GLFW_KEY_SPACE) == GLFW_PRESS) {
kekData.activeCamera->translateY(0.1f);
}
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
if(glfwGetKey(kekData.window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) {
kekData.activeCamera->translateY(-0.1f);
}
if(glfwGetKey(kekData.window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
break;
}
shader->use();
kekData.shader->use();
glm::mat4 view = cam->transformationMatrix();
glm::mat4 view = kekData.activeCamera->transformationMatrix();
glm::mat4 projection;
projection = glm::perspective(glm::radians(90.0f), screenWidth / (float) screenHeight, KEK_CAMERA_NEAR, KEK_CAMERA_FAR);
projection = glm::perspective(glm::radians(90.0f), kekData.screenWidth / (float) kekData.screenHeight, KEK_CAMERA_NEAR, KEK_CAMERA_FAR);
glm::vec3 position = cam->getPosition();
glm::vec3 position = kekData.activeCamera->getPosition();
glUniformMatrix4fv(glGetUniformLocation(shader->id, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(shader->id, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniform3fv(glGetUniformLocation(shader->id, "cameraPos"), 1, glm::value_ptr(position));
glUniformMatrix4fv(glGetUniformLocation(kekData.shader->id, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(kekData.shader->id, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniform3fv(glGetUniformLocation(kekData.shader->id, "cameraPos"), 1, glm::value_ptr(position));
glm::mat4 model = glm::mat4(1.0f);
glUniformMatrix4fv(glGetUniformLocation(shader->id, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(glGetUniformLocation(kekData.shader->id, "model"), 1, GL_FALSE, glm::value_ptr(model));
mesh->draw(shader);
if(kekData.activeScene) kekData.activeScene->draw(kekData.shader);
// Swap buffers and poll window events
glfwSwapBuffers(window);
glfwSwapBuffers(kekData.window);
glfwPollEvents();
}
return KEK_SUCCESS;
}
void setActiveScene(Scene *scene) {
kekData.activeScene = scene;
}
}

View File

@ -0,0 +1,25 @@
#include "gameobject.h"
namespace kek {
GameObject::GameObject() {
}
GameObject::~GameObject() {
for(Mesh *mesh : meshes) {
delete mesh;
}
}
void GameObject::addMesh(Mesh *mesh) {
meshes.push_back(mesh);
}
void GameObject::draw(Shader *shader) {
for(Mesh *mesh : meshes) {
mesh->draw(shader);
}
}
}

View File

@ -0,0 +1,41 @@
#include "input.h"
#include <map>
#include "internal.h"
namespace kek::Input {
static InputListener nextID = 0;
InputListener addPeriodicCallback(PeriodicCallback callback) {
InputListener id = nextID++;
kekData.periodicCallbacks.emplace(id, callback);
return id;
}
void removePeriodicCallback(InputListener listener) {
kekData.periodicCallbacks.erase(listener);
}
InputListener addKeyListener(KeyCallback callback) {
InputListener id = nextID++;
kekData.keyCallbacks.emplace(id, callback);
return id;
}
void removeKeyListener(InputListener listener) {
kekData.keyCallbacks.erase(listener);
}
InputListener addMouseListener(MouseCallback callback) {
InputListener id = nextID++;
kekData.mouseCallbacks.emplace(id, callback);
return id;
}
void removeMouseListener(InputListener listener) {
kekData.mouseCallbacks.erase(listener);
}
}

View File

@ -59,7 +59,7 @@ void Mesh::draw(Shader *shader) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
/*if(!light) {
/*if(!light) { // TODO: check if props exist
material->diffuse->use(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(shader->id, "material.diffuse"), 0);

View File

@ -4,7 +4,6 @@
#include <string>
#include <sstream>
#include <glm/glm.hpp>
#include <memory>
#include "types.h"

View File

@ -0,0 +1,33 @@
#include "scene.h"
namespace kek {
Scene::Scene() {
}
Scene::~Scene() {
for(GameObject *obj : objects) delete obj;
}
void Scene::addObject(GameObject *object) {
objects.push_back(object);
}
void Scene::removeObject(GameObject *object) {
for(auto it = objects.begin(); it < objects.end(); it++) {
if(*it == object) {
objects.erase(it);
delete object;
break;
}
}
}
void Scene::draw(Shader *shader) {
for(GameObject *obj : objects) {
obj->draw(shader);
}
}
}

View File

@ -13,10 +13,25 @@ static GLuint compileShader(GLenum type, std::string path) {
throw std::exception();
}
std::istream inStream(buf);
std::ostringstream stream;
stream << buf;
std::string code = stream.str();
std::string line;
while(std::getline(inStream, line)) {
if(line.find("!include ") == 0) {
std::string includePath = line.substr(9);
MemoryBuffer *includeBuf = Resource::loadResource("shader/include/" + includePath);
if(!includeBuf) {
std::cerr << "Include error: Failed to find path '" << includePath << "'" << std::endl;
throw std::exception();
}
stream << includeBuf;
delete includeBuf;
}else {
stream << line << '\n';
}
}
std::string code = stream.str();
delete buf;
const char *src = code.c_str();

View File

@ -0,0 +1,13 @@
#pragma once
#include "scene.h"
namespace kek::Engine {
int init();
int start();
void setActiveScene(Scene *scene);
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "object.h"
#include "mesh.h"
namespace kek {
class GameObject: public DefaultRotateableObject {
protected:
std::vector<Mesh *> meshes;
public:
GameObject();
~GameObject();
// Adds a mesh to the GameObject. The GameObject takes ownership of the Mesh, so don't use Meshes in multiple GameObjects
void addMesh(Mesh *mesh);
void draw(Shader *shader);
};
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <GLFW/glfw3.h>
#include "utils.h"
namespace kek {
typedef generic_callable_t<GLFWwindow *> PeriodicCallback;
typedef generic_callable_t<GLFWwindow *> KeyCallback;
typedef generic_callable_t<GLFWwindow *, double, double> MouseCallback;
typedef unsigned int InputListener;
}
namespace kek::Input {
InputListener addPeriodicCallback(PeriodicCallback callback);
void removePeriodicCallback(InputListener listener);
InputListener addKeyListener(KeyCallback callback);
void removeKeyListener(InputListener listener);
InputListener addMouseListener(MouseCallback callback);
void removeMouseListener(InputListener listener);
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "input.h"
#include "camera.h"
#include "scene.h"
#include <map>
namespace kek {
struct KekData {
std::map<InputListener, PeriodicCallback> periodicCallbacks;
std::map<InputListener, KeyCallback> keyCallbacks;
std::map<InputListener, MouseCallback> mouseCallbacks;
GLFWwindow *window;
Shader *shader;
Camera *activeCamera;
Scene *activeScene;
int screenWidth;
int screenHeight;
};
extern KekData kekData;
}

View File

@ -2,17 +2,14 @@
#include "camera.h"
#include "constants.h"
#include "engine.h"
#include "errordialog.h"
#include "gameobject.h"
#include "mesh.h"
#include "object.h"
#include "objparser.h"
#include "resource.h"
#include "scene.h"
#include "shader.h"
#include "types.h"
#include "utils.h"
namespace kek {
int init();
}

View File

@ -0,0 +1,30 @@
#pragma once
#include <vector>
#include "gameobject.h"
namespace kek {
class Scene {
protected:
std::vector<GameObject *> objects;
public:
Scene();
~Scene();
// Adds an object to the scene. The scene will take ownership of the object
void addObject(GameObject *object);
// Removes an object from the scene. The object will be deleted
void removeObject(GameObject *object);
// Draws the scene
void draw(Shader *shader);
};
}

View File

@ -0,0 +1,44 @@
struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
};
struct PointLight {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
};
struct DirectionalLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
mat4 lightSpaceMatrix;
};
struct SpotLight {
vec3 position;
vec3 direction;
float innerCutOff;
float outerCutOff;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
mat4 lightSpaceMatrix;
};

View File

@ -1,5 +1,7 @@
#version 330 core
!include types.glsl
in VS_OUT {
vec3 fragmentPosition;
vec2 textureCoordinate;

View File

@ -1,5 +1,7 @@
#version 330 core
!include types.glsl
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;

View File

@ -4,6 +4,21 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
using namespace kek;
int main(int argc, char **argv) {
kek::init();
Engine::init();
MemoryBuffer *buf = Resource::loadResource("object/sphere/Sphere.obj");
Mesh *mesh = ObjParser::parse(buf);
delete buf;
GameObject *test = new GameObject();
test->addMesh(mesh);
Scene *scene = new Scene();
scene->addObject(test);
Engine::setActiveScene(scene);
Engine::start();
}