#include #include "../include/RenderBackend/OpenGL/opengl.hpp" #include "../include/RenderBackend/OpenGL/Shader.hpp" #include "../include/RenderBackend/OpenGL/ShaderProgram.hpp" #include "../include/RenderBackend/OpenGL/DeviceMemory.hpp" #include "../include/RenderBackend/OpenGL/DeviceFrame.hpp" #include "../include/Triangle2D.hpp" // TODO: Disallow shader variables that begin with "gl_" as reserved variables // start with that. What about hlsl? // TODO: Creating buffers etc should be somehow created/drawn using the window object, since they are associated with the window // opengl context using namespace amalgine; using namespace std; static void glfwErrorHandler(int errorCode, const char *errorDescription); static void initGlfw(); static void initGlew(); static GLFWwindow *createWindow(); static std::unique_ptr load_shader_from_file(const char *filepath, Shader::Type shader_type); int main() { initGlfw(); glfwSetErrorCallback(glfwErrorHandler); GLFWwindow *window = createWindow(); DeviceFrame frame; Triangle2D cpuTriangle( Vertex2D(0.0f, 0.5f), Vertex2D(0.5f, -0.5f), Vertex2D(-0.5f, -0.5f) ); DataView cpuTriangles(&cpuTriangle, 1); DeviceMemory *gpuTriangle = frame.alloc(); gpuTriangle->copy(cpuTriangles, DeviceMemory::StorageType::STATIC); std::unique_ptr vertex_shader = load_shader_from_file("shaders/vertex.vert", Shader::Type::VERTEX); std::unique_ptr pixel_shader = load_shader_from_file("shaders/fragment.frag", Shader::Type::PIXEL); Result> shader_program_result = ShaderProgram::build({ vertex_shader.get(), pixel_shader.get() }); if(!shader_program_result) { fprintf(stderr, "Failed to link shaders, error: %s\n", shader_program_result.getErrorMsg().c_str()); exit(13); } std::unique_ptr shader_program = std::move(shader_program_result.unwrap()); shader_program->set_vertex_input("position", *gpuTriangle); shader_program->set_uniform("triangle_color", vec3f{ 1.0f, 0.0f, 0.0f }); while(!glfwWindowShouldClose(window)) { glfwPollEvents(); if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); // Set color for clearing glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Do the actual screen clearing, using the color set using glClearColor glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); frame.draw(shader_program.get()); glfwSwapBuffers(window); } glfwTerminate(); return 0; } void glfwErrorHandler(int errorCode, const char *errorDescription) { printf("GLFW error code: %d, description: %s\n", errorCode, errorDescription); } void initGlfw() { if(!glfwInit()) { fprintf(stderr, "Failed to initialize GLFW\n"); exit(-1); } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); } void initGlew() { glewExperimental = true; if(glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); glfwTerminate(); exit(-1); } } GLFWwindow* createWindow() { GLFWwindow *window = glfwCreateWindow(1280, 720, "Amalgine", nullptr, nullptr); if(!window) { fprintf(stderr, "Failed to open GLFW window\n"); glfwTerminate(); exit(10); } glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); glfwMakeContextCurrent(window); glfwSwapInterval(0); initGlew(); return window; } static int file_read_all(const char *filepath, std::string &result) { FILE *file = fopen(filepath, "rb"); if(!file) { perror("file_read_all"); return errno; } fseek(file, 0, SEEK_END); size_t file_size = ftell(file); fseek(file, 0, SEEK_SET); result.resize(file_size); fread(&result[0], 1, result.size(), file); fclose(file); return 0; } std::unique_ptr load_shader_from_file(const char *filepath, Shader::Type shader_type) { std::string file_content; if(file_read_all(filepath, file_content) != 0) exit(13); Result> vertex_shader_result = Shader::compile(shader_type, file_content.data(), file_content.size()); if(!vertex_shader_result) { fprintf(stderr, "Failed to compile shader, error: %s\n", vertex_shader_result.getErrorMsg().c_str()); exit(12); } return std::move(vertex_shader_result.unwrap()); }