#include #include #include "rglcore.hpp" namespace hibis::rglcore { RGLCore::RGLCore(std::string title, IntVec2 size, LoggerCallback callback) : Renderer(callback), mTextures() { mLogger(Information, "Preparing GLFW3..."); if (!glfwInit()) { mLogger(Fatal, "GLFW couldn't be initialised!"); exit(1); } mLogger(Information, "Creating GLFWwindow..."); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); mWindow = glfwCreateWindow(size.x, size.y, title.c_str(), NULL, NULL); if (!mWindow) { mLogger(Fatal, "Window could not be created!"); exit(1); } glfwMakeContextCurrent(mWindow); mLogger(Information, "Preparing GLEW..."); glewExperimental = GL_FALSE; GLenum err = glewInit(); if (err != GLEW_OK) { mLogger(Fatal, "GLEW could not be created due to GLEW err " + std::to_string(err)); exit(err); } mLogger(Information, "Setting viewport..."); glViewport(0, 0, size.x, size.y); mLogger(Information, "Finished setting up RGLCore!"); } RGLCore::~RGLCore() { glfwDestroyWindow(mWindow); glfwTerminate(); } // Draw void RGLCore::clearScreen(Color col) { float r = (float)(col.r) / 255, g = (float)(col.g) / 255, b = (float)(col.b) / 255, a = (float)(col.a) / 255; glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void RGLCore::renderCurrent() { glfwSwapBuffers(mWindow); } void RGLCore::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {} void RGLCore::drawTexture(Texture* resource, IntRect size) { TODO("finish this") return; unsigned int glTextureID; if (mTextures.find(resource) != mTextures.end()) { glTextureID = mTextures[resource]; } else { glGenTextures(1, &glTextureID); glBindTexture(GL_TEXTURE_2D, glTextureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resource->mImageWidth, resource->mImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, resource->mData); glGenerateMipmap(GL_TEXTURE_2D); } } void RGLCore::useShader(Shader* shader, Point2D points[3]) { float vertices[] = { points[0].x, points[0].y, 0.0f, points[1].x, points[1].y, 0.0f, points[2].x, points[2].y, 0.0f }; if (shader->mShaderVAO == 0) { glGenVertexArrays(1, &shader->mShaderVAO); glBindVertexArray(shader->mShaderVAO); glBindBuffer(GL_ARRAY_BUFFER, shader->mShaderVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); } glUseProgram(shader->mShaderProgram); glBindVertexArray(shader->mShaderVAO); glDrawArrays(GL_TRIANGLES, 0, 3); } void RGLCore::stopUsingShaders() { glUseProgram(0); } // Pre and Post draw void RGLCore::preDraw() {} void RGLCore::postDraw() {} void RGLCore::update() { mKeepOpen = !glfwWindowShouldClose(mWindow); glfwPollEvents(); } void RGLCore::compileShader(Shader* shader) { if (shader->mShaderProgram != 0) return; mLogger(Information, fmt::format("Compiling shader {}", shader->mShaderPaths[0])); glGenBuffers(1, &shader->mShaderVBO); glBindBuffer(GL_ARRAY_BUFFER, shader->mShaderVBO); shader->mShaderIDs[0] = glCreateShader(GL_VERTEX_SHADER); const char* vertShader = loadFile(shader->mShaderPaths[0]); glShaderSource(shader->mShaderIDs[0], 1, &vertShader, NULL); glCompileShader(shader->mShaderIDs[0]); mLogger(Information, fmt::format("Compiling shader {}", shader->mShaderPaths[1])); shader->mShaderIDs[1] = glCreateShader(GL_VERTEX_SHADER); const char* fragShader = loadFile(shader->mShaderPaths[1]); glShaderSource(shader->mShaderIDs[1], 1, &fragShader, NULL); glCompileShader(shader->mShaderIDs[1]); shader->mShaderProgram = glCreateProgram(); glAttachShader(shader->mShaderProgram, shader->mShaderIDs[0]); glAttachShader(shader->mShaderProgram, shader->mShaderIDs[1]); glLinkProgram(shader->mShaderProgram); mLogger(Information, "Linked shader."); glDeleteShader(shader->mShaderIDs[0]); glDeleteShader(shader->mShaderIDs[1]); mLogger(Information, "Cleaned up leftover shader objects."); } void RGLCore::toggleWireframe() { if (mIsWireframeMode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); else glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); mIsWireframeMode = !mIsWireframeMode; } void RGLCore::setWindowTitle(std::string title) { glfwSetWindowTitle(mWindow, title.c_str()); } const char* RGLCore::loadFile(std::string path) { std::string text, line; std::ifstream textFile(path); if (textFile.is_open()) { while (getline(textFile, line)) { text += line + '\n'; } textFile.close(); } else { text = ""; mLogger(Error, fmt::format("Couldn't load file '{}'", path)); } const char* textChar = text.c_str(); return textChar; } }