Compare commits

...

118 Commits

Author SHA1 Message Date
1e4279f671 Move basic window functionality to a superclass. Makes it easier to share implementation with other concrete windows using GLFW 2022-02-24 19:04:27 -08:00
283ce10697 Move math library to separate project 2022-02-23 19:26:58 -08:00
96b409adc2 Move multipurpose files over to rexylib so I can reuse them in other codebases 2022-02-23 17:01:31 -08:00
8a0947e750 Rearrange the wip stuff again. I think combining shaders with vaos is a good idea since they seem to work together a lot. Plus I'm pretty sure that's sorta how vulkan works. 2022-02-23 16:34:26 -08:00
6e54ae74a7 Allow build on system without standard library concepts 2022-02-21 19:13:41 -08:00
46e8d73d22 Work on api agnostic shader interface 2022-02-21 18:52:39 -08:00
a15efd2ae7 Remove use of older renderer setup from play_state. Some functionality is lost, namely the color changing of the squares. This would require manually operating on the ogl::shader_program which I can't allow to happen in that context. An intermediary class must be created so that data in the shader can be manipulated render api agnostically. 2022-02-21 13:10:41 -08:00
f7c0b4a177 Remove need to know the shader type from pause_state. Moves rendering api dependance elsewhere 2022-02-20 18:47:15 -08:00
621bf0349a Rename egn::object_base to egn::object 2022-02-18 18:14:09 -08:00
f40559f543 Add explicit template instantiation for most common matrix, vector, and quaternion types 2022-02-18 18:11:17 -08:00
106c7009b5 Clean up some of the concept jank 2022-02-18 17:46:17 -08:00
3a2e1c27a4 Fix forgotten typenames in header. GCC didn't notice but clang did 2022-02-18 17:03:32 -08:00
ae068a8688 Playing with c++20 concepts 2022-02-18 16:57:27 -08:00
f2fa02336b Integrate some wip changes into pause_state 2022-02-18 16:57:14 -08:00
0cc6c7fff6 Add wip cleasses. Change coding standard to have 'void' in empty parameter lists. change instances of math::vecN<GLfloat> to math::vecNf 2022-02-17 05:13:33 -08:00
85d6acad11 Restructure directories 2022-02-10 16:56:01 -08:00
daa5f13a60 Remove files that were not being used anymore 2022-02-10 10:43:55 -08:00
d862fa5fc0 Removed all this random testing bs 2022-02-10 10:42:02 -08:00
06d3c3d9c7 Fix incorrect type in uniform 2022-02-06 13:37:42 -08:00
e0924c5895 I forgot to commit for a while so there's a lot in here.
Added ubo class template for handling Uniform Buffer Objects. This class automatically finds the offset and alignment for given data in a GLSL std140 uniform block. This makes it easy to just assign data through the gfx::ubo interface and bind that to the relevant shader_program's uniform block
Changed shader_program's method of handling uniforms to match more closely to how vao handles its attributes. That is to call  with the location as argument to get a proxy object on which to operate. I find this nicer to work with than having everything to do with uniforms in the shader_program class itself
Add a flat_camera class which just assigns the near and far plane to 0 and 1 respectively
Start work on a gui system which i'm really not confident about.
Attempting to rethink how renderers work, but also no really confident about where i'm going with it
Break out vbo_scoped_map into a more general scoped_buffer_map class so that vbo and ubo can utilize it
Remove old gl_buffers units that were not really being used since my change over to opengl DSA functions
Change the gfx::resource_manager to keep shared_ptr's in the container so the data can be more nicely shared
Add missing aliases in math::fwd_declare.hpp for boolean types
Change orthographic projection generator function to have the z values behave more in line with how opengl handles z depth. May have to undo this at some point but it seems to behave correctly now
Fix some rvalue related aspects of util::deferred
'
2022-02-04 13:49:22 -08:00
1b884a9a48 Update makefile 2022-01-26 19:03:03 -08:00
7622aa74a6 Fix memory leak and undefined behavior in stb_alloc.cpp 2022-01-26 17:46:14 -08:00
6f670b6cd9 Rendering some amount of text bby 2022-01-26 16:43:31 -08:00
fa15721c94 Work on text rendering. All just tinkering really 2022-01-20 17:03:00 -08:00
a8082b6885 Add some font test comments 2022-01-18 15:28:26 -08:00
da9b871626 Add ability to buffer data to the middle of a vbo 2022-01-18 15:28:10 -08:00
80cb7f9528 Add deferred_function for when you want to call something other than a constructor lazily 2022-01-18 15:27:47 -08:00
54014cf460 Update font atlas generator to make smaller textures 2022-01-18 15:27:04 -08:00
01a20905f4 Add convenience aliases to math classes 2022-01-18 15:26:14 -08:00
52808c3826 Change resource manager to be more closely tied to the opengl context instance rather than the game instance 2022-01-18 12:03:46 -08:00
6580fdd4d5 Add debug output on reset in play_state 2022-01-17 14:57:13 -08:00
512cd70145 Update makefile to actually work. Add reset button in play_state (r) 2022-01-17 13:58:39 -08:00
21137971ca Start work on figuring out interface between graphics and engine subsystems. I did this by creating a 'board_gfx' class that became a member of the 'board' class. This gfx member does all the graphics legwork for the type.
I also put all the tic-tac-toe specific files into 'ttt' subdirectories to make it easier to see what's specifically for this game and what's just a wip idea
2022-01-17 13:35:29 -08:00
5857c442aa Add geometry shader to the square_shader for tests. Add texture_base class to allow easier addition of the texture_array class. Finally got some level of instance rendering to work, even if it's not technically instanced. 2022-01-16 15:17:43 -08:00
a49d24d61e Add basic font atlas loading 2022-01-15 15:26:21 -08:00
1c4d5cd304 Add subimage to texture 2022-01-15 11:36:42 -08:00
913285e57a Make board tiles change color if they are hovered and clicked 2022-01-10 12:44:14 -08:00
46c22c6193 Add pause screen image 2022-01-10 10:35:33 -08:00
56e4599ea1 Add resource manager. Add tic tac toe board abstraction 2022-01-09 15:46:53 -08:00
9a16c6ca69 Merge branch 'rexy-graphics' of ssh://rexy712.chickenkiller.com:1995/var/git/repos/rexy712/our_dick into rexy-graphics 2021-08-01 13:27:37 -07:00
59b6cd65fd Fix wayland build and merge fixes from other project using audio 2021-08-01 13:27:13 -07:00
rexy712
2857345b87 Add line-line collision check 2021-01-17 16:26:33 -08:00
rexy712
835f190aa9 Add sphere-rectangle collision check 2021-01-13 10:21:15 -08:00
rexy712
73cf1e3f42 Add sphere-linesegment collision check 2021-01-13 10:17:57 -08:00
rexy712
e7bbfb4591 Add sphere-sphere collision check 2021-01-13 10:15:10 -08:00
rexy712
93cc1b4d02 Add sphere-point collision check 2021-01-13 10:13:19 -08:00
rexy712
5a22d09e47 Fix retard rectangle-point collision check 2021-01-12 14:32:51 -08:00
rexy712
de510b1f14 Fix rectangle-point collision checks in the cases where the point is only outside the coplanar rectangle on 1 primary axis. 2021-01-11 18:02:33 -08:00
rexy712
3946f9157c Add point-rectangle collision check 2021-01-11 16:38:10 -08:00
rexy712
bc7846b697 Clarify for myself how the line-point intersection check works 2021-01-05 13:38:55 -08:00
rexy712
34f4b22ad8 Change around collision related classes to allow for collision detection between classes without vtables given we know the dynamic type 2020-12-03 12:57:42 -08:00
rexy712
aea6fb5320 Change line-point intersection check to no longer be constrained to 3D space only 2020-12-02 15:34:05 -08:00
rexy712
fd282607ae Add epsilon tunable to collision checks. Add line-point collision check logic 2020-12-01 12:19:16 -08:00
rexy712
478b82582b Add collidable point 2020-11-30 14:07:35 -08:00
rexy712
32aabb472a Change some stuff about collision setup. Trying out double dispatch to make it easy to just call check_collision(a, b) with unknown dynamic type 2020-10-26 17:34:43 -07:00
rexy712
ffc584e56d Remove exceptions 2020-10-25 16:41:25 -07:00
rexy712
6a47a796b9 Change function naming in object class to better match the naming convention 2020-10-24 08:33:57 -07:00
rexy712
0959517d08 Work on bounding volumes 2020-10-18 10:00:55 -07:00
rexy712
05efb3c006 Remove aliased warning option 2020-10-18 10:00:21 -07:00
rexy712
b488d80dc9 Add converting constructors and assignment operators to math objects 2020-10-18 09:59:35 -07:00
rexy712
fc11e5dd0e Fix typo 2020-10-17 19:37:57 -07:00
rexy712
20b3a47aba Add a bunch more debug_print calls 2020-10-17 19:16:34 -07:00
rexy712
f66e20aa3d Working very unpolished tic-tac-toe game. 2020-10-11 12:36:05 -07:00
rexy712
60ab28d37a Change how window handles initial viewport setup. Add option to make context current upon window creation 2020-10-06 17:13:27 -07:00
rexy712
befab0f495 Remove unused render.cpp and render.hpp 2020-10-06 17:12:43 -07:00
rexy712
223dbc7006 Change how fbo's manage viewports since I misunderstood how glViewportIndexedf works 2020-10-06 17:11:49 -07:00
rexy712
b514cd2e87 Add some projection functions to math namespace. Break projection into their own header 2020-10-06 17:10:59 -07:00
rexy712
6fe392258b Make x and o images squares 2020-10-05 11:29:25 -07:00
rexy712
07a5f0a36f Add ortho camera function to set view bounding box. Add some debug printouts 2020-10-05 11:29:00 -07:00
rexy712
e44a577ff0 Make graphics interface more cohesive. Remove texture functionality that was broken, add more debug printouts and debug levels 2020-10-05 11:27:03 -07:00
rexy712
026b3c129a Fix matrix multiply working backwards 2020-10-05 11:25:10 -07:00
rexy712
a4e684beb5 Add fbo constructor that will bind existing textures/rbos in a single call 2020-10-02 06:56:39 -07:00
rexy712
9fea54d971 Remove annoying debug_print 2020-10-01 11:33:39 -07:00
rexy712
7874a6d4fd Layout rendering idea 2020-10-01 11:32:52 -07:00
rexy712
c914489eca Fix a lot of math inconsistencies and add missing functionality 2020-10-01 11:32:28 -07:00
rexy712
9c87c4399f Figure out how to resize a framebuffer (just fucking delete all attachments and rebuild them lol). Remove render_manager from main.cpp. Move game logic out of main to make it less cluttered. Remove unused audio functions from main.cpp. 2020-10-01 07:51:32 -07:00
rexy712
b2c8b0b3b5 Switch to true modern opengl (DSA) 2020-10-01 05:01:30 -07:00
rexy712
c45875c108 Change default opengl version to 4.5 to support dsa functions. Will start work on changing to using those new functions 2020-09-30 09:59:02 -07:00
rexy712
2d081fc7e1 Fix linking on non-linux posix systems 2020-09-29 13:55:44 -07:00
rexy712
5449357396 Add license disclaimers to all shared development source files 2020-09-29 13:55:17 -07:00
rexy712
cf33a851e4 Add better glfw debug error reporting 2020-09-29 10:35:02 -07:00
rexy712
8758be4379 push correct change to glfwinit 2020-09-29 07:23:02 -07:00
rexy712
f628a2845a Revert "Add debug printout to glfwInit"
This reverts commit 94718e4608b0a2499f4699f4330af64145e25749.
2020-09-29 07:19:42 -07:00
rexy712
94718e4608 Add debug printout to glfwInit 2020-09-29 07:13:08 -07:00
rexy712
317bf89ea0 fix inclusion of alsa header in non GNU/Linux systems 2020-09-29 03:44:43 -07:00
rexy712
b6aab8e832 Fix makefile libraries being in the wrong variable 2020-09-28 15:30:01 -07:00
rexy712
f44051baae Put default debug level back to 1 in makefile. 2020-09-28 15:27:47 -07:00
rexy712
dd993e6b60 Add scoped_buffer_bind class for RAII style binding of gl_buffer_managers. Also some renaming of 'gl_buffer' and 'buffer_iface' to more descriptive 'gl_buffer_manager' and 'buffer_accessor' 2020-09-28 15:26:43 -07:00
rexy712
b3c909a93a got framebuffer objects functional with texture and renderbuffer attachments 2020-09-27 16:50:17 -07:00
rexy712
fe31a9568f Add kinda hacky fbo and rbo 2020-09-27 13:53:45 -07:00
rexy712
ffa2b06ff2 Improve the debug output system so that it's controlled by the makefile. Also easier to check for debug enable in preprocessor. Add a debug_print_succ macro for outputting success messages 2020-09-27 09:32:58 -07:00
rexy712
78f664c2a5 fix build when using libc++ 2020-09-27 08:41:04 -07:00
rexy712
96de779f55 Change gl extension loader from gl3w to glad since gl3w was loading incorrect addresses and causing segfaults. Also add opengl context debugging output 2020-09-27 08:19:59 -07:00
rexy712
c13bf59949 Add camera class because I felt like it 2020-09-26 16:47:00 -07:00
rexy712
65e08c5464 Fix matrix multiply not returning anything lol 2020-09-26 16:46:39 -07:00
rexy712
41780c24f0 Fix quaternion access to matrix elements 2020-09-26 15:46:53 -07:00
rexy712
180922c6fc Rudimentary grid 2020-09-26 10:51:14 -07:00
rexy712
5787a362ca add long double matrix debug overload 2020-09-26 10:17:29 -07:00
rexy712
1f6de5ba70 Fix mat warnings and add debug printout functions 2020-09-26 09:50:58 -07:00
rexy712
2245e8cea1 Fix _rad and _deg literal operators not working 2020-09-26 09:27:34 -07:00
rexy712
38954946e8 Add shader uniform getters 2020-09-26 09:26:50 -07:00
rexy712
85fad726cc Remove unused global variable 2020-09-23 10:29:44 -07:00
rexy712
adde85b8f6 change 'graphics' namespace to 'gfx' and 'audio' namespace to 'sfx' to make it less cluttery and easier to type out 2020-09-23 10:28:26 -07:00
rexy712
d28201824b Make graphics::window initialize gl3w upon context creation 2020-09-23 10:19:37 -07:00
rexy712
868ab5225e Add option to colorize error/warning debug messages 2020-09-23 10:18:38 -07:00
rexy712
7503a2320d Add glfw global initialization 2020-09-23 09:27:18 -07:00
rexy712
fb692b80b4 Add RAII window class 2020-09-22 15:24:31 -07:00
rexy712
d0fc25d3c2 Add gay thread back into test program 2020-08-31 11:21:51 -07:00
rexy712
0eb54012dc Add example usage of the RAII opengl wrappers 2020-08-31 11:17:53 -07:00
rexy712
eb334a2a90 Add default framebuffer clearing to render.cpp 2020-08-31 11:17:37 -07:00
rexy712
089ab7539c Fix issues with vbos and binding. Also fix issue with multiple definition of explicit template specialization 2020-08-31 11:17:10 -07:00
rexy712
aad6db9b29 Add vao RAII class 2020-08-31 10:12:10 -07:00
rexy712
f6bc17f71b Add some more small clarification comments 2020-08-30 10:48:06 -07:00
rexy712
92be9fad8b Add some documentation comments 2020-08-30 10:33:23 -07:00
rexy712
74700fcf18 Add an untested vbo class and helpers 2020-08-30 09:41:26 -07:00
rexy712
dd57ac2c71 Fix some #include issues with stb and gl3w 2020-08-30 05:29:15 -07:00
rexy712
10cdd3b52b Merge branch 'master' into rexy-graphics 2020-08-29 13:08:21 -07:00
rexy712
36b45e6161 Add some graphics building blocks borrowed from old projects 2020-08-29 13:05:52 -07:00
153 changed files with 10316 additions and 2854 deletions

View File

