Initial OpenGL Core port

This commit is contained in:
Tulpen 2023-06-01 20:19:18 +01:00
parent b00ece6f2a
commit 205919e1a9
15 changed files with 8183 additions and 9118 deletions

View file

@ -0,0 +1,5 @@
#include "renderer.hpp"
namespace hibis {
Renderer::Renderer(LoggerCallback logger) : mLogger(logger) {}
}

View file

@ -5,19 +5,23 @@
#include "../math/types.hpp"
#include "../resources/resource.hpp"
#include "../resources/texture.hpp"
#include "../resources/shader.hpp"
#include "../callback.hpp"
namespace hibis {
class Renderer {
public:
Renderer(LoggerCallback logger) : mLogger(logger) {}
Renderer(LoggerCallback logger);
// Draw
virtual void clearScreen(Color col) = 0;
virtual void renderCurrent() = 0;
virtual void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) = 0;
virtual void drawTexture(Texture* resource, float scale, IntVec2 pos) = 0;
virtual void drawTexture(Texture* resource, IntRect size) = 0;
virtual void useShader(Shader* shader, Point2D points[3]) = 0;
virtual void stopUsingShaders() = 0;
// Pre and Post draw
virtual void preDraw() = 0;
@ -27,10 +31,13 @@ namespace hibis {
virtual void update() = 0;
// Util
virtual void compileShader(Shader* shader) = 0;
virtual void toggleWireframe() = 0;
virtual void setWindowTitle(std::string title) = 0;
bool mKeepOpen = true;
protected:
LoggerCallback mLogger;
bool mIsWireframeMode = false;
};
}

10
core/resources/shader.cpp Normal file
View file

@ -0,0 +1,10 @@
#include "shader.hpp"
namespace hibis {
Shader::Shader(std::string vertexShaderPath, std::string fragShaderPath) {
mShaderPaths[0] = vertexShaderPath;
mShaderPaths[1] = fragShaderPath;
}
Shader::~Shader() {}
}

20
core/resources/shader.hpp Normal file
View file

@ -0,0 +1,20 @@
#pragma once
#include <string>
#include "resource.hpp"
namespace hibis {
class Shader : public Resource {
public:
Shader(std::string vertexShaderPath, std::string fragShaderPath);
~Shader();
// Vertex then Frag shader
unsigned int mShaderIDs[2] = {0, 0};
unsigned int mShaderProgram = 0;
unsigned int mShaderVAO = 0;
unsigned int mShaderVBO = 0;
std::string mShaderPaths[2];
};
}

View file

