hibiscus/renderer/rglcore/rglcore.cpp
2023-06-26 15:22:34 +02:00

204 lines
6.1 KiB
C++

#include <fmt/format.h>
#include <fstream>
#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);
glBindVertexArray(0);
}
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;
}
}