@ -1,25 +0,0 @@
project(our_dick)
cmake_minimum_required(VERSION 3.0.2)
include(GNUInstallDirs)
set(INCLUDE_PATH ${CMAKE_SOURCE_DIR}/include)
include_directories(BEFORE SYSTEM "${INCLUDE_PATH}")
option(ENABLE_PROFILING "Enable asan" OFF)
option(BUILD_TESTS "Enable testing" OFF)
mark_as_advanced(ENABLE_PROFILING)
add_executable(main "src/main.cpp")
target_compile_options(main PRIVATE -Wall -Wextra -pedantic -std=c++17)
if(ENABLE_PROFILING)
target_compile_options(main PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
target_link_options(main PRIVATE -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls)
endif()
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
target_compile_options(main PRIVATE -Wall -Wextra -pedantic -std=c++17)

67
TODO Normal file
View File

@ -0,0 +1,67 @@
game
basically handles the game logic and delegates audio/video to respective management tools
track current state and updates state
calls renderers to draw the scene to framebuffer(s)
calls a mixer to play audio for a scene
key functions:
render()
update()
holds any scenes required for gameplay
holds window for game to be drawn in
scene
basically a central repository for raw data in a scene
holds cameras that exist in a given scene
holds objects that exist in a given scene
holds textures that exists for a given scene
holds audio that exists for a given scene
renderer
basically takes a scene and draws it a specific way to a framebuffer
key functions:
set_vpmatrix(mat4&)
set up view-projection matrix for use in rendering
render(scene&)
draw the given scene the this renderer's framebuffer
vertex
basically describes a vertex
holds position
holds texture coordinates
holds vertex color
holds normals
mesh
basically holds vertex data for a given shape
holds an array of vertices that describe a shape to draw
key functions:
render(shader&)
draw this mesh onto the currently bound framebuffer using the given shader
model
basically handles a collection of meshes that constitute a single entity
hold an array of meshes that describe the composition of a complex model
key functions:
render(shader&)
draw this model onto the currently bound framebuffer using the given shader
instance
basically holds handles to a mesh/model/any other needed data for use by multiple objects
renderable
basically any type with a render(shader_program&) function
hold an instance object reffing to a model
hold a model matrix
square
is a renderable that specifically references a square model

Binary file not shown.

BIN
assets/images/blank.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
assets/images/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
class diagram.dia Normal file

Binary file not shown.

View File

@ -29,7 +29,7 @@ must do's:
functions:
50 max length
comments max 2 lines
no void in parameter list: void func(){}
void in parameter list: void func(void){}
brace formatting:
namespace thing{

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -22,12 +22,9 @@
#include <cstdlib> //size_t
#include "mixdata.hpp"
#include "impl/channel.hpp"
namespace audio{
namespace impl{
class channel;
}
namespace sfx{
//needs to be thread safe, lock free, and avoid false sharing
class channel
@ -35,29 +32,43 @@ namespace audio{
private:
impl::channel* m_impl;
public:
using native_chunk = impl::channel::chunk;
public:
channel(impl::channel& c);
channel(const channel& c) = default;
channel(channel&& c) = default;
~channel() = default;
~channel(void) = default;
channel& operator=(const channel&) = default;
channel& operator=(channel&&) = default;
void resize_buffer(size_t newsize);
void play(const mixchunk& m);
void play(const mixdata& m);
template<size_t Size>
void play(const mixrawdata<Size>& m);
template<size_t Size>
bool try_play(const mixrawdata<Size>& m);
void pause();
void resume();
void stop();
void pause(void);
void resume(void);
void stop(void);
bool is_paused()const;
bool is_playing()const;
bool is_stopped()const;
bool is_paused(void)const;
bool is_playing(void)const;
bool is_stopped(void)const;
};
template<size_t Size>
void channel::play(const mixrawdata<Size>& m){
m_impl->play(m);
}
template<size_t Size>
bool channel::try_play(const mixrawdata<Size>& m){
return m_impl->try_play(m);
}
}
#endif

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -21,8 +21,9 @@
#include <tuple> //tuple, get
#include <utility> //forward, integer_sequence
#include <rexy/meta.hpp> //sequence_gen
namespace audio::detail{
namespace sfx::detail{
template<typename Func, typename... Args>
struct callback_helper{
Func&& m_f;
@ -30,7 +31,7 @@ namespace audio::detail{
template<int... Indices>
int operator()(const void* input, void* output, unsigned long frame_count,
unsigned long flags, std::integer_sequence<int,Indices...>)
unsigned long flags, rexy::sequence_tuple<Indices...>)
{
return std::forward<Func>(m_f)(input, output, frame_count, flags, std::get<Indices>(m_args)...);
}
@ -39,9 +40,9 @@ namespace audio::detail{
class callback_iface
{
public:
callback_iface() = default;
callback_iface(void) = default;
virtual ~callback_iface() = default;
virtual ~callback_iface(void) = default;
virtual int operator()(const void* input, void* output, unsigned long frame_count, unsigned long flags) = 0;
};
@ -55,7 +56,7 @@ namespace audio::detail{
callback_impl(Fn&& f, Ts&&... ts):
m_ch{std::forward<Fn>(f), {std::forward<Ts>(ts)...}}{}
int operator()(const void* input, void* output, unsigned long frame_count, unsigned long flags)override{
return m_ch(input, output, frame_count, flags, typename ::util::sequence_gen<sizeof...(Args)>::type{});
return m_ch(input, output, frame_count, flags, typename rexy::sequence_gen<sizeof...(Args)>::type{});
}
};
}

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -19,7 +19,7 @@
#ifndef OUR_DICK_AUDIO_ERROR_HPP
#define OUR_DICK_AUDIO_ERROR_HPP
namespace audio{
namespace sfx{
class error
{
@ -55,13 +55,13 @@ namespace audio{
error(int actual);
error(const error&) = default;
error(error&&) = default;
~error() = default;
~error(void) = default;
error& operator=(const error&) = default;
error& operator=(error&&) = default;
operator int()const;
int get()const;
int get_raw()const;
operator int(void)const;
int get(void)const;
int get_raw(void)const;
};
}

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -21,7 +21,7 @@
#include <portaudio.h>
namespace audio{
namespace sfx{
enum class frame_fmt{
float32 = paFloat32,

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -21,62 +21,95 @@
#include <atomic>
#include <cstdlib> //size_t
#include "util/ring_buffer.hpp"
#include <rexy/mpmc_queue.hpp>
#include "audio/mixdata.hpp"
namespace audio::impl{
namespace sfx::impl{
class channel
{
public:
static constexpr size_t chunk_size = 256;
using chunk = mixrawdata<chunk_size>;
private:
util::mpmc_ring_buffer<mixdata> m_data;
rexy::mpmc_queue<mixrawdata<chunk_size>> m_data;
std::atomic_bool m_paused;
std::atomic_bool m_active;
bool m_stopped;
//audio thread access only!
struct alignas(64){
mixdata data = {};
chunk data = {};
size_t offset = 0;
}m_playing_chunk;
public:
channel();
channel(void);
explicit channel(size_t maxsize);
channel(const channel& c);
channel(channel&& c);
~channel() = default;
~channel(void) = default;
channel& operator=(const channel& c);
channel& operator=(channel&& c);
mixdata pop();
bool try_pop(mixdata& m);
chunk pop(void);
bool try_pop(chunk& m);
void resize_buffer(size_t newsize);
void play(const mixdata& m);
template<size_t Size>
void play(const mixrawdata<Size>& m);
template<size_t Size>
bool try_play(const mixrawdata<Size>& m);
void pause();
void resume();
void stop();
void pause(void);
void resume(void);
void stop(void);
bool is_paused()const;
bool is_playing()const;
bool is_stopped()const;
bool is_paused(void)const;
bool is_playing(void)const;
bool is_stopped(void)const;
mixdata& playing_chunk();
const mixdata& playing_chunk()const;
size_t& playing_offset();
const size_t& playing_offset()const;
chunk& playing_chunk(void);
const chunk& playing_chunk(void)const;
size_t& playing_offset(void);
const size_t& playing_offset(void)const;
bool is_active()const;
bool is_active(void)const;
void set_active(bool b);
private:
void wait_for_consumer();
void wait_for_consumer(void);
};
template<size_t Size>
void channel::play(const mixrawdata<Size>& m){
if constexpr(Size > chunk_size){
size_t chunk_frames = chunk_size / m.channels;
for(size_t i = 0;i < m.frames;i += chunk_frames){
m_data.emplace(m, i);
}
}else{
m_data.emplace(m);
}
}
template<size_t Size>
bool channel::try_play(const mixrawdata<Size>& m){
if constexpr(Size > chunk_size){
size_t chunk_frames = chunk_size / m.channels;
for(size_t i = 0;i < m.frames;i += chunk_frames){
if(!m_data.try_emplace(m, i))
return false;
}
return true;
}else{
return m_data.try_emplace(m);
}
}
}
#endif

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -26,7 +26,7 @@
#include "channel.hpp"
#include "audio/stream.hpp"
namespace audio::impl{
namespace sfx::impl{
//channel reservation needs to be thread safe and lock free
class mixer
@ -41,38 +41,38 @@ namespace audio::impl{
//producer thread stuff
std::mutex m_copy_lock;
std::unique_lock<std::mutex> m_lk;
audio::stream m_output_sink;
sfx::stream m_output_sink;
public:
mixer(int output_channels, size_t channel_count, size_t samplerate);
mixer(const mixer&) = delete;
mixer(mixer&&) = delete;
~mixer();
~mixer(void);
void reserve_channels(size_t count);
std::vector<channel>& channels();
const std::vector<channel>& channels()const;
std::vector<channel>& channels(void);
const std::vector<channel>& channels(void)const;
channel& get_channel(size_t i);
const channel& get_channel(size_t i)const;
void lock();
void consumer_lock();
void unlock();
void consumer_unlock();
bool is_active()const;
void lock(void);
void consumer_lock(void);
void unlock(void);
void consumer_unlock(void);
bool is_active(void)const;
void set_active(bool b);
bool is_paused()const;
void pause();
void resume();
bool should_exit()const;
void exit();
size_t output_channels()const;
bool is_paused(void)const;
void pause(void);
void resume(void);
bool should_exit(void)const;
void exit(void);
size_t output_count(void)const;
size_t get_samplerate()const;
size_t channel_count()const;
size_t samplerate(void)const;
size_t channel_count(void)const;
private:
static int callback(const void* /*input*/, void* output, unsigned long frame_count, unsigned long flags, mixer& mix);
static int callback(const void* /*input*/, void* output, unsigned long frame_count, unsigned long flags, const stream_info&, mixer& mix);
};
}

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -19,16 +19,16 @@
#ifndef OUR_DICK_AUDIO_INIT_HPP
#define OUR_DICK_AUDIO_INIT_HPP
namespace audio{
namespace sfx{
class pa_system
{
private:
pa_system();
~pa_system();
pa_system(void);
~pa_system(void);
public:
static pa_system& instance();
static pa_system& instance(void);
};
}

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -20,49 +20,111 @@
#define OUR_DICK_AUDIO_MIXDATA_HPP
#include <cstdlib> //size_t
#include <cstring> //memcpy
#include <initializer_list>
#include <algorithm>
namespace audio{
#include <rexy/buffer.hpp>
struct mixdata {
float* data = nullptr;
namespace sfx{
template<size_t Size>
struct mixrawdata{
static constexpr size_t max_size = Size;
float data[Size];
size_t frames = 0;
size_t channels = 0;
size_t samplerate = 0;
float volume = 1;
bool allocated = true;
constexpr mixrawdata(void);
constexpr mixrawdata(std::initializer_list<float> l, size_t channels, size_t samplerate);
template<size_t Other>
mixrawdata(const mixrawdata<Other>&, size_t offset_frames = 0);
mixrawdata(const mixrawdata&);
~mixrawdata(void) = default;
mixrawdata& operator=(const mixrawdata&);
};
class mixchunk
{
private:
mixdata m_data;
rexy::buffer<float> m_buf;
size_t m_channels = 1;
size_t m_samplerate = 48000;
float m_volume = 1;
public:
constexpr mixchunk() = default;
constexpr mixchunk(void);
mixchunk(size_t frames, size_t channels, size_t samplerate);
mixchunk(const mixdata&);
mixchunk(mixdata&&);
mixchunk(const mixchunk&);
mixchunk(mixchunk&&);
~mixchunk();
~mixchunk(void) = default;
mixchunk& operator=(const mixchunk&);
mixchunk& operator=(mixchunk&&);
const float* data()const;
float* data();
const float* data(void)const;
float* data(void);
size_t floats()const;
size_t frames()const;
size_t channels()const;
size_t samplerate()const;
float volume()const;
size_t floats(void)const;
size_t frames(void)const;
size_t channels(void)const;
size_t samplerate(void)const;
float volume(void)const;
void set_samplerate(size_t s);
void set_volume(float v);
const mixdata& raw()const;
};
constexpr mixchunk::mixchunk(void):
m_buf(){}
template<size_t Size>
constexpr mixrawdata<Size>::mixrawdata(void){}
template<size_t Size>
constexpr mixrawdata<Size>::mixrawdata(std::initializer_list<float> l, size_t ch, size_t sr):
frames(l.size() / ch),
channels(ch),
samplerate(sr)
{
size_t i = 0;
for(auto it = l.begin();it != l.end();++it){
data[i++] = *it;
}
}
template<size_t Size>
template<size_t Other>
mixrawdata<Size>::mixrawdata(const mixrawdata<Other>& o, size_t offset_frames):
frames(std::min(Size / o.channels, o.frames - offset_frames)),
channels(o.channels),
samplerate(o.samplerate),
volume(o.volume)
{
memcpy(data, o.data + (offset_frames * o.channels), frames * channels * sizeof(float));
}
template<size_t Size>
mixrawdata<Size>::mixrawdata(const mixrawdata& m):
frames(m.frames),
channels(m.channels),
samplerate(m.samplerate),
volume(m.volume)
{
memcpy(data, m.data, m.frames * sizeof(float) * m.channels);
}
template<size_t Size>
mixrawdata<Size>& mixrawdata<Size>::operator=(const mixrawdata& m){
frames = m.frames;
channels = m.channels;
samplerate = m.samplerate;
volume = m.volume;
memcpy(data, m.data, m.frames * sizeof(float) * m.channels);
return *this;
}
}

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -22,7 +22,7 @@
#include <cstdlib> //size_t
#include "channel.hpp"
namespace audio{
namespace sfx{
namespace impl{
class mixer;
@ -41,24 +41,26 @@ namespace audio{
mixer(mode m, size_t channel_count, size_t samplerate = 48000);
mixer(const mixer&) = delete;
mixer(mixer&&) = delete;
~mixer();
~mixer(void);
mixer& operator=(const mixer&) = delete;
mixer& operator=(mixer&&) = delete;
void reserve_channels(size_t count);
channel get_channel(size_t index);
channel get_channel();
channel get_channel(void);
bool is_paused()const;
bool is_terminated()const;
bool is_paused(void)const;
bool is_terminated(void)const;
void pause();
void resume();
void terminate();
void pause(void);
void resume(void);
void terminate(void);
size_t get_samplerate()const;
size_t channel_count()const;
size_t samplerate(void)const;
size_t channel_count(void)const;
size_t output_count(void)const;
};
}

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -27,7 +27,7 @@
#include "error.hpp"
#include "mixdata.hpp"
namespace audio{
namespace sfx{
class sndrd
{
@ -63,9 +63,9 @@ namespace audio{
operator const SNDFILE*(void)const noexcept;
SNDFILE* get(void)noexcept;
const SNDFILE* get(void)const noexcept;
bool valid()const noexcept;
bool valid(void)const noexcept;
mixchunk read_all()noexcept;
mixchunk read_all(void)noexcept;
mixchunk read(size_t items)noexcept;
size_t read(float* dest, size_t items)noexcept;
mixchunk read_frames(size_t frames)noexcept;
@ -76,17 +76,17 @@ namespace audio{
size_t write_frames(const float* src, size_t frames)noexcept;
//TODO other formats
void close()noexcept;
void close(void)noexcept;
//getters
size_t frames()const noexcept;
int samplerate()const noexcept;
int channels()const noexcept;
int file_format()const noexcept;
int sections()const noexcept;
bool seekable()const noexcept;
size_t frames(void)const noexcept;
int samplerate(void)const noexcept;
int channels(void)const noexcept;
int file_format(void)const noexcept;
int sections(void)const noexcept;
bool seekable(void)const noexcept;
error last_error()const noexcept;
error last_error(void)const noexcept;
};
}

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -22,11 +22,12 @@
#include <utility> //forward
#include <portaudio.h>
#include "util/sequence.hpp"
#include "detail.hpp"
#include "error.hpp"
#include "stream_info.hpp"
#include <cstdlib>
namespace audio{
namespace sfx{
class stream
{
@ -34,9 +35,13 @@ namespace audio{
detail::callback_iface* m_cb = nullptr;
PaStream* m_stream = nullptr;
mutable PaError m_err = paNoError;
double m_samplerate;
int m_in_channels;
int m_out_channels;
stream_info m_info;
public:
enum state{
STOP = paComplete,
CONTINUE = paContinue,
};
public:
//buffersize of 0 means to automatically pick a good size
@ -44,39 +49,34 @@ namespace audio{
//TODO: allow choosing device by index
template<typename Callback, typename... Args>
stream(int in_c, int out_c, double samplerate, size_t buffersize, Callback&& cb, Args&&... cbargs):
m_cb(new detail::callback_impl<Callback,Args...>(std::forward<Callback>(cb), std::forward<Args>(cbargs)...)),
m_cb(new detail::callback_impl<Callback,const stream_info&, Args...>(std::forward<Callback>(cb), m_info, std::forward<Args>(cbargs)...)),
m_stream(initialize_global_instance()),
m_err(open_default_stream(&m_stream, in_c, out_c, paFloat32, samplerate, buffersize, m_cb)),
m_samplerate(samplerate),
m_in_channels(in_c),
m_out_channels(out_c){}
m_info{out_c, in_c, samplerate}{}
~stream();
~stream(void);
error start();
error stop();
error abort();
error close();
error start(void);
error stop(void);
error abort(void);
error close(void);
bool is_stopped()const;
bool is_active()const;
bool is_stopped(void)const;
bool is_active(void)const;
int input_count()const;
int output_count()const;
int input_count(void)const;
int output_count(void)const;
double get_samplerate()const;
double samplerate(void)const;
error last_error()const;
error last_error(void)const;
private:
static PaStream* initialize_global_instance();
static PaStream* initialize_global_instance(void);
//to avoid using portaudio functions in the header
static int open_default_stream(PaStream**, int in_c, int out_c,
long unsigned int fmt, double samplerate,
size_t bufsize, detail::callback_iface* cb);
static int callback(const void* input, void* output, unsigned long framecount,
const PaStreamCallbackTimeInfo* /*timeInfo*/, PaStreamCallbackFlags statusflags,
void* userdata);
};
}

View File

@ -0,0 +1,32 @@
/**
This file is a part of our_dick
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_AUDIO_STREAM_INFO_HPP
#define OUR_DICK_AUDIO_STREAM_INFO_HPP
namespace sfx{
struct stream_info{
int out_channels;
int in_channels;
double samplerate;
};
}
#endif

View File

@ -0,0 +1,46 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_BASIC_FRAMEBUFFER_HPP
#define OUR_DICK_BASIC_FRAMEBUFFER_HPP
#include "gfx/ogl/texture.hpp"
#include "gfx/ogl/rbo.hpp"
#include "gfx/ogl/fbo.hpp"
class basic_framebuffer : public gfx::ogl::fbo
{
private:
gfx::ogl::texture m_colorbuffer;
gfx::ogl::rbo m_depthbuffer;
public:
basic_framebuffer(int width, int height);
basic_framebuffer(basic_framebuffer&&) = default;
~basic_framebuffer(void) = default;
basic_framebuffer& operator=(basic_framebuffer&&) = default;
gfx::ogl::texture& colorbuffer(void);
const gfx::ogl::texture& colorbuffer(void)const;
gfx::ogl::rbo& depthbuffer(void);
const gfx::ogl::rbo& depthbuffer(void)const;
};
#endif

View File

@ -1,14 +1,39 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_CONFIG_HPP
#define OUR_DICK_CONFIG_HPP
//multiple levels just so i can stop alsa errors without stopping everything else
#define OUR_DICK_DEBUG 1
#ifdef OUR_DICK_DEBUG
#include <cstdio>
#define debug_print(...) fprintf(stderr, __VA_ARGS__)
#define OUR_DICK_ENABLE_DEBUG_OUTPUT_LEVEL OUR_DICK_DEBUG
#if OUR_DICK_DEBUG > 1
#define OUR_DICK_ENABLE_DEBUG_CONTEXT
#endif
#else
#define debug_print(...)
#define OUR_DICK_ENABLE_DEBUG_OUTPUT_LEVEL 0
#endif
//Debug output section
#define REXY_ENABLE_DEBUG_LEVEL OUR_DICK_ENABLE_DEBUG_OUTPUT_LEVEL
#define REXY_ENABLE_COLOR_DEBUG 1
#include <rexy/debug_print.hpp>
#endif

View File

@ -0,0 +1,81 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_BASE_TYPES_HPP
#define OUR_DICK_ENGINE_BASE_TYPES_HPP
#include <rml/vec.hpp>
namespace egn{
//Represent a 3D point
using point = rml::vec3f;
//Represent a line segment in 3D space given the end points
class line_segment
{
public:
point point1;
point point2;
};
//Represent a 2D rectangle in 3D space given the four corners
class rectangle
{
public:
point point1;
point point2;
point point3;
point point4;
};
//Axis aligned bounding box. Given the 2 opposite corners.
class aabb
{
public:
point point1 = {};
point point2 = {};
public:
aabb(void) = default;
aabb(const rml::vec3f& p1, const rml::vec3f& p2);
aabb(const aabb&) = default;
aabb(aabb&&) = default;
~aabb(void) = default;
aabb& operator=(const aabb&) = default;
aabb& operator=(aabb&&) = default;
};
//3D sphere represented using a point and radius
class sphere
{
public:
point point1 = {};
float radius = 0.0f;
public:
sphere(void) = default;
sphere(float r);
sphere(const sphere&) = default;
sphere(sphere&&) = default;
~sphere(void) = default;
sphere& operator=(const sphere&) = default;
sphere& operator=(sphere&&) = default;
};
}
#endif

119
include/egn/camera.hpp Normal file
View File

@ -0,0 +1,119 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_CAMERA_HPP
#define OUR_DICK_ENGINE_CAMERA_HPP
#include <rml/math.hpp>
#include "object.hpp"
namespace egn{
//Virtual base for camera types
//Provides general object functionality as well as projection and view matrices.
//Derived classes must provide method of recalculating the projection matrix.
class camera_iface : public object
{
protected:
enum update{
VIEW_UPDATE = 8,
PROJ_UPDATE = 16,
};
protected:
//mutable because they're only really a cached value representation of the data
//in position, orientation, near, far, etc
mutable rml::mat4f m_projection_matrix; //camera-to-sceen matrix
mutable rml::mat4f m_view_matrix; //world-to-camera matrix
float m_near = 1; //near clipping plane in camera space
float m_far = 100; //far clipping plane in camera space
public:
camera_iface(void) = default;
//Initialize with given projection matrix and clipping planes
camera_iface(const rml::mat4f& proj, float n, float f);
camera_iface(const camera_iface&) = default;
camera_iface(camera_iface&&) = default;
virtual ~camera_iface(void) = default;
camera_iface& operator=(const camera_iface&) = default;
camera_iface& operator=(camera_iface&&) = default;
//Set the camera's location and update relevant data structures
void set_position(const rml::vec3f& pos)override;
//Set the camera's facing angle and update relevant data structures
void set_orientation(const rml::quat_f& distance)override;
//getters
const rml::mat4f& get_projection_matrix(void)const;
const rml::mat4f& get_view_matrix(void)const;
float get_near_plane(void)const;
float get_far_plane(void)const;
//setters
void set_near_plane(float n);
void set_far_plane(float f);
//No control over matrices directly is done purposefully
protected:
void recalc_view_matrix(void)const;
virtual void recalc_projection_matrix(void)const = 0;
};
//Camera which performs an orthographic projection. Essentially camera will have no depth perspective
class ortho_camera : public camera_iface
{
protected:
float m_width, m_height; //width and height of the camera space box
public:
//Build camera with width, height, near, and far planes
ortho_camera(float w, float h, float n, float f);
ortho_camera(const ortho_camera&) = default;
ortho_camera(ortho_camera&&) = default;
~ortho_camera(void) = default;
ortho_camera& operator=(const ortho_camera&) = default;
ortho_camera& operator=(ortho_camera&&) = default;
//Getters
float get_projection_width(void)const;
float get_projection_height(void)const;
//Setters
void set_projection_width(float w);
void set_projection_height(float h);
void set_projection_box(float w, float h);
protected:
void recalc_projection_matrix(void)const override;
};
class flat_camera : public ortho_camera
{
public:
flat_camera(float w, float h);
flat_camera(const flat_camera&) = default;
flat_camera(flat_camera&&) = default;
~flat_camera(void) = default;
flat_camera& operator=(const flat_camera&) = default;
flat_camera& operator=(flat_camera&&) = default;
};
}
#endif

193
include/egn/collision.hpp Normal file
View File

@ -0,0 +1,193 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_COLLISION_HPP
#define OUR_DICK_ENGINE_COLLISION_HPP
#include "base_types.hpp"
namespace egn{
//How far away before a collision is considered to have occurred
static constexpr float default_collision_epsilon = 1.0e-10f;
class collidable_visitor;
//Anything which derives from this is considered collidable and must be comparible to any other collidable
class collidable_iface
{
public:
//Check if this and the other collidable have collided
virtual bool check_collision(const collidable_iface& c, float epsilon)const = 0;
virtual void accept_visitor(collidable_visitor& v)const = 0;
};
//CRTP collidable to allow the collision checks to determine the concrete type of the collidable
template<typename Derived>
class collidable : public collidable_iface
{
public:
bool check_collision(const collidable_iface& c, float epsilon = default_collision_epsilon)const override final;
private:
void accept_visitor(collidable_visitor& v)const override final;
};
namespace collision{
//Basic collidable objects
//A 1D point
class point : public egn::point, public collidable<point>
{
public:
using egn::point::point;
using egn::point::operator=;
};
//A 2D line
class line_segment : public egn::line_segment, public collidable<line_segment>{};
//A 2D rectangle
class rectangle : public egn::rectangle, public collidable<rectangle>{};
//A 3D bounding box
class aabb : public egn::aabb, public collidable<aabb>
{
public:
using egn::aabb::aabb;
using egn::aabb::operator=;
aabb(const egn::aabb& b);
aabb& operator=(const egn::aabb& b);
};
//A 3D sphere
class sphere : public egn::sphere, public collidable<sphere>
{
public:
using egn::sphere::sphere;
using egn::sphere::operator=;
sphere(const egn::sphere& b);
sphere& operator=(const egn::sphere& b);
};
}
//base class for collision visitor to provide polymorphic access to visitation functions
class collidable_visitor
{
public:
virtual void visit(const collision::aabb& a) = 0;
virtual void visit(const collision::sphere& a) = 0;
virtual void visit(const collision::line_segment& a) = 0;
virtual void visit(const collision::rectangle& a) = 0;
virtual void visit(const collision::point& p) = 0;
};
//Templated visitor to allow checking collision from polymorphic types
template<typename T>
class collision_visitor : public collidable_visitor
{
private:
const T& m_l;
float m_epsilon;
bool m_result = false;
public:
constexpr explicit collision_visitor(const T& l, float epsilon);
void visit(const collision::aabb& a)override;
void visit(const collision::sphere& a)override;
void visit(const collision::line_segment& a)override;
void visit(const collision::rectangle& a)override;
void visit(const collision::point& p)override;
constexpr bool result(void)const;
};
//Concrete collision detection that is eventually called
//bool check_collision(const collidable_iface& l, const collidable_iface& r, float epsilon = default_collision_epsilon);
bool check_collision(const aabb& l, const aabb& r, float epsilon = default_collision_epsilon);
bool check_collision(const aabb& l, const sphere& r, float epsilon = default_collision_epsilon);
bool check_collision(const aabb& l, const line_segment& r, float epsilon = default_collision_epsilon);
bool check_collision(const aabb& l, const rectangle& r, float epsilon = default_collision_epsilon);
bool check_collision(const aabb& l, const point& r, float epsilon = default_collision_epsilon);
bool check_collision(const sphere& l, const sphere& r, float epsilon = default_collision_epsilon);
bool check_collision(const sphere& l, const aabb& r, float epsilon = default_collision_epsilon);
bool check_collision(const sphere& l, const line_segment& r, float epsilon = default_collision_epsilon);
bool check_collision(const sphere& l, const rectangle& r, float epsilon = default_collision_epsilon);
bool check_collision(const sphere& l, const point& r, float epsilon = default_collision_epsilon);
bool check_collision(const line_segment& l, const line_segment& r, float epsilon = default_collision_epsilon);
bool check_collision(const line_segment& l, const aabb& r, float epsilon = default_collision_epsilon);
bool check_collision(const line_segment& l, const sphere& r, float epsilon = default_collision_epsilon);
bool check_collision(const line_segment& l, const rectangle& r, float epsilon = default_collision_epsilon);
bool check_collision(const line_segment& l, const point& r, float epsilon = default_collision_epsilon);
bool check_collision(const rectangle& l, const rectangle& r, float epsilon = default_collision_epsilon);
bool check_collision(const rectangle& l, const aabb& r, float epsilon = default_collision_epsilon);
bool check_collision(const rectangle& l, const sphere& r, float epsilon = default_collision_epsilon);
bool check_collision(const rectangle& l, const line_segment& r, float epsilon = default_collision_epsilon);
bool check_collision(const rectangle& l, const point& r, float epsilon = default_collision_epsilon);
bool check_collision(const point& l, const point& r, float epsilon = default_collision_epsilon);
bool check_collision(const point& l, const aabb& r, float epsilon = default_collision_epsilon);
bool check_collision(const point& l, const sphere& r, float epsilon = default_collision_epsilon);
bool check_collision(const point& l, const line_segment& r, float epsilon = default_collision_epsilon);
bool check_collision(const point& l, const rectangle& r, float epsilon = default_collision_epsilon);
//Check collision between this and c via a visitor
template<typename Derived>
bool collidable<Derived>::check_collision(const collidable_iface& c, float epsilon)const{
collision_visitor<Derived> vis(static_cast<const Derived&>(*this), epsilon); //Determine our true type for visitor
c.accept_visitor(vis); //have c give its true type to our visitor and check for collision
return vis.result();
}
template<typename Derived>
void collidable<Derived>::accept_visitor(collidable_visitor& v)const{
v.visit(static_cast<const Derived&>(*this)); //Give the visitor our true type to allow calling correct collision check function
}
template<typename T>
constexpr collision_visitor<T>::collision_visitor(const T& l, float epsilon):
m_l(l),
m_epsilon(epsilon){}
//Call correct concrete function for given collision
template<typename T>
void collision_visitor<T>::visit(const collision::aabb& a){
m_result = check_collision(m_l, a, m_epsilon);
}
template<typename T>
void collision_visitor<T>::visit(const collision::sphere& a){
m_result = check_collision(m_l, a, m_epsilon);
}
template<typename T>
void collision_visitor<T>::visit(const collision::line_segment& a){
m_result = check_collision(m_l, a, m_epsilon);
}
template<typename T>
void collision_visitor<T>::visit(const collision::rectangle& a){
m_result = check_collision(m_l, a, m_epsilon);
}
template<typename T>
void collision_visitor<T>::visit(const collision::point& a){
m_result = check_collision(m_l, a, m_epsilon);
}
template<typename T>
constexpr bool collision_visitor<T>::result(void)const{
return m_result;
}
}
#endif

162
include/egn/font.hpp Normal file
View File

@ -0,0 +1,162 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_FONT_HPP
#define OUR_DICK_ENGINE_FONT_HPP
#include <freetype2/ft2build.h>
#include FT_FREETYPE_H
#include <map>
#include <optional>
#include <utility> //pair
#include <memory>
#include <algorithm> //min, max
#include "gfx/ogl/texture.hpp"
#include "config.hpp"
namespace egn{
struct font_character{
rml::vec2<size_t> atlas_offset;
rml::vec2i size;
rml::vec2i bearing;
rml::vec2i advance;
rml::vec2f texture_coords[4];
public:
float aspect_ratio(void)const;
};
class font_atlas : public gfx::ogl::texture
{
public:
using map_type = std::map<int, font_character>;
private:
map_type m_atlas_data;
size_t m_requested_width, m_requested_height;
public:
font_atlas(gfx::ogl::texture&& t, map_type&& map, size_t w, size_t h);
font_atlas(const font_atlas&) = default;
font_atlas(font_atlas&&) = default;
~font_atlas(void) = default;
font_atlas& operator=(const font_atlas&) = default;
font_atlas& operator=(font_atlas&&) = default;
map_type& metadata(void);
const map_type& metadata(void)const;
map_type&& release_metadata(void);
font_character& operator[](int character);
rml::vec2<size_t> glyph_size(void)const;
};
class font
{
private:
static inline bool s_initialized = false;
static inline FT_Library s_ft;
private:
FT_Face m_face = nullptr;
int m_depth = 3;
public:
font(const char* file, int depth = 3);
~font(void);
template<class... Ts>
font_atlas generate_atlas(size_t glyph_w, size_t glyph_h, Ts&&... ranges);
std::optional<gfx::ogl::texture> generate_glyph(char character, int width, int height);
private:
using atlas_meta = std::tuple<size_t,size_t,size_t,size_t>;
template<class... Ts>
void generate_atlas_piece_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, rml::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range, Ts&&... ranges);
void generate_atlas_piece_impl_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, rml::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range);
template<class... Ts>
atlas_meta get_atlas_size_ranges_(Ts&&... ranges);
template<class... Ts>
void get_atlas_size_ranges_recurse_(size_t& avg_w, size_t& avg_h, size_t& mgw, size_t& mgh, size_t& count, const std::pair<int, int>& range, Ts&&... ranges);
void get_atlas_size_ranges_impl_(size_t& avg_w, size_t& avg_h, size_t& mgw, size_t& mgh, size_t& count, const std::pair<int, int>& range);
private:
static bool initialize_freetype_(void);
};
template<class... Ts>
void font::generate_atlas_piece_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, rml::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range, Ts&&... ranges){
generate_atlas_piece_impl_(atlas, metadata, target_pos, info, data_buffer, range);
if constexpr(sizeof...(ranges) > 0){
generate_atlas_piece_(atlas, metadata, target_pos, info, data_buffer, std::forward<Ts>(ranges)...);
}
}
template<class... Ts>
font_atlas font::generate_atlas(size_t glyph_w, size_t glyph_h, Ts&&... ranges){
rexy::debug::verbose::print("Generating font atlas for font '%s'\n", m_face->family_name);
FT_Set_Pixel_Sizes(m_face, glyph_w, glyph_h);
auto [atlas_width, atlas_height, max_glyph_width, max_glyph_height] = get_atlas_size_ranges_(std::forward<Ts>(ranges)...);
const auto format = (m_depth == 3) ? GL_RGB : GL_RED;
gfx::ogl::texture atlas(format, atlas_width, atlas_height, GL_UNSIGNED_BYTE, false);
font_atlas::map_type atlas_metadata;
rml::vec2<size_t> target_position = {0, 0};
std::unique_ptr<unsigned char[]> dest_data(new unsigned char[max_glyph_height * max_glyph_width * m_depth]);
generate_atlas_piece_(atlas, atlas_metadata, target_position, std::tuple{atlas_width, atlas_height, max_glyph_width, max_glyph_height}, dest_data.get(), std::forward<Ts>(ranges)...);
return {std::move(atlas), std::move(atlas_metadata), glyph_w, glyph_h};
}
template<class... Ts>
auto font::get_atlas_size_ranges_(Ts&&... ranges) -> atlas_meta{
size_t avg_width = 0;
size_t avg_height = 0;
size_t max_glyph_width = 0;
size_t max_glyph_height = 0;
size_t count = 0;
get_atlas_size_ranges_recurse_(avg_width, avg_height, max_glyph_width, max_glyph_height, count, std::forward<Ts>(ranges)...);
avg_width /= count;
avg_height /= count;
const size_t est_width = avg_width * (std::min(size_t{20}, count) + 1);
const size_t est_height = (max_glyph_height * (std::round(count / 20) + 1));
return {est_width / m_depth, est_height, max_glyph_width / m_depth, max_glyph_height};
}
template<class... Ts>
void font::get_atlas_size_ranges_recurse_(size_t& avg_w, size_t& avg_h, size_t& mgw, size_t& mgh, size_t& count, const std::pair<int, int>& range, Ts&&... ranges){
get_atlas_size_ranges_impl_(avg_w, avg_h, mgw, mgh, count, range);
if constexpr(sizeof...(ranges) > 0){
get_atlas_size_ranges_recurse_(avg_w, avg_h, mgw, mgh, count, std::forward<Ts>(ranges)...);
}
}
}
#endif

72
include/egn/game.hpp Normal file
View File

@ -0,0 +1,72 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_GAME_HPP
#define OUR_DICK_ENGINE_GAME_HPP
#include "observable.hpp"
#include "game_state.hpp"
#include "gfx/ogl/window.hpp"
#include "input.hpp"
#include <rml/vec.hpp>
#include "wip/renderer.hpp"
#include <queue>
namespace egn{
class game : public observer<game_state_event>
{
protected:
gfx::ogl::window m_window;
wip::gfx::renderer m_renderer;
game_state_manager m_states_manager;
std::queue<input_event> m_event_queue;
double m_last_time;
public:
game(int cver_maj, int cver_min, int width, int height, const char* title);
void update(void);
void render(void);
void mouse_button(int button, double xpos, double ypos, int action, int mods);
void mouse_move(double xpos, double ypos);
void keypress(int key, int action, int mods);
void resize(int width, int height);
rml::vec2<double> get_mouse_pos(void)const;
void on_notify(const game_state_event& e)override;
wip::gfx::renderer& renderer(void);
const wip::gfx::renderer& renderer(void)const;
void push_state(std::unique_ptr<game_state_iface>&&);
void pop_state(void);
int get_width(void)const;
int get_height(void)const;
private:
void setup_window_(void);
};
}
#endif

View File

@ -0,0 +1,91 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_GAME_STATE_HPP
#define OUR_DICK_ENGINE_GAME_STATE_HPP
#include "observable.hpp"
#include "input.hpp"
#include "wip/renderer.hpp"
#include <stack>
#include <memory>
#include <queue>
namespace egn{
class game;
struct game_state_event {
enum class state_type{
SHOULD_CLOSE,
RESIZE_WINDOW,
};
state_type type;
int value1;
int value2;
};
class game_state_iface;
class game_state_manager : public egn::observable<game_state_event>
{
private:
std::stack<std::unique_ptr<game_state_iface>> m_state_stack;
public:
template<typename... Args>
void emplace_state(Args&&... args);
void push_state(std::unique_ptr<game_state_iface>&& state);
void pop_state(void);
void replace_state(std::unique_ptr<game_state_iface>&& state);
void handle_input(std::queue<egn::input_event>& events);
void update(double time_diff);
void render(void);
};
class game_state_iface
{
protected:
game* m_owner = nullptr;
protected:
game_state_iface(game* owner);
game_state_iface(const game_state_iface& g) = default;
game_state_iface(game_state_iface&& g) = default;
game_state_iface& operator=(const game_state_iface&) = default;
game_state_iface& operator=(game_state_iface&&) = default;
wip::gfx::renderer& renderer(void);
const wip::gfx::renderer& renderer(void)const;
public:
virtual ~game_state_iface(void) = default;
virtual void enter(void) = 0;
virtual void leave(void) = 0;
virtual void handle_input(const egn::input_event& event) = 0;
virtual void update(double time) = 0;
virtual void render(void) = 0;
};
}
#endif

59
include/egn/image.hpp Normal file
View File

@ -0,0 +1,59 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_IMAGE_HPP
#define OUR_DICK_ENGINE_IMAGE_HPP
#include <string>
namespace egn{
//class handling image loading from files
class image
{
private:
int m_width;
int m_height;
int m_channels; //color channels
unsigned char* m_data;
public:
//read in image data from 'file', trying to load with 'req_chan' number of channels.
image(const char* file, bool flip = false, int req_chan = 0);
image(const image&);
image(image&&);
~image(void);
image& operator=(const image&);
image& operator=(image&&);
//check if m_data is a null pointer
operator bool(void)const;
bool valid(void)const;
int get_width(void)const;
int get_height(void)const;
int get_channels(void)const;
const unsigned char* data(void)const;
unsigned char* data(void);
};
}
#endif

42
include/egn/input.hpp Normal file
View File

@ -0,0 +1,42 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_INPUT_HPP
#define OUR_DICK_ENGINE_INPUT_HPP
namespace egn{
struct input_event {
enum class type{
KEY,
MOUSE_BUTTON,
SCROLL,
RESIZE,
MOUSE_MOVE,
};
type ev_type;
double time;
int key;
int action;
int mods;
double x, y;
};
}
#endif

78
include/egn/object.hpp Normal file
View File

@ -0,0 +1,78 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_OBJECT_HPP
#define OUR_DICK_ENGINE_OBJECT_HPP
#include <rml/math.hpp>
#include "base_types.hpp"
namespace egn{
class object
{
protected:
enum update{
NO_UPDATE,
SCALE_UPDATE = 1,
TRANSLATION_UPDATE = 2,
ROTATION_UPDATE = 4,
BOUNDING_VOLUME_UPDATE = 8,
};
protected:
rml::vec3f m_position; //track current positon in world space
rml::quat_f m_orientation; //track current model space rotation
rml::vec3f m_scale{1.0f, 1.0f, 1.0f}; //track model space scale
private:
mutable rml::mat4f m_model_matrix; //compile all the above info into a matrix
protected:
mutable int m_update_flag = NO_UPDATE; //whether or not to update the matrix upon access
//make the update flag protected so subclasses can share it
public:
object(void) = default;
explicit object(const rml::vec3f& position);
object(const rml::vec3f& position, const rml::quat_f& orientation);
object(const object&) = default;
object(object&&) = default;
virtual ~object(void) = default;
object& operator=(const object&) = default;
object& operator=(object&&) = default;
void translate(const rml::vec3f& distance);
void rotate(const rml::quat_f& distance);
void scale(const rml::vec3f& distance);
void look_at(const rml::vec3f& targ, const rml::vec3f& up);
virtual void set_position(const rml::vec3f& pos);
virtual void set_orientation(const rml::quat_f& orient);
virtual void set_scale(const rml::vec3f& scale);
const rml::mat4f& model_matrix(void)const;
const rml::vec3f& position(void)const;
const rml::vec3f& scale(void)const;
const rml::quat_f& orientation(void)const;
protected:
void recalc_model_matrix(void)const;
};
}
#endif

View File

@ -0,0 +1,73 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_OBSERVABLE_HPP
#define OUR_DICK_ENGINE_OBSERVABLE_HPP
#include <vector>
namespace egn{
template<typename Event>
class observable;
template<typename Event>
class observer
{
public:
using event_type = Event;
using event_ref = event_type&;
using const_event_ref = const event_type&;
using observed_type = observable<event_type>;
using observed_ref = observed_type&;
using const_observed_ref = const observed_type&;
using observed_pointer = observed_type*;
using const_observed_pointer = const observed_type*;
public:
virtual ~observer(void) = default;
virtual void on_notify(const_event_ref e) = 0;
};
template<typename Event>
class observable
{
public:
using event_type = Event;
using event_ref = event_type&;
using const_event_ref = const event_type&;
using observer_type = observer<event_type>;
using observer_ref = observer_type&;
using const_observer_ref = const observer_type&;
using observer_pointer = observer_type*;
using const_observer_pointer = const observer_type*;
private:
std::vector<observer_pointer> m_observers;
public:
void notify(const_event_ref e);
void add_observer(observer_ref o);
void remove_observer(observer_ref o);
};
}
#include "observable.tpp"
#endif

View File

@ -0,0 +1,46 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_OBSERVABLE_TPP
#define OUR_DICK_ENGINE_OBSERVABLE_TPP
namespace egn{
template<typename Event>
void observable<Event>::notify(const_event_ref e){
for(auto i = m_observers.begin();i != m_observers.end();++i){
(*i)->on_notify(e);
}
}
template<typename Event>
void observable<Event>::add_observer(observer_ref o){
m_observers.push_back(&o);
}
template<typename Event>
void observable<Event>::remove_observer(observer_ref o){
for(auto i = m_observers.begin();i != m_observers.end();++i){
if(*i == &o){
m_observers.erase(i);
break;
}
}
}
}
#endif

View File

@ -16,21 +16,16 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_SEQUENCE_HPP
#define OUR_DICK_SEQUENCE_HPP
#ifndef OUR_DICK_GRAPHICS_STB_ALLOC_HPP
#define OUR_DICK_GRAPHICS_STB_ALLOC_HPP
#include <utility> //integer_sequence
namespace util{
template<int I, int... Is>
struct sequence_gen{
using type = typename sequence_gen<I-1, Is..., sizeof...(Is)>::type;
};
template<int... Is>
struct sequence_gen<0,Is...>{
using type = std::integer_sequence<int,Is...>;
};
#include <cstdlib> //size_t
//allocation functions for use by stb_image
extern "C"{
void* our_dick_stb_malloc(size_t s);
void our_dick_stb_free(void* data);
void* our_dick_stb_realloc(void* data, size_t olds, size_t news);
}
#endif

View File

@ -0,0 +1,27 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_STB_INCLUDE_HPP
#define OUR_DICK_GRAPHICS_STB_INCLUDE_HPP
//this header makes sure you include the proper allocation functions and the library itself
#include "stb_alloc.hpp"
#include <stb/stb_image.h>
#endif

View File

@ -1,11 +0,0 @@
#ifndef OUR_DICK_GAME_STATE_HPP
#define OUR_DICK_GAME_STATE_HPP
#define TILE_COUNT 9
struct game_state {
int turn;
char board[TILE_COUNT];
};
#endif

View File

@ -0,0 +1,23 @@
/**
This file is a part of our_dick
Copyright (C) 2021 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace gfx::backend{
bool is_wayland_display(void);
}

40
include/gfx/glfw_init.hpp Normal file
View File

@ -0,0 +1,40 @@
/**
This file is a part of vulkan
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VULKAN_GRAPHICS_GLFW_SYSTEM_HPP
#define VULKAN_GRAPHICS_GLFW_SYSTEM_HPP
#include <mutex>
namespace gfx{
class glfw_system
{
private:
static inline std::mutex s_ref_lock;
static inline int s_ref_count;
static inline int s_status = false;
public:
glfw_system(void);
~glfw_system(void);
int status(void)const;
};
}
#endif

View File

@ -0,0 +1,136 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_BUFFER_MAP_HPP
#define OUR_DICK_GRAPHICS_OGL_BUFFER_MAP_HPP
#include "gl_include.hpp"
#include <cstdlib> //size_t, ptrdiff_t
namespace gfx::ogl{
namespace buffer{
//strongly typed enum for different mapping styles
enum class maptype : GLenum{
READ = GL_READ_ONLY,
WRITE = GL_WRITE_ONLY,
RW = GL_READ_WRITE,
};
//strongly typed enum for different usages
enum class usage : GLenum{
STATIC_DRAW = GL_STATIC_DRAW,
DYNAMIC_DRAW = GL_DYNAMIC_DRAW,
STREAM_DRAW = GL_STREAM_DRAW,
STATIC_READ = GL_STATIC_READ,
DYNAMIC_READ = GL_DYNAMIC_READ,
STREAM_READ = GL_STREAM_READ,
STATIC_COPY = GL_STATIC_COPY,
DYNAMIC_COPY = GL_DYNAMIC_COPY,
STREAM_COPY = GL_STREAM_COPY,
};
}
//RAII wrapper for mapping vbo's
template<typename T>
class scoped_buffer_map
{
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
private:
pointer m_data = nullptr; //pointer to the mapped region
GLuint m_buffer;
public:
//create a mapping for 'v' on 'targ' with map style 'm'
explicit scoped_buffer_map(GLuint bid, buffer::maptype m);
scoped_buffer_map(const scoped_buffer_map&) = delete;
scoped_buffer_map(scoped_buffer_map&&);
~scoped_buffer_map(void);
scoped_buffer_map& operator=(const scoped_buffer_map&) = delete;
scoped_buffer_map& operator=(scoped_buffer_map&&);
//size of the mapped region as reported by glGetBufferParameteriv
size_type length(void)const;
//release ownership of the mapping. unsafe
pointer release(void);
//direct access to the underlaying data region
operator pointer(void);
operator const_pointer(void)const;
pointer raw(void);
const_pointer raw(void)const;
bool valid(void)const;
//indexed access to the data region
reference operator[](size_type i);
const_reference operator[](size_type i)const;
};
//specialization for void pointers. The same in every way except no subscript operators
template<>
class scoped_buffer_map<void>
{
public:
using value_type = void;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = void;
using const_reference = void;
using pointer = void*;
using const_pointer = const void*;
private:
pointer m_data = nullptr;
GLuint m_buffer;
public:
explicit scoped_buffer_map(GLuint bid, buffer::maptype m);
scoped_buffer_map(const scoped_buffer_map&) = delete;
scoped_buffer_map(scoped_buffer_map&&);
~scoped_buffer_map(void);
scoped_buffer_map& operator=(const scoped_buffer_map&) = delete;
scoped_buffer_map& operator=(scoped_buffer_map&&);
size_type length(void)const;
pointer release(void);
operator pointer(void);
operator const_pointer(void)const;
pointer raw(void);
const_pointer raw(void)const;
bool valid(void)const;
};
}
#include "buffer_map.tpp"
#endif

View File

@ -0,0 +1,91 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_BUFFER_MAP_TPP
#define OUR_DICK_GRAPHICS_OGL_BUFFER_MAP_TPP
#include <utility> //exchange, swap
#include "gl_include.hpp"
namespace gfx::ogl{
template<typename T>
scoped_buffer_map<T>::scoped_buffer_map(GLuint bid, buffer::maptype m):
m_buffer(bid)
{
m_data = reinterpret_cast<pointer>(glMapNamedBuffer(m_buffer, static_cast<GLenum>(m)));
}
template<typename T>
scoped_buffer_map<T>::scoped_buffer_map(scoped_buffer_map&& m):
m_data(std::exchange(m.m_data, nullptr)),
m_buffer(std::exchange(m.m_buffer, 0)){}
template<typename T>
scoped_buffer_map<T>::~scoped_buffer_map(void){
if(m_data){
glUnmapNamedBuffer(m_buffer);
}
}
template<typename T>
scoped_buffer_map<T>& scoped_buffer_map<T>::operator=(scoped_buffer_map&& m){
std::swap(m_data, m.m_data);
std::swap(m_buffer, m.m_buffer);
return *this;
}
template<typename T>
auto scoped_buffer_map<T>::length(void)const -> size_type{
GLint64 retval;
glGetNamedBufferParameteri64v(m_buffer, GL_BUFFER_MAP_LENGTH, &retval);
return retval;
}
template<typename T>
auto scoped_buffer_map<T>::release(void) -> pointer{
m_buffer = 0;
return std::exchange(m_data, nullptr);
}
template<typename T>
scoped_buffer_map<T>::operator pointer(void){
return m_data;
}
template<typename T>
scoped_buffer_map<T>::operator const_pointer(void)const{
return m_data;
}
template<typename T>
auto scoped_buffer_map<T>::raw(void) -> pointer{
return m_data;
}
template<typename T>
auto scoped_buffer_map<T>::raw(void)const -> const_pointer{
return m_data;
}
template<typename T>
bool scoped_buffer_map<T>::valid(void)const{
return m_data;
}
template<typename T>
auto scoped_buffer_map<T>::operator[](size_type i) -> reference{
return m_data[i];
}
template<typename T>
auto scoped_buffer_map<T>::operator[](size_type i)const -> const_reference{
return m_data[i];
}
}
#endif

107
include/gfx/ogl/fbo.hpp Normal file
View File

@ -0,0 +1,107 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_FBO_HPP
#define OUR_DICK_GRAPHICS_OGL_FBO_HPP
#include "gl_include.hpp"
#include "texture.hpp"
#include "rbo.hpp"
#include <rml/vec.hpp>
#include "util/init_constants.hpp"
namespace gfx::ogl{
//Class representing a framebuffer object
class fbo
{
private:
GLuint m_buffer;
rml::vec4f m_vp_coords; //Opengl doesn't associate viewports with framebuffers, so i do
public:
//Construct an object representing the default 'root' framebuffer
fbo(void);
//build a framebuffer object with given attachments of textures or render buffers
template<typename... Args>
explicit fbo(Args&&... args);
explicit fbo(util::no_initialize_t);
fbo(const fbo&) = delete; //TODO
fbo(fbo&& f);
~fbo(void);
fbo& operator=(const fbo&) = delete;
fbo& operator=(fbo&& f);
//Direct access to opengl handle
GLuint raw(void)const;
//Remove attached textures or renderbuffers
bool detach(GLenum point);
//Add a new texture or renderbuffer attachment
bool attach(const texture& tex, GLenum point);
bool attach(const rbo& r, GLenum point);
//Clear individual fields
void clear_color_buffer(const rml::vec4f& color = {0.0f, 0.0f, 0.0f, 1.0f});
void clear_depth_buffer(GLfloat value = 1.0f);
void clear_stencil_buffer(GLint value = 0);
//Clear fields as by glClear
void clear(GLbitfield mask);
//Assign this framebuffer's viewport
void set_viewport(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
//Activate this framebuffer's viewport. Calls glViewport
void apply_viewport(void)const;
const rml::vec4f& get_viewport(void)const;
//Set this as the active framebuffer
bool bind(void)const;
private:
template<typename... Args>
void i_attach(const rbo& r, GLenum point, Args&&... args);
template<typename... Args>
void i_attach(const texture& r, GLenum point, Args&&... args);
};
template<typename... Args>
fbo::fbo(Args&&... args):
fbo()
{
i_attach(std::forward<Args>(args)...);
}
template<typename... Args>
void fbo::i_attach(const rbo& r, GLenum point, Args&&... args){
attach(r, point);
if constexpr(sizeof...(args) > 0){
i_attach(std::forward<Args>(args)...);
}
}
template<typename... Args>
void fbo::i_attach(const texture& t, GLenum point, Args&&... args){
attach(t, point);
if constexpr(sizeof...(args) > 0){
i_attach(std::forward<Args>(args)...);
}
}
}
#endif

View File

@ -0,0 +1,26 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//ensure proper inclusion order at all times
#ifndef OUR_DICK_GRAPHICS_OGL_GL_INCLUDE_HPP
#define OUR_DICK_GRAPHICS_OGL_GL_INCLUDE_HPP
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#endif

66
include/gfx/ogl/rbo.hpp Normal file
View File

@ -0,0 +1,66 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_RBO_HPP
#define OUR_DICK_GRAPHICS_OGL_RBO_HPP
#include "gl_include.hpp"
namespace gfx::ogl{
//Class representing a renderbuffer object
class rbo
{
private:
GLuint m_buffer;
GLenum m_format;
GLsizei m_width;
GLsizei m_height;
GLsizei m_samples;
public:
rbo(GLsizei width, GLsizei height, GLenum format, GLsizei samples = 0);
rbo(const rbo& r) = delete;
rbo(rbo&& r);
~rbo(void);
rbo& operator=(const rbo& r) = delete;
rbo& operator=(rbo&& r);
//Raw access to opengl handle
GLuint raw(void)const;
//Set this as the active renderbuffer
void bind(void)const;
//Reset to default renderbuffer binding
void unbind(void)const;
void resize(GLsizei w, GLsizei h);
void resize(GLsizei w, GLsizei h, GLenum format, GLsizei samples);
void reformat(GLenum format);
GLuint release(void);
GLsizei get_width(void)const;
GLsizei get_height(void)const;
};
}
#endif

View File

@ -0,0 +1,296 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_SHADER_PROGRAM_HPP
#define OUR_DICK_GRAPHICS_OGL_SHADER_PROGRAM_HPP
#include "gl_include.hpp"
#include "shader_stage.hpp"
#include "texture.hpp"
#include "ubo.hpp"
#include <utility> //forward
#include <string>
#include <rml/math.hpp>
namespace gfx::ogl{
class uniform
{
private:
GLuint m_shader_id;
GLint m_location;
public:
uniform(GLuint owner, const char* name);
uniform(GLuint owner, GLint location);
uniform(const uniform&) = default;
uniform(uniform&&) = default;
~uniform(void) = default;
uniform& operator=(const uniform&) = default;
uniform& operator=(uniform&&) = default;
GLenum get_type(void)const;
GLfloat get_float(void)const;
rml::vec2f get_vec2(void)const;
rml::vec3f get_vec3(void)const;
rml::vec4f get_vec4(void)const;
GLdouble get_double(void)const;
rml::vec2d get_dvec2(void)const;
rml::vec3d get_dvec3(void)const;
rml::vec4d get_dvec4(void)const;
GLint get_int(void)const;
rml::vec2i get_ivec2(void)const;
rml::vec3i get_ivec3(void)const;
rml::vec4i get_ivec4(void)const;
GLuint get_uint(void)const;
rml::vec2u get_uvec2(void)const;
rml::vec3u get_uvec3(void)const;
rml::vec4u get_uvec4(void)const;
GLboolean get_bool(void)const;
rml::vec2i get_bvec2(void)const;
rml::vec3i get_bvec3(void)const;
rml::vec4i get_bvec4(void)const;
rml::mat2f get_mat2(void)const;
rml::mat3f get_mat3(void)const;
rml::mat4f get_mat4(void)const;
rml::matrix<float,2,3> get_mat2x3(void)const;
rml::matrix<float,2,4> get_mat2x4(void)const;
rml::matrix<float,3,2> get_mat3x2(void)const;
rml::matrix<float,3,4> get_mat3x4(void)const;
rml::matrix<float,4,2> get_mat4x2(void)const;
rml::matrix<float,4,3> get_mat4x3(void)const;
rml::mat2d get_dmat2(void)const;
rml::mat3d get_dmat3(void)const;
rml::mat4d get_dmat4(void)const;
rml::matrix<double,2,3> get_dmat2x3(void)const;
rml::matrix<double,2,4> get_dmat2x4(void)const;
rml::matrix<double,3,2> get_dmat3x2(void)const;
rml::matrix<double,3,4> get_dmat3x4(void)const;
rml::matrix<double,4,2> get_dmat4x2(void)const;
rml::matrix<double,4,3> get_dmat4x3(void)const;
//float
void set(GLfloat);
void set(GLfloat, GLfloat);
void set(GLfloat, GLfloat, GLfloat);
void set(GLfloat, GLfloat, GLfloat, GLfloat);
//int
void set(GLint);
void set(GLint, GLint);
void set(GLint, GLint, GLint);
void set(GLint, GLint, GLint, GLint);
//unsigned int
void set(GLuint);
void set(GLuint, GLuint);
void set(GLuint, GLuint, GLuint);
void set(GLuint, GLuint, GLuint, GLuint);
//Texture
void set(const texture&, GLuint tex_unit = 0);
void set(const texture_array& t, GLuint tex_unit = 0);
//Float vectors
void set(const rml::vec2f&);
void set(const rml::vec3f&);
void set(const rml::vec4f&);
//Float vector array
void set(GLsizei count, const rml::vec2f*);
void set(GLsizei count, const rml::vec3f*);
void set(GLsizei count, const rml::vec4f*);
//Explicit float vectors
void set_1(GLsizei count, const GLfloat*);
void set_2(GLsizei count, const GLfloat*);
void set_3(GLsizei count, const GLfloat*);
void set_4(GLsizei count, const GLfloat*);
//Int vectors
void set(const rml::vec2i&);
void set(const rml::vec3i&);
void set(const rml::vec4i&);
//Int vector array
void set(GLsizei count, const rml::vec2i*);
void set(GLsizei count, const rml::vec3i*);
void set(GLsizei count, const rml::vec4i*);
//Explicit int vectors
void set_1(GLsizei count, const GLint*);
void set_2(GLsizei count, const GLint*);
void set_3(GLsizei count, const GLint*);
void set_4(GLsizei count, const GLint*);
//Unsigned int vectors
void set(const rml::vec2u&);
void set(const rml::vec3u&);
void set(const rml::vec4u&);
//Unsigned int vector array
void set(GLsizei count, const rml::vec2u*);
void set(GLsizei count, const rml::vec3u*);
void set(GLsizei count, const rml::vec4u*);
//Explicit unsigned int vectors
void set_1(GLsizei count, const GLuint*);
void set_2(GLsizei count, const GLuint*);
void set_3(GLsizei count, const GLuint*);
void set_4(GLsizei count, const GLuint*);
//Matrices
void set(const rml::mat2f&);
void set(const rml::mat3f&);
void set(const rml::mat4f&);
//Matrix array
void set(GLsizei count, const rml::mat2f*);
void set(GLsizei count, const rml::mat3f*);
void set(GLsizei count, const rml::mat4f*);
//Explicit matrices
void set_mat2(GLsizei count, const GLfloat*);
void set_mat3(GLsizei count, const GLfloat*);
void set_mat4(GLsizei count, const GLfloat*);
void set_mat2x3(GLsizei count, const GLfloat*);
void set_mat3x2(GLsizei count, const GLfloat*);
void set_mat2x4(GLsizei count, const GLfloat*);
void set_mat4x2(GLsizei count, const GLfloat*);
void set_mat3x4(GLsizei count, const GLfloat*);
void set_mat4x3(GLsizei count, const GLfloat*);
private:
GLint get_location_from_name_(const char* name);
};
class uniform_block
{
private:
GLuint m_shader_id;
GLuint m_index;
public:
uniform_block(GLuint owner, GLuint index);
uniform_block(GLuint owner, const char* name);
uniform_block(const uniform_block&) = default;
uniform_block(uniform_block&&) = default;
~uniform_block(void) = default;
uniform_block& operator=(const uniform_block&) = default;
uniform_block& operator=(uniform_block&&) = default;
void set_binding(size_t binding);
template<class... Types>
void set_binding(size_t binding, const ubo<Types...>& u);
private:
GLuint get_index_from_name_(const char* name);
};
//represents an opengl program (NOT a shader object)
class shader_program
{
private:
GLuint m_shader_id = 0; //handle to opengl program
public:
//create the program with no shaders attached
shader_program(void);
//create the program and attach 'args'... as shaders
template<class... Args>
shader_program(Args&&... args);
shader_program(const shader_program&) = delete;
shader_program(shader_program&&);
~shader_program(void);
shader_program& operator=(const shader_program&) = delete;
shader_program& operator=(shader_program&&);
//release ownership of the program handle. unsafe
GLuint release(void);
//attach a single shader to this program
void attach_shader(const shader_stage& s);
//attach many shaders to this program
template<class... Args>
void attach_shaders(const shader_stage& s, Args&&... args);
//attempt to link the program with the currently attached shaders. returns true on success
bool link(void);
//set this program as the currently active one in the gl context
void use(void);
//search for a uniform by name in this program
GLint get_uniform_loc(const char* u)const;
GLuint get_uniform_block_loc(const char* u)const;
//raw access to the program handle
GLuint raw(void)const;
//check if an error exists after a link attempt
bool has_link_error(void)const;
//get the most recently generated error from this program's infolog
std::string get_error(void)const;
uniform get_uniform(const char* name);
uniform get_uniform(int uloc);
GLenum get_uniform_type(const char* name)const;
GLenum get_uniform_type(int uloc)const;
uniform_block get_uniform_block(const char* name);
uniform_block get_uniform_block(unsigned int uloc);
};
template<class... Args>
shader_program::shader_program(Args&&... args):
shader_program()
{
attach_shaders(std::forward<Args>(args)...);
link();
}
template<class... Args>
void shader_program::attach_shaders(const shader_stage& s, Args&&... args){
attach_shader(s);
if constexpr(sizeof...(args) > 0){
attach_shaders(std::forward<Args>(args)...);
}
}
template<class... Types>
void uniform_block::set_binding(size_t binding, const ubo<Types...>& u){
u.bind(binding);
set_binding(binding);
}
}
#endif

View File

@ -0,0 +1,82 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_SHADER_STAGE_HPP
#define OUR_DICK_GRAPHICS_OGL_SHADER_STAGE_HPP
#include "gl_include.hpp"
#include <string>
namespace wip::gfx{
struct shader_source;
}
namespace gfx::ogl{
//class representing an opengl shader (NOT an opengl program)
class shader_stage
{
public:
//Strongly typed enum of possible shader types
enum class type : unsigned int{
FRAGMENT = GL_FRAGMENT_SHADER,
VERTEX = GL_VERTEX_SHADER,
GEOMETRY = GL_GEOMETRY_SHADER,
COMPUTE = GL_COMPUTE_SHADER,
TESS_CONTROL = GL_TESS_CONTROL_SHADER,
TESS_EVALUATION = GL_TESS_EVALUATION_SHADER,
};
private:
GLuint m_shader_id = 0; //handle to shader object
public:
//initialize this shader with the type 't' and add no source text
explicit shader_stage(type t);
//initialize this shader with the type 't' and load in 'data' as source text
shader_stage(const char* data, type t);
shader_stage(const wip::gfx::shader_source&);
shader_stage(const shader_stage&);
shader_stage(shader_stage&&);
~shader_stage(void);
shader_stage& operator=(const shader_stage&);
shader_stage& operator=(shader_stage&&);
//change the shader source to 'data' and recompile
bool load(const char* data);
//change the shader source and shader type then recompile
bool reload(const char* data, type t);
//release ownership of the shader handle. unsafe
GLuint release(void);
type get_type(void)const;
//raw access to shader handle
GLuint raw(void)const;
//get most recently generated error from this shader's infolog
std::string get_error(void)const;
//check if an error exists after a compilation attempt
bool has_compile_error(void)const;
};
}
#endif

208
include/gfx/ogl/texture.hpp Normal file
View File

@ -0,0 +1,208 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_TEXTURE_HPP
#define OUR_DICK_GRAPHICS_OGL_TEXTURE_HPP
#include "egn/image.hpp"
#include "gl_include.hpp"
#include <rml/vec.hpp>
namespace gfx::ogl{
//class representing an opengl 2D texture
class texture_base
{
public:
//all available wrapping styles as a strongly typed enum
enum class wrap : GLint{
CLAMP_EDGE = GL_CLAMP_TO_EDGE,
CLAMP_BORDER = GL_CLAMP_TO_BORDER,
MIRROR_REPEAT = GL_MIRRORED_REPEAT,
REPEAT = GL_REPEAT,
MIRROR_CLAMP_EDGE = GL_MIRROR_CLAMP_TO_EDGE,
};
//all available minfilter styles as a strongly typed enum
enum class minfilter : GLint{
NEAREST = GL_NEAREST,
LINEAR = GL_LINEAR,
NMIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
LMIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
NMIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
LMIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR,
};
//all available magfilter styles as a strongly typed enum
enum class magfilter : GLint{
NEAREST = GL_NEAREST,
LINEAR = GL_LINEAR,
};
protected:
GLuint m_tex_id = 0; //handle to texture object
GLsizei m_width = 0;
GLsizei m_height = 0;
GLenum m_format = 0;
GLenum m_type = GL_UNSIGNED_BYTE;
bool m_mipmapped = true;
texture_base(void) = default;
texture_base(GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap);
texture_base(const texture_base&);
texture_base(texture_base&&);
~texture_base(void);
texture_base& operator=(const texture_base&);
texture_base& operator=(texture_base&&);
public:
GLuint raw(void)const;
//change wrap mode for both x and y
void set_wrap_mode(wrap w);
void set_wrap_mode(wrap w, wrap h);
//change wrap mode for one direction
void set_wrap_x(wrap w);
void set_wrap_y(wrap h);
void set_border_color(GLfloat r, GLfloat g, GLfloat b, GLfloat a = 1.0f);
void set_filter(minfilter min, magfilter mag);
void set_mag_filter(magfilter m);
void set_min_filter(minfilter m);
magfilter get_mag_filter(void)const;
minfilter get_min_filter(void)const;
rml::vec4f get_border_color(void)const;
wrap get_wrap_x(void)const;
wrap get_wrap_y(void)const;
GLsizei get_width(void)const;
GLsizei get_height(void)const;
void enable_auto_mipmap(bool enable);
void generate_mipmap(void);
//release ownership of this texture object
GLuint release(void);
};
class texture : public texture_base
{
public:
//create the texture with no image data
texture(void);
texture(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap = true);
texture(GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap = true);
//create the texture with image data from 'i'
texture(const egn::image& i, bool mipmap = true);
texture(const texture&);
texture(texture&&);
~texture(void) = default;
texture& operator=(const texture&);
texture& operator=(texture&&);
//overwrite the current image data with 'i'
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type);
bool set_image(const egn::image& i);
bool set_subimage(const unsigned char* data, GLenum format, GLenum type,
GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h);
bool set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset);
//bind to target
void bind(GLuint target = GL_TEXTURE_2D)const;
//bind to given texture unit and load into given program uniform location
void bind_unit(GLuint tunit)const;
private:
bool create_texture_storage_(void);
};
class texture_array;
//Represents a single layer of a texture_array
class texture_slice
{
private:
texture_array* m_owner;
size_t m_level;
public:
texture_slice(texture_array* tex, int level);
texture_slice(const texture_slice&) = default;
texture_slice(texture_slice&&) = default;
~texture_slice(void) = default;
texture_slice& operator=(const texture_slice&) = default;
texture_slice& operator=(texture_slice&&) = default;
bool valid(void)const;
GLuint raw(void)const;
int get_level(void)const;
GLsizei get_width(void)const;
GLsizei get_height(void)const;
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type);
bool set_image(const egn::image& i);
bool set_subimage(const unsigned char* data, GLenum format, GLenum type, GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h);
bool set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset);
};
class texture_array : public texture_base
{
private:
size_t m_levels = 0;
public:
texture_array(void);
texture_array(size_t layers);
texture_array(const egn::image& i, size_t layers, bool mipmap = true);
texture_array(GLenum format, GLsizei w, GLsizei h, GLenum type, size_t layers, bool mipmap = true);
texture_array(const texture_array&);
texture_array(texture_array&&);
~texture_array(void) = default;
texture_array& operator=(const texture_array&);
texture_array& operator=(texture_array&&);
//overwrite the current image data with 'i'
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type, size_t layer);
bool set_image(const egn::image& i, size_t layer);
bool set_subimage(const unsigned char* data, GLenum format, GLenum type,
GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h, size_t layer);
bool set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset, size_t layer);
//bind to target
void bind(GLuint target = GL_TEXTURE_2D_ARRAY)const;
//bind to given texture unit and load into given program uniform location
void bind_unit(GLuint tunit)const;
texture_slice operator[](size_t layer);
private:
bool create_texture_storage_(void);
};
class texture_view
{
//TODO
//lookup glTextureView to remind yourself
};
}
#endif

157
include/gfx/ogl/ubo.hpp Normal file
View File

@ -0,0 +1,157 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_UBO_HPP
#define OUR_DICK_GRAPHICS_OGL_UBO_HPP
#include "gl_include.hpp"
#include <rml/mat.hpp>
#include <rml/vec.hpp>
#include <type_traits> //a lot of stuff
#include "buffer_map.hpp"
namespace gfx::ogl{
namespace detail{
template<class T>
struct is_bounded_array{
static constexpr bool value = false;
};
template<class T, size_t I>
struct is_bounded_array<T[I]>{
static constexpr bool value = true;
};
template<class T>
struct is_valid_uniform_scalar{
static constexpr bool value = std::is_same_v<T,GLint> ||
std::is_same_v<T,GLuint> ||
std::is_same_v<T,bool> ||
std::is_same_v<T,GLfloat> ||
std::is_same_v<T,GLdouble>;
};
template<class T>
struct is_valid_uniform_matrix{
template<class U, size_t R, size_t C>
static constexpr bool test(rml::matrix_base<U,R,C>*){
return is_valid_uniform_scalar<typename T::value_type>::value && T::Columns <= 4 && T::Rows <= 4;
}
static constexpr bool test(void*){
return false;
}
static constexpr bool value = test(static_cast<std::decay_t<T>*>(nullptr));
};
template<class T>
struct is_valid_uniform_type{
static constexpr bool value = is_valid_uniform_scalar<T>::value || is_valid_uniform_matrix<T>::value || is_bounded_array<T>::value;
};
template<size_t I, class Type, class... Types>
struct get_type{
using type = typename get_type<I-1, Types...>::type;
};
template<class Type, class... Types>
struct get_type<0, Type, Types...>{
using type = Type;
};
template<class... Types>
struct get_type<0,bool,Types...>{
using type = int;
};
template<size_t I, class... Types>
using get_type_t = typename get_type<I, Types...>::type;
template<class T>
constexpr size_t get_alignment_of_(void);
template<class T>
constexpr size_t get_alignment_multiple_(void);
template<class T>
constexpr size_t size_of_(void);
}
//Class for a uniform buffer object
//automatically sets alignments for std140 uniform blocks
template<class... Types>
class ubo
{
private:
static_assert((detail::is_valid_uniform_type<Types>::value && ...));
public:
static constexpr size_t num_elements = sizeof...(Types);
template<size_t I>
using type_of = detail::get_type_t<I, Types...>;
private:
GLuint m_buffer = 0;
public:
ubo(buffer::usage usage = buffer::usage::DYNAMIC_DRAW);
ubo(const ubo&);
ubo(ubo&&);
~ubo(void);
ubo& operator=(const ubo&);
ubo& operator=(ubo&&);
//raw modify the data (NOT A GOOD IDEA)
scoped_buffer_map<void> map(buffer::maptype m);
void buffer(const void* data, size_t datasize, size_t start);
void initialize(unsigned char value = 0);
//Safely modify the data to comply with GLSL std140 layout
template<size_t I>
auto get(void);
template<size_t I, class T>
void set(T&& t);
//Direct access to opengl handle
GLuint raw(void)const;
size_t get_size(void)const;
size_t get_cap(void)const;
buffer::usage get_usage(void)const;
//Bind to uniform block binding location
void bind(size_t index)const;
private:
template<size_t I>
static constexpr size_t get_offset_of_(void);
template<size_t I>
static constexpr size_t get_alignment_of_(void);
static constexpr size_t get_total_size_(void);
public:
template<size_t I>
static constexpr size_t offset_of = get_offset_of_<I>();
template<size_t I>
static constexpr size_t alignment_of = get_alignment_of_<I>();
};
}
#include "ubo.tpp"
#endif

267
include/gfx/ogl/ubo.tpp Normal file
View File

@ -0,0 +1,267 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_UBO_TPP
#define OUR_DICK_GRAPHICS_OGL_UBO_TPP
#include <utility> //swap, exchange
#include <type_traits> //a lot of stuff
#include <array>
#include <cstring> //memcpy, memset
#include "config.hpp"
namespace gfx::ogl{
template<class... Types>
ubo<Types...>::ubo(buffer::usage usage){
glCreateBuffers(1, &m_buffer);
glNamedBufferData(m_buffer, get_total_size_(), NULL, static_cast<GLenum>(usage));
}
template<class... Types>
ubo<Types...>::ubo(const ubo& u){
glCreateBuffers(1, &m_buffer);
auto data = u.map(buffer::maptype::READ);
if(!data)
return;
glNamedBufferData(m_buffer, u.get_size(), data, static_cast<GLenum>(u.get_usage()));
}
template<class... Types>
ubo<Types...>::ubo(ubo&& u):
m_buffer(std::exchange(u.m_buffer, 0)){}
template<class... Types>
ubo<Types...>::~ubo(void){
if(m_buffer)
glDeleteBuffers(1, &m_buffer);
}
template<class... Types>
auto ubo<Types...>::operator=(const ubo& u) -> ubo&{
return (*this = ubo(u));
}
template<class... Types>
auto ubo<Types...>::operator=(ubo&& u) -> ubo&{
std::swap(m_buffer, u.m_buffer);
return *this;
}
template<class... Types>
template<size_t I>
constexpr size_t ubo<Types...>::get_offset_of_(void){
static_assert(I < sizeof...(Types), "Index out of bounds");
if constexpr(I == 0){
return 0;
}else{
using this_type = detail::get_type_t<I,Types...>;
using prev_type = detail::get_type_t<I-1,Types...>;
size_t prev_offset = get_offset_of_<I-1>();
constexpr size_t prev_alignment = detail::get_alignment_of_<prev_type>();
constexpr size_t this_alignment = detail::get_alignment_of_<this_type>();
prev_offset += (prev_alignment * (detail::get_alignment_multiple_<prev_type>() - 1));
bool is_on_alignment_multiple = (((prev_offset + prev_alignment) % this_alignment) == 0);
if(is_on_alignment_multiple){
return prev_offset + prev_alignment;
}else if(this_alignment > prev_alignment){
return prev_offset + this_alignment;
}else{
size_t i;
for(i = this_alignment * 2;i < prev_alignment;i += this_alignment);
return prev_offset + i;
}
}
}
template<class... Types>
template<size_t I>
constexpr size_t ubo<Types...>::get_alignment_of_(void){
return detail::get_alignment_of_<detail::get_type_t<I,Types...>>();
}
template<class... Types>
constexpr size_t ubo<Types...>::get_total_size_(void){
constexpr size_t type_num = sizeof...(Types) - 1;
using last_type = detail::get_type_t<type_num,Types...>;
return get_offset_of_<type_num>() + (detail::get_alignment_of_<last_type>() * detail::get_alignment_multiple_<last_type>());
}
template<class... Types>
scoped_buffer_map<void> ubo<Types...>::map(buffer::maptype m){
return scoped_buffer_map<void>(m_buffer, m);
}
template<class... Types>
void ubo<Types...>::buffer(const void* data, size_t datasize, size_t start){
rexy::debug::print_warn("Manually editing values of ubo!\n");
if(start > get_size())
return;
glNamedBufferSubData(m_buffer, start, std::min(datasize, get_size() - start), data);
}
template<class... Types>
void ubo<Types...>::initialize(unsigned char value){
rexy::debug::print_warn("Manually editing values of ubo!\n");
const size_t size = get_size();
auto m = map(buffer::maptype::WRITE);
if(!m){
return;
}
memset(m, size, value);
}
template<class... Types>
template<size_t I>
auto ubo<Types...>::get(void){
using type = detail::get_type_t<I, Types...>;
constexpr size_t offset = get_offset_of_<I>();
constexpr size_t align = detail::get_alignment_of_<type>();
auto m = map(buffer::maptype::READ);
unsigned char* data = static_cast<unsigned char*>(m.raw());
data += offset;
if constexpr(detail::is_valid_uniform_matrix<type>::value){
type t{};
constexpr size_t rows = type::Rows;
constexpr size_t cols = type::Columns;
for(size_t i = 0;i < cols;++i){
memcpy(t.raw() + (rows * i), data + (align * i), sizeof(typename type::value_type) * rows);
}
return t;
}else if constexpr(detail::is_bounded_array<type>::value){
static constexpr size_t arr_size = std::extent<type>::value;
using this_value = std::decay_t<decltype(std::declval<type>()[0])>;
std::array<this_value,arr_size> t;
for(size_t i = 0;i < arr_size;++i){
t[i] = *reinterpret_cast<this_value*>(data + (align * i));
}
return t;
}else{
type t{};
memcpy(&t, data, sizeof(type));
return t;
}
}
template<class... Types>
template<size_t I, class T>
void ubo<Types...>::set(T&& t){
using type = detail::get_type_t<I, Types...>;
constexpr size_t offset = get_offset_of_<I>();
constexpr size_t align = detail::get_alignment_of_<type>();
auto m = map(buffer::maptype::WRITE);
unsigned char* data = static_cast<unsigned char*>(m.raw());
data += offset;
if constexpr(detail::is_valid_uniform_matrix<type>::value){
static_assert(std::is_convertible_v<std::decay_t<T>,type>);
constexpr size_t rows = type::Rows;
constexpr size_t cols = type::Columns;
for(size_t i = 0;i < cols;++i){
memcpy(data + (align * i), t.raw() + (rows * i), sizeof(typename type::value_type) * rows);
}
}else if constexpr(detail::is_bounded_array<type>::value){
using this_value = std::decay_t<decltype(std::declval<type>()[0])>;
using that_value = std::decay_t<decltype(std::declval<T>()[0])>;
static_assert(std::is_convertible_v<that_value,this_value>);
for(size_t i = 0;i < std::extent<type>::value;++i){
this_value tmp = t[i];
memcpy(data + (align * i), &tmp, sizeof(this_value));
}
}else{
static_assert(std::is_convertible_v<std::decay_t<T>,type>);
type tmp = t;
memcpy(data, &tmp, sizeof(type));
}
}
template<class... Types>
GLuint ubo<Types...>::raw(void)const{
return m_buffer;
}
template<class... Types>
size_t ubo<Types...>::get_size(void)const{
return get_total_size_();
}
template<class... Types>
size_t ubo<Types...>::get_cap(void)const{
return get_total_size_();
}
template<class... Types>
buffer::usage ubo<Types...>::get_usage(void)const{
GLint retval;
glGetNamedBufferParameteriv(m_buffer, GL_BUFFER_USAGE, &retval);
return static_cast<buffer::usage>(retval);
}
template<class... Types>
void ubo<Types...>::bind(size_t index)const{
glBindBufferBase(GL_UNIFORM_BUFFER, index, m_buffer);
}
namespace detail{
template<class T>
constexpr size_t get_alignment_of_(void){
if constexpr(detail::is_valid_uniform_scalar<T>::value){ //scalar
if constexpr(std::is_same_v<T,GLdouble>){
return 8;
}else{
return 4;
}
}else if constexpr(detail::is_bounded_array<T>::value){
return get_alignment_of_<rml::vec4f>();
}else{
constexpr size_t element_alignment = get_alignment_of_<typename T::value_type>();
if constexpr(T::Columns > 1){ //matrix
return element_alignment * 4;
}else{ //vector
if constexpr(T::Rows == 2){
return element_alignment * 2;
}else{
return element_alignment * 4;
}
}
}
}
template<class T>
constexpr size_t get_alignment_multiple_(void){
if constexpr(detail::is_valid_uniform_scalar<T>::value){
return 1;
}else if constexpr(detail::is_bounded_array<T>::value){
return std::extent<T>::value;
}else{
return T::Columns;
}
}
template<class T>
constexpr size_t size_of_(void){
if constexpr(std::is_same<bool,std::decay_t<T>>::value){
return 4;
}
return sizeof(T);
}
}
}
#endif

100
include/gfx/ogl/vao.hpp Normal file
View File

@ -0,0 +1,100 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_VAO_HPP
#define OUR_DICK_GRAPHICS_OGL_VAO_HPP
#include "gl_include.hpp"
#include <rml/math.hpp>
#include "vbo.hpp"
namespace gfx::ogl{
class vertex_attribute;
//class representing a vertex array object
class vao
{
private:
GLuint m_buffer; //handle to the vertex array
public:
//create a default initialized opengl vao
vao(void);
vao(const vao&) = delete;
vao(vao&&);
~vao(void);
vao& operator=(const vao&) = delete;
vao& operator=(vao&&);
GLuint raw(void)const;
//Set the instanced divisor of this binding point. Used with instanced rendering.
void set_instance_divisor(GLuint binding, GLuint divisor);
void bind_buffer(const vbo& buffer, GLuint bind_point, GLuint offset, GLuint stride);
void bind_element_buffer(const vbo& buffer);
//Get access to a generic vertex attribute within this vao
vertex_attribute get_attribute(int index);
//bind this vao for use with rendering program
void bind(void);
//unbind this vao and rebind state machine to 0
void unbind(void);
};
//class representing a generic vertex attribute in a vao
class vertex_attribute
{
private:
GLuint m_vao; //handle to vertex array object
int m_index; //index of this attribute
public:
constexpr vertex_attribute(GLuint vao, int index):
m_vao(vao),
m_index(index){}
constexpr vertex_attribute(const vertex_attribute&) = default;
constexpr vertex_attribute(vertex_attribute&&) = default;
~vertex_attribute(void) = default;
constexpr vertex_attribute& operator=(const vertex_attribute&) = default;
constexpr vertex_attribute& operator=(vertex_attribute&&) = default;
//enable use as an array attribute (most likely what is desired)
void enable(void);
//disable use as an array attribute. used for static data in attributes during rendering
void disable(void);
//Associate this attribute's location with the given buffer binding location
void associate_with(GLuint buffer_binding);
//setters for use in array mode. Same arguments as glVertexAttribPointer but these take arguments
//as object counts rather than bytes. a valid vbo must be bound to buffers::array_buffer before these are called.
void set_float_array(GLint size, GLsizei offset);
void set_double_array(GLint size, GLsizei offset);
void set_byte_array(GLint size, GLsizei offset);
void set_ubyte_array(GLint size, GLsizei offset);
void set_short_array(GLint size, GLsizei offset);
void set_ushort_array(GLint size, GLsizei offset);
void set_int_array(GLint size, GLsizei offset);
void set_uint_array(GLint size, GLsizei offset);
};
}
#endif

73
include/gfx/ogl/vbo.hpp Normal file
View File

@ -0,0 +1,73 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_VBO_HPP
#define OUR_DICK_GRAPHICS_OGL_VBO_HPP
#include "gl_include.hpp"
#include <cstdlib> //size_t
#include "buffer_map.hpp"
namespace gfx::ogl{
//class representing a vertex buffer object
class vbo
{
private:
GLuint m_buffer; //handle to vbo
size_t m_buffer_size; //amount of buffer currently in use
public:
//create a buffer with given capacity with predicted usage case 't'
vbo(size_t cap, buffer::usage t);
vbo(const void* data, size_t datasize, buffer::usage t);
vbo(const vbo&);
vbo(vbo&&);
~vbo(void);
vbo& operator=(const vbo&);
vbo& operator=(vbo&&);
//add data to the end of this buffer (starts loading at data+get_size())
bool buffer(const void* data, size_t datasize);
bool buffer(const void* data, size_t datasize, size_t start);
bool initialize(unsigned char value = 0);
//change capacity of buffer
bool resize(size_t newcap);
GLuint raw(void)const;
//glMapBuffer to given target with map style 'm'
scoped_buffer_map<void> map(buffer::maptype m)const;
//emties the buffer. does not clear contents, just sets size to 0.
void clear(void);
size_t get_size(void)const;
size_t get_cap(void)const;
buffer::usage get_usage(void)const;
private:
static bool copy_buffer(vbo& dest, const vbo& src);
};
}
#endif

View File

@ -0,0 +1,72 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_WINDOW_HPP
#define OUR_DICK_GRAPHICS_OGL_WINDOW_HPP
#include "gl_include.hpp"
#include "gfx/glfw_init.hpp"
#include <rml/math.hpp>
#include "gfx/window.hpp"
#include <string>
namespace gfx::ogl{
class window : public ::gfx::window
{
private:
//opengl 4.5 has been supported since intel broadwell, nvidia 400 series, and radeon hd 5000
//should be supported on any system I care about
static constexpr int s_default_cver_maj = 4;
static constexpr int s_default_cver_min = 5;
private:
std::string m_title = {};
int m_antialias_level = 0;
int m_refresh_rate = GLFW_DONT_CARE;
int m_swap_interval = 1;
public:
window(int width, int height, const char* title, bool make_current = true);
window(int context_vmaj, int context_vmin, int width, int height, const char* title, bool make_current = true, int antialias = 0, int refresh = GLFW_DONT_CARE);
window(const window&);
window(window&&);
~window(void) = default;
window& operator=(const window&);
window& operator=(window&&);
void make_current(void);
void swap_buffers(void);
void set_antialias(int level);
void set_refresh_rate(int rate);
void set_swap_interval(int i);
void set_active(void);
rml::vec2i get_context_version(void)const;
int get_context_vmaj(void)const;
int get_context_vmin(void)const;
int get_swap_interval(void)const;
};
}
#endif

View File

@ -0,0 +1,105 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_RESOURCE_CONTAINER_HPP
#define OUR_DICK_GRAPHICS_RESOURCE_CONTAINER_HPP
#include <string>
#include <map>
#include <utility> //pair, forward
#include <tuple>
#include <memory> //shared_ptr
#include <rexy/deferred.hpp>
#include "config.hpp"
namespace gfx{
template<class T>
class resource_container
{
public:
using value_type = T;
using key_type = std::string;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using node = std::shared_ptr<value_type>;
using const_node = std::shared_ptr<value_type>;
private:
std::map<key_type,std::shared_ptr<value_type>> m_map;
public:
resource_container(void) = default;
resource_container(const resource_container&) = default;
resource_container(resource_container&&) = default;
~resource_container(void) = default;
resource_container& operator=(const resource_container&) = default;
resource_container& operator=(resource_container&&) = default;
bool has_value(const char* key)const;
template<class... Args>
std::pair<node,bool> emplace_value(const char* key, Args&&... args);
node get_value(const char* file);
bool erase_value(const char* key);
};
template<class T>
bool resource_container<T>::has_value(const char* key)const{
if(auto it = m_map.find(key);it != m_map.end())
return true;
return false;
}
template<class T>
template<class... Args>
auto resource_container<T>::emplace_value(const char* key, Args&&... args) -> std::pair<node,bool>{
#ifdef OUR_DICK_ENABLE_DEBUG_VERBOSE_OUTPUT
//print out construction to check if things only get built once
//must enable rtti for typeid() which is disabled by default in the makefile
//add -frtti in the DEBUG_CXXFLAGS variable
if(node n = get_value(key);!n){
rexy::debug::verbose::print("Constructing new %s in container\n", ::util::demangle(typeid(T).name()).c_str());
auto p = m_map.emplace(key, rexy::deferred_function(std::make_shared<T,Args&&...>, std::forward<Args>(args)...));
return {(*p.first).second, p.second};
}else{
return {n, false};
}
#else
auto p = m_map.try_emplace(key, rexy::deferred_function(std::make_shared<T,Args&&...>, std::forward<Args>(args)...));
return {(*p.first).second, p.second};
#endif
}
template<class T>
auto resource_container<T>::get_value(const char* key) -> node{
if(auto it = m_map.find(key);it != m_map.end())
return (*it).second;
return nullptr;
}
template<class T>
bool resource_container<T>::erase_value(const char* key){
return m_map.erase(key) == 1;
}
}
#endif

104
include/gfx/window.hpp Normal file
View File

@ -0,0 +1,104 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WINDOW_HPP
#define OUR_DICK_GRAPHICS_WINDOW_HPP
#include "glfw_init.hpp"
#include <GLFW/glfw3.h>
#include <rml/vec.hpp>
namespace gfx{
class window
{
public:
enum class mousemode : int{
DISABLED,
HIDDEN,
NORMAL,
};
protected:
GLFWwindow* m_window = nullptr;
glfw_system m_glfw_handle;
protected:
window(void);
window(const window&) = delete; //Implement in derived classes
window(window&&);
~window(void);
window& operator=(const window&) = delete; //Implement in derived classes
window& operator=(window&&);
public:
GLFWwindow* raw(void);
const GLFWwindow* raw(void)const;
operator GLFWwindow*(void);
operator const GLFWwindow*(void)const;
void destroy(void);
void set_size(const rml::vec2i&);
void set_size(int w, int h);
void set_width(int w);
void set_height(int h);
void set_title(const char* t);
void set_pos(const rml::vec2i&);
void set_pos(int x, int y);
void set_x(int x);
void set_y(int y);
void set_visible(bool b = true);
void toggle_visible(void);
void set_resizable(bool b = true);
void set_decorated(bool b = true);
void set_always_on_top(bool b = true);
void set_antialias(int level);
void set_should_close(bool b = true);
void set_mousemode(mousemode m);
void set_key_callback(void);
//TODO callbacks
rml::vec2i get_size(void)const;
int get_width(void)const;
int get_height(void)const;
rml::vec2i get_pos(void)const;
int get_posx(void)const;
int get_posy(void)const;
rml::vec2d get_cursor_pos(void)const;
double get_cursor_posx(void)const;
double get_cursor_posy(void)const;
bool get_key(int key, int action)const;
bool is_visible(void)const;
bool is_resizable(void)const;
bool is_decorated(void)const;
bool is_always_on_top(void)const;
bool is_fullscreen(void)const;
bool should_close(void)const;
};
}
#endif

View File

@ -1,116 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_DETAIL_MATRIX_HPP
#define REXY_DETAIL_MATRIX_HPP
#include <cstdlib> //size_t
#include <utility> //integer_sequence
namespace math::detail{
template<size_t SW, size_t W = SW, size_t H = SW-1, size_t... Args>
struct gen_id_tup {
using tup = typename gen_id_tup<SW, W-1, H, Args..., 0>::tup;
};
template<size_t SW, size_t H, size_t... Args>
struct gen_id_tup<SW,SW,H,Args...> {
using tup = typename gen_id_tup<SW, SW-1, H, Args..., 1>::tup;
};
template<size_t SW, size_t H, size_t... Args>
struct gen_id_tup<SW,0,H,Args...> {
using tup = typename gen_id_tup<SW, SW, H-1, Args..., 0>::tup;
};
template<size_t SW, size_t... Args>
struct gen_id_tup<SW,SW,0,Args...> {
using tup = std::integer_sequence<size_t,Args...,1>;
};
template<size_t N, size_t... Args>
struct gen_zero_tup {
using tup = typename gen_zero_tup<N-1,Args...,0>::tup;
};
template<size_t... Args>
struct gen_zero_tup<0,Args...> {
using tup = std::integer_sequence<size_t,Args...>;
};
template<size_t W>
struct id_initialization_matrix {
using tuple = typename gen_id_tup<W>::tup;
};
template<size_t W, size_t H>
struct default_initialization_matrix {
using tuple = typename gen_zero_tup<W>::tup;
};
template<size_t W>
struct default_initialization_matrix<W,W> {
using tuple = typename id_initialization_matrix<W>::tuple;
};
template<typename T, size_t R>
class mat_ref_obj
{
public:
using size_type = size_t;
protected:
T* m_data = nullptr;
public:
constexpr mat_ref_obj(T* d, size_type i);
constexpr T& operator[](size_type i);
constexpr const T& operator[](size_type i)const;
};
template<typename T, size_t R>
struct determinate_helper {
static constexpr T perform(const matrix<T,R,R>& m);
};
template<typename T>
struct determinate_helper<T,3> {
static constexpr T perform(const matrix<T,3,3>& m);
};
template<typename T>
struct determinate_helper<T,2> {
static constexpr T perform(const matrix<T,2,2>& m);
};
template<typename T, size_t R>
struct inverse_helper {
//TODO generalized inverse
};
template<typename T>
struct inverse_helper<T,2> {
static constexpr matrix<T,2,2> perform(const matrix<T,2,2>& m);
};
template<typename T>
struct inverse_helper<T,3> {
static constexpr matrix<T,3,3> perform(const matrix<T,3,3>& m);
};
template<typename T>
struct inverse_helper<T,4> {
static constexpr matrix<T,4,4> perform(const matrix<T,4,4>& m);
};
}
#include "matrix.tpp"
#endif

View File

@ -1,151 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_DETAIL_MATRIX_TPP
#define REXY_DETAIL_MATRIX_TPP
#include <cstdlib> //size_t
#include <utility> //integer_sequence
namespace math::detail{
template<typename T, size_t R>
constexpr mat_ref_obj<T,R>::mat_ref_obj(T* d, size_type i):
m_data(d+i){}
template<typename T, size_t R>
constexpr T& mat_ref_obj<T,R>::operator[](size_type i){
return m_data[i*R];
}
template<typename T, size_t R>
constexpr const T& mat_ref_obj<T,R>::operator[](size_type i)const{
return m_data[i*R];
}
template<typename T, size_t R>
constexpr T determinate_helper<T,R>::perform(const matrix<T,R,R>& m){
T sum = 0;
T op = 1;
for(size_t i = 0; i < R; ++i){
T item = op * m[0][i];
matrix<T,R-1,R-1> mul(no_initialize);
for(size_t j = 1, mj = 0; j < R; ++j){
for(size_t k = 0, mk = 0; k < R; ++k){
if(k == i)
continue;
mul[mj][mk] = m[j][k];
++mk;
}
++mj;
}
sum += item * determinate_helper<T,R-1>::perform(mul);
op = -op;
}
return sum;
}
template<typename T>
constexpr T determinate_helper<T,3>::perform(const matrix<T,3,3>& m){
return (m.get(0) * ((m.get(4) * m.get(8)) - (m.get(5) * m.get(7))) -
m.get(1) * ((m.get(3) * m.get(8)) - (m.get(5) * m.get(6))) +
m.get(2) * ((m.get(3) * m.get(7)) - (m.get(4) * m.get(6))));
}
template<typename T>
constexpr T determinate_helper<T,2>::perform(const matrix<T,2,2>& m){
return m.get(0) * m.get(3) - m.get(1) * m.get(2);
}
template<typename T>
constexpr matrix<T,2,2> inverse_helper<T,2>::perform(const matrix<T,2,2>& m){
T det = m.determinate();
if(!det)
return matrix<T,2,2>(zero_initialize);
return matrix<T,2,2>(m.get(3) / det, -(m.get(1)) / det, -(m.get(2)) / det, m.get(0) / det);
}
template<typename T>
constexpr matrix<T,3,3> inverse_helper<T,3>::perform(const matrix<T,3,3>& m){
T det = m.determinate();
if(!det)
return matrix<T,3,3>(zero_initialize);
return matrix<T,3,3>(((m.get(4) * m.get(8)) - (m.get(5) * m.get(7))) / det,
-((m.get(1) * m.get(8)) - (m.get(2) * m.get(7))) / det,
((m.get(1) * m.get(5)) - (m.get(2) * m.get(4))) / det,
-((m.get(3) * m.get(8)) - (m.get(5) * m.get(6))) / det,
((m.get(0) * m.get(8)) - (m.get(2) * m.get(6))) / det,
-((m.get(0) * m.get(5)) - (m.get(2) * m.get(3))) / det,
((m.get(3) * m.get(7)) - (m.get(4) * m.get(6))) / det,
-((m.get(0) * m.get(7)) - (m.get(1) * m.get(6))) / det,
((m.get(0) * m.get(4)) - (m.get(1) * m.get(3))) / det);
}
template<typename T>
constexpr matrix<T,4,4> inverse_helper<T,4>::perform(const matrix<T,4,4>& m){
//barely over 50 lines, can be made slightly shorter by making the return statement unreadable
T det = m.determinate();
if(!det)
return matrix<T,4,4>(zero_initialize);
return matrix<T,4,4>((m.get(5) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(6) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) +
m.get(7) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det,
-(m.get(1) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(2) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) +
m.get(3) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det,
(m.get(1) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) -
m.get(2) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) +
m.get(3) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13)))) / det,
-(m.get(1) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) -
m.get(2) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) +
m.get(3) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9)))) / det,
-(m.get(4) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(6) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(7) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det,
(m.get(0) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(2) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(3) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det,
-(m.get(0) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) -
m.get(2) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) +
m.get(3) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12)))) / det,
(m.get(0) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) -
m.get(2) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) +
m.get(3) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8)))) / det,
(m.get(4) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) -
m.get(5) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(7) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
-(m.get(0) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) -
m.get(1) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(3) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
(m.get(0) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) -
m.get(1) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) +
m.get(3) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det,
-(m.get(0) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) -
m.get(1) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) +
m.get(3) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det,
-(m.get(4) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) -
m.get(5) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) +
m.get(6) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
(m.get(0) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) -
m.get(1) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) +
m.get(2) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
-(m.get(0) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13))) -
m.get(1) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12))) +
m.get(2) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det,
(m.get(0) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9))) -
m.get(1) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8))) +
m.get(2) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det);
}
}
#endif

View File

@ -1,259 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MAT_HPP
#define REXY_MAT_HPP
#include <cstdlib> //size_t
#include <utility> //integer_sequence
#include <type_traits> //decay_t, is_same, integral_constant
#include "math_common.hpp"
#include "fwd_declare.hpp"
namespace math{
template<typename T, size_t R, size_t C>
class matrix_base
{
static_assert(C > 0, "Cannot have 0 columns matrix");
static_assert(R > 0, "Cannot have 0 rows matrix");
public:
using value_type = T;
using size_type = size_t;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
static constexpr size_type Columns = C;
static constexpr size_type Rows = R;
protected:
value_type m_data[R*C];
protected:
template<size_t... Ss>
constexpr matrix_base(std::integer_sequence<size_type,Ss...>);
public:
//Default construct as identity when square, zero otherwise
constexpr matrix_base();
//Range initializing constructors
constexpr explicit matrix_base(detail::zero_initialize_t);
constexpr explicit matrix_base(detail::no_initialize_t);
//Value initializing constructors
constexpr explicit matrix_base(value_type v);
template<typename... Args>
constexpr explicit matrix_base(Args&&... args);
//Copying constructors
constexpr matrix_base(const matrix_base&) = default;
constexpr matrix_base(matrix_base&&) = default;
template<typename U>
constexpr matrix_base(const matrix_base<U,Columns,Rows>& m);
~matrix_base() = default;
constexpr matrix_base& operator=(const matrix_base&) = default;
constexpr matrix_base& operator=(matrix_base&&) = default;
template<typename U>
constexpr matrix_base& operator=(const matrix_base<U,Columns,Rows>& m);
//Getters/Setters
constexpr auto operator[](size_type x);
constexpr auto operator[](size_type x)const;
constexpr reference get(size_type x, size_type y);
constexpr const_reference get(size_type x, size_type y)const;
constexpr reference get(size_type i);
constexpr const_reference get(size_type i)const;
constexpr size_type columns()const;
constexpr size_type rows()const;
constexpr size_type size()const;
constexpr pointer raw();
constexpr const_pointer raw()const;
constexpr operator pointer();
constexpr operator const_pointer()const;
};
template<typename T, size_t R, size_t C>
class matrix : public matrix_base<T,R,C>
{
private:
using base = matrix_base<T,R,C>;
public:
using value_type = typename base::value_type;
using size_type = typename base::size_type;
using pointer = typename base::pointer;
using const_pointer = typename base::const_pointer;
using reference = typename base::reference;
using const_reference = typename base::const_reference;
public:
using base::base;
constexpr matrix(const matrix&) = default;
constexpr matrix(matrix&&) = default;
~matrix() = default;
//Assignement
constexpr matrix& operator=(const matrix&) = default;
constexpr matrix& operator=(matrix&&) = default;
template<typename U>
constexpr matrix& operator=(const matrix<U,R,C>& m);
};
template<typename T, size_t R>
class matrix<T,R,R> : public matrix_base<T,R,R>
{
private:
using base = matrix_base<T,R,R>;
public:
using value_type = typename base::value_type;
using size_type = typename base::size_type;
using pointer = typename base::pointer;
using const_pointer = typename base::const_pointer;
using reference = typename base::reference;
using const_reference = typename base::const_reference;
public:
using base::base;
constexpr matrix(const matrix&) = default;
constexpr matrix(matrix&&) = default;
constexpr explicit matrix(detail::id_initialize_t);
~matrix() = default;
//Assignement
constexpr matrix& operator=(const matrix&) = default;
constexpr matrix& operator=(matrix&&) = default;
template<typename U>
constexpr matrix& operator=(const matrix<U,R,R>& m);
//square matrix arithmetic operations
constexpr value_type determinate()const;
constexpr value_type trace()const;
constexpr matrix transpose()const;
constexpr matrix inverse()const;
};
template<typename T, size_t R>
constexpr T determinate(const matrix<T,R,R>& m);
template<typename T, size_t R>
constexpr matrix<T,R,R> inverse(const matrix<T,R,R>& m);
template<typename T>
matrix<T,2,2> rotation2d_pure(T angle);
template<typename T>
constexpr matrix<T,2,2> rotation2d_pure(T sin, T cos);
template<typename T>
constexpr matrix<T,2,2> scale2d(T x, T y);
template<typename T>
matrix<T,3,3> rotation2d(T angle);
template<typename T>
constexpr matrix<T,3,3> rotation2d(T sin, T cos);
template<typename T>
matrix<T,3,3> rotation2d(T x, T y, T z);
template<typename T>
matrix<T,4,4> fov_projection(T fov, T asp, T near, T far);
template<typename T>
matrix<T,4,4> fov_asymetric_projection(T fovl, T fovr, T fovb, T fovt, T asp, T near, T far);
template<typename T>
matrix<T,4,4> ortho_projection(T w, T h, T n, T f);
template<typename T>
matrix<T,4,4> ortho_asymetric_projection(T l, T r, T b, T t, T n, T f);
template<typename T>
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z);
template<typename T>
constexpr matrix<T,4,4> translation3d(T x, T y, T z);
template<typename T>
constexpr matrix<T,4,4> scale3d(T x, T y, T z);
namespace detail{
template<typename T>
struct is_matrix_helper {
template<typename U, size_t R, size_t C>
static std::true_type test(matrix_base<U,R,C>*);
static std::false_type test(void*);
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
};
}
template<typename... Ms>
struct is_matrix {
static constexpr bool value = (detail::is_matrix_helper<Ms>::value && ...);
};
namespace detail{
template<typename M1, typename M2>
struct are_same_size_matrix {
using l = std::decay_t<M1>;
using r = std::decay_t<M2>;
static constexpr bool value = is_matrix<M1,M2>::value && l::Columns == r::Columns && l::Rows == r::Rows;
};
template<typename... Ms>
using enable_if_matrix = std::enable_if_t<is_matrix<Ms...>::value,int>;
template<typename M1, typename M2>
using enable_if_eq_matrix = std::enable_if_t<are_same_size_matrix<M1,M2>::value,int>;
}
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
template<typename T, typename U, size_t R1, size_t C1, size_t R2>
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,R2>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left);
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
}
#include "mat.tpp"
#endif

View File

@ -1,385 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MAT_TPP
#define REXY_MAT_TPP
#include <cstdlib> //size_t
#include <cmath> //sin, cos
#include <type_traits> //decay_t, declval
#include "detail/matrix.hpp"
#include "quat.hpp"
namespace math{
template<typename T, size_t R, size_t C>
template<size_t... Ss>
constexpr matrix_base<T,R,C>::matrix_base(std::integer_sequence<size_type,Ss...>):
m_data{Ss...}{}
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base():
matrix_base(typename detail::default_initialization_matrix<Columns,Rows>::tuple{}){}
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::zero_initialize_t):
m_data{}{}
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::no_initialize_t){}
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(value_type v){
for(size_type i = 0; i < Columns*Rows; ++i)
m_data[i] = v;
}
template<typename T, size_t R, size_t C>
template<typename... Args>
constexpr matrix_base<T,R,C>::matrix_base(Args&&... args):
m_data{std::forward<Args>(args)...}{}
template<typename T, size_t R, size_t C>
template<typename U>
constexpr matrix_base<T,R,C>::matrix_base(const matrix_base<U,Columns,Rows>& m){
using mat = decltype(m);
for(typename mat::size_type i = 0; i < mat::Columns*mat::Rows; ++i)
m_data[i] = m.get(i);
}
template<typename T, size_t R, size_t C>
template<typename U>
constexpr matrix_base<T,R,C>& matrix_base<T,R,C>::operator=(const matrix_base<U,Columns,Rows>& m){
using mat = decltype(m);
for(typename mat::size_type i = 0; i < mat::Columns*mat::Rows; ++i)
m_data[i] = m.get(i);
return *this;
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x){
return detail::mat_ref_obj<value_type,Rows>{m_data, x};
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x)const{
return detail::mat_ref_obj<const value_type,Rows>{m_data, x};
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y) -> reference{
return m_data[x+(y*Rows)];
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y)const -> const_reference{
return m_data[x+(y*Rows)];
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i) -> reference{
return m_data[i];
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i)const -> const_reference{
return m_data[i];
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::columns()const -> size_type{
return Columns;
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::rows()const -> size_type{
return Rows;
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::size()const -> size_type{
return Columns*Rows;
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw() -> pointer{
return m_data;
}
template<typename T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw()const -> const_pointer{
return m_data;
}
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator pointer(){
return m_data;
}
template<typename T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator const_pointer()const{
return m_data;
}
template<typename T, size_t R, size_t C>
template<typename U>
constexpr matrix<T,R,C>& matrix<T,R,C>::operator=(const matrix<U,R,C>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t R>
constexpr matrix<T,R,R>::matrix(detail::id_initialize_t):
base(){}
template<typename T, size_t R>
template<typename U>
constexpr matrix<T,R,R>& matrix<T,R,R>::operator=(const matrix<U,R,R>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t R>
constexpr auto matrix<T,R,R>::determinate()const -> value_type{
return math::determinate(*this);
}
template<typename T, size_t R>
constexpr auto matrix<T,R,R>::trace()const -> value_type{
value_type sum = 0;
for(size_type i = 0; i < R; ++i){
sum += get(i, i);
}
}
template<typename T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::transpose()const{
matrix m(no_initialize);
for(size_type i = 0; i < R; ++i){
for(size_type j = 0; j < R; ++j){
m.get(j, i) = get(i, j);
}
}
return m;
}
template<typename T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::inverse()const{
return math::inverse(*this);
}
template<typename T, size_t R>
constexpr T determinate(const matrix<T,R,R>& m){
return detail::determinate_helper<T,R>::perform(m);
}
template<typename T, size_t R>
constexpr matrix<T,R,R> inverse(const matrix<T,R,R>& m){
return detail::inverse_helper<T,R>::perform(m);
}
template<typename T>
matrix<T,2,2> rotation2d_pure(T angle){
return rotation2d_pure(std::sin(angle), std::cos(angle));
}
template<typename T>
constexpr matrix<T,2,2> rotation2d_pure(T sin, T cos){
return matrix<T,2,2>(cos, sin, -sin, cos);
}
template<typename T>
constexpr matrix<T,2,2> scale2d(T x, T y){
return matrix<T,2,2>(x, 0, 0, y);
}
template<typename T>
matrix<T,3,3> rotation2d(T angle){
return rotation2d(std::sin(angle), std::cos(angle));
}
template<typename T>
constexpr matrix<T,3,3> rotation2d(T sin, T cos){
return matrix<T,3,3>(cos, -sin, 0,
sin, cos, 0,
0, 0, 1);
}
template<typename T>
matrix<T,3,3> rotation2d(T x, T y, T z){
quaternion<T> q(x, y, z);
return q.to_mat3();
}
template<typename T>
matrix<T,4,4> fov_projection(T fov, T asp, T near, T far){
T r = near * std::tan(fov / T{2.0});
return matrix<T,4,4>((near / r) / asp, 0, 0, 0,
0, (near / r), 0, 0,
0, 0, (far + near) / (near - far), -1,
0, 0, (2 * near * far) / (near - far), 0);
}
template<typename T>
matrix<T,4,4> fov_asymetric_projection(T fovl, T fovr, T fovb, T fovt, T asp, T n, T f){
T l = n * std::tan(fovl);
T r = n * std::tan(fovr);
T b = n * std::tan(fovb);
T t = n * std::tan(fovt);
return matrix<T,4,4>(((2 * n) / (r - l)) * asp, 0, 0, 0,
0, (2 * n) / (t - b), 0, 0,
(r + l) / (r - l), (t + b) / (t - b), (f + n) / (n - f), -1,
0, 0, (2 * n * f) / (n - f), 0);
}
template<typename T>
matrix<T,4,4> ortho_projection(T w, T h, T n, T f){
return matrix<T,4,4>(2 / w, 0, 0, 0,
0, 2 / h, 0, 0,
0, 0, 2 / (n - f), 0,
0, 0, (n + f) / (n - f), 1);
}
template<typename T>
matrix<T,4,4> ortho_asymetric_projection(T l, T r, T b, T t, T n, T f){
return matrix<T,4,4>(2 / (r - l), 0, 0, 0,
0, 2 / (t - b), 0, 0,
0, 0, 2 / (n - f), 0,
(r + l) / (l - r), (t + b) / (b - t), (n + f) / (n - f), 1);
}
template<typename T>
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z){
quaternion<T> q(angle_x, angle_y, angle_z);
return q.to_mat4();
}
template<typename T>
constexpr matrix<T,4,4> translation3d(T x, T y, T z){
return matrix<T,4,4>(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1);
}
template<typename T>
constexpr matrix<T,4,4> scale3d(T x, T y, T z){
return matrix<T,4,4>(x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1);
}
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
for(size_t i = 0; i < left.size(); ++i){
if(left.get(i) != right.get(i))
return false;
}
return true;
}
template<typename T, typename U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
return !(left == right);
}
template<typename T, typename U, size_t R1, size_t C1, size_t C2>
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,C2>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R1,C2> res(zero_initialize);
size_t index = 0;
for(size_t i = 0; i < left.rows(); ++i){
for(size_t j = 0; j < right.columns(); ++j){
for(size_t k = 0; k < right.rows(); ++k){
res.get(index) += left[i][k] * right[k][j];
}
++index;
}
}
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) * std::forward<U>(right);
}
return res;
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < right.size(); ++i){
res.get(i) = std::forward<U>(left) * right.get(i);
}
return res;
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) / std::forward<U>(right);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) + right.get(i);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) - right.get(i);
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left){
using res_t = decltype(-std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = -left.get(i);
}
return res;
}
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right){
//have to evaluate entire expression first since matrix multiplication depends on reusing many elements
//cannot be expression templatized, TODO
return (left = (left * right));
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) * std::forward<U>(right);
}
return left;
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) / std::forward<U>(right);
}
return left;
}
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) + right.get(i);
}
return left;
}
template<typename T, typename U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) - right.get(i);
}
return left;
}
}
#endif

View File

@ -1,58 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_DETAIL_MATH_HPP
#define REXY_DETAIL_MATH_HPP
namespace math{
namespace detail{
struct zero_initialize_t {};
struct no_initialize_t {};
struct id_initialize_t {};
struct manual_initialize_t {};
}
static inline constexpr detail::zero_initialize_t zero_initialize;
static inline constexpr detail::no_initialize_t no_initialize;
static inline constexpr detail::id_initialize_t id_initialize;
static inline constexpr detail::manual_initialize_t manual_initialize;
template<typename T>
static constexpr T pi(){
return static_cast<T>(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821);
}
template<typename T>
static constexpr T to_degrees(T t){
return (t * 180.0) / pi<T>();
}
template<typename T>
static constexpr T to_radians(T t){
return (t * pi<T>()) / 180.0;
}
constexpr long double operator"" _rad(long double f){
return f;
}
constexpr long double operator"" _deg(long double f){
return to_radians(f);
}
}
#endif

View File

@ -1,160 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_QUAT_HPP
#define REXY_QUAT_HPP
#include <cstdlib> //size_t
#include <utility> //pair
#include <type_traits> //is_same, is_arithmetic, integral_constant
#include "math_common.hpp"
#include "fwd_declare.hpp"
namespace math{
template<typename T>
class quaternion
{
public:
using value_type = T;
using size_type = size_t;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
private:
value_type m_data[4];
public:
constexpr quaternion();
//Construct from Euler angles
constexpr quaternion(detail::zero_initialize_t);
constexpr quaternion(detail::id_initialize_t);
constexpr quaternion(detail::no_initialize_t);
constexpr quaternion(detail::manual_initialize_t,
value_type w, value_type x,
value_type y, value_type z);
quaternion(value_type bank, value_type heading, value_type attitude);
quaternion(const vec3<value_type>& angles);
//Construct from axis-angle
quaternion(value_type angle, const vec3<value_type>& axis);
quaternion(value_type angle, value_type x, value_type y, value_type z);
//Copy ctor
constexpr quaternion(const quaternion&) = default;
constexpr quaternion(quaternion&&) = default;
~quaternion() = default;
//Assignment
constexpr quaternion& operator=(const quaternion&) = default;
constexpr quaternion& operator=(quaternion&&) = default;
//Direct array access
constexpr operator pointer();
constexpr operator const_pointer()const;
constexpr reference operator[](size_type i);
constexpr const_reference operator[](size_type i)const;
constexpr reference get(size_type i);
constexpr const_reference get(size_type i)const;
constexpr reference w();
constexpr const_reference w()const;
constexpr reference x();
constexpr const_reference x()const;
constexpr reference y();
constexpr const_reference y()const;
constexpr reference z();
constexpr const_reference z()const;
//Assign axis from angle-axis
void set_axis(value_type x, value_type y, value_type z);
void set_axis(const vec3<value_type>& axis);
vec3<value_type> get_axis()const;
void set_angle(value_type a);
value_type get_angle()const;
value_type norm()const;
quaternion conjugate()const;
quaternion inverse()const;
value_type magnitude()const;
quaternion normalize()const;
vec3<value_type> get_right()const;
vec3<value_type> get_up()const;
vec3<value_type> get_forward()const;
//Explicit Conversion1
vec3<value_type> to_vec3()const;
vec4<value_type> to_vec4()const;
mat3<value_type> to_mat3()const;
mat4<value_type> to_mat4()const;
vec3<value_type> to_euler_angles()const;
std::pair<value_type,vec3<value_type>> to_axis_angle()const;
};
namespace detail{
template<typename T>
struct is_quat_helper {
template<class U>
static std::true_type test(quaternion<U>*);
static std::false_type test(void*);
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
};
}
template<typename... Qs>
struct is_quaternion {
static constexpr bool value = (detail::is_quat_helper<Qs>::value && ...);
};
template<typename T, typename U>
bool operator==(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
bool operator!=(const quaternion<T>& left, const quaternion<U>& right);
template<typename T>
auto operator-(const quaternion<T>& left);
template<typename T, typename U>
auto operator-(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
auto operator+(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
auto operator*(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
auto operator*(const quaternion<T>& left, const vec3<U>& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
auto operator*(const quaternion<T>& left, U&& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
auto operator/(const quaternion<T>& left, U&& right);
template<typename T, typename U>
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
decltype(auto) operator*=(quaternion<T>& left, U&& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
decltype(auto) operator/=(quaternion<T>& left, U&& right);
}
#include "quat.tpp"
#endif

View File

@ -1,403 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_QUAT_TPP
#define REXY_QUAT_TPP
#include <cmath> //sin, cos, tan, sqrt, etc
#include "mat.hpp"
#include "vec.hpp"
namespace math{
template<typename T>
constexpr quaternion<T>::quaternion():
quaternion(id_initialize){}
template<typename T>
constexpr quaternion<T>::quaternion(detail::zero_initialize_t):
m_data{0, 0, 0, 0}{}
template<typename T>
constexpr quaternion<T>::quaternion(detail::id_initialize_t):
m_data{1, 0, 0, 0}{}
template<typename T>
constexpr quaternion<T>::quaternion(detail::no_initialize_t){}
template<typename T>
constexpr quaternion<T>::quaternion(detail::manual_initialize_t,
value_type w, value_type x,
value_type y, value_type z):
m_data{w, x, y, z}{}
template<typename T>
quaternion<T>::quaternion(value_type bank, value_type heading, value_type attitude){
bank /= value_type{2};
heading /= value_type{2};
attitude /= value_type{2};
value_type cos_heading = std::cos(heading);
value_type sin_heading = std::sin(heading);
value_type cos_attitude = std::cos(attitude);
value_type sin_attitude = std::sin(attitude);
value_type cos_bank = std::cos(bank);
value_type sin_bank = std::sin(bank);
m_data[0] = (cos_heading * cos_attitude * cos_bank) - (sin_heading * sin_attitude * sin_bank);
m_data[1] = (sin_heading * sin_attitude * cos_bank) + (cos_heading * cos_attitude * sin_bank);
m_data[2] = (sin_heading * cos_attitude * cos_bank) + (cos_heading * sin_attitude * sin_bank);
m_data[3] = (cos_heading * sin_attitude * cos_bank) - (sin_heading * cos_attitude * sin_bank);
}
template<typename T>
quaternion<T>::quaternion(const vec3<T>& angles):
quaternion(angles.x(), angles.y(), angles.z()){}
template<typename T>
quaternion<T>::quaternion(value_type angle, const vec3<value_type>& axis):
quaternion(angle, axis.get_x(), axis.get_y(), axis.get_z()){}
template<typename T>
quaternion<T>::quaternion(value_type angle, value_type x, value_type y, value_type z){
angle /= value_type{2.0};
value_type sin_angle = std::sin(angle);
m_data[0] = std::cos(angle);
m_data[1] = sin_angle * x;
m_data[2] = sin_angle * y;
m_data[3] = sin_angle * z;
}
template<typename T>
constexpr quaternion<T>::operator pointer(void){
return m_data;
}
template<typename T>
constexpr quaternion<T>::operator const_pointer(void)const{
return m_data;
}
template<typename T>
constexpr auto quaternion<T>::operator[](size_type i) -> reference{
return m_data[i];
}
template<typename T>
constexpr auto quaternion<T>::operator[](size_type i)const -> const_reference{
return m_data[i];
}
template<typename T>
constexpr auto quaternion<T>::get(size_type i) -> reference{
return m_data[i];
}
template<typename T>
constexpr auto quaternion<T>::get(size_type i)const -> const_reference{
return m_data[i];
}
template<typename T>
constexpr auto quaternion<T>::w() -> reference{
return m_data[0];
}
template<typename T>
constexpr auto quaternion<T>::w()const -> const_reference{
return m_data[0];
}
template<typename T>
constexpr auto quaternion<T>::x() -> reference{
return m_data[1];
}
template<typename T>
constexpr auto quaternion<T>::x()const -> const_reference{
return m_data[1];
}
template<typename T>
constexpr auto quaternion<T>::y() -> reference{
return m_data[2];
}
template<typename T>
constexpr auto quaternion<T>::y()const -> const_reference{
return m_data[2];
}
template<typename T>
constexpr auto quaternion<T>::z() -> reference{
return m_data[3];
}
template<typename T>
constexpr auto quaternion<T>::z()const -> const_reference{
return m_data[3];
}
template<typename T>
void quaternion<T>::set_axis(value_type x, value_type y, value_type z){
value_type sin_angle = std::sin(std::acos(m_data[0]));
m_data[1] = sin_angle * x;
m_data[2] = sin_angle * y;
m_data[3] = sin_angle * z;
}
template<typename T>
void quaternion<T>::set_axis(const vec3<value_type>& v){
set_axis(v.x(), v.y(), v.z());
}
template<typename T>
auto quaternion<T>::get_axis()const -> vec3<value_type>{
quaternion tmp(*this);
if(m_data[0] > value_type{1.0})
tmp.set_normalized();
value_type s = std::sqrt(1 - tmp.m_data[0] * tmp.m_data[0]);
if(s <= value_type{0.001})
return vec3<T>(1, 0, 0);
return vec3<T>(tmp.data[1] / s, tmp.data[2] / s, tmp.data[3] / s);
}
template<typename T>
void quaternion<T>::set_angle(value_type t){
t /= value_type{2.0};
value_type old_sin_angle = std::sin(std::acos(m_data[0]));
value_type sin_angle = std::sin(t);
m_data[0] = std::cos(t);
m_data[1] = (m_data[1] / old_sin_angle) * sin_angle;
m_data[2] = (m_data[2] / old_sin_angle) * sin_angle;
m_data[3] = (m_data[3] / old_sin_angle) * sin_angle;
}
template<typename T>
auto quaternion<T>::get_angle(void)const -> value_type{
return 2.0 * std::acos(m_data[0]);
}
template<typename T>
auto quaternion<T>::norm(void)const -> value_type{
return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2] + m_data[3] * m_data[3];
}
template<typename T>
quaternion<T> quaternion<T>::conjugate(void)const{
return quaternion(manual_initialize, m_data[0], -m_data[1], -m_data[2], -m_data[3]);
}
template<typename T>
quaternion<T> quaternion<T>::inverse(void)const{
return conjugate() / norm();
}
template<typename T>
auto quaternion<T>::magnitude(void)const -> value_type{
return std::sqrt(norm());
}
template<typename T>
quaternion<T> quaternion<T>::normalize(void)const{
value_type mag = magnitude();
return quaternion(manual_initialize, m_data[0] / mag, m_data[1] / mag, m_data[2] / mag, m_data[3] / mag);
}
template<typename T>
auto quaternion<T>::get_right(void)const -> vec3<value_type>{
return vec3<value_type>(1 - 2 * ((m_data[2] * m_data[2]) + (m_data[3] * m_data[3])),
2 * ((m_data[1] * m_data[2]) - (m_data[3] * m_data[0])),
2 * ((m_data[1] * m_data[3]) + (m_data[2] * m_data[0])));
}
template<typename T>
auto quaternion<T>::get_up(void)const -> vec3<value_type>{
return vec3<value_type>( 2 * ((m_data[1] * m_data[2]) + (m_data[3] * m_data[0])),
1 - 2 * ((m_data[1] * m_data[1]) + (m_data[3] * m_data[3])),
2 * ((m_data[2] * m_data[3]) - (m_data[1] * m_data[0])));
}
template<typename T>
auto quaternion<T>::get_forward(void)const -> vec3<value_type>{
return vec3<value_type>( 2 * ((m_data[1] * m_data[3]) - (m_data[2] * m_data[0])),
2 * ((m_data[2] * m_data[3]) + (m_data[1] * m_data[0])),
1 - 2 * ((m_data[1] * m_data[1]) + (m_data[2] * m_data[2])));
}
template<typename T>
auto quaternion<T>::to_vec3(void)const -> vec3<value_type>{
return vec3<value_type>(m_data[1], m_data[2], m_data[3]);
}
template<typename T>
auto quaternion<T>::to_vec4(void)const -> vec4<value_type>{
return vec4<value_type>(m_data[1], m_data[2], m_data[3]);
}
template<typename T>
auto quaternion<T>::to_mat3(void)const -> mat3<value_type>{
mat3<value_type> m;
value_type xx = m_data[1] * m_data[1];
value_type yy = m_data[2] * m_data[2];
value_type zz = m_data[3] * m_data[3];
value_type xy = m_data[1] * m_data[2];
value_type xz = m_data[1] * m_data[3];
value_type xw = m_data[1] * m_data[0];
value_type yz = m_data[2] * m_data[3];
value_type yw = m_data[2] * m_data[0];
value_type zw = m_data[3] * m_data[0];
m[0] = 1 - 2 * (yy + zz);
m[1] = 2 * (xy + zw);
m[2] = 2 * (xz - yw);
m[3] = 2 * (xy - zw);
m[4] = 1 - 2 * (xx + zz);
m[5] = 2 * (yz + xw);
m[6] = 2 * (xz + yw);
m[7] = 2 * (yz - xw);
m[8] = 1 - 2 * (xx + yy);
return m;
}
template<typename T>
auto quaternion<T>::to_mat4(void)const -> mat4<value_type>{
mat4<value_type> m;
value_type xx = m_data[1] * m_data[1];
value_type yy = m_data[2] * m_data[2];
value_type zz = m_data[3] * m_data[3];
value_type xy = m_data[1] * m_data[2];
value_type xz = m_data[1] * m_data[3];
value_type xw = m_data[1] * m_data[0];
value_type yz = m_data[2] * m_data[3];
value_type yw = m_data[2] * m_data[0];
value_type zw = m_data[3] * m_data[0];
m[0] = 1 - 2 * (yy + zz);
m[1] = 2 * (xy + zw);
m[2] = 2 * (xz - yw);
m[3] = 0;
m[4] = 2 * (xy - zw);
m[5] = 1 - 2 * (xx + zz);
m[6] = 2 * (yz + xw);
m[7] = 0;
m[8] = 2 * (xz + yw);
m[9] = 2 * (yz - xw);
m[10] = 1 - 2 * (xx + yy);
m[11] = 0;
m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;
return m;
}
template<typename T>
auto quaternion<T>::to_euler_angles(void)const -> vec3<value_type>{
value_type ww = m_data[0] * m_data[0];
value_type xx = m_data[1] * m_data[1];
value_type yy = m_data[2] * m_data[2];
value_type zz = m_data[3] * m_data[3];
value_type correction = ww + xx + yy + zz;
value_type test = m_data[1] * m_data[2] + m_data[3] * m_data[0];
if(test > 0.499 * correction){
return vec3<value_type>(0, 2 * std::atan2(m_data[1], m_data[0]), pi<value_type>() / 2.0);
}else if(test < -0.499 * correction){
return vec3<value_type>(0, -2 * std::atan2(m_data[1], m_data[0]), -pi<value_type>() / 2.0);
}
return vec3<value_type>(std::atan2((2 * m_data[1] * m_data[0]) - (2 * m_data[2] * m_data[3]), ww - xx + yy - zz),
std::atan2((2 * m_data[2] * m_data[0]) - (2 * m_data[1] * m_data[3]), xx - yy - zz + ww),
std::asin(2 * test / correction));
}
template<typename T>
auto quaternion<T>::to_axis_angle()const -> std::pair<value_type,vec3<value_type>>{
quaternion q(*this);
if(m_data[0] > 1.0)
q = q.normalize();
value_type s = std::sqrt(1 - q.m_data[0] * q.m_data[0]);
if(s <= value_type{0.001}){
return {2 * std::acos(q.m_data[0]), {1, 0, 0}};
}
return {2 * std::acos(q.m_data[0]), {q.m_data[1] / s, q.m_data[2] / s, q.m_data[3] / s}};
}
template<typename T, typename U>
bool operator==(const quaternion<T>& left, const quaternion<U>& right){
return left.w() == right.w() &&
left.x() == right.x() &&
left.y() == right.y() &&
left.z() == right.z();
}
template<typename T, typename U>
bool operator!=(const quaternion<T>& left, const quaternion<U>& right){
return !(left == right);
}
template<typename T>
auto operator-(const quaternion<T>& left){
using res_t = T;
return quaternion<res_t>(manual_initialize, -left.w(), -left.x(), -left.y(), -left.z());
}
template<typename T, typename U>
auto operator-(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() - right.w(), left.x() - right.x(),
left.y() - right.y(), left.z() - right.z());
}
template<typename T, typename U>
auto operator+(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() + right.w(), left.x() + right.x(),
left.y() + right.y(), left.z() + right.z());
}
template<typename T, typename U>
auto operator*(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
return quaternion<res_t>(manual_initialize,
(right.w() * left.w()) - (right.x() * left.x()) -
(right.y() * left.y()) - (right.z() * left.z()),
(right.w() * left.x()) + (right.x() * left.w()) +
(right.y() * left.z()) - (right.z() * left.y()),
(right.w() * left.y()) - (right.x() * left.z()) +
(right.y() * left.w()) + (right.z() * left.x()),
(right.w() * left.z()) + (right.x() * left.y()) -
(right.y() * left.x()) + (right.z() * left.w()));
}
template<typename T, typename U>
auto operator*(const quaternion<T>& left, const vec3<U>& right){
return left.to_mat3() * right;
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
auto operator*(const quaternion<T>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() * right, left.x() * right, left.y() * right, left.z() * right);
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
auto operator/(const quaternion<T>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() / right, left.x() / right, left.y() / right, left.z() / right);
}
template<typename T, typename U>
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right){
left.w() += right.w();
left.x() += right.x();
left.y() += right.y();
left.z() += right.z();
return left;
}
template<typename T, typename U>
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right){
left.w() -= right.w();
left.x() -= right.x();
left.y() -= right.y();
left.z() -= right.z();
return left;
}
template<typename T, typename U>
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right){
left = left * right;
return left;
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
decltype(auto) operator*=(quaternion<T>& left, U&& right){
left.w() *= right;
left.x() *= right;
left.y() *= right;
left.z() *= right;
return left;
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
decltype(auto) operator/=(quaternion<T>& left, U&& right){
left.w() /= right;
left.x() /= right;
left.y() /= right;
left.z() /= right;
return left;
}
}
#endif

View File

@ -1,102 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_VEC_HPP
#define REXY_VEC_HPP
#include "mat.hpp"
namespace math{
template<typename T, size_t R>
class vector : public matrix_base<T,R,1>
{
private:
using base = matrix_base<T,R,1>;
public:
using value_type = typename base::value_type;
using size_type = typename base::size_type;
using pointer = typename base::pointer;
using const_pointer = typename base::const_pointer;
using reference = typename base::reference;
using const_reference = typename base::const_reference;
public:
using base::base;
constexpr vector(const vector&) = default;
constexpr vector(vector&&) = default;
~vector() = default;
//Assignement
constexpr vector& operator=(const vector&) = default;
constexpr vector& operator=(vector&&) = default;
template<typename U>
constexpr vector& operator=(const vector<U,R>& m);
constexpr reference operator[](size_type i);
constexpr const_reference operator[](size_type i)const;
constexpr reference x();
constexpr const_reference x()const;
template<typename U = T>
constexpr reference y();
template<typename U = T>
constexpr const_reference y()const;
template<typename U = T>
constexpr reference z();
template<typename U = T>
constexpr const_reference z()const;
template<typename U = T>
constexpr reference w();
template<typename U = T>
constexpr const_reference w()const;
};
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right);
template<typename T, typename U, size_t R>
constexpr auto operator*(const vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr auto operator*(const vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr auto operator*(U&& left, const vector<T,R>& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr auto operator/(const vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R>
constexpr auto operator+(const vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R>
constexpr auto operator-(const vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R>
constexpr auto operator-(const vector<T,R>& left);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator-=(vector<T,R>& left, const vector<U,R>& right);
}
#include "vec.tpp"
#endif

View File

@ -1,193 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_VEC_TPP
#define REXY_VEC_TPP
namespace math{
template<typename T, size_t R>
template<typename U>
constexpr vector<T,R>& vector<T,R>::operator=(const vector<U,R>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t R>
constexpr auto vector<T,R>::operator[](size_type i) -> reference{
return this->m_data[i];
}
template<typename T, size_t R>
constexpr auto vector<T,R>::operator[](size_type i)const -> const_reference{
return this->m_data[i];
}
template<typename T, size_t R>
constexpr auto vector<T,R>::x() -> reference{
return this->m_data[0];
}
template<typename T, size_t R>
constexpr auto vector<T,R>::x()const -> const_reference{
return this->m_data[0];
}
template<typename T, size_t R>
template<typename U>
constexpr auto vector<T,R>::y() -> reference{
static_assert(R > 1, "Vector does not contain a 2nd element");
return this->m_data[1];
}
template<typename T, size_t R>
template<typename U>
constexpr auto vector<T,R>::y()const -> const_reference{
static_assert(R > 1, "Vector does not contain a 2nd element");
return this->m_data[1];
}
template<typename T, size_t R>
template<typename U>
constexpr auto vector<T,R>::z() -> reference{
static_assert(R > 2, "Vector does not contain a 3rd element");
return this->m_data[2];
}
template<typename T, size_t R>
template<typename U>
constexpr auto vector<T,R>::z()const -> const_reference{
static_assert(R > 2, "Vector does not contain a 3rd element");
return this->m_data[2];
}
template<typename T, size_t R>
template<typename U>
constexpr auto vector<T,R>::w() -> reference{
static_assert(R > 3, "Vector does not contain a 4th element");
return this->m_data[3];
}
template<typename T, size_t R>
template<typename U>
constexpr auto vector<T,R>::w()const -> const_reference{
static_assert(R > 3, "Vector does not contain a 4th element");
return this->m_data[3];
}
template<typename T, typename U, size_t C, size_t R>
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
vector<res_t,R> res(zero_initialize);
size_t index = 0;
//columns == rows
for(size_t i = 0; i < R; ++i){
for(size_t k = 0; k < C; ++k){
res.get(index) += left[i][k] * right[k];
}
++index;
}
return res;
}
template<typename T, typename U, size_t R>
constexpr auto operator*(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
res_t res = 0;
for(size_t i = 0; i < R; ++i){
res += left[i] * right[i];
}
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator*(const vector<T,R>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] * std::forward<U>(right);
}
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator*(U&& left, const vector<T,R>& right){
using res_t = decltype(std::declval<U>() * std::declval<T>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = std::forward<U>(right) * left[i];
}
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr auto operator/(const vector<T,R>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] / std::forward<U>(right);
}
return res;
}
template<typename T, typename U, size_t R>
constexpr auto operator+(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] + right[i];
}
return res;
}
template<typename T, typename U, size_t R>
constexpr auto operator-(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] - right[i];
}
return res;
}
template<typename T, typename U, size_t R>
constexpr auto operator-(const vector<T,R>& left){
using res_t = decltype(-std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = -left[i];
}
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right){
for(size_t i = 0; i < R; ++i){
left[i] *= right;
}
return left;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right){
for(size_t i = 0; i < R; ++i){
left[i] /= right;
}
return left;
}
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right){
for(size_t i = 0; i < R; ++i){
left[i] += right[i];
}
return left;
}
template<typename T, typename U, size_t R>
constexpr decltype(auto) operator-=(vector<T,R>& left, const vector<U,R>& right){
for(size_t i = 0; i < R; ++i){
left[i] -= right[i];
}
return left;
}
}
#endif

View File

@ -1,48 +0,0 @@
#ifndef OUR_DICK_RENDER_HPP
#define OUR_DICK_RENDER_HPP
#include <cstdint>
#include <GLFW/glfw3.h>
#define OPENGL_VERSION 400
#define GLSL_VERSION 400
class GLFWwindow;
class render_manager
{
private:
using close_callback = void(*)(void);
using input_callback = void(*)(GLFWwindow*, int, int, int, int);
close_callback m_window_close_callback;
input_callback m_input_handler;
GLFWwindow* m_main_window;
public:
enum renderer_error{
RENDERER_OK,
RENDERER_CONTEXT_ERROR,
RENDERER_WINDOW_ERROR,
RENDERER_INIT_ERROR,
};
render_manager(const render_manager&) = delete;
render_manager(render_manager&&) = delete;
render_manager();
renderer_error init(int width, int height, const char* title); // Sets up the OpenGL environment
void update(); // Update the GL context and draw new frame
void request_exit();
void handle_window_close_event(close_callback handle){
m_window_close_callback = handle;
}
void handle_keypress_event(input_callback handle){
m_input_handler = handle;
glfwSetKeyCallback(m_main_window, m_input_handler);
}
};
#endif

35
include/renderable.hpp Normal file
View File

@ -0,0 +1,35 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_RENDERABLE_HPP
#define OUR_DICK_RENDERABLE_HPP
#include "gfx/ogl/shader_program.hpp"
#include "egn/object.hpp"
class renderable_iface
{
public:
virtual ~renderable_iface(void) = default;
virtual void render(gfx::ogl::shader_program&) = 0;
};
class renderable_object : public renderable_iface, public egn::object{};
#endif

98
include/ttt/board.hpp Normal file
View File

@ -0,0 +1,98 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_BOARD_HPP
#define OUR_DICK_BOARD_HPP
#include <rml/vec.hpp>
#include "config.hpp"
#include <memory> //unique_ptr, shared_ptr
#include "egn/object.hpp"
#include "wip/renderable.hpp"
#include "wip/renderer.hpp"
#include "wip/mesh.hpp"
#include "wip/material.hpp"
#include "wip/draw_command.hpp"
#include "wip/shader.hpp"
class new_tile : public egn::object
{
public:
enum class state{
BLANK = 0,
X,
O
};
private:
rml::vec4f m_color_filter;
public:
state value = state::BLANK;
new_tile(void);
new_tile(state start_value);
void set_color(const rml::vec4f& color);
const rml::vec4f& get_color(void)const;
};
class new_board : public wip::gfx::renderable, public egn::object
{
private:
static constexpr wip::gfx::vertex s_mesh_vertices[] = {
{{-1, 1, 0}, {0, 1}},
{{-1, -1, 0}, {0, 0}},
{{ 1, -1, 0}, {1, 0}},
{{ 1, -1, 0}, {1, 0}},
{{ 1, 1, 0}, {1, 1}},
{{-1, 1, 0}, {0, 1}}
};
private:
std::shared_ptr<wip::gfx::material> m_blank;
std::shared_ptr<wip::gfx::material> m_x;
std::shared_ptr<wip::gfx::material> m_o;
std::shared_ptr<wip::gfx::mesh> m_tile_mesh;
std::unique_ptr<new_tile[]> m_tiles;
public:
new_board(wip::gfx::renderer& r, const std::shared_ptr<wip::gfx::material>& blank, const std::shared_ptr<wip::gfx::material>& x, const std::shared_ptr<wip::gfx::material>& o);
new_tile::state check_winner(void)const;
bool is_full(void)const;
int click_collision_cheat(const rml::vec3f&)const;
void set_tile(int index, new_tile::state value);
new_tile& get_tile(int index);
const new_tile& get_tile(int index)const;
void reset(void);
void submit_render(wip::gfx::renderer& r)override;
void render(wip::gfx::renderer& r, wip::gfx::draw_command& c)override;
private:
new_tile::state check_rows_(void)const;
new_tile::state check_columns_(void)const;
new_tile::state check_diagonals_(void)const;
wip::gfx::material& get_material_for_(new_tile::state v);
};
#endif

147
include/ttt/font_shader.hpp Normal file
View File

@ -0,0 +1,147 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_FONT_SHADER_HPP
#define OUR_DICK_FONT_SHADER_HPP
namespace font_shader{
static constexpr char vertex_shader_text[] =
R"glsl(
#version 430 core
layout (location = 0) in vec4 tex_coords;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 offset;
layout (location = 3) in vec2 size;
out VS_OUT{
vec4 tex_coords;
vec4 color;
vec2 offset;
vec2 size;
}vs_out;
void main(){
vs_out.tex_coords = tex_coords;
vs_out.color = color;
vs_out.offset = offset;
vs_out.size = size;
}
)glsl";
static constexpr char geometry_shader_text[] =
R"glsl(
#version 430 core
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
in VS_OUT{
vec4 tex_coords;
vec4 color;
vec2 offset;
vec2 size;
}gs_in[];
out GS_OUT{
vec2 tex_coords;
flat vec4 color;
}gs_out;
layout (std140) uniform view_proj_matrix{
mat4 vp_mat;
};
uniform vec2 start_pos;
void main(){
//texture coordinates need done botleft->topleft->botright->topright
//whereas the position goes topleft->botleft->topright->botright
//because freetype generates bitmaps with inverse y axis to opengl
const vec4 position = vec4(gs_in[0].offset, -1, 1);
const mat2 scaler = mat2(vp_mat[0][0], vp_mat[0][1], vp_mat[1][0], vp_mat[1][1]);
const vec2 start_position = scaler * start_pos;
const vec2 screen_pos = start_position + (scaler * gs_in[0].offset);
const vec2 size = scaler * gs_in[0].size;
const mat4 scale = vp_mat;
const vec4 p1 = scale * vec4(gs_in[0].offset.x, gs_in[0].offset.y + gs_in[0].size.y, -1, 1);
const vec4 p2 = scale * vec4(gs_in[0].offset, -1, 1);
const vec4 p3 = scale * vec4(gs_in[0].offset.x + gs_in[0].size.x, gs_in[0].offset.y + gs_in[0].size.y, -1, 1);
const vec4 p4 = scale * vec4(gs_in[0].offset.x + gs_in[0].size.x, gs_in[0].offset.y, -1, 1);
gl_Position = p1;
gs_out.tex_coords = gs_in[0].tex_coords.xy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = p2;
gs_out.tex_coords = gs_in[0].tex_coords.xw;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = p3;
gs_out.tex_coords = gs_in[0].tex_coords.zy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = p4;
gs_out.tex_coords = gs_in[0].tex_coords.zw;
gs_out.color = gs_in[0].color;
EmitVertex();
/* gl_Position = vec4(screen_pos.x, screen_pos.y + size.y, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.xy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(screen_pos, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.xw;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(screen_pos.x + size.x, screen_pos.y + size.y, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.zy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(screen_pos.x + size.x, screen_pos.y, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.zw;
gs_out.color = gs_in[0].color;
EmitVertex();
*/
EndPrimitive();
}
)glsl";
static constexpr char fragment_shader_text[] =
R"glsl(
#version 430 core
out vec4 frag_color;
in GS_OUT{
vec2 tex_coords;
flat vec4 color;
}fs_in;
uniform sampler2D texture1;
void main(){
vec4 s = texture(texture1, fs_in.tex_coords);
float alpha = (s.r + s.g + s.b) / 3.0;
vec4 alpha_texture = vec4(s.rgb, alpha);
frag_color = alpha_texture * fs_in.color; //NOT the dot product in glsl
}
)glsl";
}
#endif

View File

@ -0,0 +1,71 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_MAIN_RENDERER_HPP
#define OUR_DICK_MAIN_RENDERER_HPP
#include "gfx/ogl/shader_program.hpp"
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/vbo.hpp"
#include <rml/math.hpp>
#include "basic_framebuffer.hpp"
#include "wip/renderer.hpp"
#include <memory> //shared_ptr
//TODO remove this file
class scene{};
class main_renderer
{
private:
struct vertex{
rml::vec2f pos;
rml::vec2f tex_coord;
};
static constexpr vertex s_vertices[] = {
{{-1.0f, 1.0f}, {0.0f, 1.0f}},
{{-1.0f, -1.0f}, {0.0f, 0.0f}},
{{ 1.0f, -1.0f}, {1.0f, 0.0f}},
{{ 1.0f, -1.0f}, {1.0f, 0.0f}},
{{ 1.0f, 1.0f}, {1.0f, 1.0f}},
{{-1.0f, 1.0f}, {0.0f, 1.0f}}
};
private:
basic_framebuffer m_fb;
gfx::ogl::fbo m_primary_fb;
std::shared_ptr<gfx::ogl::shader_program> m_square_shader;
std::shared_ptr<gfx::ogl::shader_program> m_screen_shader;
gfx::ogl::vbo m_vbo;
gfx::ogl::vao m_vao;
gfx::ogl::vao m_board_vao;
gfx::ogl::vbo m_board_vbo;
public:
main_renderer(wip::gfx::renderer& res, int width, int height);
void set_vp_matrix(const rml::mat4f& vp);
void render(scene&);
gfx::ogl::texture& color_buffer(void);
void resize_viewport(int width, int height);
const rml::vec4f& get_viewport(void)const;
};
#endif

View File

@ -0,0 +1,47 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_PAUSE_STATE_HPP
#define OUR_DICK_PAUSE_STATE_HPP
#include "egn/game_state.hpp"
#include "egn/input.hpp"
#include "gfx/ogl/texture.hpp"
#include "wip/renderer.hpp"
#include "wip/square.hpp"
#include "egn/camera.hpp"
class pause_state : public egn::game_state_iface
{
private:
egn::game_state_iface* m_under_state;
std::shared_ptr<wip::square> m_square;
egn::ortho_camera m_main_camera;
double m_elapsed_time;
public:
pause_state(egn::game& owner, egn::game_state_iface* under);
void enter(void);
void leave(void);
void handle_input(const egn::input_event& event);
void update(double time);
void render(void);
};
#endif

View File

@ -0,0 +1,52 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_PLAY_STATE_HPP
#define OUR_DICK_PLAY_STATE_HPP
#include "egn/game_state.hpp"
#include "main_renderer.hpp"
#include "egn/camera.hpp"
#include <rml/vec.hpp>
#include "board.hpp"
class play_state : public egn::game_state_iface
{
private:
main_renderer m_main_renderer;
std::shared_ptr<new_board> m_board;
int m_current_player = 1;
double m_last_time;
int m_current_tile = -1;
bool m_mouse_held = false;
egn::ortho_camera m_main_camera;
public:
play_state(egn::game& owner, int width, int height);
void enter(void)override;
void leave(void)override;
void handle_input(const egn::input_event& events)override;
void update(double time)override;
void render(void)override;
private:
rml::vec3f project_screen_to_world_(const rml::vec3f& screen);
};
#endif

View File

@ -0,0 +1,65 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_SCREEN_RENDERER_HPP
#define OUR_DICK_SCREEN_RENDERER_HPP
#include "gfx/ogl/vbo.hpp"
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/texture.hpp"
#include <rml/math.hpp>
#include "gfx/ogl/shader_program.hpp"
#include "wip/renderer.hpp"
#include "egn/font.hpp"
#include <memory> //shared_ptr
//TODO remove this file
class scene{};
class screen_renderer
{
private:
struct vertex{
rml::vec2f pos;
rml::vec2f tex_coord;
};
static constexpr vertex s_vertices[] = {
{{-1.0f, 1.0f}, {0.0f, 1.0f}},
{{-1.0f, -1.0f}, {0.0f, 0.0f}},
{{ 1.0f, -1.0f}, {1.0f, 0.0f}},
{{ 1.0f, -1.0f}, {1.0f, 0.0f}},
{{ 1.0f, 1.0f}, {1.0f, 1.0f}},
{{-1.0f, 1.0f}, {0.0f, 1.0f}}
};
private:
std::shared_ptr<gfx::ogl::shader_program> m_screen_shader;
gfx::ogl::vbo m_vbo;
gfx::ogl::vao m_vao;
std::shared_ptr<gfx::ogl::texture> m_texture;
int m_screen_width, m_screen_height;
public:
screen_renderer(wip::gfx::renderer& res, int width, int height, const std::shared_ptr<gfx::ogl::texture>& base_tex);
void render(scene&);
void resize_viewport(int width, int height);
};
#endif

View File

@ -0,0 +1,46 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_SCREEN_SHADER_HPP
#define OUR_DICK_SCREEN_SHADER_HPP
namespace screen_shader{
static constexpr char vertex_shader_text[] = "#version 430 core\n"
"layout (location = 0) in vec2 position;"
"layout (location = 1) in vec2 tex_coords;"
"out vec2 frag_tex_coords;"
"void main(){"
"gl_Position = vec4(position, -1.0, 1.0);"
"frag_tex_coords = tex_coords;"
"}";
static constexpr char fragment_shader_text[] = "#version 430 core\n"
"out vec4 FragColor;"
"in vec2 frag_tex_coords;"
"uniform sampler2D texture1;"
"void main(){"
"FragColor = texture(texture1, frag_tex_coords);"
//texture(texture1, frag_tex_coords);"
"}";
}
#endif

View File

@ -0,0 +1,110 @@
/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_SQUARE_SHADER_HPP
#define OUR_DICK_SQUARE_SHADER_HPP
namespace square_shader{
static constexpr char vertex_shader_text[] =
R"glsl(
#version 430 core
//Purely a passthrough vertex shader
layout (location = 0) in int texture_id;
layout (location = 1) in vec4 color;
layout (location = 2) in mat4 model_mat;
out VS_OUT{
mat4 model_mat;
int texture_id;
vec4 color;
}vs_out;
void main(){
vs_out.model_mat = model_mat;
vs_out.texture_id = texture_id;
vs_out.color = color;
}
)glsl";
static constexpr char geometry_shader_text[] =
R"glsl(
#version 430 core
//Generate a square around a point defined by a model matrix
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
//perspective*view matrix
uniform mat4 vp_mat;
in VS_OUT{
mat4 model_mat;
int texture_id;
vec4 color;
}gs_in[];
out GS_OUT{
vec2 frag_coord;
flat int texture_id;
vec4 color;
}gs_out;
//define square's corner offsets
const vec2 offsets[4] = vec2[](
vec2(-1, 1),
vec2(-1, -1),
vec2(1, 1),
vec2(1, -1)
);
void main(){
for(int i = 0;i < 4;++i){
gl_Position = vp_mat * gs_in[0].model_mat * vec4(offsets[i], 0, 1);
gs_out.frag_coord = vec2(clamp(offsets[i].x, 0, 1), clamp(offsets[i].y, 0, 1));
gs_out.texture_id = gs_in[0].texture_id;
gs_out.color = gs_in[0].color;
EmitVertex();
}
EndPrimitive();
}
)glsl";
static constexpr char fragment_shader_text[] =
R"glsl(
#version 430 core
in GS_OUT{
vec2 frag_coord;
flat int texture_id;
vec4 color;
}fs_in;
out vec4 frag_color;
uniform sampler2DArray textures;
void main(){
frag_color = mix(texture(textures, vec3(fs_in.frag_coord, fs_in.texture_id)), fs_in.color, fs_in.color.a);
}
)glsl";
}
#endif

View File

@ -0,0 +1,41 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_TIC_TAC_TOE_HPP
#define OUR_DICK_TIC_TAC_TOE_HPP
#include "egn/game.hpp"
#include "egn/game_state.hpp"
#include "config.hpp"
#include <queue>
class tic_tac_toe : public egn::game
{
private:
bool m_game_over = false;
public:
tic_tac_toe(int width, int height);
bool is_game_over(void)const;
void on_notify(const egn::game_state_event& e)override;
};
#endif

View File

@ -16,13 +16,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MATH_HPP
#define REXY_MATH_HPP
#ifndef OUR_DICK_UTIL_INIT_CONSTANTS_HPP
#define OUR_DICK_UTIL_INIT_CONSTANTS_HPP
#include "fwd_declare.hpp"
#include "math_common.hpp"
#include "vec.hpp"
#include "mat.hpp"
#include "quat.hpp"
namespace util{
struct no_initialize_t{};
static constexpr no_initialize_t no_initialize;
}
#endif

View File

@ -1,123 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_UTIL_RING_BUFFER_HPP
#define OUR_DICK_UTIL_RING_BUFFER_HPP
#include <vector> //vector (duh)
#include <cstdlib> //size_t
#include <atomic> //atomic (duh)
#ifdef __cpp_lib_hardware_interference_size
#include <new> //hardware_destructive_interference_size
#endif
#ifndef __cpp_aligned_new
//TODO: custom aligned allocator
#error "Require aligned new allocation"
#endif
namespace util{
template<typename T>
class mpmc_ring_buffer
{
public:
using value_type = T;
using size_type = size_t;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using rvalue_reference = value_type&&;
using const_reference = const value_type&;
private:
#ifdef __cpp_lib_hardware_interference_size
static constexpr size_t cacheline_size = std::hardware_destructive_interference_size;
#else
//Best guess
static constexpr size_t cacheline_size = 64;
#endif
class slot
{
public:
static constexpr size_type active_bit = 1;
private:
//ensure no false sharing with previous slot in queue
alignas(cacheline_size) std::atomic<size_type> m_turn = {0};
alignas(alignof(value_type)) unsigned char m_data[sizeof(value_type)] = {};
//ensure no false sharing with following data
char cachline_padding[cacheline_size - (sizeof(m_data) + sizeof(m_turn))];
public:
slot() = default;
slot(const slot& s);
slot(slot&& s);
~slot();
template<typename... Args>
void construct(Args&&... args);
void destruct();
const_reference get()const&;
reference get()&;
rvalue_reference get()&&;
std::atomic<size_type>& turn();
const std::atomic<size_type>& turn()const;
};
private:
std::vector<slot> m_slots;
//keep head and tail on separate cache lines to prevent thread thrashing
alignas(cacheline_size) std::atomic<size_type> m_head;
alignas(cacheline_size) std::atomic<size_type> m_tail;
public:
explicit mpmc_ring_buffer(size_type capacity);
//copy/move NOT thread safe! requires external locking mechanism!
mpmc_ring_buffer(const mpmc_ring_buffer& m);
constexpr mpmc_ring_buffer(mpmc_ring_buffer&& m);
~mpmc_ring_buffer() = default;
mpmc_ring_buffer& operator=(const mpmc_ring_buffer& m);
constexpr mpmc_ring_buffer& operator=(mpmc_ring_buffer&& m);
//NOT thread safe! requires external locking mechanism!
void resize(size_type newcap);
//NOT thread safe! requires external locking mechanism!
void clear();
template<typename... Args>
void emplace(Args&&... args);
template<typename... Args>
bool try_emplace(Args&&... args);
void push(const_reference t);
void push(rvalue_reference t);
bool try_push(const_reference t);
bool try_push(rvalue_reference t);
void pop(reference t);
bool try_pop(reference t);
private:
constexpr size_type rotation_cnt(size_type t);
};
}
#include "ring_buffer.tpp"
#endif

View File

@ -1,217 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_UTIL_RING_BUFFER_TPP
#define OUR_DICK_UTIL_RING_BUFFER_TPP
#include <utility> //forward, move
#include <atomic> //memory_order, atomic
#include <cstring> //memcpy
namespace util{
template<typename T>
mpmc_ring_buffer<T>::slot::slot(const slot& s):
m_turn(s.m_turn.load(std::memory_order_acquire))
{
memcpy(m_data, s.m_data, sizeof(s.m_data));
}
template<typename T>
mpmc_ring_buffer<T>::slot::slot(slot&& s):
m_turn(s.m_turn.load(std::memory_order_acquire))
{
memcpy(m_data, s.m_data, sizeof(s.m_data));
}
template<typename T>
mpmc_ring_buffer<T>::slot::~slot(){
if(m_turn & active_bit){
destruct();
}
}
template<typename T>
template<typename... Args>
void mpmc_ring_buffer<T>::slot::construct(Args&&... args){
new (&m_data) value_type(std::forward<Args>(args)...);
}
template<typename T>
void mpmc_ring_buffer<T>::slot::destruct(){
reinterpret_cast<pointer>(&m_data)->~value_type();
}
template<typename T>
auto mpmc_ring_buffer<T>::slot::get()const& -> const_reference{
return reinterpret_cast<const_reference>(m_data);
}
template<typename T>
auto mpmc_ring_buffer<T>::slot::get()& -> reference{
return reinterpret_cast<reference>(m_data);
}
template<typename T>
auto mpmc_ring_buffer<T>::slot::get()&& -> rvalue_reference{
return std::move(reinterpret_cast<reference>(m_data));
}
template<typename T>
auto mpmc_ring_buffer<T>::slot::turn() -> std::atomic<size_type>&{
return m_turn;
}
template<typename T>
auto mpmc_ring_buffer<T>::slot::turn()const -> const std::atomic<size_type>&{
return m_turn;
}
template<typename T>
mpmc_ring_buffer<T>::mpmc_ring_buffer(size_type capacity):
m_slots(capacity),
m_head(0),
m_tail(0){}
template<typename T>
mpmc_ring_buffer<T>::mpmc_ring_buffer(const mpmc_ring_buffer& m):
m_slots(m.m_slots),
m_head(m.m_head.load()),
m_tail(m.m_tail.load()){}
template<typename T>
constexpr mpmc_ring_buffer<T>::mpmc_ring_buffer(mpmc_ring_buffer&& m):
m_slots(std::move(m.m_slots)),
m_head(m.m_head.load()),
m_tail(m.m_tail.load()){}
template<typename T>
mpmc_ring_buffer<T>& mpmc_ring_buffer<T>::operator=(const mpmc_ring_buffer& m){
return (*this = mpmc_ring_buffer(m));
}
template<typename T>
constexpr mpmc_ring_buffer<T>& mpmc_ring_buffer<T>::operator=(mpmc_ring_buffer&& m){
std::swap(m_slots, m.m_slots);
m_head = m.m_head.load();
m_tail = m.m_tail.load();
return *this;
}
template<typename T>
void mpmc_ring_buffer<T>::resize(size_type newcap){
mpmc_ring_buffer tmp(newcap);
size_type max = (m_head - m_tail) < newcap ? (m_head - m_tail) : newcap;
for(size_type i = m_tail, j = 0;j < max;++i, ++j){
tmp.m_slots[j].get() = std::move(m_slots[i % m_slots.capacity()].get());
tmp.m_slots[j].turn() |= 1; //in-use bit
}
tmp.m_head = max;
tmp.m_tail = 0;
*this = std::move(tmp);
}
template<typename T>
void mpmc_ring_buffer<T>::clear(){
size_type head = m_head.load(std::memory_order_acquire);
for(size_type i = m_tail;i < head;++i){
m_slots[i].destruct();
m_slots[i].turn().store(0, std::memory_order_release);
}
m_head.store(0, std::memory_order_release);
m_tail.store(0, std::memory_order_release);
}
template<typename T>
template<typename... Args>
void mpmc_ring_buffer<T>::emplace(Args&&... args){
const size_type head = m_head.fetch_add(1, std::memory_order_seq_cst);
slot& s = m_slots[head % m_slots.capacity()];
//lsb is in-use flag. wait for it to be 0
while(rotation_cnt(head) << 1 != s.turn().load(std::memory_order_acquire));
s.construct(std::forward<Args>(args)...);
//set in-use flag
s.turn().store((rotation_cnt(head) << 1) + 1, std::memory_order_release);
}
template<typename T>
template<typename... Args>
bool mpmc_ring_buffer<T>::try_emplace(Args&&... args){
size_type head = m_head.load(std::memory_order_acquire);
while(1){
slot& s = m_slots[head % m_slots.capacity()];
if((rotation_cnt(head) << 1) == s.turn().load(std::memory_order_acquire)){
if(m_head.compare_exchange_strong(head, head+1, std::memory_order_seq_cst)){
s.construct(std::forward<Args>(args)...);
s.turn().store((rotation_cnt(head) << 1) + 1, std::memory_order_release);
return true;
}
}else{
const size_type prev_head = head;
head = m_head.load(std::memory_order_acquire);
if(head == prev_head)
return false;
}
}
}
template<typename T>
void mpmc_ring_buffer<T>::push(const_reference t){
emplace(t);
}
template<typename T>
bool mpmc_ring_buffer<T>::try_push(const_reference t){
return try_emplace(t);
}
template<typename T>
void mpmc_ring_buffer<T>::push(rvalue_reference t){
emplace(std::move(t));
}
template<typename T>
bool mpmc_ring_buffer<T>::try_push(rvalue_reference t){
return try_emplace(std::move(t));
}
template<typename T>
void mpmc_ring_buffer<T>::pop(reference t){
const size_type tail = m_tail.fetch_add(1, std::memory_order_seq_cst);
slot& s = m_slots[tail % m_slots.capacity()];
//lsb is in-use flag. wait for it to be 1
while((rotation_cnt(tail) << 1) + 1 != s.turn().load(std::memory_order_acquire));
t = std::move(s).get();
s.destruct();
s.turn().store((rotation_cnt(tail) << 1) + 2, std::memory_order_release);
}
template<typename T>
bool mpmc_ring_buffer<T>::try_pop(reference t){
size_type tail = m_tail.load(std::memory_order_acquire);
while(1){
slot& s = m_slots[tail % m_slots.capacity()];
if((rotation_cnt(tail) << 1) + 1 == s.turn().load(std::memory_order_acquire)){
if(m_tail.compare_exchange_strong(tail, tail+1, std::memory_order_seq_cst)){
t = std::move(s).get();
s.destruct();
s.turn().store((rotation_cnt(tail) << 1) + 2, std::memory_order_release);
return true;
}
}else{
//if the tail hasn't moved, then we're still waiting on producer.
//if it has moved, another consumer took our data. try again.
const size_type prev_tail = tail;
tail = m_tail.load(std::memory_order_acquire);
if(tail == prev_tail)
return false;
}
}
}
template<typename T>
constexpr auto mpmc_ring_buffer<T>::rotation_cnt(size_type t) -> size_type{
return (t / m_slots.capacity());
}
}
#endif

View File

@ -0,0 +1,29 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_BASE_SHADER_HPP
#define OUR_DICK_GRAPHICS_WIP_BASE_SHADER_HPP
#include "ogl_base_shader.hpp"
namespace wip::gfx{
using base_shader = ogl::base_shader;
}
#endif

View File

@ -0,0 +1,41 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_DRAW_COMMAND_HPP
#define OUR_DICK_GRAPHICS_WIP_DRAW_COMMAND_HPP
#include "mesh.hpp"
#include "material.hpp"
#include "surface.hpp"
#include "renderable.hpp"
namespace wip::gfx{
struct draw_command{
renderable* instance;
material* mat;
mesh* msh;
surface* surf;
float distance;
unsigned int pass;
void* userptr;
};
}
#endif

34
include/wip/material.hpp Normal file
View File

@ -0,0 +1,34 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_MATERIAL_HPP
#define OUR_DICK_GRAPHICS_WIP_MATERIAL_HPP
#include "ogl_material.hpp"
namespace wip::gfx{
class material : public ogl::material
{
public:
using ogl::material::material;
};
}
#endif

32
include/wip/mesh.hpp Normal file
View File

@ -0,0 +1,32 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_MESH_HPP
#define OUR_DICK_GRAPHICS_WIP_MESH_HPP
#include "ogl_mesh.hpp"
namespace wip::gfx{
class mesh : public ogl::mesh
{
public:
using ogl::mesh::mesh;
};
}
#endif

View File

@ -0,0 +1,94 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_BASE_SHADER_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_BASE_SHADER_HPP
#include "shader_source.hpp"
#include "gfx/ogl/shader_stage.hpp"
#include "shader.hpp"
namespace wip::gfx::ogl{
class base_shader
{
public:
static inline constexpr shader_source sources[] = {
{
.text =
R"glsl(
#version 450 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 tex_coords;
layout (location = 3) in vec4 fcolor;
layout (binding = 0, std140) uniform mvp_matrix{
mat4 vp_mat;
};
layout (binding = 1, std140) uniform model_matrix{
mat4 model_mat;
};
out VS_OUT{
vec2 tex_coords;
vec4 fcolor;
}vs_out;
const vec4 vertices[6] = vec4[](vec4(0,1,0,1), vec4(0,0,0,1), vec4(1,0,0,1), vec4(1,0,0,1), vec4(1,1,0,1), vec4(0,1,0,1));
void main(){
gl_Position = vp_mat * model_mat * vec4(position, 1);
vs_out.tex_coords = tex_coords;
}
)glsl",
.len = 0,
.type = shader_type::VERTEX
},
{
.text =
R"glsl(
#version 450 core
in VS_OUT{
vec2 tex_coords;
vec4 fcolor;
}fs_in;
out vec4 frag_color;
layout (binding = 0) uniform sampler2D diffuse_texture;
uniform vec4 diffuse;
void main(){
frag_color = mix(texture(diffuse_texture, fs_in.tex_coords), fs_in.fcolor, fs_in.fcolor.a);
}
)glsl",
.len = 0,
.type = shader_type::FRAGMENT
}
};
static inline constexpr const char* vertex_shader_text = sources[0].text;
static inline constexpr const char* fragment_shader_text = sources[1].text;
};
}
#endif

77
include/wip/ogl_enums.hpp Normal file
View File

@ -0,0 +1,77 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_ENUMS_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_ENUMS_HPP
#include "gfx/ogl/vbo.hpp"
#include "gfx/ogl/shader_stage.hpp"
namespace wip::gfx::ogl{
enum class attrib_type{
FLOAT,
DOUBLE,
BYTE,
UBYTE,
SHORT,
USHORT,
INT,
UINT
};
struct shader_type
{
protected:
using underlying_type = ::gfx::ogl::shader_stage::type;
underlying_type m_value;
constexpr shader_type(underlying_type t):
m_value(t){}
public:
constexpr operator underlying_type(void)const{return m_value;}
public:
static const shader_type VERTEX;
static const shader_type FRAGMENT;
static const shader_type GEOMETRY;
static const shader_type COMPUTE;
};
constexpr shader_type shader_type::VERTEX = underlying_type::VERTEX;
constexpr shader_type shader_type::FRAGMENT = underlying_type::FRAGMENT;
constexpr shader_type shader_type::GEOMETRY = underlying_type::GEOMETRY;
constexpr shader_type shader_type::COMPUTE = underlying_type::COMPUTE;
struct buffer_type
{
protected:
using underlying_type = ::gfx::ogl::buffer::usage;
underlying_type m_value;
constexpr buffer_type(underlying_type t):
m_value(t){}
public:
constexpr operator underlying_type(void)const{return m_value;}
public:
static const buffer_type STATIC;
static const buffer_type DYNAMIC;
static const buffer_type STREAM;
};
constexpr buffer_type buffer_type::STATIC = underlying_type::STATIC_DRAW;
constexpr buffer_type buffer_type::DYNAMIC = underlying_type::DYNAMIC_DRAW;
constexpr buffer_type buffer_type::STREAM = underlying_type::STREAM_DRAW;
}
#endif

View File

@ -0,0 +1,53 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_MATERIAL_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_MATERIAL_HPP
#include <rml/vec.hpp>
#include "gfx/ogl/shader_program.hpp"
#include "gfx/ogl/texture.hpp"
#include <memory> //shared_ptr
namespace wip::gfx::ogl{
class material
{
public:
std::shared_ptr<::gfx::ogl::shader_program> shader;
std::shared_ptr<::gfx::ogl::texture> diffuse_texture;
rml::vec4f diffuse;
rml::vec4f specular;
rml::vec4f ambient;
float shininess;
material(const std::shared_ptr<::gfx::ogl::shader_program>& sh);
material(const material&) = default;
material(material&&) = default;
~material(void) = default;
material& operator=(const material&) = default;
material& operator=(material&&) = default;
void bind(void);
};
}
#endif

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@ -16,36 +16,39 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MATH_FWD_DECLARE_HPP
#define REXY_MATH_FWD_DECLARE_HPP
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_MESH_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_MESH_HPP
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/vbo.hpp"
#include "material.hpp"
#include "vertex.hpp"
#include <cstdlib> //size_t
#include <vector>
namespace math{
namespace wip::gfx{
class renderer;
}
template<typename T, size_t R, size_t C>
class matrix;
template<typename T, size_t R>
class vector;
template<typename T>
class quaternion;
namespace wip::gfx::ogl{
template<typename T>
using mat2 = matrix<T,2,2>;
template<typename T>
using mat3 = matrix<T,3,3>;
template<typename T>
using mat4 = matrix<T,4,4>;
class mesh
{
public:
size_t m_num_vertices;
::gfx::ogl::vbo m_buffer;
::gfx::ogl::vao m_attributes;
template<typename T>
using vec2 = vector<T,2>;
template<typename T>
using vec3 = vector<T,3>;
template<typename T>
using vec4 = vector<T,4>;
public:
mesh(const std::vector<vertex>& vertices);
mesh(const vertex* v, size_t count);
void bind(void);
void render(::wip::gfx::renderer& r);
};
template<typename T>
using quat = quaternion<T>;
}
#endif

View File

@ -0,0 +1,68 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_RENDERER_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_RENDERER_HPP
#include "gfx/resource_container.hpp"
#include <rml/vec.hpp>
#include <rml/mat.hpp>
#include "gfx/ogl/ubo.hpp"
#include "ogl_resource_manager.hpp"
#include "draw_command.hpp"
namespace wip::gfx::ogl{
class renderer : public resource_manager
{
public:
template<class T>
using container_type = resource_manager::container_type<T>;
protected:
::gfx::ogl::ubo<rml::mat4f> m_camera_uniform;
::gfx::ogl::ubo<rml::mat4f> m_model_uniform;
public:
renderer(void) = default;
renderer(const renderer&) = default;
renderer(renderer&&) = default;
~renderer(void) = default;
renderer& operator=(const renderer&) = default;
renderer& operator=(renderer&&) = default;
void set_viewport(const rml::vec4f& vp);
void set_model_matrix(const rml::mat4f& mat);
void set_camera(const rml::mat4f& view, const rml::mat4f& proj);
void bind_default_surface(void);
void clear_current_surface(void);
void draw_tris(int offset, int vertex_count);
void process_command(draw_command& c);
};
}
#endif

View File

@ -0,0 +1,59 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_RESOURCE_MANAGER_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_RESOURCE_MANAGER_HPP
#include "gfx/resource_container.hpp"
#include "gfx/ogl/shader_program.hpp"
#include "gfx/ogl/texture.hpp"
#include "gfx/ogl/fbo.hpp"
namespace wip::gfx::ogl{
class resource_manager
{
public:
template<class T>
using container_type = ::gfx::resource_container<T>;
protected:
container_type<::gfx::ogl::shader_program> m_shader_programs;
container_type<::gfx::ogl::shader_stage> m_shader_stages;
container_type<::gfx::ogl::texture> m_textures;
container_type<::gfx::ogl::texture_array> m_texture_arrays;
container_type<::gfx::ogl::fbo> m_framebuffers;
public:
resource_manager(void);
const container_type<::gfx::ogl::shader_program>& shader_programs(void)const;
container_type<::gfx::ogl::shader_program>& shader_programs(void);
const container_type<::gfx::ogl::shader_stage>& shader_stages(void)const;
container_type<::gfx::ogl::shader_stage>& shader_stages(void);
const container_type<::gfx::ogl::texture>& textures(void)const;
container_type<::gfx::ogl::texture>& textures(void);
const container_type<::gfx::ogl::texture_array>& texture_arrays(void)const;
container_type<::gfx::ogl::texture_array>& texture_arrays(void);
const container_type<::gfx::ogl::fbo>& framebuffers(void)const;
container_type<::gfx::ogl::fbo>& framebuffers(void);
};
}
#endif

View File

@ -0,0 +1,65 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_SHADER_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_SHADER_HPP
#include "gfx/ogl/shader_program.hpp"
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/vbo.hpp"
#include "gfx/ogl/texture.hpp"
#include "ogl_enums.hpp"
#include <cstdlib> //size_t
namespace wip::gfx{
class pipeline_setup;
}
namespace wip::gfx::ogl{
using buffer = ::gfx::ogl::vbo;
using shader_stage = ::gfx::ogl::shader_stage;
class shader
{
private:
struct attrib_info{
size_t stride;
};
private:
::gfx::ogl::shader_program m_shader;
::gfx::ogl::vao m_attributes;
public:
shader(const pipeline_setup& s);
void bind_attribute(const buffer&, int binding, size_t offset, size_t stride);
void bind_uniform(const buffer&, int binding);
void bind_texture(const ::gfx::ogl::texture&, int binding);
void bind(void);
private:
void enable_attribs_(const pipeline_setup& s);
void attach_stages_(const pipeline_setup& s);
};
}
#endif

View File

@ -0,0 +1,44 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_SURFACE_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_SURFACE_HPP
#include "gfx/ogl/fbo.hpp"
#include <memory> //shared_ptr
namespace wip::gfx::ogl{
class surface
{
public:
std::shared_ptr<::gfx::ogl::fbo> framebuffer;
public:
surface(void);
surface(const std::shared_ptr<::gfx::ogl::fbo>& fb);
void clear(void);
void bind(void);
};
}
#endif

49
include/wip/pipeline.hpp Normal file
View File

@ -0,0 +1,49 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_PIPELINE_HPP
#define OUR_DICK_GRAPHICS_WIP_PIPELINE_HPP
#include "shader.hpp"
#include <vector>
namespace wip::gfx{
class pipeline_setup
{
friend shader;
protected:
std::vector<shader_stage> m_stages;
std::vector<vertex_attribute> m_attributes;
public:
pipeline_setup(void) = default;
void add_attribute(const vertex_attribute&);
void add_shader_stage(const shader_stage&);
template<class... Ts>
void emplace_shader_stage(Ts&&... ts);
};
template<class... Ts>
void pipeline_setup::emplace_shader_stage(Ts&&... ts){
m_stages.emplace_back(std::forward<Ts>(ts)...);
}
}
#endif

View File

@ -0,0 +1,40 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_RENDERABLE_HPP
#define OUR_DICK_GRAPHICS_WIP_RENDERABLE_HPP
#include "gfx/ogl/shader_program.hpp"
namespace wip::gfx{
class renderer;
struct draw_command;
class renderable
{
public:
virtual ~renderable(void) = default;
virtual void submit_render(renderer& r) = 0;
virtual void render(renderer& r, draw_command& c) = 0;
};
}
#endif

75
include/wip/renderer.hpp Normal file
View File

@ -0,0 +1,75 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_RENDERER_HPP
#define OUR_DICK_GRAPHICS_WIP_RENDERER_HPP
#include "ogl_renderer.hpp"
#include "material.hpp"
#include "mesh.hpp"
#include "surface.hpp"
#include "draw_command.hpp"
#include "shader.hpp"
#include <list>
namespace wip::gfx{
class renderer : public ogl::renderer
{
public:
using parent = ogl::renderer;
template<class T>
using container_type = parent::container_type<T>;
template<class T>
using node = typename container_type<T>::node;
protected:
container_type<material> m_materials;
container_type<mesh> m_meshs;
container_type<surface> m_surfaces;
container_type<shader> m_shaders;
std::list<draw_command> m_commands;
public:
renderer(void);
renderer(const renderer&) = default;
renderer(renderer&&) = default;
~renderer(void) = default;
renderer& operator=(const renderer&) = default;
renderer& operator=(renderer&&) = default;
//Access to resources
const container_type<mesh>& meshs(void)const;
container_type<mesh>& meshs(void);
const container_type<material>& materials(void)const;
container_type<material>& materials(void);
const container_type<surface>& surfaces(void)const;
container_type<surface>& surfaces(void);
const container_type<shader>& shaders(void)const;
container_type<shader>& shaders(void);
void submit_command(const draw_command& c);
void render(void);
};
}
#endif

View File

@ -0,0 +1,41 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_ENGINE_WIP_SCENE_MANAGER_HPP
#define OUR_DICK_ENGINE_WIP_SCENE_MANAGER_HPP
namespace wip::egn{
class renderable
{
public:
virtual void render(::wip::gfx::renderer&) = 0;
};
class scene_manager
{
protected:
std::list<std::shared_ptr<renderable>> m_renderables;
std::list<std::shared_ptr<::egn::object>> m_objects;
public:
};
}
#endif

49
include/wip/shader.hpp Normal file
View File

@ -0,0 +1,49 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_SHADER_HPP
#define OUR_DICK_GRAPHICS_WIP_SHADER_HPP
#include "ogl_shader.hpp"
#include <utility> //forward
#include <cstdlib> //size_t
namespace wip::gfx{
namespace impl = ogl;
using attrib_type = impl::attrib_type;
using shader_type = impl::shader_type;
using buffer_type = impl::buffer_type;
using buffer = impl::buffer;
using shader_stage = impl::shader_stage;
using shader = impl::shader;
struct vertex_attribute{
int location;
int binding;
size_t offset;
size_t count;
attrib_type type;
};
}
#endif

View File

@ -0,0 +1,36 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_SHADER_SOURCE_HPP
#define OUR_DICK_GRAPHICS_WIP_SHADER_SOURCE_HPP
#include <cstdlib> //size_t
#include "shader.hpp"
namespace wip::gfx{
struct shader_source{
const char* text;
size_t len;
shader_type type;
};
}
#endif

57
include/wip/square.hpp Normal file
View File

@ -0,0 +1,57 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_WIP_SQUARE_HPP
#define OUR_DICK_WIP_SQUARE_HPP
#include "vertex.hpp"
#include "mesh.hpp"
#include "material.hpp"
#include "renderer.hpp"
#include "renderable.hpp"
#include <memory> //shared_ptr
namespace wip{
class square : public gfx::renderable
{
public:
static constexpr gfx::vertex mesh_vertices[] = {
{{-1, 1, 0}, {0, 1}},
{{-1, -1, 0}, {0, 0}},
{{ 1, -1, 0}, {1, 0}},
{{ 1, -1, 0}, {1, 0}},
{{ 1, 1, 0}, {1, 1}},
{{-1, 1, 0}, {0, 1}}
};
public:
std::shared_ptr<gfx::mesh> m_mesh;
std::shared_ptr<gfx::material> m_material;
public:
square(const std::shared_ptr<gfx::mesh>& msh, const std::shared_ptr<gfx::material>& mat);
void submit_render(gfx::renderer& r)override;
void render(gfx::renderer& r, gfx::draw_command&)override;
};
}
#endif

34
include/wip/surface.hpp Normal file
View File

@ -0,0 +1,34 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_SURFACE_HPP
#define OUR_DICK_GRAPHICS_WIP_SURFACE_HPP
#include "ogl_surface.hpp"
namespace wip::gfx{
class surface : public ogl::surface
{
public:
using ogl::surface::surface;
};
}
#endif

33
include/wip/vertex.hpp Normal file
View File

@ -0,0 +1,33 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_WIP_VERTEX_HPP
#define OUR_DICK_GRAPHICS_WIP_VERTEX_HPP
#include <rml/vec.hpp>
namespace wip::gfx{
struct vertex{
rml::vec3f position;
rml::vec2f tex_coords;
};
}
#endif

View File

@ -19,14 +19,17 @@ ifeq ($(OS),Windows_NT)
WINDOWS::=1
endif
SOURCE_DIRS::=src src/audio src/audio/impl
SOURCE_DIRS::=src src/audio src/audio/impl src/gfx src/gfx/ogl src/egn src/ttt src/wip src/math
SOURCES::=
OBJDIR::=obj
DEPDIR::=$(OBJDIR)/dep
LIBDIRS::=
LIBDIRS::=lib
INCLUDE_DIRS::=include
CFLAGS::=-std=c18 -Wall -pedantic -Wextra
CXXFLAGS::=-std=c++17 -Wall -pedantic -Wextra
CXXFLAGS::=-std=c++20 -Wall -pedantic -Wextra -fno-rtti -fno-exceptions
PKGS::=freetype2 librml librexy
DEBUG_CFLAGS::=
DEBUG_CXXFLAGS::=-DOUR_DICK_DEBUG=2
EXT::=cpp
LANG::=$(EXT)
MAIN_EXECUTABLE::=tester
@ -39,8 +42,13 @@ ifneq ($(WINDOWS),1)
#*nix settings
CC::=gcc
CXX::=g++
LDLIBS::=
LDFLAGS::= -lglfw -lgl3w -ldl -lm -lportaudio -lasound -lsndfile -lpthread
LDLIBS::=-lglfw -lglad -ldl -lm -lportaudio -lsndfile -lpthread -lrexy $(shell pkg-config --libs freetype2)
ifeq ($(shell uname -s),Linux)
LDLIBS+=-lasound
endif
LDFLAGS::=
DEBUG_LDLIBS::=
DEBUG_LDFLAGS::=
STRIP::=strip
RANLIB::=ranlib
AR::=ar
@ -51,8 +59,10 @@ else #windows
MINGW_PREFIX::=x86_64-w64-mingw32-
CC::=$(MINGW_PREFIX)gcc
CXX::=$(MINGW_PREFIX)g++
LDLIBS::=-lglfw -lgl3w -ldl -lm -lportaudio
LDLIBS::=-lglfw -lglad -ldl -lm -lportaudio -lsndfile -lpthread
LDFLAGS::=
DEBUG_LDLIBS::=
DEBUG_LDFLAGS::=
STRIP::=$(MINGW_PREFIX)strip
RANLIB::=$(MINGW_PREFIX)ranlib
AR::=$(MINGW_PREFIX)ar
@ -100,27 +110,32 @@ endif
#setup compiler and flags based on language
ifeq ($(LANG),cpp)
COMPILER_FLAGS::=$(CXXFLAGS)
ifneq ($(RELEASE),1)
COMPILER_FLAGS+= $(DEBUG_CXXFLAGS)
endif
COMPILER::=$(CXX)
else ifeq ($(LANG),c)
COMPILER_FLAGS::=$(CFLAGS)
ifneq ($(RELEASE),1)
COMPILER_FLAGS+= $(DEBUG_CFLAGS)
endif
COMPILER::=$(CC)
endif
ifeq ($(RELEASE),1)
#a lot of false strict aliasing warnings from gcc 9
COMPILER_FLAGS+=-O2 -Wno-strict-aliasing
COMPILER_FLAGS+=-O2
else
#default target
COMPILER_FLAGS+=-O0 -g3 -ggdb
ifeq ($(MEMCHK),1)
#use asan to check memory leaks/invalid accesses
LDFLAGS+=-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls
COMPILER_FLAGS+=-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls
COMPILER_FLAGS+=-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls -DOUR_DICK_DISABLE_NOTHROW_ALLOCATE -DENABLE_MEMCHK=1
endif
ifeq ($(UNDEFCHK),1)
LDFLAGS+=-fsanitize=undefined
COMPILER_FLAGS+=-fsanitize=undefined
COMPILER_FLAGS+=-fsanitize=undefined -DENABLE_UNDEFCHK=1
endif
endif
@ -133,13 +148,18 @@ endif
#add dependency tracking and include directories
INTERNAL_COMPILERFLAGS=-c $(foreach dir,$(INCLUDE_DIRS),-I"$(dir)") -MMD -MP -MF"$(DEPDIR)/$(notdir $(patsubst %.o,%.d,$@))"
INTERNAL_LINKFLAGS=$(foreach dir,$(LIBDIRS),-L"$(dir)")
INTERNAL_COMPILERFLAGS=-c $(foreach dir,$(INCLUDE_DIRS),-I"$(dir)") $(foreach pkg,$(PKGS),$(shell pkg-config --cflags "$(pkg)")) -MMD -MP -MF"$(DEPDIR)/$(notdir $(patsubst %.o,%.d,$@))"
INTERNAL_LINKFLAGS=$(foreach dir,$(LIBDIRS),-L"$(dir)") $(foreach pkg,$(PKGS),$(shell pkg-config --libs "$(pkg)"))
INTERNAL_SOURCES::=$(SOURCES) $(foreach source,$(SOURCE_DIRS),$(foreach ext,$(EXT),$(wildcard $(source)/*.$(ext))))
OBJECTS::=$(addprefix $(OBJDIR)/,$(subst \,.,$(subst /,.,$(addsuffix .o,$(INTERNAL_SOURCES)))))
ALL_COMPILEFLAGS=$(COMPILER_FLAGS) $(INTERNAL_COMPILERFLAGS)
ifeq ($(RELEASE),1)
ALL_LINKFLAGS=$(INTERNAL_LINKFLAGS) $(LDFLAGS)
ALL_LDLIBS=$(LDLIBS)
else
ALL_LINKFLAGS=$(INTERNAL_LINKFLAGS) $(LDFLAGS) $(DEBUG_LDFLAGS)
ALL_LDLIBS=$(LDLIBS) $(DEBUG_LDLIBS)
endif
#just a variable for a newline
define \n
@ -168,7 +188,7 @@ flags-update: cflags-update ldflags-update
#Link executable
$(MAIN_EXECUTABLE): $(OBJECTS) $(LDFLAGS_TMPFILE)
$(COMPILER) $(OBJECTS) -o "$(basename $@)" $(ALL_LINKFLAGS) $(LDLIBS)
$(COMPILER) $(OBJECTS) -o "$(basename $@)" $(ALL_LINKFLAGS) $(ALL_LDLIBS)
ifeq ($(RELEASE),1)
$(STRIP) --strip-all "$(MAIN_EXECUTABLE)"
endif

Some files were not shown because too many files have changed in this diff Show More