202 lines
6.1 KiB
C++
202 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);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|