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 "../math/types.hpp"
#include "../resources/resource.hpp" #include "../resources/resource.hpp"
#include "../resources/texture.hpp" #include "../resources/texture.hpp"
#include "../resources/shader.hpp"
#include "../callback.hpp" #include "../callback.hpp"
namespace hibis { namespace hibis {
class Renderer { class Renderer {
public: public:
Renderer(LoggerCallback logger) : mLogger(logger) {} Renderer(LoggerCallback logger);
// Draw // Draw
virtual void clearScreen(Color col) = 0; virtual void clearScreen(Color col) = 0;
virtual void renderCurrent() = 0; virtual void renderCurrent() = 0;
virtual void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) = 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 // Pre and Post draw
virtual void preDraw() = 0; virtual void preDraw() = 0;
@ -27,10 +31,13 @@ namespace hibis {
virtual void update() = 0; virtual void update() = 0;
// Util // Util
virtual void compileShader(Shader* shader) = 0;
virtual void toggleWireframe() = 0;
virtual void setWindowTitle(std::string title) = 0; virtual void setWindowTitle(std::string title) = 0;
bool mKeepOpen = true; bool mKeepOpen = true;
protected: protected:
LoggerCallback mLogger; 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" #include "texture.hpp"
namespace hibis { namespace hibis {
Texture::Texture(char* path) : mData(), mImageWidth(0), mImageHeight(0), mBuffer() { Texture::Texture(const char* path) : mData(), mImageWidth(0), mImageHeight(0), mImageChannels(0) {
unsigned int error = lodepng::load_file(mBuffer, path); mData = stbi_load(path, &mImageWidth, &mImageHeight, &mImageChannels, 0);
if (error) {
TODO("error message")
return;
} }
error = lodepng::decode(mData, mImageWidth, mImageHeight, mBuffer); Texture::~Texture() {
stbi_image_free(mData);
if (error) {
TODO("error message")
return;
} }
}
Texture::~Texture() {}
} }

View file

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

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 # Files
libhibis_src_core = files('core/engine/engine.cpp') libhibis_src_core = files('core/engine/engine.cpp')
libhibis_src_resources = files('core/resources/texture.cpp', 'core/resources/font.cpp') libhibis_src_renderer = files('core/renderer/renderer.cpp')
libhibis_src = [libhibis_src_core, libhibis_src_resources] 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_rglcore_src = files('renderer/rglcore/rglcore.cpp')
libhibis_test_src = files('test/app.cpp') libhibis_test_src = files('test/app.cpp')
@ -24,9 +25,8 @@ libglfw = dependency('glfw3')
libglew = dependency('GLEW') libglew = dependency('GLEW')
libfmt = dependency('fmt') libfmt = dependency('fmt')
libfreetype2 = dependency('freetype2') libfreetype2 = dependency('freetype2')
liblodepng = static_library('lodepng', 'external/lodepng/lodepng.cpp')
# Compile # 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]) 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]) 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 <fmt/format.h>
#include <fstream>
#include "rglcore.hpp" #include "rglcore.hpp"
namespace hibis::rglcore { 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..."); mLogger(Information, "Preparing GLFW3...");
if (!glfwInit()) { if (!glfwInit()) {
mLogger(Fatal, "GLFW couldn't be initialised!"); 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::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 // Pre and Post draw
void RGLCore::preDraw() {} void RGLCore::preDraw() {}
@ -65,7 +108,63 @@ namespace hibis::rglcore {
glfwPollEvents(); 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) { void RGLCore::setWindowTitle(std::string title) {
glfwSetWindowTitle(mWindow, title.c_str()); 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 #pragma once
#include <unordered_map>
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@ -16,11 +17,14 @@ namespace hibis::rglcore {
~RGLCore(); ~RGLCore();
// Draw // Draw
void clearScreen(Color col) override; void clearScreen(Color col = Color {0, 0, 0, 255}) override;
void renderCurrent() override; void renderCurrent() override;
void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) 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 // Pre and Post draw
void preDraw() override; void preDraw() override;
@ -30,8 +34,13 @@ namespace hibis::rglcore {
void update() override; void update() override;
// Util // Util
void compileShader(Shader* shader) override;
void toggleWireframe() override;
void setWindowTitle(std::string title) override; void setWindowTitle(std::string title) override;
private: private:
GLFWwindow* mWindow; 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; std::string sevString;
switch (severity) { switch (severity) {
case Message: case Message:
sevString = "Message"; sevString = " Message ";
break; break;
case Information: case Information:
sevString = "Information"; sevString = "Information";
break; break;
case Warning: case Warning:
sevString = "Warning"; sevString = " Warning ";
break; break;
case Error: case Error:
sevString = "Error"; sevString = " Error ";
break; break;
case Fatal: case Fatal:
sevString = "Fatal"; sevString = " Fatal ";
break; break;
} }
@ -44,16 +44,19 @@ void logger(LoggingSeverity severity, std::string message) {
} }
int main() { int main() {
logger(Information, fmt::format("PWD: {}", std::getenv("PWD")));
RGLCore renderer = RGLCore("test", IntVec2 {800, 600}, &logger); RGLCore renderer = RGLCore("test", IntVec2 {800, 600}, &logger);
Engine engine = Engine(&renderer, &logger); Engine engine = Engine(&renderer, &logger);
#ifdef _WIN32 #ifdef _WIN32
Font font = Font("C:\\Windows\\Fonts\\Arial.ttf", 16); Font font = Font(engine.mFreeTypeLibrary, "C:\\Windows\\Fonts\\Arial.ttf", 16);
#else #else
Font font = Font(engine.mFreeTypeLibrary, "/usr/share/fonts/noto/NotoSans-Light.ttf", 16); Font font = Font(engine.mFreeTypeLibrary, "/usr/share/fonts/noto/NotoSans-Light.ttf", 16);
#endif #endif
Texture image = Texture((char*)"test.png"); Texture image = Texture((char*)"test.png");
Shader shader = Shader("../test/test.vert", "../test/test.frag");
renderer.compileShader(&shader);
uint8_t red = 0; uint8_t red = 0;
bool increaseRed = true; bool increaseRed = true;
@ -61,6 +64,8 @@ int main() {
uint size = 16; uint size = 16;
uint f = 0; 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."); logger(Information, "Started Hibis test app! BEHOLD: Colours.");
while (renderer.mKeepOpen) { while (renderer.mKeepOpen) {
engine.runNodeProcesses(); engine.runNodeProcesses();
@ -85,8 +90,9 @@ int main() {
// Clear screen then sleep for ~16ms // Clear screen then sleep for ~16ms
renderer.clearScreen(Color {red, 0, 0, 255}); renderer.clearScreen(Color {red, 0, 0, 255});
renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255}); renderer.useShader(&shader, points);
renderer.drawTexture(&image, 1.0f, IntVec2 {10, 10}); //renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255});
//renderer.drawTexture(&image, 1.0f, IntVec2 {10, 10});
engine.drawNodes(); engine.drawNodes();
renderer.renderCurrent(); 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);
}