Compare commits

...

5 Commits

Author SHA1 Message Date
2aed98d688 Some refactoring and better usage of text 2021-05-04 12:22:23 +02:00
10138d5fd8 Add draft for text rendering 2021-05-04 12:07:56 +02:00
307d000253 Rename String::get_length 2021-05-04 11:44:54 +02:00
482116018f Add Parallax Demo + some bugfixes
The initialization order in the Application was wrong, so some code has been moved from run to the constructor.
2021-05-03 22:23:15 +02:00
3dacb0c095 Add ability for client to override fixed and dynamic update 2021-05-03 21:33:38 +02:00
14 changed files with 1067 additions and 734 deletions

View File

@ -10,12 +10,16 @@ def add_strict_compile_flags(env):
env.Append(CCFLAGS=["-Wall", "-Wextra", "-pedantic", "-std=c++17"])
def add_debug_compile_flags(env):
env.Append(CCFLAGS=["-g"])
# Create the environment and create a Compilation Database for use in VSCodium
env = Environment(tools=['default', 'compilation_db'])
env.CompilationDatabase()
env.Append(CPPPATH=['cpp/', 'include/'])
env.Append(LIBS=['glfw', 'dl'])
env.Append(LIBS=['glfw', 'dl', 'freetype'])
add_third_party_includes(env)
add_strict_compile_flags(env)
@ -45,9 +49,11 @@ testEnv.Append(LINKFLAGS=[
add_third_party_includes(testEnv)
add_strict_compile_flags(testEnv)
add_debug_compile_flags(testEnv)
# Build the test programs
catch_cpp = "test/catch_amalgamated.cpp"
testEnv.Program('test/bin/vector-test.out', [catch_cpp, 'test/vector/vector-test.cpp'])
testEnv.Program('test/bin/test-app.out', Glob('test/test-app/*.cpp'))
testEnv.Program('test/bin/parallax-demo.out', Glob('test/parallax-demo/*.cpp'))

View File

@ -6,12 +6,16 @@
namespace Gedeng {
void Application::run() {
Application::Application(unsigned long ms_per_update, unsigned int window_size_x, unsigned int window_size_y,
String window_name)
: MS_PER_UPDATE(ms_per_update), WINDOW_SIZE_X(window_size_x), WINDOW_SIZE_Y(window_size_y),
WINDOW_NAME(window_name) {
// Setup Rendering
// FIXME: Make these parameters variable, maybe move this to a different function
RenderBackend::initialize_window(1920, 1080, String("Application"));
RenderBackend::initialize_window(WINDOW_SIZE_X, WINDOW_SIZE_Y, WINDOW_NAME);
Input::initialize(RenderBackend::get_window());
}
void Application::run() {
unsigned long previous_time_ms = Time::get_time_ms();
unsigned long time_until_fixed_update_ms = 0.0;
@ -26,13 +30,13 @@ void Application::run() {
// Update fixed time step
while (time_until_fixed_update_ms >= MS_PER_UPDATE) {
// Fixed Update
GG_CORE_INFO("Fixed Update");
fixed_update(static_cast<double>(MS_PER_UPDATE) / 1000.0);
time_until_fixed_update_ms -= MS_PER_UPDATE;
}
// Variable update
GG_CORE_INFO("Variable Update");
dynamic_update(static_cast<double>(elapsed_time_ms) / 1000.0);
RenderBackend::render();
}
}

View File

@ -15,6 +15,11 @@ void RenderBackend::initialize_window(unsigned int width, unsigned int height, S
window = glfwCreateWindow(width, height, title, NULL, NULL);
glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
bool RenderBackend::is_window_created() {

View File

@ -5,13 +5,11 @@ namespace Gedeng {
String::String() : String("") {
}
String::String(const char *stringText)
: length(strlen(stringText)), text(new char[length + sizeof(char)]) {
String::String(const char *stringText) : length(strlen(stringText)), text(new char[length + sizeof(char)]) {
memcpy(text, stringText, length + sizeof(char));
}
String::String(const String &other)
: length(other.getLength()), text(new char[length + sizeof(char)]) {
String::String(const String &other) : length(other.get_length()), text(new char[length + sizeof(char)]) {
memcpy(text, other.c_str(), length + sizeof(char));
}
@ -116,7 +114,7 @@ const char *String::c_str() const {
return text;
}
size_t String::getLength() const {
size_t String::get_length() const {
return length;
}

132
cpp/TextLabel.cpp Normal file
View File

@ -0,0 +1,132 @@
// Must be the first include
#include <glad/glad.h>
// Other includes
#include <GLFW/glfw3.h>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Gedeng/Logger.h"
#include "Gedeng/TextLabel.h"
namespace Gedeng {
TextLabel::TextLabel(const String &text) : text(text), shader(Shader("Shader/text.vs", "Shader/text.fs")) {
FT_Library ft;
if (FT_Init_FreeType(&ft)) {
GG_CORE_ERROR("Couldn't create font library!");
return;
}
FT_Face face;
if (FT_New_Face(ft, "Resources/Fonts/Inter.ttf", 0, &face)) {
GG_CORE_ERROR("Couldn't load font from path!");
return;
}
// Set size
FT_Set_Pixel_Sizes(face, 0, 12);
// Load first 128 ASCII Characters
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // disable byte-alignment restriction
for (unsigned char c = 0; c < 128; c++) {
// load character glyph
if (FT_Load_Char(face, c, FT_LOAD_RENDER)) {
GG_CORE_ERROR("Couldn't load character glyph!");
continue;
}
// generate texture
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_RED,
GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);
// set texture options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// now store character for later use
Character character = {texture, glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
static_cast<unsigned int>(face->glyph->advance.x)};
characters.insert(std::pair<char, Character>(c, character));
}
glBindTexture(GL_TEXTURE_2D, 0);
// destroy FreeType once we're finished
FT_Done_Face(face);
FT_Done_FreeType(ft);
// configure VAO/VBO for texture quads
// -----------------------------------
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
valid = true;
}
void TextLabel::set_text(const String &text) {
this->text = text;
}
void TextLabel::render_text(float x, float y, float scale, Vector3 color) {
// activate corresponding render state
shader.use();
glUniform3f(glGetUniformLocation(shader.ID, "textColor"), color.x, color.y, color.z);
// FIXME: We need the screen size here... (or UI module size?)
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(900), 0.0f, static_cast<float>(600));
glUniformMatrix4fv(glGetUniformLocation(shader.ID, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(vao);
// iterate through all characters
for (size_t i = 0; i < text.get_length(); i++) {
Character ch = characters[text[i]];
float xpos = x + ch.bearing.x * scale;
float ypos = y - (ch.size.y - ch.bearing.y) * scale;
float w = ch.size.x * scale;
float h = ch.size.y * scale;
// update VBO for each character
float vertices[6][4] = {
{xpos, ypos + h, 0.0f, 0.0f}, {xpos, ypos, 0.0f, 1.0f}, {xpos + w, ypos, 1.0f, 1.0f},
{xpos, ypos + h, 0.0f, 0.0f}, {xpos + w, ypos, 1.0f, 1.0f}, {xpos + w, ypos + h, 1.0f, 0.0f}};
// render glyph texture over quad
glBindTexture(GL_TEXTURE_2D, ch.texture_id);
// update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices),
vertices); // be sure to use glBufferSubData and not glBufferData
glBindBuffer(GL_ARRAY_BUFFER, 0);
// render quad
glDrawArrays(GL_TRIANGLES, 0, 6);
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th
// pixels by 64 to get amount of pixels))
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
bool TextLabel::is_valid() {
return valid;
}
} // namespace Gedeng

79
cpp/vendor/glad.c vendored
View File

@ -19,10 +19,10 @@
https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.3
*/
#include <glad/glad.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glad/glad.h>
static void *get_proc(const char *namez);
@ -53,8 +53,7 @@ static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
#endif
#endif
static
int open_gl(void) {
static int open_gl(void) {
#ifndef IS_UWP
libGL = LoadLibraryW(L"opengl32.dll");
if (libGL != NULL) {
@ -68,8 +67,7 @@ int open_gl(void) {
return 0;
}
static
void close_gl(void) {
static void close_gl(void) {
if (libGL != NULL) {
FreeLibrary((HMODULE)libGL);
libGL = NULL;
@ -84,15 +82,12 @@ typedef void* (APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char*);
static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
#endif
static
int open_gl(void) {
static int open_gl(void) {
#ifdef __APPLE__
static const char *NAMES[] = {
"../Frameworks/OpenGL.framework/OpenGL",
static const char *NAMES[] = {"../Frameworks/OpenGL.framework/OpenGL",
"/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
};
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"};
#else
static const char *NAMES[] = {"libGL.so.1", "libGL.so"};
#endif
@ -105,8 +100,7 @@ int open_gl(void) {
#if defined(__APPLE__) || defined(__HAIKU__)
return 1;
#else
gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE)dlsym(libGL,
"glXGetProcAddressARB");
gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE)dlsym(libGL, "glXGetProcAddressARB");
return gladGetProcAddressPtr != NULL;
#endif
}
@ -115,8 +109,7 @@ int open_gl(void) {
return 0;
}
static
void close_gl(void) {
static void close_gl(void) {
if (libGL != NULL) {
dlclose(libGL);
libGL = NULL;
@ -124,8 +117,7 @@ void close_gl(void) {
}
#endif
static
void* get_proc(const char *namez) {
static void *get_proc(const char *namez) {
void *result = NULL;
if (libGL == NULL) return NULL;
@ -233,8 +225,7 @@ static int has_ext(const char *ext) {
}
terminator = loc + strlen(ext);
if((loc == extensions || *(loc - 1) == ' ') &&
(*terminator == ' ' || *terminator == '\0')) {
if ((loc == extensions || *(loc - 1) == ' ') && (*terminator == ' ' || *terminator == '\0')) {
return 1;
}
extensions = terminator;
@ -1135,10 +1126,12 @@ static void load_GL_VERSION_3_0(GLADloadproc load) {
glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D");
glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D");
glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer");
glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv");
glad_glGetFramebufferAttachmentParameteriv =
(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv");
glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap");
glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer");
glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample");
glad_glRenderbufferStorageMultisample =
(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample");
glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer");
glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange");
glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange");
@ -1169,7 +1162,8 @@ static void load_GL_VERSION_3_2(GLADloadproc load) {
if (!GLAD_GL_VERSION_3_2) return;
glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex");
glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex");
glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex");
glad_glDrawElementsInstancedBaseVertex =
(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex");
glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex");
glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex");
glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync");
@ -1278,7 +1272,8 @@ static void load_GL_VERSION_4_0(GLADloadproc load) {
glad_glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)load("glGetSubroutineUniformLocation");
glad_glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)load("glGetSubroutineIndex");
glad_glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)load("glGetActiveSubroutineUniformiv");
glad_glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)load("glGetActiveSubroutineUniformName");
glad_glGetActiveSubroutineUniformName =
(PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)load("glGetActiveSubroutineUniformName");
glad_glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)load("glGetActiveSubroutineName");
glad_glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)load("glUniformSubroutinesuiv");
glad_glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)load("glGetUniformSubroutineuiv");
@ -1391,18 +1386,24 @@ static void load_GL_VERSION_4_1(GLADloadproc load) {
}
static void load_GL_VERSION_4_2(GLADloadproc load) {
if (!GLAD_GL_VERSION_4_2) return;
glad_glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)load("glDrawArraysInstancedBaseInstance");
glad_glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)load("glDrawElementsInstancedBaseInstance");
glad_glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)load("glDrawElementsInstancedBaseVertexBaseInstance");
glad_glDrawArraysInstancedBaseInstance =
(PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)load("glDrawArraysInstancedBaseInstance");
glad_glDrawElementsInstancedBaseInstance =
(PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)load("glDrawElementsInstancedBaseInstance");
glad_glDrawElementsInstancedBaseVertexBaseInstance =
(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)load("glDrawElementsInstancedBaseVertexBaseInstance");
glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)load("glGetInternalformativ");
glad_glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)load("glGetActiveAtomicCounterBufferiv");
glad_glGetActiveAtomicCounterBufferiv =
(PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)load("glGetActiveAtomicCounterBufferiv");
glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)load("glBindImageTexture");
glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)load("glMemoryBarrier");
glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)load("glTexStorage1D");
glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)load("glTexStorage2D");
glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)load("glTexStorage3D");
glad_glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)load("glDrawTransformFeedbackInstanced");
glad_glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)load("glDrawTransformFeedbackStreamInstanced");
glad_glDrawTransformFeedbackInstanced =
(PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)load("glDrawTransformFeedbackInstanced");
glad_glDrawTransformFeedbackStreamInstanced =
(PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)load("glDrawTransformFeedbackStreamInstanced");
}
static void load_GL_VERSION_4_3(GLADloadproc load) {
if (!GLAD_GL_VERSION_4_3) return;
@ -1427,7 +1428,8 @@ static void load_GL_VERSION_4_3(GLADloadproc load) {
glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)load("glGetProgramResourceName");
glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)load("glGetProgramResourceiv");
glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)load("glGetProgramResourceLocation");
glad_glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)load("glGetProgramResourceLocationIndex");
glad_glGetProgramResourceLocationIndex =
(PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)load("glGetProgramResourceLocationIndex");
glad_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)load("glShaderStorageBlockBinding");
glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)load("glTexBufferRange");
glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)load("glTexStorage2DMultisample");
@ -1467,12 +1469,7 @@ static void find_coreGL(void) {
int i, major, minor;
const char *version;
const char* prefixes[] = {
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
NULL
};
const char *prefixes[] = {"OpenGL ES-CM ", "OpenGL ES-CL ", "OpenGL ES ", NULL};
version = (const char *)glGetString(GL_VERSION);
if (!version) return;
@ -1492,8 +1489,10 @@ static void find_coreGL(void) {
sscanf(version, "%d.%d", &major, &minor);
#endif
GLVersion.major = major; GLVersion.minor = minor;
max_loaded_major = major; max_loaded_minor = minor;
GLVersion.major = major;
GLVersion.minor = minor;
max_loaded_major = major;
max_loaded_minor = minor;
GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
@ -1517,7 +1516,8 @@ static void find_coreGL(void) {
}
int gladLoadGLLoader(GLADloadproc load) {
GLVersion.major = 0; GLVersion.minor = 0;
GLVersion.major = 0;
GLVersion.minor = 0;
glGetString = (PFNGLGETSTRINGPROC)load("glGetString");
if (glGetString == NULL) return 0;
if (glGetString(GL_VERSION) == NULL) return 0;
@ -1542,4 +1542,3 @@ int gladLoadGLLoader(GLADloadproc load) {
if (!find_extensionsGL()) return 0;
return GLVersion.major != 0 || GLVersion.minor != 0;
}

View File

@ -1,18 +1,34 @@
#pragma once
#include "String.h"
namespace Gedeng {
class Application {
public:
Application() = default;
Application(unsigned long ms_per_update, unsigned int window_size_x, unsigned int window_size_y,
String window_name);
// Virtual since this class will be inherited by user-created applications
virtual ~Application() = default;
// Game Loop
void run();
// Primarily for gameplay and physics
// To be overridden by client applications
virtual void fixed_update(double delta) = 0;
// Primarily for rendering
// To be overridden by client applications
virtual void dynamic_update(double delta) = 0;
private:
const unsigned long MS_PER_UPDATE = 20;
// TODO: These will probably become a separate Settings struct
const unsigned long MS_PER_UPDATE;
const unsigned int WINDOW_SIZE_X;
const unsigned int WINDOW_SIZE_Y;
const String WINDOW_NAME;
};
// To be defined in client applications

View File

@ -17,7 +17,8 @@ class Input {
glfwSetKeyCallback(window, key_callback);
}
// FIXME: Ignore warnings produced by these unused variables -- they're required for the callback to work
// FIXME: Ignore warnings produced by these unused variables -- they're required for the callback to work:
// https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE);

View File

@ -2,7 +2,11 @@
// Adapted from LearnOpenGL
// Must be the first include
#include <glad/glad.h>
// Other includes
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <fstream>
@ -152,21 +156,17 @@ class Shader {
if (!success) {
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n"
<< infoLog
<< "\n -- --------------------------------------------------- -- "
<< std::endl;
<< infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
} else {
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n"
<< infoLog
<< "\n -- --------------------------------------------------- -- "
<< std::endl;
<< infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
}
};
}
} // namespace Gedeng

View File

@ -48,7 +48,7 @@ class String {
const char *c_str() const;
/// Return the length of the String (without the terminator).
size_t getLength() const;
size_t get_length() const;
private:
size_t length;

View File

@ -0,0 +1,41 @@
#pragma once
#include <ft2build.h>
#include <glm/glm.hpp>
#include <map>
#include FT_FREETYPE_H
#include "Gedeng/Shader.h"
#include "Gedeng/String.h"
#include "Gedeng/Vector3.h"
namespace Gedeng {
class TextLabel {
public:
TextLabel(const String &text = String(""));
void set_text(const String &text);
void render_text(float x, float y, float scale, Vector3 color);
bool is_valid();
private:
struct Character {
unsigned int texture_id; // ID handle of the glyph texture
glm::ivec2 size; // Size of glyph
glm::ivec2 bearing; // Offset from baseline to left/top of glyph
unsigned int advance; // Offset to advance to next glyph
};
std::map<char, Character> characters;
unsigned int vao, vbo;
String text;
bool valid;
Shader shader;
};
} // namespace Gedeng

View File

@ -2,6 +2,14 @@
namespace Gedeng {
class Vector3 {};
class Vector3 {
public:
Vector3(float x, float y, float z) : x(x), y(y), z(z) {
}
float x;
float y;
float z;
};
} // namespace Gedeng

112
test/parallax-demo/main.cpp Normal file
View File

@ -0,0 +1,112 @@
#include "Gedeng/Logger.h"
#include "Gedeng/TextLabel.h"
#include "Gedeng/Vector3.h"
#define GEDENG_MAIN
#include <Gedeng.h>
class ParallaxApp : public Gedeng::Application {
public:
ParallaxApp(unsigned long ms_per_update, unsigned int window_size_x, unsigned int window_size_y,
Gedeng::String window_name)
: Application(ms_per_update, window_size_x, window_size_y, window_name), number_of_steps(10.0),
number_of_refinement_steps(10.0), bump_depth(0.1),
render_shader(Gedeng::Shader("Shader/bump.vs", "Shader/bump.fs")),
camera(Gedeng::Camera(90, 1920, 1080, 0.1, 1000.0)),
albedo("Resources/Textures/PavingStones/PavingStones070_2K_Color.jpg", Gedeng::Texture::Settings()),
bump("Resources/Textures/PavingStones/PavingStones070_2K_Displacement.jpg", Gedeng::Texture::Settings()),
normal("Resources/Textures/PavingStones/PavingStones070_2K_Normal.jpg", Gedeng::Texture::Settings()) {
// Move and rotate the camera so we see the quad well
camera.translate(glm::vec3(0.0, -1.0, 1.0));
camera.rotate(30, glm::vec3(1.0, 0.0, 0.0));
}
~ParallaxApp() = default;
void fixed_update(double delta) override {
// Settings for bump mapping
if (Gedeng::Input::is_key_down(GLFW_KEY_Q)) {
number_of_steps += delta * 5.0;
}
if (Gedeng::Input::is_key_down(GLFW_KEY_W)) {
number_of_steps -= delta * 5.0;
}
if (Gedeng::Input::is_key_down(GLFW_KEY_A)) {
number_of_refinement_steps += delta * 5.0;
}
if (Gedeng::Input::is_key_down(GLFW_KEY_S)) {
number_of_refinement_steps -= delta * 5.0;
}
if (Gedeng::Input::is_key_down(GLFW_KEY_Z)) {
bump_depth += delta * 0.1;
}
if (Gedeng::Input::is_key_down(GLFW_KEY_X)) {
bump_depth -= delta * 0.1;
}
Gedeng::String text;
text += std::to_string(number_of_steps).c_str();
text += " steps, ";
text += std::to_string(number_of_refinement_steps).c_str();
text += " refinement steps, ";
text += std::to_string(bump_depth).c_str();
text += " bump depth";
debug_text.set_text(text);
}
void dynamic_update(double delta) override {
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
render_shader.use();
// Camera
render_shader.setMat4("projection", camera.get_projection());
render_shader.setMat4("view", camera.get_view());
render_shader.setVec3("viewPos", camera.get_translation());
// Lighting
render_shader.setVec3("lightPos", glm::vec3(0.0, 1.0, 5.0));
render_shader.setFloat("number_of_steps", glm::max(0.0f, number_of_steps));
render_shader.setFloat("number_of_refinement_steps", glm::max(0.0f, number_of_refinement_steps));
render_shader.setFloat("bump_depth", glm::max(0.0f, bump_depth));
// Textures
albedo.bind_to(0);
normal.bind_to(1);
bump.bind_to(2);
// Quad which is rendered onto
quad_mesh.rotate(delta * 25.0f, glm::normalize(glm::vec3(0.0, 0.0, 1.0)));
quad_mesh.render(render_shader);
debug_text.render_text(25.0f, 25.0f, 1.0f, Gedeng::Vector3(1.0, 1.0, 0.0));
}
private:
float number_of_steps;
float number_of_refinement_steps;
float bump_depth;
Gedeng::Shader render_shader;
Gedeng::VertexBuffer vertex_rectangle;
Gedeng::Camera camera;
Gedeng::Texture albedo;
Gedeng::Texture bump;
Gedeng::Texture normal;
Gedeng::QuadMesh quad_mesh;
Gedeng::TextLabel debug_text;
};
Gedeng::Application *Gedeng::create_application() {
GG_CLIENT_INFO("Creating Application");
return new ParallaxApp(20, 900, 600, String("Parallax Demo"));
}

View File

@ -4,12 +4,23 @@
class TestApp : public Gedeng::Application {
public:
TestApp() = default;
TestApp(unsigned long ms_per_update, unsigned int window_size_x, unsigned int window_size_y,
Gedeng::String window_name)
: Application(ms_per_update, window_size_x, window_size_y, window_name) {
}
~TestApp() = default;
void fixed_update(double delta) override {
GG_CLIENT_INFO("Fixed update");
}
void dynamic_update(double delta) override {
GG_CLIENT_INFO("Dynamic update");
}
};
Gedeng::Application *Gedeng::create_application() {
GG_CLIENT_INFO("Creating Application");
return new TestApp();
return new TestApp(20, 900, 600, String("Test App"));
}