#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, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 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); } 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]) { 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; char infoLog[512]; int success; unsigned int shaderIDs[2] = {0, 0}; mLogger(Information, fmt::format("Compiling shader {}", shader->mShaderPaths[0])); shaderIDs[0] = glCreateShader(GL_VERTEX_SHADER); const std::string vertShaderStr = loadFile(shader->mShaderPaths[1]); const char* vertShader = vertShaderStr.c_str(); glShaderSource(shaderIDs[0], 1, &vertShader, NULL); glCompileShader(shaderIDs[0]); glGetShaderiv(shaderIDs[0], GL_COMPILE_STATUS, &success); if(!success) { glGetShaderInfoLog(shaderIDs[0], 512, NULL, infoLog); printf("%s", infoLog); mLogger(Error, fmt::format("Couldn't compile shader '{}'! what: {}", shader->mShaderPaths[0], std::string(infoLog))); } mLogger(Information, fmt::format("Compiling shader {}", shader->mShaderPaths[1])); shaderIDs[1] = glCreateShader(GL_FRAGMENT_SHADER); const std::string fragShaderStr = loadFile(shader->mShaderPaths[1]); const char* fragShader = fragShaderStr.c_str(); glShaderSource(shaderIDs[1], 1, &fragShader, NULL); glCompileShader(shaderIDs[1]); glGetShaderiv(shaderIDs[1], GL_COMPILE_STATUS, &success); if(!success) { glGetShaderInfoLog(shaderIDs[1], 512, NULL, infoLog); mLogger(Error, fmt::format("Couldn't compile shader '{}'! what: {}", shader->mShaderPaths[1], std::string(infoLog))); } shader->mShaderProgram = glCreateProgram(); glAttachShader(shader->mShaderProgram, shaderIDs[0]); glAttachShader(shader->mShaderProgram, shaderIDs[1]); glLinkProgram(shader->mShaderProgram); glGetProgramiv(shader->mShaderProgram, GL_LINK_STATUS, &success); if (!success) { TODO("what the fuck, this isn't helpful") glGetShaderInfoLog(shader->mShaderProgram, 512, NULL, infoLog); mLogger(Error, fmt::format("Couldn't link shader! what: {}", std::string(infoLog))); } else mLogger(Information, "Linked shader."); glDeleteShader(shaderIDs[0]); glDeleteShader(shaderIDs[1]); GLfloat vertices[] = { -0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f, // Lower left corner 0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f, // Lower right corner 0.0f, 0.5f * float(sqrt(3)) * 2 / 3, 0.0f // Upper corner }; glGenVertexArrays(1, &shader->mShaderVAO); glGenBuffers(1, &shader->mShaderVBO); glBindVertexArray(shader->mShaderVAO); glBindBuffer(GL_ARRAY_BUFFER, shader->mShaderVBO); 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); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); 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()); } std::string 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)); } return text; } }