Compare commits
5 Commits
d69d982398
...
2aed98d688
Author | SHA1 | Date | |
---|---|---|---|
2aed98d688 | |||
10138d5fd8 | |||
307d000253 | |||
482116018f | |||
3dacb0c095 |
@ -10,12 +10,16 @@ def add_strict_compile_flags(env):
|
|||||||
env.Append(CCFLAGS=["-Wall", "-Wextra", "-pedantic", "-std=c++17"])
|
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
|
# Create the environment and create a Compilation Database for use in VSCodium
|
||||||
env = Environment(tools=['default', 'compilation_db'])
|
env = Environment(tools=['default', 'compilation_db'])
|
||||||
env.CompilationDatabase()
|
env.CompilationDatabase()
|
||||||
|
|
||||||
env.Append(CPPPATH=['cpp/', 'include/'])
|
env.Append(CPPPATH=['cpp/', 'include/'])
|
||||||
env.Append(LIBS=['glfw', 'dl'])
|
env.Append(LIBS=['glfw', 'dl', 'freetype'])
|
||||||
|
|
||||||
add_third_party_includes(env)
|
add_third_party_includes(env)
|
||||||
add_strict_compile_flags(env)
|
add_strict_compile_flags(env)
|
||||||
@ -45,9 +49,11 @@ testEnv.Append(LINKFLAGS=[
|
|||||||
|
|
||||||
add_third_party_includes(testEnv)
|
add_third_party_includes(testEnv)
|
||||||
add_strict_compile_flags(testEnv)
|
add_strict_compile_flags(testEnv)
|
||||||
|
add_debug_compile_flags(testEnv)
|
||||||
|
|
||||||
# Build the test programs
|
# Build the test programs
|
||||||
catch_cpp = "test/catch_amalgamated.cpp"
|
catch_cpp = "test/catch_amalgamated.cpp"
|
||||||
testEnv.Program('test/bin/vector-test.out', [catch_cpp, 'test/vector/vector-test.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/test-app.out', Glob('test/test-app/*.cpp'))
|
||||||
|
testEnv.Program('test/bin/parallax-demo.out', Glob('test/parallax-demo/*.cpp'))
|
||||||
|
@ -6,12 +6,16 @@
|
|||||||
|
|
||||||
namespace Gedeng {
|
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
|
// Setup Rendering
|
||||||
// FIXME: Make these parameters variable, maybe move this to a different function
|
RenderBackend::initialize_window(WINDOW_SIZE_X, WINDOW_SIZE_Y, WINDOW_NAME);
|
||||||
RenderBackend::initialize_window(1920, 1080, String("Application"));
|
|
||||||
Input::initialize(RenderBackend::get_window());
|
Input::initialize(RenderBackend::get_window());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::run() {
|
||||||
unsigned long previous_time_ms = Time::get_time_ms();
|
unsigned long previous_time_ms = Time::get_time_ms();
|
||||||
unsigned long time_until_fixed_update_ms = 0.0;
|
unsigned long time_until_fixed_update_ms = 0.0;
|
||||||
|
|
||||||
@ -26,13 +30,13 @@ void Application::run() {
|
|||||||
|
|
||||||
// Update fixed time step
|
// Update fixed time step
|
||||||
while (time_until_fixed_update_ms >= MS_PER_UPDATE) {
|
while (time_until_fixed_update_ms >= MS_PER_UPDATE) {
|
||||||
// Fixed Update
|
fixed_update(static_cast<double>(MS_PER_UPDATE) / 1000.0);
|
||||||
GG_CORE_INFO("Fixed Update");
|
|
||||||
time_until_fixed_update_ms -= MS_PER_UPDATE;
|
time_until_fixed_update_ms -= MS_PER_UPDATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable update
|
dynamic_update(static_cast<double>(elapsed_time_ms) / 1000.0);
|
||||||
GG_CORE_INFO("Variable Update");
|
|
||||||
|
RenderBackend::render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@ void RenderBackend::initialize_window(unsigned int width, unsigned int height, S
|
|||||||
window = glfwCreateWindow(width, height, title, NULL, NULL);
|
window = glfwCreateWindow(width, height, title, NULL, NULL);
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
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() {
|
bool RenderBackend::is_window_created() {
|
||||||
|
@ -5,13 +5,11 @@ namespace Gedeng {
|
|||||||
String::String() : String("") {
|
String::String() : String("") {
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const char *stringText)
|
String::String(const char *stringText) : length(strlen(stringText)), text(new char[length + sizeof(char)]) {
|
||||||
: length(strlen(stringText)), text(new char[length + sizeof(char)]) {
|
|
||||||
memcpy(text, stringText, length + sizeof(char));
|
memcpy(text, stringText, length + sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const String &other)
|
String::String(const String &other) : length(other.get_length()), text(new char[length + sizeof(char)]) {
|
||||||
: length(other.getLength()), text(new char[length + sizeof(char)]) {
|
|
||||||
memcpy(text, other.c_str(), length + sizeof(char));
|
memcpy(text, other.c_str(), length + sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +114,7 @@ const char *String::c_str() const {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t String::getLength() const {
|
size_t String::get_length() const {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
132
cpp/TextLabel.cpp
Normal file
132
cpp/TextLabel.cpp
Normal 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
|
1411
cpp/vendor/glad.c
vendored
1411
cpp/vendor/glad.c
vendored
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,34 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
namespace Gedeng {
|
namespace Gedeng {
|
||||||
|
|
||||||
class Application {
|
class Application {
|
||||||
public:
|
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 since this class will be inherited by user-created applications
|
||||||
virtual ~Application() = default;
|
virtual ~Application() = default;
|
||||||
|
|
||||||
|
// Game Loop
|
||||||
void run();
|
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:
|
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
|
// To be defined in client applications
|
||||||
|
@ -17,7 +17,8 @@ class Input {
|
|||||||
glfwSetKeyCallback(window, key_callback);
|
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) {
|
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);
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||||
|
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
// Adapted from LearnOpenGL
|
// Adapted from LearnOpenGL
|
||||||
|
|
||||||
|
// Must be the first include
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
// Other includes
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -152,21 +156,17 @@ class Shader {
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||||
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n"
|
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n"
|
||||||
<< infoLog
|
<< infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
|
||||||
<< "\n -- --------------------------------------------------- -- "
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
||||||
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n"
|
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n"
|
||||||
<< infoLog
|
<< infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
|
||||||
<< "\n -- --------------------------------------------------- -- "
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace Gedeng
|
@ -48,7 +48,7 @@ class String {
|
|||||||
const char *c_str() const;
|
const char *c_str() const;
|
||||||
|
|
||||||
/// Return the length of the String (without the terminator).
|
/// Return the length of the String (without the terminator).
|
||||||
size_t getLength() const;
|
size_t get_length() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t length;
|
size_t length;
|
||||||
|
41
include/Gedeng/TextLabel.h
Normal file
41
include/Gedeng/TextLabel.h
Normal 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
|
@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
namespace Gedeng {
|
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
|
} // namespace Gedeng
|
112
test/parallax-demo/main.cpp
Normal file
112
test/parallax-demo/main.cpp
Normal 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"));
|
||||||
|
}
|
@ -4,12 +4,23 @@
|
|||||||
|
|
||||||
class TestApp : public Gedeng::Application {
|
class TestApp : public Gedeng::Application {
|
||||||
public:
|
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;
|
~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() {
|
Gedeng::Application *Gedeng::create_application() {
|
||||||
GG_CLIENT_INFO("Creating Application");
|
GG_CLIENT_INFO("Creating Application");
|
||||||
return new TestApp();
|
return new TestApp(20, 900, 600, String("Test App"));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user