@ -1,20 +1,14 @@
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image/stb_image.h>
#include "texture.hpp"
namespace hibis {
Texture::Texture(char* path) : mData(), mImageWidth(0), mImageHeight(0), mBuffer() {
unsigned int error = lodepng::load_file(mBuffer, path);
if (error) {
TODO("error message")
return;
}
error = lodepng::decode(mData, mImageWidth, mImageHeight, mBuffer);
if (error) {
TODO("error message")
return;
}
Texture::Texture(const char* path) : mData(), mImageWidth(0), mImageHeight(0), mImageChannels(0) {
mData = stbi_load(path, &mImageWidth, &mImageHeight, &mImageChannels, 0);
}
Texture::~Texture() {}
Texture::~Texture() {
stbi_image_free(mData);
}
}

View file

@ -2,8 +2,6 @@
#include <vector>
#include <lodepng/lodepng.h>
#include "resource.hpp"
#include "../pragmautil.hpp"
@ -11,11 +9,9 @@ namespace hibis {
TODO("Make this function")
class Texture : Resource {
public:
Texture(char* path);
Texture(const char* path);
~Texture();
std::vector<unsigned char> mData;
unsigned int mImageWidth, mImageHeight;
private:
std::vector<unsigned char> mBuffer;
unsigned char* mData;
int mImageWidth, mImageHeight, mImageChannels;
};
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

7987
external/stb_image/stb_image.h vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -12,8 +12,9 @@ include_dirs = include_directories('./external')
# Files
libhibis_src_core = files('core/engine/engine.cpp')
libhibis_src_resources = files('core/resources/texture.cpp', 'core/resources/font.cpp')
libhibis_src = [libhibis_src_core, libhibis_src_resources]
libhibis_src_renderer = files('core/renderer/renderer.cpp')
libhibis_src_resources = files('core/resources/texture.cpp', 'core/resources/font.cpp', 'core/resources/shader.cpp')
libhibis_src = [libhibis_src_core, libhibis_src_renderer, libhibis_src_resources]
libhibis_rglcore_src = files('renderer/rglcore/rglcore.cpp')
libhibis_test_src = files('test/app.cpp')
@ -24,9 +25,8 @@ libglfw = dependency('glfw3')
libglew = dependency('GLEW')
libfmt = dependency('fmt')
libfreetype2 = dependency('freetype2')
liblodepng = static_library('lodepng', 'external/lodepng/lodepng.cpp')
# Compile
libhibis = library('hibis', libhibis_src, include_directories: include_dirs, link_with: liblodepng, dependencies: [libfreetype2])
libhibis = library('hibis', libhibis_src, include_directories: include_dirs, dependencies: [libfreetype2])
libhibis_rglcore = library('hibis_rglcore', libhibis_rglcore_src, include_directories: [include_dirs, './core'], link_with: libhibis, dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])
hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rglcore'], link_with: [libhibis, libhibis_rglcore], dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])

View file

@ -1,9 +1,10 @@
#include <fmt/format.h>
#include <fstream>
#include "rglcore.hpp"
namespace hibis::rglcore {
RGLCore::RGLCore(std::string title, IntVec2 size, LoggerCallback callback) : Renderer(callback) {
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!");
@ -54,7 +55,49 @@ namespace hibis::rglcore {
}
void RGLCore::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {}
void RGLCore::drawTexture(Texture* resource, float scale, IntVec2 pos) {}
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() {}
@ -65,7 +108,63 @@ namespace hibis::rglcore {
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;
}
}

View file

@ -1,5 +1,6 @@
#pragma once
#include <unordered_map>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
@ -16,11 +17,14 @@ namespace hibis::rglcore {
~RGLCore();
// Draw
void clearScreen(Color col) override;
void clearScreen(Color col = Color {0, 0, 0, 255}) override;
void renderCurrent() override;
void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) override;
void drawTexture(Texture* resource, float scale, IntVec2 pos) override;
void drawTexture(Texture* resource, IntRect size) override;
void useShader(Shader* shader, Point2D points[3]) override;
void stopUsingShaders() override;
// Pre and Post draw
void preDraw() override;
@ -30,8 +34,13 @@ namespace hibis::rglcore {
void update() override;
// Util
void compileShader(Shader* shader) override;
void toggleWireframe() override;
void setWindowTitle(std::string title) override;
private:
GLFWwindow* mWindow;
std::unordered_map<Texture*, unsigned int> mTextures;
const char* loadFile(std::string path);
};
}

View file

@ -24,19 +24,19 @@ void logger(LoggingSeverity severity, std::string message) {
std::string sevString;
switch (severity) {
case Message:
sevString = "Message";
sevString = " Message ";
break;
case Information:
sevString = "Information";
break;
case Warning:
sevString = "Warning";
sevString = " Warning ";
break;
case Error:
sevString = "Error";
sevString = " Error ";
break;
case Fatal:
sevString = "Fatal";
sevString = " Fatal ";
break;
}
@ -44,16 +44,19 @@ void logger(LoggingSeverity severity, std::string message) {
}
int main() {
logger(Information, fmt::format("PWD: {}", std::getenv("PWD")));
RGLCore renderer = RGLCore("test", IntVec2 {800, 600}, &logger);
Engine engine = Engine(&renderer, &logger);
#ifdef _WIN32
Font font = Font("C:\\Windows\\Fonts\\Arial.ttf", 16);
Font font = Font(engine.mFreeTypeLibrary, "C:\\Windows\\Fonts\\Arial.ttf", 16);
#else
Font font = Font(engine.mFreeTypeLibrary, "/usr/share/fonts/noto/NotoSans-Light.ttf", 16);
#endif
Texture image = Texture((char*)"test.png");
Shader shader = Shader("../test/test.vert", "../test/test.frag");
renderer.compileShader(&shader);
uint8_t red = 0;
bool increaseRed = true;
@ -61,6 +64,8 @@ int main() {
uint size = 16;
uint f = 0;
Point2D points[3] = {{-0.5f, -0.5f}, {0.5f, -0.5f}, {0.0f, 0.5f}};
logger(Information, "Started Hibis test app! BEHOLD: Colours.");
while (renderer.mKeepOpen) {
engine.runNodeProcesses();
@ -85,8 +90,9 @@ int main() {
// Clear screen then sleep for ~16ms
renderer.clearScreen(Color {red, 0, 0, 255});
renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255});
renderer.drawTexture(&image, 1.0f, IntVec2 {10, 10});
renderer.useShader(&shader, points);
//renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255});
//renderer.drawTexture(&image, 1.0f, IntVec2 {10, 10});
engine.drawNodes();
renderer.renderCurrent();

6
test/test.frag Normal file
View file

@ -0,0 +1,6 @@
#version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}

6
test/test.vert Normal file
View file

@ -0,0 +1,6 @@
#version 330 core
layout (location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}