159 lines
3.7 KiB
C++
159 lines
3.7 KiB
C++
#define _USE_MATH_DEFINES
|
|
#include <stb_image.h>
|
|
#include "scene.hpp"
|
|
#include "utils.hpp"
|
|
#include <print>
|
|
|
|
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
|
|
|
|
void init_glfw() {
|
|
glfwInit();
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
|
|
#ifdef __APPLE__
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
|
#endif
|
|
}
|
|
|
|
void framebuffer_size_callback(GLFWwindow *, int width, int height) {
|
|
glViewport(0, 0, width, height);
|
|
}
|
|
|
|
void mouse_callback(GLFWwindow *window, double xpos, double ypos) {
|
|
Scene* scene = static_cast<Scene*>(glfwGetWindowUserPointer(window));
|
|
scene->camera.mouse_move(xpos, ypos);
|
|
}
|
|
|
|
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
|
|
Scene* scene = static_cast<Scene*>(glfwGetWindowUserPointer(window));
|
|
scene->camera.mouse_scroll(xoffset, yoffset);
|
|
}
|
|
|
|
GLFWwindow* create_window() {
|
|
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
|
|
dbc::check(window != NULL, "failed to open window");
|
|
|
|
glfwMakeContextCurrent(window);
|
|
|
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
|
|
|
auto good = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
|
dbc::check(good, "failed to load GLAD");
|
|
|
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
glfwSetCursorPosCallback(window, mouse_callback);
|
|
glfwSetScrollCallback(window, scroll_callback);
|
|
|
|
return window;
|
|
}
|
|
|
|
|
|
void process_input(GLFWwindow *window, Scene& scene) {
|
|
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
|
glfwSetWindowShouldClose(window, true);
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
|
|
scene.camera.forward();
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
|
|
scene.camera.back();
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
|
|
scene.camera.left();
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
|
|
scene.camera.right();
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) {
|
|
scene.reflect_on = !scene.reflect_on;
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {
|
|
scene.light.camera.on = !scene.light.camera.on;
|
|
|
|
scene.shader.apply_lighting(scene.light);
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) {
|
|
for(auto& light : scene.light.directional) {
|
|
light.adjust(-0.01f);
|
|
}
|
|
|
|
scene.shader.apply_lighting(scene.light);
|
|
}
|
|
|
|
if(glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS) {
|
|
for(auto& light : scene.light.directional) {
|
|
light.adjust(0.01f);
|
|
}
|
|
|
|
scene.shader.apply_lighting(scene.light);
|
|
}
|
|
}
|
|
|
|
Scene setup() {
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_BLEND);
|
|
glEnable(GL_CULL_FACE);
|
|
glEnable(GL_MULTISAMPLE);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glDepthFunc(GL_LESS);
|
|
|
|
components::Scene config = utils::load_scene_config("config.json");
|
|
|
|
return {config};
|
|
}
|
|
|
|
void update(GLFWwindow* window, Scene& scene) {
|
|
glfwPollEvents();
|
|
process_input(window, scene);
|
|
scene.update();
|
|
}
|
|
|
|
void render(GLFWwindow* window, Scene& scene, Text& text) {
|
|
scene.render(window);
|
|
float scale = 0.5f;
|
|
|
|
float X_height = text.characters['X'].size.y * scale + 0.5f;
|
|
float y = 0.0f;
|
|
|
|
for(int i = 0; i < 100; i++) {
|
|
y += X_height;
|
|
text.render(std::format("y={}", y), 25.0f, y, scale, glm::vec3(1.0, 0.0f, 0.0f));
|
|
}
|
|
|
|
glfwSwapBuffers(window);
|
|
}
|
|
|
|
void quit(GLFWwindow* window, Scene& scene) {
|
|
scene.cleanup();
|
|
glfwTerminate();
|
|
}
|
|
|
|
int main() {
|
|
init_glfw();
|
|
|
|
auto window = create_window();
|
|
auto scene = setup();
|
|
Text text;
|
|
|
|
glfwSetWindowUserPointer(window, &scene);
|
|
|
|
while(!glfwWindowShouldClose(window)) {
|
|
update(window, scene);
|
|
render(window, scene, text);
|
|
}
|
|
|
|
quit(window, scene);
|
|
|
|
return 0;
|
|
}
|