Moved to linux so depends aren't such a mess! Also decided to bundle the thirdparty glad.c library with the project. Debugging fonts added. General fixes and new GLM version

This commit is contained in:
Ethan 2025-03-19 22:11:37 -04:00
parent 78540b8ac6
commit 294d75ff59
46 changed files with 5926 additions and 283 deletions

1
.gitignore vendored
View file

@ -32,6 +32,7 @@ bld/
[Oo]ut/
[Ll]og/
[Ll]ogs/
[Bb]uild/
# Visual Studio 2015/2017 cache/options directory
.vs/

View file

@ -14,9 +14,9 @@ include(FetchContent)
SET(CMAKE_EXPORT_COMPILE_COMMANDS 1)
#SET(SOL_LUAJIT 1)
SET(TRACY_ENABLE 1)
SET(TRACY_ON_DEMAND 1)
SET(TRACY_ONLY_LOCALHOST 1)
#SET(TRACY_ENABLE 1)
#SET(TRACY_ON_DEMAND 1)
#SET(TRACY_ONLY_LOCALHOST 1)
SET(FT_DISABLE_BROTLI 1)
SET(FT_DISABLE_BZIP2 1)
@ -26,6 +26,8 @@ SET(FT_DISABLE_ZLIB 1)
option(GLM_ENABLE_FAST_MATH OFF)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffloat-store -fexcess-precision=standard -ffp-contract=off")
FetchContent_Declare(
tracy
GIT_REPOSITORY https://github.com/wolfpld/tracy.git
@ -34,35 +36,6 @@ FetchContent_Declare(
GIT_PROGRESS TRUE
)
FetchContent_Declare(
tinyxml2
GIT_REPOSITORY https://github.com/leethomason/tinyxml2.git
GIT_TAG 10.0.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
FetchContent_Declare(
sol2
GIT_REPOSITORY https://github.com/ThePhD/sol2.git
GIT_TAG v3.3.1
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
FetchContent_Declare(
freetype
GIT_REPOSITORY https://github.com/freetype/freetype.git
GIT_TAG VER-2-13-3
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(tracy)
FetchContent_MakeAvailable(tinyxml2)
FetchContent_MakeAvailable(sol2)
FetchContent_MakeAvailable(freetype)
project ("YuppleMayham")
# Include sub-projects.

View file

@ -17,5 +17,5 @@ end
-- How the bullet, target or wielder respond when the bullet hits a target.
function onHit(target, bullet, normal)
target.physics.rigidBody:applyForce(vec3.new(normal.x, normal.y, 0.0), 5000.0);
target.physics.rigidBody:applyForce(normal, 5000.0);
end

View file

@ -1,14 +1,15 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec2 texCoord;
uniform mat4 MVP;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
void main()
{

View file

@ -1,12 +1,14 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec2 texCoord;
uniform mat4 projection;
uniform mat4 view;
void main()
{
texCoord = aTexCoord;

View file

@ -1,13 +1,14 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec2 texCoord;
uniform mat4 MVP;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform bool flip;

View file

@ -1,15 +1,16 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexPos;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec3 pos;
out vec2 texPos;
uniform mat4 MVP;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
void main()
{

View file

@ -7,10 +7,13 @@ layout (location = 4) in int aTilesPerRow;
layout (location = 5) in int aStartIndex;
layout (location = 6) in vec2 aOriginalSize;
layout (location = 7) in mat4 aModel;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
uniform vec2 uCanvasSize;
uniform mat4 projection;
uniform mat4 view;
out vec2 texCoord;
flat out int textureIndex;

View file

@ -4,12 +4,17 @@
find_package(SDL2 2.30.2 REQUIRED)
find_package(SDL2_IMAGE 2.8.2 REQUIRED)
#find_package(luajit CONFIG REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LuaJIT REQUIRED IMPORTED_TARGET GLOBAL luajit)
find_package(sol2 REQUIRED)
find_package(tinyxml2 REQUIRED)
find_package(Freetype REQUIRED)
find_package(glm CONFIG REQUIRED)
include_directories(SYSTEM "c:/sdks/glad/include")
#include_directories(SYSTEM "c:/sdks/glad/include")
#include_directories(SYSTEM "c:/sdks/tinyxml2-10.0.0/debug/include")
include_directories(SYSTEM "c:/sdks/glm")
#include_directories(SYSTEM "c:/sdks/glm")
#include_directories(SYSTEM "C:/sdks/sol2-3.3.0/single/single/include")
#include_directories(SYSTEM "c:/sdks/lua-5.4.6/include")
#include_directories(SYSTEM "C:/sdks/freetype-2.13.2/include")
@ -26,7 +31,9 @@ include_directories(SYSTEM "c:/sdks/glm")
# Add source to this project's executable.
add_executable (YuppleMayham
"src/main.cpp"
"c:/sdks/glad/src/glad.c"
"src/thirdparty/glad.c"
"src/utility/data/font_data.c"
"src/utility/ftfont.cpp"
"src/graphics/sprite.cpp"
"src/graphics/mesh.cpp"
"src/gameplay/entity.cpp"
@ -51,7 +58,6 @@ add_executable (YuppleMayham
"src/utility/debugdraw.cpp"
"src/utility/script.cpp"
"src/gameplay/ai.cpp"
"src/utility/ftfont.cpp"
"include/graphics/glwindow.h"
"include/gameplay/camera.h"
"include/utility/mousestate.h"
@ -86,14 +92,11 @@ add_custom_command(TARGET YuppleMayham PRE_BUILD COMMAND ${CMAKE_COMMAND} -E cop
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET YuppleMayham PROPERTY CXX_STANDARD 20)
message("this is freetype include dirs: ${FREETYPE_INCLUDE_DIR_ft2build}")
endif()
target_include_directories(YuppleMayham PRIVATE "C:/sdks/luajit/include")
target_include_directories(YuppleMayham PRIVATE "${PROJECT_SOURCE_DIR}/YuppleMayham/include")
target_include_directories(YuppleMayham PRIVATE ${freetype_SOURCE_DIR})
target_include_directories(YuppleMayham PRIVATE ${tinyxml2_SOURCE_DIR})
target_include_directories(YuppleMayham PRIVATE "${sol2_SOURCE_DIR}/include")
target_include_directories(YuppleMayham PRIVATE "${PROJECT_SOURCE_DIR}/YuppleMayham/include" ${LuaJIT_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIR_ft2build})
target_link_libraries(YuppleMayham SDL2::SDL2main SDL2::SDL2 SDL2_image::SDL2_image "C:/sdks/luajit/lib/luajit.lib" "C:/sdks/luajit/lib/lua51.lib" tinyxml2 freetype Tracy::TracyClient)
target_link_libraries(YuppleMayham SDL2::SDL2main SDL2::SDL2 SDL2_image::SDL2_image glm::glm-header-only sol2 tinyxml2 freetype ${LuaJIT_LINK_LIBRARIES})
# TODO: Add tests and install targets if needed.

View file

@ -7,6 +7,7 @@
#include <SDL_timer.h>
#include "graphics/renderer.h"
#include "util.h"
class Camera;
struct PhysicsComponent;

View file

@ -1,6 +1,7 @@
#ifndef _H_INPUT_H
#define _H_INPUT_H
#include "utility/logger.h"
#include <unordered_map>
#include <SDL_keycode.h>
#include <SDL_events.h>
@ -49,6 +50,8 @@ protected:
{
mouse_state.x = static_cast<float>(e.motion.x);
mouse_state.y = static_cast<float>(e.motion.y);
// Quick fix regarding linux holding storing too many mouse events
SDL_FlushEvent(SDL_MOUSEMOTION);
}
if (e.type == SDL_MOUSEWHEEL)
mouse_state.scroll = e.wheel.preciseY;

View file

@ -12,20 +12,20 @@ struct PhysicsComponent {
// This ID holds the ID of the gameactor that owns this object, that being themselves or a bullet.
unsigned int ID = 0; // If the ID stays 0 then that object has no owner and will be uncollidable
struct RigidBody {
glm::vec3 position;
glm::vec3 velocity;
glm::vec3 acceleration;
glm::vec2 position;
glm::vec2 velocity = glm::vec2(0.f);
glm::vec2 acceleration = glm::vec2(0.f);
float elasticity = 0.7f;
float mass = 1.0f;
void applyForce(glm::vec3 dir, float mag) {
void applyForce(glm::vec2 dir, float mag) {
acceleration += ((dir * mag) / mass);
}
}rigidBody;
struct Collider {
enum class Shape { Square, Circle } shape = Shape::Circle;
glm::vec3 offset = glm::vec3(0.f);
glm::vec3 dimensions;
glm::vec2 offset = glm::vec2(0.f);
glm::vec2 dimensions;
}collider;
};
@ -36,7 +36,7 @@ public:
p.ID = ID;
p.rigidBody.position = pos;
p.rigidBody.mass = mass;
p.collider = { PhysicsComponent::Collider::Shape::Circle, glm::vec3(0.f, 0.f, 0.f), glm::vec3(radius) };
p.collider = { PhysicsComponent::Collider::Shape::Circle, glm::vec2(0.f, 0.f), glm::vec2(radius) };
p.isBullet = true;
return p;
}
@ -59,7 +59,7 @@ private:
void resolveWorldCollision(const std::shared_ptr<PhysicsComponent>&);
void resolvePossibleCollisions();
void getPossibleCollisions();
int getTileCollider(const glm::vec3& position);
int getTileCollider(const glm::vec2& position);
std::vector<std::shared_ptr<PhysicsComponent>> objects;
std::vector<CollisionPair> objCollisions;
std::vector<std::vector<int>> collisionMap;

View file

@ -3,6 +3,7 @@
#include <memory>
#include <SDL_timer.h>
#include <vector>
#include <string>
#include <unordered_map>

View file

@ -4,7 +4,7 @@
#include <SDL_video.h>
//#include <SDL_opengl.h>
#include <glad/glad.h>
#include <thirdparty/glad/glad.h>
class GLWindow
{

View file

@ -3,6 +3,8 @@
#include <vector>
#include <glm/glm.hpp>
#include <thirdparty/glad/glad.h>
#include <cstring>
#define MAX_INSTANCES 1000
#define MAX_TEXTURES 31

View file

@ -3,7 +3,7 @@
#include <vector>
#include <glad/glad.h>
#include <thirdparty/glad/glad.h>
#include <glm/glm.hpp>
typedef struct {

View file

@ -1,8 +1,8 @@
#ifndef _H_POSTPROCESS_H
#define _H_POSTPROCESS_H
#include <SDL_Timer.h>
#include <glad/glad.h>
#include <SDL_timer.h>
#include <thirdparty/glad/glad.h>
#include <glm/glm.hpp>
#include <limits>
#include <memory>

View file

@ -1,7 +1,8 @@
#ifndef _H_QUAD_H
#define _H_QUAD_H
#include <glad/glad.h>
#include <thirdparty/glad/glad.h>
#include <cstring>
class Quad
{

View file

@ -15,102 +15,102 @@ class ResourceManager;
class Shader;
enum class RenderLayer {
Background,
Map,
GameObjects,
Effects,
HUD,
Menu
Background,
Map,
GameObjects,
Effects,
HUD,
Menu
};
using UniformValue = std::variant<
int,
bool,
float,
double,
glm::mat4,
glm::vec2
int,
bool,
float,
double,
glm::mat4,
glm::vec2
>;
struct Uniform {
std::string name;
UniformValue value;
std::string name;
UniformValue value;
};
class Drawable
{
public:
virtual void draw() = 0;
const unsigned getShaderID() const { return shaderID; }
const std::vector<Uniform>& getUniforms() { return uniforms; }
const std::vector<Uniform>& getOneShotUniforms() { return oneShotUniforms; }
void clearOneShot() { oneShotUniforms.clear(); }
void clearUniforms() { uniforms.clear(); }
virtual void draw() = 0;
const unsigned getShaderID() const { return shaderID; }
const std::vector<Uniform>& getUniforms() { return uniforms; }
const std::vector<Uniform>& getOneShotUniforms() { return oneShotUniforms; }
void clearOneShot() { oneShotUniforms.clear(); }
void clearUniforms() { uniforms.clear(); }
protected:
unsigned shaderID;
template <typename T>
void editUniform(const std::string& name, T value)
{
uniforms.emplace_back(Uniform {name, value});
}
unsigned shaderID;
template <typename T>
void editUniform(const std::string& name, T value)
{
uniforms.emplace_back(Uniform {name, value});
}
template <typename T>
void editUniformOnce(const std::string& name, T value)
{
oneShotUniforms.emplace_back(Uniform {name, value});
}
template <typename T>
void editUniformOnce(const std::string& name, T value)
{
oneShotUniforms.emplace_back(Uniform {name, value});
}
private:
std::vector<Uniform> uniforms;
std::vector<Uniform> oneShotUniforms;
std::vector<Uniform> uniforms;
std::vector<Uniform> oneShotUniforms;
};
class Renderer
{
public:
Renderer(const std::shared_ptr<ResourceManager>&);
Renderer(const std::shared_ptr<ResourceManager>&);
void clear();
void clear();
void hookEventManager(const std::weak_ptr<EventManager> eventManager);
void hookEventManager(const std::weak_ptr<EventManager> eventManager);
void setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view);
void addDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable);
void removeDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable);
void setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view);
void addDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable);
void removeDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable);
void render();
void render();
private:
std::unordered_map<RenderLayer, std::vector<std::shared_ptr<Drawable>>> worldLayerPool;
std::unordered_map<RenderLayer, std::vector<std::shared_ptr<Drawable>>> HUDLayerPool;
std::vector<RenderLayer> renderingOrder = {
RenderLayer::Background,
RenderLayer::Map,
RenderLayer::GameObjects,
RenderLayer::Effects,
RenderLayer::HUD,
RenderLayer::Menu
};
std::unordered_map<RenderLayer, std::vector<std::shared_ptr<Drawable>>> worldLayerPool;
std::unordered_map<RenderLayer, std::vector<std::shared_ptr<Drawable>>> HUDLayerPool;
std::vector<RenderLayer> renderingOrder = {
RenderLayer::Background,
RenderLayer::Map,
RenderLayer::GameObjects,
RenderLayer::Effects,
RenderLayer::HUD,
RenderLayer::Menu
};
void uploadUniforms(const unsigned shaderID, const std::vector<Uniform>& uniforms);
void uploadUniforms(const unsigned shaderID, const std::vector<Uniform>& uniforms);
glm::mat4 projMat;
glm::mat4 viewMat;
unsigned uboMatrices;
union FrameBuffer {
unsigned int frame;
unsigned int texture;
}worldBuffer, hudBuffer;
union FrameBuffer {
unsigned int frame;
unsigned int texture;
}worldBuffer, hudBuffer;
std::unique_ptr<ScreenQuad> screenQuad;
std::unique_ptr<ScreenQuad> screenQuad;
std::shared_ptr<ResourceManager> resourceManager;
std::shared_ptr<ResourceManager> resourceManager;
void initFrameBuffers();
void initFrameBuffers();
void initUniformBuffers();
std::unique_ptr<Postprocessor> postProcessor;
std::unique_ptr<Postprocessor> postProcessor;
void sortLayerPool(auto& layerPool);
void renderPool(auto& layerPool);
void sortLayerPool(auto& layerPool);
void renderPool(auto& layerPool);
};
#endif

View file

@ -1,7 +1,7 @@
#ifndef _H_SHADER_H
#define _H_SHADER_H
#include <glad/glad.h>
#include <thirdparty/glad/glad.h>
#include <fstream>
#include <string>

View file

@ -2,13 +2,14 @@
#define _H_SPRITE_H
#include <SDL_image.h>
#include <glad/glad.h>
#include <thirdparty/glad/glad.h>
#include <glm/glm.hpp>
#include <vector>
#include <unordered_map>
#include <memory>
#include <algorithm>
#include "utility/direction.h"

View file

@ -2,6 +2,8 @@
#define _H_TEXTURE_H
#include <vector>
#include <thirdparty/glad/glad.h>
#include <SDL_image.h>
struct SDL_Surface;

View file

@ -0,0 +1,311 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
/*
* To support platform where unsigned long cannot be used interchangeably with
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
* unsigned long long or similar (this results in different C++ name mangling).
* To avoid changes for existing platforms, we restrict usage of intptr_t to
* platforms where the size of a pointer is larger than the size of long.
*/
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
#define KHRONOS_USE_INTPTR_T
#endif
#endif
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef KHRONOS_USE_INTPTR_T
typedef intptr_t khronos_intptr_t;
typedef uintptr_t khronos_uintptr_t;
#elif defined(_WIN64)
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
#endif
#if defined(_WIN64)
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
/* C array of file 'Px437_IBM_VGA_9x8.ttf' */
#ifndef _H_FONT_DATA_H
#define _H_FONT_DATA_H
extern const unsigned char debug_font_data[];
extern const unsigned int debug_font_len;
#endif // _H_FONT_DATA_H

View file

@ -1,12 +1,13 @@
#ifndef _H_DEBUGDRAW_H
#define _H_DEBUGDRAW_H
#include <glad/glad.h>
#include <thirdparty/glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <utility/ftfont.h>
#include <iostream>
#include <vector>
#include <memory>
struct ShaderSource {
const char* vertexShader;

View file

@ -4,13 +4,19 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include <thirdparty/glad/glad.h>
#include <filesystem>
#include <format>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <map>
#include <mutex>
#include <unordered_map>
#define DEBUG_TEXT(pos_vec2, col_vec4, scale, text, ...) DebugText::getInstance()->DrawDebugText(pos_vec2, col_vec4, scale, text, __VA_ARGS__)
class Text {
private:
protected:
struct Font {
struct Character {
unsigned int TextureID;
@ -25,15 +31,11 @@ private:
unsigned int programID = 0;
unsigned int VAO = 0, VBO = 0;
unsigned int colorPos = 0;
unsigned int projPos = 0;
glm::mat4 projMatrix = glm::mat4(1.f);
public:
Text();
bool loadFonts(const std::string& font_folder);
void setProjectionMatrix(const glm::mat4& proj) { projMatrix = proj; }
void DrawText(
const std::string& fontName,
const std::string& text,
@ -48,6 +50,45 @@ public:
float scale,
const glm::vec4& color = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)
);
~Text() { };
};
class DebugText : public Text {
public:
static DebugText* getInstance();
bool loadFonts(const std::string &font_folder) = delete;
DebugText(DebugText const&) = delete;
void operator=(DebugText const&) = delete;
template<typename... Args>
void DrawDebugText(const glm::vec2& pos,
const glm::vec4& color,
const float scale,
const std::string& text,
Args... args)
{
DrawText(pos, color, scale, formatString(text, args...));
}
private:
static std::mutex mutex;
static DebugText *instance;
Font font;
DebugText();
void loadDebugFont();
~DebugText();
template <typename... Args>
std::string formatString(const std::string& str, Args... args) const
{
return std::vformat(str, std::make_format_args(args...));
}
void DrawText(const glm::vec2& pos,
const glm::vec4& color,
const float scale,
const std::string& text);
};
#endif // _H_FTFONT_H

View file

@ -4,13 +4,6 @@
#include "utility/raycaster.h"
#include "utility/script.h"
#if _DEBUG
#else
#include <tracy/Tracy.hpp>
#endif
AI::AI(const std::shared_ptr<GameActor>& actor, const std::shared_ptr<Raycaster>& raycaster)
: state(AIState::Idle), raycaster(raycaster), actor(actor),
lastGCTime(std::chrono::high_resolution_clock::now()), GCTimeout(3)

View file

@ -1,5 +1,4 @@
#include "gameplay/entity.h"
#include "gameplay/camera.h"
#include "gameplay/physics.h"
void Entity::setPosition(const glm::vec3& position)
@ -40,9 +39,9 @@ void Entity::addPhysicsComponent(const std::shared_ptr<PhysicsComponent>& physic
void Entity::update(double deltaTime)
{
if (physics && physics->rigidBody.velocity != glm::vec3(0.0f))
if (physics && physics->rigidBody.velocity != glm::vec2(0.0f))
{
position = physics->rigidBody.position;
position = glm::vec3(physics->rigidBody.position, 0.f);
updateModelMatrix();
deltaPosition = glm::vec3(0.0f);
}
@ -63,6 +62,7 @@ void Entity::draw()
void Entity::updateModelMatrix()
{
position.z = 0.f;
glm::mat4 rotationMat = (isRotatable) ? glm::rotate(glm::mat4(1.f), glm::radians(rotation), glm::vec3(0.0f, 0.0f, 1.0f)) : glm::mat4(1.0f);
glm::mat4 translation = glm::translate(glm::mat4(1.f), position);
modelMatrix =

View file

@ -13,7 +13,6 @@
#include "graphics/glwindow.h"
#include <iostream>
#include <glm/gtc/matrix_transform.hpp>
#include <memory>
#include <utility/events.h>
@ -26,7 +25,7 @@ bool Game::init()
ERROR_LOG("Failed to init GLWindow: {}", SDL_GetError());
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
ERROR_LOG("Failed to load GLLoader");
ERROR_LOG("Failed to load GLLoader", NULL);
#if _DEBUG
LOG_LEVEL(DEBUG);
@ -36,6 +35,7 @@ bool Game::init()
SDL_GL_SetSwapInterval(1);
glViewport(0, 0, window->width(), window->height());
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -58,7 +58,6 @@ bool Game::init()
textHandler = std::make_shared<Text>();
if (!textHandler->loadFonts("fonts"))
return false;
textHandler->setProjectionMatrix(glm::ortho(0.f, static_cast<float>(window->width()), 0.f, static_cast<float>(window->height())));
return true;
}

View file

@ -29,6 +29,7 @@ std::shared_ptr<PhysicsComponent> PhysicsEngine::createObject(const unsigned int
auto component = std::make_shared <PhysicsComponent>();
component->ID = ID;
component->rigidBody.position = pos;
component->rigidBody.acceleration = glm::vec2(0.f);
component->rigidBody.mass = mass;
component->collider.shape = shape;
component->collider.dimensions = dimensions;
@ -56,7 +57,7 @@ void PhysicsEngine::removeObject(const std::shared_ptr<PhysicsComponent>& compon
objects.erase(std::remove(objects.begin(), objects.end(), component));
}
int PhysicsEngine::getTileCollider(const glm::vec3& position)
int PhysicsEngine::getTileCollider(const glm::vec2& position)
{
int x = static_cast<int>((position.x + 0.5f * tileSize) / tileSize);
int y = static_cast<int>((position.y + 0.5f * tileSize) / tileSize);
@ -97,13 +98,13 @@ void PhysicsEngine::resolvePossibleCollisions()
{
// Solve for two circles, we'll need to expand upon this for different colliders...
float sumOfRadius = objs.first->collider.dimensions.x + objs.second->collider.dimensions.x;
glm::vec3 objFirstCenter = objs.first->rigidBody.position + objs.first->collider.offset;
glm::vec3 objSecondCenter = objs.second->rigidBody.position + objs.second->collider.offset;
glm::vec3 distance = objFirstCenter - objSecondCenter;
glm::vec2 objFirstCenter = objs.first->rigidBody.position + objs.first->collider.offset;
glm::vec2 objSecondCenter = objs.second->rigidBody.position + objs.second->collider.offset;
glm::vec2 distance = objFirstCenter - objSecondCenter;
if (glm::length(distance) < sumOfRadius)
{
// We got impact!
glm::vec3 normal = distance / glm::length(distance);
glm::vec2 normal = distance / glm::length(distance);
// That impact is a bullet hitting a gameactor!
if ((objs.first->isBullet || objs.second->isBullet) && !(objs.first->isBullet && objs.second->isBullet))
{
@ -116,8 +117,8 @@ void PhysicsEngine::resolvePossibleCollisions()
}
// Apply impulse force
float penetrationDepth = sumOfRadius - glm::length(distance);
glm::vec3 correctionVector = normal * (penetrationDepth / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass)));
glm::vec3 vrel = objs.first->rigidBody.velocity - objs.second->rigidBody.velocity;
glm::vec2 correctionVector = normal * (penetrationDepth / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass)));
glm::vec2 vrel = objs.first->rigidBody.velocity - objs.second->rigidBody.velocity;
// smallest elasticity of the two colliders
float e = std::min(objs.first->rigidBody.elasticity, objs.second->rigidBody.elasticity);
@ -137,11 +138,11 @@ void PhysicsEngine::resolveWorldCollision(const std::shared_ptr<PhysicsComponent
{
case PhysicsComponent::Collider::Shape::Circle:
float radius = obj->collider.dimensions.x;
glm::vec3 position = obj->rigidBody.position + obj->collider.offset;
int topTile = getTileCollider(position - glm::vec3(0, radius, 0));
int bottomTile = getTileCollider(position + glm::vec3(0, radius, 0));
int leftTile = getTileCollider(position - glm::vec3(radius, 0, 0));
int rightTile = getTileCollider(position + glm::vec3(radius, 0, 0));
glm::vec2 position = obj->rigidBody.position + obj->collider.offset;
int topTile = getTileCollider(position - glm::vec2(0, radius));
int bottomTile = getTileCollider(position + glm::vec2(0, radius));
int leftTile = getTileCollider(position - glm::vec2(radius, 0));
int rightTile = getTileCollider(position + glm::vec2(radius, 0));
if (obj->isBullet)
{
if (topTile || bottomTile || leftTile || rightTile)
@ -180,7 +181,7 @@ void PhysicsEngine::update(double deltaTime)
for (auto& obj : objects)
{
if (!obj) continue;
glm::vec3 frictionForce = obj->rigidBody.velocity * -0.1f;
glm::vec2 frictionForce = obj->rigidBody.velocity * -0.1f;
if (std::abs(obj->rigidBody.acceleration.x) == std::abs(obj->rigidBody.acceleration.y))
{
obj->rigidBody.acceleration.x *= 0.75f;
@ -197,13 +198,16 @@ void PhysicsEngine::update(double deltaTime)
// Move at maxspeed
obj->rigidBody.velocity = glm::normalize(obj->rigidBody.velocity) * maxSpeed;
}
obj->rigidBody.acceleration = glm::vec3(0.f);
if (obj->collider.dimensions != glm::vec3(0.f))
obj->rigidBody.acceleration = glm::vec2(0.f);
if (obj->collider.dimensions != glm::vec2(0.f))
{
// check map collisions
resolveWorldCollision(obj);
}
obj->rigidBody.position += obj->rigidBody.velocity * static_cast<float>(deltaTime);
// Make sure we keep our Z at 0.f, a better choice would be to remove the need for vec3 all together!
// TODO: REMOVE VEC3 NO NEED FOR Z COODINATE!
// obj->rigidBody.position.z = 0.f;
}
getPossibleCollisions();
if (!objCollisions.empty())

View file

@ -11,6 +11,7 @@
#include "graphics/animation.h"
#include "utility/component.h"
#include "utility/ftfont.h"
#include "utility/xmlloader.h"
#include "utility/resourcemanager.h"
#include "utility/events.h"
@ -18,7 +19,6 @@
#include "utility/debugdraw.h"
#include <memory>
#include <tracy/Tracy.hpp>
#include <execution>
@ -118,6 +118,7 @@ void Scene::loadDebugShooterScene()
}
}
entities.emplace(entity->getEntityID(), entity);
SDL_Delay(1); // This is to make sure each entity gets a unique ID
}
physicsEngine->loadCollisionMap(map->getCollisionMap(), mapData->tileSize);
@ -132,10 +133,6 @@ std::shared_ptr<GameActor> Scene::getPlayer() const
void Scene::update(double deltaTime)
{
#if _DEBUG
#else
ZoneScoped;
#endif
for (const auto& [id, e] : entities)
{
@ -149,10 +146,6 @@ void Scene::update(double deltaTime)
void Scene::render(std::shared_ptr<Renderer> renderer)
{
#if _DEBUG
#else
ZoneScoped;
#endif
renderer->clear();
renderer->setProjAndViewMatrix(camera->getProjectionMatrix(), camera->getViewMatrix());
@ -171,6 +164,36 @@ void Scene::render(std::shared_ptr<Renderer> renderer)
}
renderer->render();
for (const auto& bullet : player->getHeldWeapon()->getBulletManager()->getBullets()) {
DebugDrawer::getInstance().addLine(player->getCenter(), bullet->getCenter(), glm::vec4(1.f, 0.f, 0.f, 0.f));
DEBUG_TEXT(
glm::vec3(camera.get()->worldToLocal(bullet->getCenter()).x,
camera.get()->worldToLocal(bullet->getCenter()).y, 0.f),
glm::vec4(1.f, 0.f, 0.f, 1.f),
0.2f,
"( {}, {}, {} )",
bullet->getCenter().x,
bullet->getCenter().y,
bullet->getCenter().z
);
DEBUG_TEXT(
glm::vec3(camera.get()->worldToLocal(bullet->getCenter()).x,
camera.get()->worldToLocal(bullet->getCenter()).y + 10.f, 0.f),
glm::vec4(1.f, 1.f, 0.f, 1.f),
0.2f,
"( {}, {} )",
bullet->getPhysicsComponent()->rigidBody.position.x,
bullet->getPhysicsComponent()->rigidBody.position.y
);
DEBUG_TEXT(
glm::vec3(camera.get()->worldToLocal(bullet->getCenter()).x,
camera.get()->worldToLocal(bullet->getCenter()).y + 20.f, 0.f),
glm::vec4(0.f, 1.f, 1.f, 1.f),
0.2f,
"( {}, {} )",
bullet->getPhysicsComponent()->rigidBody.velocity.x,
bullet->getPhysicsComponent()->rigidBody.velocity.y);
}
DebugDrawer::getInstance().draw(camera->getProjectionMatrix() * camera->getViewMatrix());
}

View file

@ -1,6 +1,8 @@
#include "gameplay/weapons/bullet.h"
#include "utility/component.h"
#include "utility/logger.h"
void Bullet::addComponent(Component* component)
{
components.push_back(component);
@ -12,6 +14,8 @@ void Bullet::update(double deltaTime)
deltaPosition.x += direction.x * bulletSpeed;
deltaPosition.y += direction.y * bulletSpeed;
//LOG(INFO, "( {}, {}, {} )", deltaPosition.x, deltaPosition.y, deltaPosition.z);
//physics->rigidBody.position = position;
for (auto& component : components)

View file

@ -53,7 +53,7 @@ void BulletManager::update(double deltaTime)
{
if (!bullet) continue;
bullet->update(deltaTime);
float distance = glm::distance(bullet->getPhysicsComponent()->rigidBody.position, bullet->getBulletOrigin());
float distance = glm::distance(glm::vec3(bullet->getPhysicsComponent()->rigidBody.position, 0.f), bullet->getBulletOrigin());
if (distance > bullet->getBulletDrop() || glm::length(bullet->getPhysicsComponent()->rigidBody.velocity) < 100.0f)
{
if (auto event = eventManager.lock())

View file

@ -142,7 +142,7 @@ void Weapon::attachScript(const std::shared_ptr<WeaponScript>& script)
{
weaponScript = script;
weaponScript->lua["weapon"] = shared_from_this();
LOG(DEBUG, "Weapon state bound");
LOG(DEBUG, "Weapon state bound", NULL);
}
void Weapon::onHitCallback(GameActor* target, PhysicsComponent* bullet, const glm::vec2& normal)
@ -226,10 +226,11 @@ Weapon::BulletData Weapon::genBulletData()
{
BulletData b;
float rotation = glm::radians(wielder->getRotation());
float spreadOffset = glm::radians(static_cast<float>(bulletSpread->genFloat()));
b.mass = 0.1f;
glm::vec2 facing = glm::vec2(
cos(rotation + glm::radians(static_cast<float>(bulletSpread->genFloat()))),
sin(rotation + glm::radians(static_cast<float>(bulletSpread->genFloat())))
cos(rotation + spreadOffset),
sin(rotation + spreadOffset)
);
b.direction = glm::normalize(facing);
b.sizeMod = bulletModifer->genFloat();
@ -255,7 +256,7 @@ void Weapon::createBullet(const Weapon::BulletData& data)
auto bullet = std::make_shared<Bullet>(wielder->getEntityID(), bulletShaderID, data.origin, data.direction, bulletSpeed, bulletDrop, bulletSize);
bullet->addComponent(bulletSprite.get());
bullet->addPhysicsComponent(std::make_shared<PhysicsComponent>(PhysicsComponentFactory::makeBullet(wielder->getEntityID(), data.origin, data.mass, bulletSize.x / 2)));
bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * glm::vec3(data.direction.x, data.direction.y, 0.f) / data.mass;
bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * data.direction / data.mass;
if (auto event = eventManager.lock())
event->notify(std::make_shared<BulletFiredEvent>(bullet));

View file

@ -1,9 +1,6 @@
#include "graphics/instancedraw.h"
#include "graphics/texture.h"
#include <glad/glad.h>
#include <iostream>
TileTextureInstance::TileTextureInstance(const char* texturePath)
{
texture = new Texture();

View file

@ -12,7 +12,7 @@ Postprocessor::Postprocessor(const std::shared_ptr<ResourceManager>& resourceMan
);
// TODO: ADD FALLBACK SHADER!
if (postProcessShader == nullptr) {
LOG(ERROR, "Failed to load post processing shader! 'shaders/GL_postprocess.*");
LOG(ERROR, "Failed to load post processing shader! 'shaders/GL_postprocess.*", NULL);
assert(postProcessShader != nullptr); // force crash
}
postProcessShader->use();
@ -21,9 +21,9 @@ Postprocessor::Postprocessor(const std::shared_ptr<ResourceManager>& resourceMan
unsigned int uboIndex = glGetUniformBlockIndex(postProcessShader->ID, "uPostProcess");
if (uboIndex == GL_INVALID_INDEX) {
LOG(ERROR, "Could not find 'uPostProcess'!");
LOG(ERROR, "Could not find 'uPostProcess'!", NULL);
}
unsigned int bindPoint = 0;
unsigned int bindPoint = 1;
glUniformBlockBinding(postProcessShader->ID, uboIndex, bindPoint);
glGenBuffers(1, &UBO);

View file

@ -5,18 +5,17 @@
#include "utility/events.h"
#include <algorithm>
#include <glm/gtc/type_ptr.hpp>
#include <graphics/postprocess.h>
#include <memory>
Renderer::Renderer(const std::shared_ptr<ResourceManager>& r)
: resourceManager(r)
{
projMat = glm::mat4(0.f);
viewMat = glm::mat4(0.f);
initFrameBuffers();
screenQuad = std::make_unique<ScreenQuad>();
postProcessor = std::make_unique<Postprocessor>(r);
initFrameBuffers();
initUniformBuffers();
screenQuad = std::make_unique<ScreenQuad>();
postProcessor = std::make_unique<Postprocessor>(r);
}
void Renderer::hookEventManager(std::weak_ptr<EventManager> eventManager)
@ -51,48 +50,62 @@ void Renderer::initFrameBuffers()
glBindTexture(GL_TEXTURE_2D, worldBuffer.texture);
// !!! NEED TO CREATE STATIC WINDOW SIZING !!!
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
//Attaching empty texture as color buffer for framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, worldBuffer.texture, 0);
//Attaching empty texture as color buffer for framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, worldBuffer.texture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG(ERROR, "Failed to complete world framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
assert(1 == 0); // force crash
}
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG(ERROR, "Failed to complete world framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
assert(1 == 0); // force crash
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// same thing is done for the hud texture
glBindFramebuffer(GL_FRAMEBUFFER, hudBuffer.frame);
// same thing is done for the hud texture
glBindFramebuffer(GL_FRAMEBUFFER, hudBuffer.frame);
glGenTextures(1, &hudBuffer.texture);
glBindTexture(GL_TEXTURE_2D, hudBuffer.texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &hudBuffer.texture);
glBindTexture(GL_TEXTURE_2D, hudBuffer.texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hudBuffer.texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hudBuffer.texture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG(ERROR, "Failed to complete hud framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
assert(1 == 0); // force crash
}
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG(ERROR, "Failed to complete hud framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
assert(1 == 0); // force crash
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Renderer::initUniformBuffers()
{
glGenBuffers(1, &uboMatrices);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboMatrices);
//glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));
}
void Renderer::setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view)
{
projMat = proj;
viewMat = view;
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(proj));
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void Renderer::addDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable)
@ -153,8 +166,10 @@ void Renderer::renderPool(auto& layerPool)
if (curShader) {
curShader->use();
/*
curShader->setMatrix4f("projection", glm::value_ptr(projMat));
curShader->setMatrix4f("view", glm::value_ptr(viewMat));
*/
} else {
LOG(ERROR, "Shader with ID {} not found!", curShaderID);
continue;

View file

@ -79,6 +79,8 @@ Shader::Shader(const char* vertexPath, const char* fragmentPath)
glDeleteShader(vertexid);
glDeleteShader(fragmentid);
glUniformBlockBinding(ID, glGetUniformBlockIndex(ID, "Matrices"), 0);
}
void Shader::setFloat(const std::string& name, float value)

View file

@ -2,9 +2,6 @@
#include "utility/logger.h"
#include "util.h"
#include <SDL_image.h>
#include <glad/glad.h>
bool Texture::loadTexture(const char* imagePath)
{
SDL_Surface* buffer = IMG_Load(imagePath);
@ -62,9 +59,9 @@ bool TextureArray::loadTextures(std::vector<const char*> imagePaths)
ERROR_LOG("Failed to load image file: {}", imagePaths[i]);
}
if (!adjustCanvasSizes(surfaces))
ERROR_LOG("Failed to adjust canvas size of images! \n Make sure to check that every tileset has square dimensions! (512x512, 756x756 ... etc)");
ERROR_LOG("Failed to adjust canvas size of images! \n Make sure to check that every tileset has square dimensions! (512x512, 756x756 ... etc)", NULL);
if (surfaces.empty())
ERROR_LOG("No surfaces created!");
ERROR_LOG("No surfaces created!", NULL);
numOfLayers = imagePaths.size();
glGenTextures(1, &ID);
@ -123,7 +120,7 @@ bool TextureArray::adjustCanvasSizes(std::vector<SDL_Surface*>& surfaces)
for (auto& surface : surfaces)
{
if (surface->w != surface->h)
ERROR_LOG("Image must be a square!");
ERROR_LOG("Image must be a square!", NULL);
if (surface->w > maxWidth) maxWidth = surface->w;
if (surface->h > maxHeight) maxHeight = surface->h;

View file

@ -1,9 +1,12 @@
#undef GLM_FORCE_FAST_MATH
#define GLM_FORCE_PURE
#define GLM_FORCE_CTOR_INIT
#define GLM_FORCE_COLUMN_MAJOR
#include <SDL.h>
#include <SDL_events.h>
#include <SDL_image.h>
#include <iostream>
#include <tracy/Tracy.hpp>
// TODO: Fix circular dependency issues, mostly with input.h needing gameactor.h and command.h
#include "gameplay/game.h"
@ -52,9 +55,8 @@ int main(int argc, char* args[])
game->handleInput(e);
game->update(deltaTime);
game->render();
game->update(deltaTime);
lastCounter = curCounter;
}

1140
YuppleMayham/src/thirdparty/glad.c vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,8 @@
#include "utility/ftfont.h"
#include "freetype/freetype.h"
#include "utility/logger.h"
#include "utility/data/font_data.h"
#include <glad/glad.h>
#include <glm/gtc/type_ptr.hpp>
Text::Text()
@ -9,12 +10,16 @@ Text::Text()
const char* vertexShader = R"(
#version 330 core
layout (location = 0) in vec4 vertex;
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
out vec2 texCoords;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
texCoords = vertex.zw;
gl_Position = projection * vec4(vertex.x, vertex.y, 0.0, 1.0);
texCoords = vec2(vertex.z, vertex.w);
}
)";
const char* fragShader = R"(
@ -42,7 +47,7 @@ Text::Text()
if (!success)
{
glGetShaderInfoLog(vertexID, 512, 0, log);
LOG(ERROR, "ERROR::COMPILER VERTEX SHADER FAILED TO COMPILE: {}", log);
LOG(ERROR, "FONT VERTEX SHADER FAILED TO COMPILE: {}", log);
return;
}
@ -54,7 +59,7 @@ Text::Text()
if (!success)
{
glGetShaderInfoLog(fragID, 512, NULL, log);
LOG(ERROR, "ERROR::COMPILER FRAGMENT SHADER FAILED TO COMPILE: {}", log);
LOG(ERROR, "FONT FRAGMENT SHADER FAILED TO COMPILE: {}", log);
return;
}
@ -72,7 +77,6 @@ Text::Text()
}
colorPos = glGetUniformLocation(programID, "textColor");
projPos = glGetUniformLocation(programID, "projection");
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
@ -86,13 +90,15 @@ Text::Text()
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUniformBlockBinding(programID, glGetUniformBlockIndex(programID, "Matrices"), 0);
}
bool Text::loadFonts(const std::string& font_folder)
{
FT_Library ft;
if (FT_Init_FreeType(&ft)) {
ERROR_LOG("ERROR::FREETYPE Failed to init freetype library");
ERROR_LOG("ERROR::FREETYPE Failed to init freetype library", NULL);
}
// load every font in the fonts folder then create corresponding textures for each character of each font.
std::filesystem::path folder(font_folder);
@ -168,10 +174,10 @@ void Text::DrawText(
}
float x = position.x;
float y = position.y;
float y = position.y + iterator->second.characters['A'].Bearing.y * scale;
glUseProgram(programID);
glUniformMatrix4fv(projPos, 1, GL_FALSE, glm::value_ptr(projMatrix));
//glUniformMatrix4fv(projPos, 1, GL_FALSE, glm::value_ptr(projMatrix));
glUniform4fv(colorPos, 1, glm::value_ptr(color));
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);
@ -182,19 +188,19 @@ void Text::DrawText(
Font::Character ch = iterator->second.characters[*c];
float xpos = x + ch.Bearing.x * scale;
float ypos = y - (ch.Size.y - ch.Bearing.y) * scale;
float ypos = y - (ch.Bearing.y) * scale;
float w = ch.Size.x * scale;
float h = ch.Size.y * scale;
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, 1.0f },
{ xpos, ypos, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 0.0f },
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos + w, ypos + h, 1.0f, 0.0f }
{ xpos, ypos + h, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 0.0f },
{ xpos + w, ypos + h, 1.0f, 1.0f }
};
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
@ -221,3 +227,129 @@ void Text::DrawTextOutline(
DrawText("comicbd.ttf", text, position, scale, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
DrawText(fontName, text, position, scale, color);
}
DebugText::DebugText() : Text()
{
loadDebugFont();
}
DebugText* DebugText::instance{ nullptr };
std::mutex DebugText::mutex;
DebugText* DebugText::getInstance()
{
std::lock_guard<std::mutex> lock(mutex);
if (instance == nullptr) {
instance = new DebugText();
}
return instance;
}
void DebugText::DrawText(const glm::vec2& pos,
const glm::vec4& color,
const float scale,
const std::string& text)
{
float x = pos.x;
float y = pos.y + font.characters['A'].Bearing.y * scale;
glUseProgram(programID);
glUniform4fv(colorPos, 1, glm::value_ptr(color));
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++)
{
Font::Character ch = font.characters[*c];
float xpos = x + ch.Bearing.x * scale;
float ypos = y - (ch.Bearing.y) * scale;
float w = ch.Size.x * scale;
float h = ch.Size.y * scale;
float vertices[6][4] = {
{ xpos, ypos + h, 0.0f, 1.0f },
{ xpos, ypos, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 0.0f },
{ xpos, ypos + h, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 0.0f },
{ xpos + w, ypos + h, 1.0f, 1.0f }
};
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (ch.Advance >> 6) * scale;
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
void DebugText::loadDebugFont()
{
FT_Library lib;
FT_Face face;
if (FT_Init_FreeType(&lib) != FT_Err_Ok) {
LOG(ERROR, "Failed to init freetype library!", NULL);
assert(1 == 0); // Force crash
}
if (FT_New_Memory_Face(lib, debug_font_data, debug_font_len, 0, &face) != FT_Err_Ok) {
LOG(ERROR, "Failed to load debug font face from memory!", NULL);
assert(1 == 0); // Force crash
}
FT_Set_Pixel_Sizes(face, 0, 40);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for (int c = 0; c < 250; c++) {
if (FT_Load_Char(face, c, FT_LOAD_RENDER) != FT_Err_Ok) {
LOG(WARN, "Failed to load char '{}'", (char)c);
continue;
}
unsigned 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);
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Font::Character ch = {
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)
};
font.characters.emplace(std::pair<char, Font::Character>((char)c, ch));
}
FT_Done_Face(face);
FT_Done_FreeType(lib);
}
DebugText::~DebugText()
{
for (auto ch : font.characters) {
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
glDeleteTextures(1, &ch.second.TextureID);
}
glDeleteProgram(programID);
}

View file

@ -41,7 +41,7 @@ bool XMLLoader::loadXmlScene(const char* xmlFile, SceneData* out)
out->id = id;
if (scene->QueryStringAttribute("bg", &bgFile) != tinyxml2::XML_SUCCESS)
LOG(WARN, "No background set! attribute 'bg' is empty");
LOG(WARN, "No background set! attribute 'bg' is empty", NULL);
else
out->bgFile = bgFile;
@ -406,7 +406,7 @@ bool XMLLoader::loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileDat
const char* tileType;
if (tileElement == NULL)
ERROR_LOG("Failed to find 'tile' tag.");
ERROR_LOG("Failed to find 'tile' tag.", NULL);
if (tileElement->QueryIntAttribute("id", &tileData.id) != tinyxml2::XML_SUCCESS ||
tileElement->QueryStringAttribute("type", &tileType) != tinyxml2::XML_SUCCESS)
ERROR_LOG("Failed to load tile id or type. {}", tileElement->Value());
@ -430,7 +430,7 @@ bool XMLLoader::loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileDat
tileData.objects.push_back(std::make_shared<TileSetData::TileData::ObjectData>(objData));
}
if (tileData.objects.empty())
ERROR_LOG("No objects found");
ERROR_LOG("No objects found", NULL);
}
else
{
@ -470,7 +470,7 @@ bool XMLLoader::loadObject(tinyxml2::XMLElement* objElement, TileSetData::TileDa
// avoid null pointer exception
if (objElement == NULL)
ERROR_LOG("Failed to find 'object' tag");
ERROR_LOG("Failed to find 'object' tag", NULL);
// load id and name
if (objElement->QueryIntAttribute("id", &objData.id) != tinyxml2::XML_SUCCESS ||
objElement->QueryStringAttribute("name", &objName) != tinyxml2::XML_SUCCESS)