59 Commits

Author SHA1 Message Date
2049a6f7b9 Use ndef 2025-07-18 16:11:01 -05:00
889c6f9826 use only include 2025-07-18 16:10:24 -05:00
a316febd9f Remove include 2025-07-18 16:10:02 -05:00
e779e77922 Add missing pragma once. 2025-07-18 16:08:58 -05:00
588b78be69 try adding target_include 2025-07-18 16:06:58 -05:00
70c15206b8 test library statically. 2025-07-18 15:59:52 -05:00
6d89abf64e Cleaned 2025-07-17 09:06:30 -05:00
bfd1ac6953 Technically working shaders. 2024-12-29 17:58:49 -06:00
7c3225fe10 almost done with ShaderData 2024-12-29 13:04:23 -06:00
f574b60856 Shader structure done. 2024-12-29 10:09:20 -06:00
ba305de596 prog 2024-12-25 00:34:24 -06:00
afa6a1a036 Fix tool on different platforms. 2024-12-24 23:41:27 -06:00
fe69d85fab uniform testing 2024-12-24 16:41:36 -06:00
f5958f2879 Shaders now compile all the way to OpenGL 2024-12-24 16:06:55 -06:00
e10aea20a1 Stripped back old shader code for now. 2024-12-24 12:27:55 -06:00
2b36a12335 I gues Shader2 starting to come together. 2024-12-23 23:21:47 -06:00
698aeb2afc slang 2024-12-23 16:14:50 -06:00
c87f13b063 shader 2024-12-21 20:33:25 -06:00
b5958189cf Some slang progress 2024-12-17 12:32:44 -06:00
b3c2e0114f Slang actually worked. 2024-12-09 20:00:09 -06:00
ccd5b36965 map mat 2024-12-07 18:32:50 -06:00
d1d7d46826 Only buffer mesh each frame. 2024-12-07 13:25:53 -06:00
7628f33c25 Temp disable release 2024-12-07 13:04:18 -06:00
876d4c4198 Try release
All checks were successful
build-linux-glfw-x64 / build (push) Successful in 6m28s
2024-12-07 11:26:18 -06:00
872e79e4fb TEst release also
All checks were successful
build-linux-glfw-x64 / build (push) Successful in 6m29s
2024-12-06 14:01:48 -06:00
cf9af3a818 Test release
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 6m37s
2024-12-06 13:53:19 -06:00
f98be769e7 More fixing of physics not being optioned
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 7m7s
2024-12-06 13:44:51 -06:00
d35fba24fa Fix not building with jolt
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 3m44s
2024-12-06 13:39:11 -06:00
4e0bb5caa9 PIL
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 3m24s
2024-12-06 13:34:52 -06:00
7c68b7bc8b lib
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 5m0s
2024-12-06 13:28:48 -06:00
68f6453da6 Action
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 26s
2024-12-06 13:27:38 -06:00
8469da79d0 Install cmake
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 26s
2024-12-06 13:25:43 -06:00
250754af0a Test dawn build
Some checks failed
build-linux-glfw-x64 / build (push) Failing after 21s
2024-12-06 13:22:56 -06:00
9d91fa6435 Added plane 2024-12-06 10:48:00 -06:00
e6672945ae Improve mesh components 2024-12-06 09:11:03 -06:00
a4774e6189 Improved prefab loading a bit. 2024-12-05 19:27:37 -06:00
223bbed232 Made scene loader "work" for now. 2024-12-05 15:58:44 -06:00
a6ac4f029e Scene context improving but not finished. 2024-12-05 15:48:27 -06:00
5998037994 Add context sharing on prefabs. 2024-12-03 17:15:39 -06:00
68fab7c94d Bit of const cleanup 2024-12-02 22:30:41 -06:00
7989be5fe7 Fixed prefab assets 2024-12-02 20:10:44 -06:00
e660fade95 Added prefabs 2024-12-02 20:00:54 -06:00
9fd4c2399f Made scenes, items and components a lot cleaner, asset manager also cleans up properly. 2024-12-02 16:19:25 -06:00
2af55041c8 Example scene loading 2024-12-02 14:53:41 -06:00
ac0f0e86c5 Scopify assets 2024-12-02 08:46:21 -06:00
4dccd7d969 Starting scene loader. 2024-12-01 13:27:36 -06:00
bcbc8796da Add force testing. 2024-11-26 19:38:35 -06:00
f4120095ed Allowed scene items cleanup to happen earlier to prevent access null weak pointers. Also added Sphere Mesh and Sphere Collider(s) 2024-11-26 18:44:52 -06:00
e91b1983c8 Example physics implemented. 2024-11-26 14:26:53 -06:00
98f2f3e955 Fixed a bug with asset loader 2024-11-25 23:40:18 -06:00
91caebd385 Made char rotate 2024-11-25 22:12:03 -06:00
4914ec6168 cleaned things up a bit, looks good to start implementing the rpg mechs 2024-11-25 21:37:28 -06:00
de55029356 Restore pixel perfect camera code. 2024-11-25 20:59:29 -06:00
a2c841288d Make game a subclass 2024-11-25 20:13:25 -06:00
274c96bb64 bit of cleanup 2024-11-25 20:04:31 -06:00
aefbe17786 Replace dawnlibs with dawn.hpp 2024-11-25 17:08:25 -06:00
cfa9e0e99a About to relearn this version of the language. 2024-11-25 16:09:56 -06:00
f8c008fd45 Wow! I can't believe I haven't started this project again! 2024-11-25 15:59:50 -06:00
a02e87c3fa Fix modules 2024-11-25 15:17:11 -06:00
121 changed files with 30 additions and 11987 deletions

View File

@ -1,56 +0,0 @@
name: build-helloworld-vita
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
env:
VITASDK: /usr/local/vitasdk
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache VITASDK
id: cache-vitasdk-restore
uses: actions/cache/restore@v3
with:
path: /usr/local/vitasdk
key: ${{ runner.os }}-vitasdk
- name: Install Vita Toolchain
if: steps.cache-vitasdk.outputs.cache-hit != 'true'
run: ./ci/install-vita-toolchain.sh
- name: Save VITASDK
id: cache-vitasdk-save
uses: actions/cache/save@v3
with:
path: /usr/local/vitasdk
key: ${{ steps.cache-vitasdk-restore.outputs.cache-primary-key }}
- name: Install Libraries
run: ./ci/install-libraries.sh
- name: Build Tools
run: ./ci/build-tools.sh
- name: Build Game
run: |
export PATH=$VITASDK/bin:$PATH
mkdir build
cd build
cmake .. -DDAWN_BUILD_TARGET=target-helloworld-vita -DCMAKE_BUILD_TYPE=Debug
make
- name: Deploying
env:
DAWN_SSH_KEY: ${{ secrets.DAWN_SSH_KEY }}
run: |
mkdir -p ~/.ssh
echo -e "${DAWN_SSH_KEY}" > ~/.ssh/id_rsa
chmod og-rwx ~/.ssh/id_rsa
ssh-keyscan -H wish.moe >> ~/.ssh/known_hosts
ssh -t yourwishes@wish.moe "mkdir -p /home/yourwishes/Dawn/vita/debug"
scp ./build/src/dawnvita/HelloWorld.vpk yourwishes@wish.moe:/home/yourwishes/Dawn/vita/debug/

View File

@ -1,26 +0,0 @@
name: build-liminal-glfw-linux64
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Toolchain
run: ./ci/install-linux-toolchain.sh
- name: Install Libraries
run: ./ci/install-libraries.sh
- name: Build Tools
run: ./ci/build-tools.sh
- name: Build Game
run: |
mkdir build
cd build
cmake .. -DDAWN_BUILD_TARGET=target-liminial-linux64-glfw
make

4
.gitignore vendored
View File

@ -86,6 +86,4 @@ assets/borrowed
._* ._*
*~ *~
archive/*

24
.gitmodules vendored
View File

@ -1,24 +0,0 @@
[submodule "lib/glfw"]
path = lib/glfw
url = https://github.com/glfw/glfw.git
[submodule "lib/glm"]
path = lib/glm
url = https://github.com/g-truc/glm.git
[submodule "lib/SDL"]
path = lib/SDL
url = https://github.com/libsdl-org/SDL.git
[submodule "lib/openal-soft"]
path = lib/openal-soft
url = https://github.com/kcat/openal-soft
[submodule "lib/AudioFile"]
path = lib/AudioFile
url = https://github.com/adamstark/AudioFile.git
[submodule "lib/freetype"]
path = lib/freetype
url = https://gitlab.freedesktop.org/freetype/freetype.git
[submodule "lib/libarchive"]
path = lib/libarchive
url = https://github.com/libarchive/libarchive
[submodule "lib/boxer"]
path = lib/boxer
url = https://github.com/aaronmjacobs/Boxer

View File

@ -7,100 +7,10 @@ cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
set(DAWN_PROJECT_NAME "Dawn") add_library(dawn STATIC
set(DAWN_PROJECT_VERSION "01.00") src/funcs.c
# Variable Caches
set(DAWN_CACHE_TARGET "dawn-target")
# Build target
if(DEFINED ENV{DAWN_BUILD_SYSTEM})
set(DAWN_BUILD_SYSTEM $ENV{DAWN_BUILD_SYSTEM} CACHE INTERNAL ${DAWN_CACHE_TARGET})
else()
set(DAWN_BUILD_SYSTEM "linux" CACHE INTERNAL ${DAWN_CACHE_TARGET})
endif()
# Build tools specifics
if(DAWN_BUILD_SYSTEM STREQUAL "vita")
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if(DEFINED ENV{VITASDK})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file")
else()
message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
endif()
endif()
include("$ENV{VITASDK}/share/vita.cmake" REQUIRED)
set(DAWN_VITA_APP_NAME "${DAWN_PROJECT_NAME}" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_VITA_TITLEID "YWSH00001" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_VITA_VERSION "${DAWN_PROJECT_VERSION}" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(VITA_MKSFOEX_FLAGS "${VITA_MKSFOEX_FLAGS} -d PARENTAL_LEVEL=1" CACHE INTERNAL ${DAWN_CACHE_TARGET})
elseif(DAWN_BUILD_SYSTEM STREQUAL "psp")
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if(DEFINED ENV{PSPDEV})
set(CMAKE_TOOLCHAIN_FILE "$ENV{PSPDEV}/psp/share/pspdev.cmake" CACHE PATH "toolchain file")
else()
message(FATAL_ERROR "Please define PSPDEV to point to your SDK path!")
endif()
endif()
include("$ENV{PSPDEV}/psp/share/pspdev.cmake" REQUIRED)
endif()
# Set Common Build Variables
set(DAWN_ROOT_DIR "${CMAKE_SOURCE_DIR}")
set(DAWN_BUILD_DIR "${CMAKE_BINARY_DIR}")
set(DAWN_SOURCES_DIR "${DAWN_ROOT_DIR}/src")
set(DAWN_TEMP_DIR "${DAWN_BUILD_DIR}/temp")
set(DAWN_TOOLS_DIR "${DAWN_ROOT_DIR}/tools")
set(DAWN_ASSETS_DIR "${DAWN_ROOT_DIR}/assets")
set(DAWN_ASSETS_BUILD_DIR "${DAWN_BUILD_DIR}/assets")
# Variables
set(DAWN_TARGET_NAME "Dawn" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_ASSETS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_BUILD_BINARY ${DAWN_BUILD_DIR}/Dawn CACHE INTERNAL ${DAWN_CACHE_TARGET})
# Initialize Project First.
project("${DAWN_PROJECT_NAME}"
VERSION "${DAWN_PROJECT_VERSION}"
LANGUAGES C CXX
) )
add_executable(${DAWN_TARGET_NAME}) target_include_directories(dawn PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
# Add tools
add_subdirectory(tools)
# Libraries
add_subdirectory(lib)
# Sources
add_subdirectory(src)
# Append assets
add_dependencies(${DAWN_TARGET_NAME} dawnassets)
if(DAWN_BUILD_SYSTEM STREQUAL "vita")
vita_create_self(${DAWN_TARGET_NAME}.self ${DAWN_BUILD_BINARY})
vita_create_vpk(
${DAWN_TARGET_NAME}.vpk
${DAWN_VITA_TITLEID}
${DAWN_TARGET_NAME}.self
VERSION ${DAWN_VITA_VERSION}
NAME ${DAWN_VITA_APP_NAME}
)
elseif(DAWN_BUILD_SYSTEM STREQUAL "psp")
create_pbp_file(
TARGET ${PROJECT_NAME}
ICON_PATH NULL
BACKGROUND_PATH NULL
PREVIEW_PATH NULL
TITLE ${PROJECT_NAME}
VERSION ${DAWN_PROJECT_VERSION}
)
endif()

View File

@ -1,3 +0,0 @@
FROM debian:latest
RUN apt update && apt upgrade -y && apt install -y git cmake build-essential libx11-dev libgtk-3-dev python3 python3-pip
RUN ln -s /usr/bin/python3 /usr/bin/python

View File

@ -1,18 +0,0 @@
services:
dawn-linux64:
build: .
volumes:
- ./../../:/Dawn
working_dir: /Dawn
command:
- /bin/sh
- -c
- |
ln -s /usr/bin/python3 /usr/bin/python
if [ ! -d ./lib/glfw ]; then
git submodule update --init
fi
mkdir -p ./build/linux-x64
cd ./build/linux-x64
cmake ../.. -DDAWN_BUILD_SYSTEM=linux -DGLFW_BUILD_X11=ON -DGLFW_BUILD_WAYLAND=OFF
make

View File

@ -1,3 +0,0 @@
FROM pspdev/pspdev
RUN apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python
RUN psp-pacman -Sy pspgl glm

View File

@ -1,14 +0,0 @@
services:
dawn-psp:
build: .
volumes:
- ./../../:/Dawn
working_dir: /Dawn
command:
- /bin/bash
- -c
- |
mkdir -p ./build/psp
cd ./build/psp
psp-cmake ../.. -DDAWN_BUILD_SYSTEM=psp -DCMAKE_BUILD_TYPE=Debug
make

View File

@ -1,15 +0,0 @@
services:
dawn-vita:
image: gnuton/vitasdk-docker
volumes:
- ./../../:/Dawn
working_dir: /Dawn
command:
- /bin/bash
- -c
- |
rm -rf ./build/vita
mkdir -p ./build/vita
cd ./build/vita
cmake ../.. -DDAWN_BUILD_SYSTEM=vita -DCMAKE_BUILD_TYPE=Debug
make

View File

@ -1,340 +0,0 @@
# Compiling, Debugging and Running
This document's purpose is to explain how to compile, debug and run the project
on your machine. It is assumed that you have a basic understanding of the
fundamentals of your operating system and how to use a terminal.
## Preamble
The Dawn project is written almost entirely in C and C++. This includes all of
the tooling used to generate the project and assets. The only non-C/C++ code is
used by CMake to generate the output compilation files. This provides the Dawn
project an extremely high level of portability not typically seen in other
projects.
## TLDR; Version
This document is going to go over the installation and configuration of the
following items. If you are already familiar with these tools, you can skip to
the "Downloading the Source Code" section.
- C/C++ Compiler
- CMake
- Git
- IDE
You may also need *python*, since we depend on third-party libraries that may use
python scripts to generate their own build files. This is not required for the
Dawn project itself.
## Pre-Configuration
In order to compile the Dawn project, you are required to have the following
tools installed on your machine.
### 1. A C/C++ Compiler
The exact tool(s) will depend on your specific scenario. The compiler is used to
take the .cpp/.hpp files and generating binaries that execute on the target
machine. Typically you will use your own C/C++ compiler for the machine that you
are currently running, e.g. if you are running Windows, you will use the Visual
Studio compiler. If you are running Linux, you will use GCC or Clang. If you are
running macOS, you will use Clang, and so-on.
If you are intending to compile on a different machine than the one you are
currently running, you will need to use a cross-compiler that is specific for
your use-case. You will also need to refer to the documentation for creating a
new Dawn engine target.
Please follow the instructions for your specific operating system to install the
appropriate C/C++ compiler.
**Windows**
You will need to download and install [Visual Studio](https://visualstudio.microsoft.com/downloads/).
Visual Studio (not to be confused with Visual Studio Code) is a full IDE that
bundles the official Microsoft C/C++ compiler. It is the recommended compiler
for building the Dawn project on Windows.
Advanced used can also use [MinGW](http://www.mingw.org/) or another compiler if
they wish, however this is not officially supported.
After installing Visual Studio, you will need to install the C++ development
tools. This can be done by opening the Visual Studio Installer and selecting
the "Desktop development with C++" workload.
**Linux**
You will need to install the GCC and Clang compilers. The compilers are usually
installed either by default or by installing the necessary packages for your
Linux distribution.
For example, on Ubuntu, you can install the GCC and Clang compilers by running
the following command:
```bash
sudo apt install build-essential clang
```
On Arch Linux, you can install the GCC and Clang compilers by running the
following command:
```bash
sudo pacman -S base-devel clang
```
And on Fedora, you can install the GCC and Clang compilers by running the
following command:
```bash
sudo dnf install @development-tools clang
```
For other distributions, please refer to your distribution's documentation.
**macOS**
You will need to install the Xcode command line tools. This can be done by done
by running the following command in your terminal:
```bash
xcode-select --install
```
Afterwards you will need to install and enable [Brew](https://brew.sh/). This
can be done by running the following command in your terminal:
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
### 2. CMake
CMake is a tool that is used to generate the compilation files for the Dawn
project. In short this is used to create versions of the Dawn project that can
be compiled on all different sets of compilers, so if you are compiling on, for
example, Windows, you can use CMake to generate the compilation files for the
Visual Studio compiler, or if you are compiling on Linux, you can use CMake to
generate the compilation files for the GCC or Clang compilers, and so-on.
To install CMake, please follow the instructions for your specific operating
system. All other operating systems can be found on the [CMake downloads page](https://cmake.org/download/).
**Windows**
You will need to download and install [CMake](https://cmake.org/download/). The
installer will guide you through the installation process and will install the
CMake executable to your system. It is recommended that you add CMake to your
system PATH if requested by the installer.
**Linux**
Like installing the C/C++ compilers, you will need to install CMake using your
specific Linux distribution's package manager, there is also a chance that CMake
can be installed using flatpak or snap. Please refer to your distribution's
documentation for more information.
For Ubuntu and other Debian-based distributions, you can install CMake by using
the following command:
```bash
sudo apt install cmake
```
For Arch Linux, you can install CMake by using the following command:
```bash
sudo pacman -S cmake
```
And for Fedora, you can install CMake by using the following command:
```bash
sudo dnf install cmake
```
**macOS**
You will install CMake using brew. We detailed how to install brew in the C/C++
compiler section. To install CMake, run the following command in your terminal:
```bash
brew install cmake
```
### 3. Git
Git is a version control system that is used to manage the Dawn project's source
code. It is used to download the source code, and to update the source code to
the latest version. It is also used to manage the project's dependencies. Git is
a standard tool in the programming industry and is used to manage complex
projects, especially those that are worked on by multiple people.
Git, like all of the above tools, is installed slightly differently depending on
your operating system. Please follow the instructions for your specific
operating system.
**Windows**
You will need to download and install [Git](https://git-scm.com/downloads). The
installer will guide you through the installation process and will install the
Git executable to your system. It is recommended that you add Git to your system
PATH if requested by the installer. You do not need to add the Context-menu
items to your system.
**Linux**
Like installing the C/C++ compilers, you will need to install Git using your
specific Linux distribution's package manager. It is also likely that git would
have been installed by default. Please refer to your distribution's docs for
more information.
For Ubuntu and other Debian-based distributions, you can install Git by using
the following command:
```bash
sudo apt install git
```
For Arch Linux, you can install Git by using the following command:
```bash
sudo pacman -S git
```
And for Fedora, you can install Git by using the following command:
```bash
sudo dnf install git
```
**macOS**
You will install Git using brew. We detailed how to install brew in the C/C++
compiler section. To install Git, run the following command in your terminal:
```bash
brew install git
```
### 4. An IDE
An IDE (Integrated Development Environment) is a tool that is used to view and
edit code of projects. While it is not required to use an IDE, it is recommended
since it can make the process of editing and running the project much easier.
There are many different IDEs available, and often people chose an IDE that will
suit their preferences and needs, however if you are unsure of which IDE you
should be using, the Dawn project recommends using [Visual Studio Code](https://code.visualstudio.com/),
not to be confused with Visual Studio.
Visual Studio Code is a free and open-source IDE that is widely used in the
industry for its simple, modern and configurable interface. For example you can
configure VSCode to work on Web Projects, Game Projects, and more. It acts like
a text editor with a bunch of extra tools.
In addition to installing the VSCode IDE, we will add several recommended
plugins that will make editing the Dawn project easier and more seamless.
To install VSCode follow the instructions for your specific operating system on
the [VSCode downloads page](https://code.visualstudio.com/download), as it can
vary a lot between operating systems.
After installing VSCode, you will need to install the following plugins, by
clicking on the "Extensions" icon on the left-hand side of the VSCode window,
and searching for the following plugins. You may also be able to click on the
following links to install the plugins directly, but it may not work.
- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
- [CMake](https://marketplace.visualstudio.com/items?itemName=twxs.cmake)
- [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools)
## Downloading the Source Code
Now that you have all of the necessary tools installed, you can download the
source code of the project and using it to build. The source code contains all
of the code of the project, as well as the assets and the build scripts. This is
confidential information and should not be shared with anyone.
### 1. Cloning the Repository
We previously installed the git tool, which is used to download the source code
of the project, and some third-party libraries. To download the source code, you
will need to open a terminal and navigate to the directory where you want to
download the source code to.
Afterwards, you will need to run the following command:
```bash
git clone https://git.wish.moe/YourWishes/Dawn.git
```
This will download the source code of the project to a new subdirectory called
"Dawn" and put all of the projects' source code within there.
### 2. Installing the Dependencies / Libraries.
I try to keep dependencies on third-party libraries to a minimum, however there
are a few libraries that are required to build the Dawn project. These libraries
are not included in the source code, and must be downloaded separately. This is
done using the git tool.
After you have cloned the above repository, you will need to open a terminal and
navigate to the directory where you downloaded the source code to. Afterwards,
you will need to run the following command:
```bash
git submodule update --init --recursive
```
This will fetch all of the third-party libraries that are required to build the
Dawn project. This may take a while depending on your internet connection.
### 3. Loading the Project
This step is semi-optional. We are aiming to build the project using CMake, and
the easiest way to do this is to use the CMake Tools plugin for VSCode that we
installed earlier. This plugin will automatically detect the CMake files in the
project and will allow us to build the project using the VSCode interface.
If you opted out of using VSCode, you will need to set up your CMake environment
to suit your IDE or needs. This is outside of the scope of this document, and
you will need to refer to your IDE's documentation for more information.
To load the project, you will need to open VSCode and open the Dawn project
directory. Most operating systems will allow you to do this by dragging the
Dawn project directory onto the VSCode window. If this does not work, you can
open VSCode and click on the "File" menu, and click on "Open Folder". You will
then need to navigate to the Dawn project directory and click "Open".
Afterwards you will likely be prompted autometically to configure the CMake
Tools plugin. If you are not, you can click on the "CMake" icon on the left-hand
side of the VSCode window, and click on "Configure". This will configure the
CMake Tools plugin to use the CMake files in the Dawn project directory.
You may also be asked to select a compiler. If you are using Windows, you will
need to select the Visual Studio compiler. If you are using Linux, you will need
to select the GCC or Clang compiler. If you are using macOS, you will need to
select the Clang compiler. If you are using a different compiler, you will need
to select the appropriate compiler.
If prompted to select a build type, select "Debug".
## Compiling the Project
Now that we have the project loaded into our IDE, we can compile the project.
This is done using the CMake Tools plugin for VSCode. If you are not using
VSCode you will need to refer to your IDE's documentation for more information.
Firstly, you will need to create a settings file to configure the project. In
VSCode you can create a new folder called `.vscode` (Including the leading `.`)
in the Dawn project root directory. Afterwards, you will need to create a new
file called `settings.json` in the `.vscode` directory. You will then need to
paste the following into the file:
```json
{
"cmake.configureArgs": [
"-DDAWN_BUILD_TOOLS=true",
"-DDAWN_BUILD_TARGET=target-liminal-win32-glfw",
"-DDAWN_DEBUG_BUILD=true"
]
}
```
And save the file. You may want to alter the values to suit your needs. For
example, if you are compiling on Linux, you will need to change
`target-liminal-win32-glfw` to `target-liminal-linux-glfw`. If you are compiling
on macOS, you will need to change it to `target-liminal-osx-glfw`. The specific
configure arguments are outside of the scope of this document, and you will need
to refer to the specific target documentation for more information.
After you have created the settings file, you will need to configure and build
the project. To perform the build you need to click "Build" button the bottom of
the VSCode window. This will compile the project and will output the resulting
binaries in to a "build" directory within the Dawn project directory.
Upon clicking the "Build" button, you will see an output panel appear at the
bottom of the VSCode window. This will show the process of the build, and will
show any errors that may occur. This is used to debug and fix any issues that
may occur during the build process.
If the build was successful, you will see a "Build finished" message in the
output panel, typically read as;
```bash
[build] Build finished with exit code 0
```
If you do not see this message, or if the exit code is not 0, you will need to
debug the issue. The output panel will show the error message which is helpful
so we can debug the issue. If you are unable to debug the issue, you can ask for
help in the Discord server.
## Running the built project
After the build process succeeds you will be able to run the project. This is
done by clicking on the Run icon, which looks like a play button, on the bottom
of the VSCode window. This will run the project in production mode and will not
show any debug information.
If the program hangs, crashes or does not run, you can click the Debug icon,
which looks like a ladybug, on the bottom of the VSCode window. This will run
the project in debug mode and will show debug information and HALT the program
if there is an error detected. If program HALTS in debug mode you can use this
information to debug the issue. If you are unable to debug the issue, you can
ask for help in the Discord server.

Submodule lib/AudioFile deleted from 004065d01e

View File

@ -1,31 +0,0 @@
# Copyright (c) 2021 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# GLFW/GLAD
if(DAWN_BUILD_SYSTEM STREQUAL "linux")
add_subdirectory(glad)
add_subdirectory(glfw)
add_subdirectory(libarchive)
add_subdirectory(glm)
set(LIBTYPE "STATIC")
add_subdirectory(openal-soft)
set(BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE)
set(BUILD_EXAMPLES OFF CACHE BOOL "Build examples" FORCE)
add_subdirectory(AudioFile)
add_subdirectory(freetype)
add_subdirectory(boxer)
target_compile_definitions(Boxer PRIVATE UNICODE)
elseif(DAWN_BUILD_SYSTEM STREQUAL "vita")
add_subdirectory(glm)
elseif(DAWN_BUILD_SYSTEM STREQUAL "psp")
add_subdirectory(glm)
endif()

Submodule lib/SDL deleted from fb1497566c

Submodule lib/boxer deleted from 65e79c38f1

Submodule lib/freetype deleted from 7ff43d3e9f

View File

@ -1,12 +0,0 @@
cmake_minimum_required(VERSION 3.11)
project(glad)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
add_library(${PROJECT_NAME}
src/glad.c
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Submodule lib/glfw deleted from b35641f4a3

Submodule lib/glm deleted from 45008b225e

Submodule lib/libarchive deleted from 313aa1fa10

Submodule lib/openal-soft deleted from d3875f333f

View File

@ -1,24 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
if(DAWN_BUILD_SYSTEM STREQUAL "linux")
add_subdirectory(dawn)
add_subdirectory(dawnglfw)
add_subdirectory(dawnlinux)
add_subdirectory(dawnopengl)
elseif(DAWN_BUILD_SYSTEM STREQUAL "vita")
add_subdirectory(dawn)
add_subdirectory(dawnvita)
add_subdirectory(dawnopengl)
elseif(DAWN_BUILD_SYSTEM STREQUAL "psp")
set(DAWN_OPENGL_SHADERS FALSE CACHE INTERNAL "${DAWN_CACHE_TARGET}")
set(DAWN_OPENGL_FRAMEBUFFERS FALSE CACHE INTERNAL "${DAWN_CACHE_TARGET}")
set(DAWN_OPENGL_MIPMAPS FALSE CACHE INTERNAL "${DAWN_CACHE_TARGET}")
add_subdirectory(dawn)
add_subdirectory(dawnpsp)
else()
message(FATAL_ERROR "Unknown build system: ${DAWN_BUILD_SYSTEM}")
endif()

View File

@ -1,35 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libraries
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
)
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
)
# Subdirs
add_subdirectory(error)
add_subdirectory(game)
add_subdirectory(locale)
add_subdirectory(scene)
add_subdirectory(util)
# Textures
# tool_texture(texture_test
# FILE=${DAWN_ASSETS_DIR}/texture_test.png
# FILTER_MIN=NEAREST
# FILTER_MAG=NEAREST
# )

View File

@ -1,37 +0,0 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#define DAWN_GAME_NAME "Dawn"
#define DAWN_GAME_NAME_U8 u8"Dawn"
#include <vector>
#include <iostream>
#include <thread>
#include <map>
#include <array>
#include <memory>
#include <algorithm>
#include <sstream>
#include <string>
#include <functional>
#include <cstdarg>
#include <cstdint>
#include <cstring>
#include <float.h>
// #define GLM_ENABLE_EXPERIMENTAL
// #include <glm/glm.hpp>
// #include <glm/gtc/type_ptr.hpp>
// #include <glm/gtx/matrix_decompose.hpp>
typedef char char_t;
typedef char8_t u8char_t;
typedef float float_t;
typedef double double_t;
typedef bool bool_t;

View File

@ -1,9 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
assert.cpp
)

View File

@ -1,25 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert.hpp"
void assertTrueImplement(
const char *file,
const int32_t line,
const char *func,
const bool_t result,
const char *message,
...
) {
if(!result) {
va_list args;
va_start(args, message);
fprintf(stderr, "Assertion failed in %s:%d (%s): ", file, line, func);
vfprintf(stderr, message, args);
fprintf(stderr, "\n");
va_end(args);
exit(1);
}
}

View File

@ -1,115 +0,0 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.hpp"
/**
* Asserts that a given statement must evaluate to true or the assertion fails
* and the game will close semi-gracefully.
*
* @param file String filename of the file that has the assertion.
* @param line Integer line number within the file that the assertion is on.
* @param func Called function that has the assertion.
* @param result The statement that must equate to true.
* @param message Message (sprintf format) to send to the stdout.
* @param ... Varargs of the sprintf arguments.
*/
void assertTrueImplement(
const char *file,
const int32_t line,
const char *func,
const bool_t result,
const char *message,
...
);
/**
* Asserts that a statement must be true in order for the assertion to not cause
* an error. Basically this is a throw statement in disguise.
*
* @param statement Statement of the assertion.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertTrue(...) assertTrueImplement( \
__FILE__, __LINE__, __func__, __VA_ARGS__ \
)
/**
* Asserts that a statement must be false in order for the assertion to not
* cause an error.
*
* @param statement Statement of the assertion.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertFalse(x, ...) assertTrue(!(x), __VA_ARGS__)
/**
* Asserts that a specified piece of code should be entirely unreachable.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertUnreachable(...) assertTrue(false, __VA_ARGS__)
/**
* Asserts that a given pointer is not null.
* @param x Pointer to check.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertNotNull(x, ...) assertTrue(x != nullptr, __VA_ARGS__)
/**
* Asserts that a given pointer is null.
* @param x Pointer to check.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertNull(x, ...) assertTrue(x == nullptr, __VA_ARGS__)
/**
* Asserts that a given map has a specific key.
* @param map Map to check.
* @param key Key to check for.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertMapHasKey(map, key, ...) assertTrue( \
map.find(key) != map.end(), __VA_ARGS__ \
)
/**
* Asserts that a given value has a specific flag turned off.
*
* @param value Value to check.
* @param flag Flag to check for.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertFlagOff(value, flag, ...) assertTrue( \
(value & flag) == 0, __VA_ARGS__ \
)
/**
* Asserts that a given value has a specific flag turned on.
*
* @param value Value to check.
* @param flag Flag to check for.
* @param message Message (sprintf format) to send to the logger.
* @param args Optional TParam args for the sprintf message to accept.
*/
#define assertFlagOn(value, flag, ...) assertTrue( \
(value & flag) == flag, __VA_ARGS__ \
)
/**
* Asserts that the current code is deprecated and should not be used anymore.
* @deprecated
*/
#define assertDeprecated(...) assertUnreachable(__VA_ARGS__)

View File

@ -1,22 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
/**
* Shows an error message box on the host device. This method should be blocking
* and should not return until the user has acknowledged the error.
*
* @param message Message to display.
*/
void errorMessageBox(const std::u8string &message);
/**
* Logs an error message to the host device.
*
* @param message Message to log.
*/
void errorLog(const std::string &message);

View File

@ -1,141 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
namespace Dawn {
enum class CustomEventResult {
NOTHING,
REMOVE,
INVOKE,
INVOKE_AND_REMOVE
};
template<
typename InternalData,
typename InternalListenerData,
typename ListenerArgument,
typename ...InvokeArgs
>
class CustomEvent {
private:
int32_t nextId = 0;
std::unordered_map<
int32_t,
std::pair<InternalListenerData, std::function<void(InvokeArgs...)>>
> listeners;
protected:
InternalData internalData;
/**
* Custom event filter. Decides whether or not the event should be emitted
* to the listener.
*
* @param listenerData Data for this listener.
* @param args The arguments to pass to the listeners.
* @return The result of the filter.
*/
virtual enum CustomEventResult shouldEmit(
const InternalListenerData &listenerData,
const InvokeArgs... args
) = 0;
/**
* Transform the arguments for listener data when the listener is first
* subscribed.
*
* @param argument The argument to transform.
* @return The transformed argument into an internal data format.
*/
virtual InternalListenerData transformData(
const ListenerArgument &argument
) = 0;
/**
* Transform the data for listener data after the event has been emitted.
*
* @param internalData The internal data to transform.
* @return Updated/Transformed internal data.
*/
virtual InternalListenerData transformDataAfterEmit(
const InternalListenerData &internalData
) {
return internalData;
}
public:
/**
* Emits the event.
* @param args The arguments to pass to the listeners.
*/
void emit(InvokeArgs... args) {
auto copy = listeners;
for(auto &pair : copy) {
// Check emit test.
auto result = this->shouldEmit(
pair.second.first,
args...
);
if(
result == CustomEventResult::INVOKE ||
result == CustomEventResult::INVOKE_AND_REMOVE
) {
pair.second.second(args...);
}
if(
result == CustomEventResult::REMOVE ||
result == CustomEventResult::INVOKE_AND_REMOVE
) {
listeners.erase(pair.first);
continue;
}
if(
result == CustomEventResult::INVOKE ||
result == CustomEventResult::INVOKE_AND_REMOVE
) {
// Update the internal data.
listeners[pair.first].first = transformDataAfterEmit(
pair.second.first
);
}
}
}
/**
* Listens to the event.
*
* @param data Listener data to use.
* @param listener The listener to add.
* @returns A function that can be called to remove the listener.
*/
std::function<void()> listen(
const ListenerArgument &data,
const std::function<void(InvokeArgs...)> listener
) {
int32_t id = nextId++;
auto pair = std::make_pair(
transformData(data),
listener
);
listeners[id] = pair;
return [this, id]() {
listeners.erase(id);
};
}
/**
* Destroys the custom event.
*/
virtual ~CustomEvent() {
listeners.clear();
}
};
}

View File

@ -1,57 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
template<typename ...A>
class Event {
private:
int32_t nextId = 0;
std::map<int32_t, std::function<void(A...)>> listeners;
public:
/**
* Constructs a new Event.
*/
Event() {
}
/**
* Emits the event.
* @param args The arguments to pass to the listeners.
*/
void emit(A ...args) {
auto copy = listeners;
for(auto &pair : copy) {
pair.second(args...);
}
}
/**
* Listens to the event.
* @param listener The listener to add.
* @returns A function that can be called to remove the listener.
*/
std::function<void()> listen(
const std::function<void(A...)> listener
) {
int32_t id = nextId++;
listeners[id] = listener;
return [this, id]() {
listeners.erase(id);
};
}
/**
* Destroys the event.
*/
virtual ~Event() {
listeners.clear();
}
};
}

View File

@ -1,9 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Game.cpp
)

View File

@ -1,45 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Game.hpp"
#include "scene/Scene.hpp"
#include "scene/item/SceneItem2D.hpp"
using namespace Dawn;
Game::Game() {
}
void Game::init() {
currentScene = std::make_shared<Scene>(weak_from_this());
auto myItem = currentScene->addSceneItem<SceneItem2D>("myItem");
}
void Game::update() {
}
std::shared_ptr<Scene> Game::getCurrentScene() {
return currentScene;
}
void Game::setActiveScene(std::shared_ptr<Scene> scene) {
auto previousCurrent = currentScene;
if(previousCurrent != nullptr) {
previousCurrent->inactive();
}
currentScene = scene;
if(currentScene != nullptr) {
currentScene->active();
}
}
Game::~Game() {
}

View File

@ -1,53 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
class Scene;
class Game : public std::enable_shared_from_this<Game> {
private:
std::shared_ptr<Scene> currentScene;
public:
/**
* Constructs a new instance of Game, the class majorily responsible for
* handling all internal dawn functions outside of platform-centric things
* like windowing and graphics.
*/
Game();
/**
* Initializes the game and all sub managers used by game.
*/
void init();
/**
* Updates the game and all sub managers used by game.
*/
void update();
/**
* Returns the current active scene.
*
* @return The current active scene.
*/
std::shared_ptr<Scene> getCurrentScene();
/**
* Sets the active scene for the game.
*
* @param scene The scene to set as active.
*/
void setActiveScene(std::shared_ptr<Scene> scene);
/**
* Deloads game and all sub managers used by game.
*/
~Game();
};
}

View File

@ -1,10 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Language.cpp
)

View File

@ -1,15 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Language.hpp"
using namespace Dawn;
std::u8string Language::get(
const char_t key[],
const std::pair<std::string, std::u8string> &args
) {
return u8"Some language string 👍";
}

View File

@ -1,24 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
class Language {
public:
/**
* Gets a language string from the language definition set.
*
* @param key The key to look up in the language file.
* @param args A pair of strings to replace in the language string.
* @return The language string.
*/
static std::u8string get(
const char_t key[],
const std::pair<std::string, std::u8string> &args = std::make_pair("", u8"")
);
};
}

View File

@ -1,13 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Scene.cpp
)
# Subdirs
add_subdirectory(item)

View File

@ -1,33 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Scene.hpp"
using namespace Dawn;
Scene::Scene(std::weak_ptr<Game> game) : SceneItem(
std::weak_ptr<SceneItem>(),
std::enable_shared_from_this<Scene>::weak_from_this()
) {
this->game = game;
}
void Scene::active() {
auto itItems = items.begin();
}
void Scene::inactive() {
}
bool_t Scene::isActiveScene() {
auto g = game.lock();
if(g == nullptr) return false;
return g->getCurrentScene() == this->getScene();
}
Scene::~Scene() {
}

View File

@ -1,49 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma ocne
#include "scene/item/SceneItem.hpp"
#include "game/Game.hpp"
namespace Dawn {
class Scene : public SceneItem, public std::enable_shared_from_this<Scene> {
private:
std::weak_ptr<Game> game;
/**
* Invoked by the game whenever this scene has been set as the active
* scene.
*/
void active();
/**
* Invoked by the game whenever this scene has been set as the inactive
* scene.
*/
void inactive();
public:
/**
* Creates a new Scene.
*
* @param game The Game this Scene belongs to.
*/
Scene(std::weak_ptr<Game> game);
/**
* Returns true if this scene is the active scene.
*
* @return True if this scene is the active scene.
*/
bool_t isActiveScene();
/**
* Destroys this scene and all of its items.
*/
virtual ~Scene();
friend class Game;
};
}

View File

@ -1,14 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
SceneItem.cpp
SceneItem2D.cpp
)
# Subdirs
add_subdirectory(display)

View File

@ -1,45 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SceneItem.hpp"
using namespace Dawn;
SceneItem::SceneItem(
std::weak_ptr<SceneItem> parent,
std::weak_ptr<Scene> scene
) :
parent(parent),
scene(scene)
{
}
std::shared_ptr<SceneItem> SceneItem::getParent() {
return parent.lock();
}
std::shared_ptr<Scene> SceneItem::getScene() {
return scene.lock();
}
void SceneItem::removeSceneItem(std::shared_ptr<SceneItem> item) {
// I don't need to go through the trouble of removing items if I'm already
// disposing, since I'll be clearing them all anyway.
if(isDisposing) return;
auto it = std::find(items.begin(), items.end(), item);
if(it != items.end()) items.erase(it);
}
SceneItem::~SceneItem() {
this->isDisposing = true;
// Clear children first, saves them trying to remove themselves from me.
this->items.clear();
// Now remove myself from my parent.
auto parent = this->getParent();
if(parent) parent->removeSceneItem(shared_from_this());
}

View File

@ -1,110 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "event/Event.hpp"
namespace Dawn {
class Scene;
class SceneItem : public std::enable_shared_from_this<SceneItem> {
private:
std::weak_ptr<SceneItem> parent;
std::weak_ptr<Scene> scene;
bool_t isDisposing = false;
protected:
std::vector<std::shared_ptr<SceneItem>> items;
public:
std::string name;
Event<> onEnter;
Event<> onLeave;
/**
* Creates a new SceneItem.
*
* @param parent The parent SceneItem, or nullptr if root (unlikely).
* @param scene The Scene this SceneItem belongs to.
*/
SceneItem(
std::weak_ptr<SceneItem> parent,
std::weak_ptr<Scene> scene
);
/**
* Adds a SceneItem as a child of this SceneItem.
*
* @tparam SceneItem type to add.
* @return Pointer to the newly created SceneItem.
*/
template<typename C>
std::shared_ptr<C> addSceneItem(const std::string &name = "") {
auto item = std::make_shared<C>(weak_from_this(), scene);
auto asItem = std::dynamic_pointer_cast<SceneItem>(item);
if(asItem == nullptr) {
throw std::runtime_error("SceneItem must be a SceneItem.");
}
asItem->name = name;
items.push_back(asItem);
return item;
}
/**
* Finds a SceneItem by name.
*
* @tparam The type of SceneItem to find.
* @param name The name of the SceneItem to find.
* @return The SceneItem, or nullptr if not found.
*/
template<typename C>
std::shared_ptr<C> find(const std::string &name, const bool_t &recursive = false){
for(auto &item : items) {
if(item->name == name) {
auto casted = std::dynamic_pointer_cast<C>(item);
if(!casted) throw std::runtime_error("Invalid SceneItem type.");
return casted;
}
if(recursive) {
auto childFound = item->find<C>(name, recursive);
if(childFound) return childFound;
}
}
return nullptr;
}
/**
* Removes a SceneItem from this SceneItem.
*
* @param item The SceneItem to remove.
*/
void removeSceneItem(std::shared_ptr<SceneItem> item);
/**
* Gets the parent SceneItem.
*
* @return The parent SceneItem.
*/
std::shared_ptr<SceneItem> getParent();
/**
* Gets the Scene this SceneItem belongs to.
*
* @return The Scene this SceneItem belongs to.
*/
std::shared_ptr<Scene> getScene();
/**
* Destroys this SceneItem.
*/
virtual ~SceneItem();
friend class Scene;
};
}

View File

@ -1,21 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SceneItem2D.hpp"
using namespace Dawn;
SceneItem2D::SceneItem2D(
std::weak_ptr<SceneItem> parent,
std::weak_ptr<Scene> scene
) :
SceneItem(parent, scene)
{
}
SceneItem2D::~SceneItem2D() {
}

View File

@ -1,33 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/item/SceneItem.hpp"
namespace Dawn {
class SceneItem2D : public SceneItem {
private:
public:
float_t x = 0.0f;
float_t y = 0.0f;
float_t rotation = 0.0f;
/**
* Creates a new SceneItem2D.
*
* @param parent The parent item.
*/
SceneItem2D(
std::weak_ptr<SceneItem> parent,
std::weak_ptr<Scene> scene
);
/**
* Destroys this SceneItem2D.
*/
virtual ~SceneItem2D();
};
}

View File

@ -1,10 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Rectangle.cpp
)

View File

@ -1,21 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Rectangle.hpp"
using namespace Dawn;
Rectangle::Rectangle(
std::weak_ptr<SceneItem> parent,
std::weak_ptr<Scene> scene
) :
SceneItem2D(parent, scene)
{
}
Rectangle::~Rectangle() {
}

View File

@ -1,30 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/Color.hpp"
#include "scene/item/SceneItem2D.hpp"
namespace Dawn {
class Rectangle : public SceneItem2D {
public:
struct Color color = COLOR_WHITE;
float_t width = 32.0f;
float_t height = 32.0f;
/**
* Creates a new Rectangle.
*
* @param parent The parent SceneItem, or nullptr if root (unlikely).
* @param scene The Scene this item belongs to.
*/
Rectangle(std::weak_ptr<SceneItem> parent, std::weak_ptr<Scene> scene);
/**
* Destroys the Rectangle.
*/
virtual ~Rectangle();
};
}

View File

@ -1,9 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
string.cpp
)

View File

@ -1,35 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "string.hpp"
bool_t stringIncludes(
const std::string &haystack,
const std::string &needle
) {
return haystack.find(needle) != std::string::npos;
}
std::string stringToLowercase(const std::string &str) {
std::string lower = str;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower;
}
std::vector<std::string> stringSplit(
const std::string &str,
const std::string &delim
) {
std::vector<std::string> parts;
size_t start = 0;
size_t end = str.find(delim);
while(end != std::string::npos) {
parts.push_back(str.substr(start, end - start));
start = end + delim.length();
end = str.find(delim, start);
}
parts.push_back(str.substr(start, end));
return parts;
}

View File

@ -1,36 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
/**
* Returns true if the haystack string includes the needle string.
* @param haystack The string to search in.
* @param needle The string to search for.
* @return True if the needle is found in the haystack.
*/
bool_t stringIncludes(
const std::string &haystack,
const std::string &needle
);
/**
* Converts a string to lowercase.
* @param str The string to convert.
* @return The lowercase version of the string.
*/
std::string stringToLowercase(const std::string &str);
/**
* Splits a string by a delimiter.
* @param str The string to split.
* @param delim The delimiter to split by.
* @return A vector of strings split by the delimiter.
*/
std::vector<std::string> stringSplit(
const std::string &str,
const std::string &delim
);

View File

@ -1,30 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libs
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
glfw
glad
archive_static
Boxer
)
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
# dawnglfw.c
# input.c
)
# Subdirs
add_subdirectory(error)
add_subdirectory(host)

View File

@ -1,7 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <glad/glad.h>

View File

@ -1,10 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
error.cpp
)

View File

@ -1,27 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "error/error.hpp"
#include <boxer/boxer.h>
void errorMessageBox(const std::u8string &message) {
std::string titleStr = DAWN_GAME_NAME;
std::string messageStr = (
message.length() > 0 ?
std::string(message.cbegin(), message.cend()) :
std::string()
);
boxer::show(
messageStr.c_str(),
titleStr.c_str(),
boxer::Style::Error,
boxer::Buttons::Quit
);
}
void errorLog(const std::string &message) {
std::cerr << message << std::endl;
}

View File

@ -1,10 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
DawnGLFWHost.cpp
)

View File

@ -1,151 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "DawnGLFWHost.hpp"
#include "error/error.hpp"
#include "locale/Language.hpp"
#include "error/erroropengl.hpp"
using namespace Dawn;
DawnGLFWHost::DawnGLFWHost() {
}
DawnGLFWInitResult DawnGLFWHost::init(
const int32_t argc, const char_t **argv
) {
if(!glfwInit()) {
errorLog("GLFW failed to initialize.");
errorMessageBox(Language::get("glfw.error.glfw_init"));
return DawnGLFWInitResult::GLFW_INIT_FAILED;
}
// Setup window hints
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create window
this->window = glfwCreateWindow(
DAWN_GLFW_WIDTH_DEFAULT,
DAWN_GLFW_HEIGHT_DEFAULT,
DAWN_GAME_NAME,
NULL,
NULL
);
if(this->window == nullptr) {
errorLog("GLFW failed to create window.");
errorMessageBox(Language::get("glfw.error.window_create"));
glfwTerminate();
return DawnGLFWInitResult::WINDOW_CREATE_FAILED;
}
// Set back pointer
glfwSetWindowUserPointer(this->window, this);
// Load GLAD
glfwMakeContextCurrent(this->window);
glfwSwapInterval(1);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
try {
errorCheckOpenGL();
} catch(const std::runtime_error &e) {
errorLog(e.what());
errorMessageBox(Language::get("glfw.error.opengl_error"));
glfwTerminate();
return DawnGLFWInitResult::GLAD_GL_CHECK_FAILED;
}
// Override the defaults
int32_t fbWidth, fbHeight;
glfwGetFramebufferSize(this->window, &fbWidth, &fbHeight);
glfwGetWindowSize(this->window, &this->windowWidth, &this->windowHeight);
try {
errorCheckOpenGL();
} catch(const std::runtime_error &e) {
errorLog(e.what());
errorMessageBox(Language::get("glfw.error.opengl_error"));
glfwTerminate();
return DawnGLFWInitResult::GLAD_GL_CHECK_FAILED;
}
if(
fbWidth == 0 ||
fbHeight == 0 ||
this->windowWidth == 0 ||
this->windowHeight == 0
) {
errorLog(
"GLFW Returned incorrect size: " +
std::to_string(fbWidth) + "x" + std::to_string(fbHeight) + " / " +
std::to_string(windowWidth) + "x" + std::to_string(windowHeight)
);
errorMessageBox(Language::get("glfw.error.viewport_size"));
glfwTerminate();
return DawnGLFWInitResult::VIEWPORT_SIZE_FAILED;
}
// Init Game
this->game = std::make_shared<Game>();
this->game->init();
// Backbuffer
backBuffer = std::make_shared<BackBuffer>();
backBuffer->setSize((float_t)fbWidth, (float_t)fbHeight);
// Set up callbacks
glfwSetFramebufferSizeCallback(this->window, [](
GLFWwindow *window,
int32_t width,
int32_t height
) {
auto host = (DawnGLFWHost*)glfwGetWindowUserPointer(window);
if(host == nullptr) return;
host->windowWidth = width;
host->windowHeight = height;
host->backBuffer->setSize((float_t)width, (float_t)height);
});
return DawnGLFWInitResult::SUCCESS;
}
void DawnGLFWHost::start() {
double_t time, newTime;
float_t fDelta;
int32_t updateResult;
// Main Render Loop
time = 0.0f;
while(!glfwWindowShouldClose(this->window)) {
// Determine the delta.
newTime = glfwGetTime();
fDelta = (float_t)(newTime - time);
time = newTime;
// Update the game
this->game->update();
// Update GLFW
glfwSwapBuffers(this->window);
glfwPollEvents();
}
this->game = nullptr;
}
DawnGLFWHost::~DawnGLFWHost() {
this->backBuffer = nullptr;
this->game = nullptr;
// Terminate GLFW
if(this->window != nullptr) {
glfwDestroyWindow(this->window);
glfwTerminate();
}
}

View File

@ -1,62 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnopengl.hpp"
#include "dawn.hpp"
#include <GLFW/glfw3.h>
#include "game/Game.hpp"
#include "display/BackBuffer.hpp"
#ifndef DAWN_GLFW_WIDTH_DEFAULT
#define DAWN_GLFW_WIDTH_DEFAULT 800
#endif
#ifndef DAWN_GLFW_HEIGHT_DEFAULT
#define DAWN_GLFW_HEIGHT_DEFAULT 600
#endif
namespace Dawn {
enum class DawnGLFWInitResult {
SUCCESS = 0,
GLFW_INIT_FAILED = 1,
WINDOW_CREATE_FAILED = 2,
GLAD_GL_CHECK_FAILED = 3,
VIEWPORT_SIZE_FAILED = 4
};
class DawnGLFWHost {
private:
GLFWwindow *window;
int32_t windowWidth, windowHeight;
std::shared_ptr<Game> game;
std::shared_ptr<BackBuffer> backBuffer;
public:
/**
* Creates a new GLFW Host.
*/
DawnGLFWHost();
/**
* Initializes the GLFW Host.
*
* @param argc The number of arguments.
* @param argv The arguments.
* @return The result of the initialization.
*/
DawnGLFWInitResult init(const int32_t argc, const char_t **argv);
/**
* Starts the GLFW Host, called after the GLFW Host has been initialized.
*/
void start();
/**
* Destroys the GLFW Host.
*/
~DawnGLFWHost();
};
}

View File

@ -1,22 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libraries
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
m
)
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
main.cpp
)

View File

@ -1,26 +0,0 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "main.hpp"
#include "host/DawnGLFWHost.hpp"
using namespace Dawn;
int32_t main(const int32_t argc, const char_t **argv) {
std::shared_ptr<DawnGLFWHost> host = std::make_shared<DawnGLFWHost>();
auto result = host->init(argc, argv);
if(result != DawnGLFWInitResult::SUCCESS) {
return (int32_t)result;
}
host->start();
host = nullptr;
return 0;
}

View File

@ -1,18 +0,0 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawn.hpp"
/**
* Main entry to the program.
*
* @param argc The number of arguments passed to the program.
* @param argv The arguments passed to the program.
* @return The exit code of the program.
*/
int32_t main(const int32_t argc, const char_t **argv);

View File

@ -1,28 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Setup options
if(NOT DEFINED DAWN_OPENGL_SHADERS)
set(DAWN_OPENGL_SHADERS TRUE CACHE INTERNAL "${DAWN_CACHE_TARGET}")
endif()
if(NOT DEFINED DAWN_OPENGL_FRAMEBUFFERS)
set(DAWN_OPENGL_FRAMEBUFFERS TRUE CACHE INTERNAL "${DAWN_CACHE_TARGET}")
endif()
if(NOT DEFINED DAWN_OPENGL_MIPMAPS)
set(DAWN_OPENGL_MIPMAPS TRUE CACHE INTERNAL "${DAWN_CACHE_TARGET}")
endif()
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Subdirs
add_subdirectory(error)
add_subdirectory(display)

View File

@ -1,70 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "dawnopengl.hpp"
#include "error/assert.hpp"
#include "error/assertgl.hpp"
#include "BackBuffer.hpp"
using namespace Dawn;
BackBuffer::BackBuffer() {
}
float_t BackBuffer::getScale() {
return this->scale;
}
float_t BackBuffer::getWidth() {
return this->width;
}
float_t BackBuffer::getHeight() {
return this->height;
}
void BackBuffer::setSize(
const float_t width,
const float_t height
) {
if(this->width == width && this->height == height) return;
// Fixes a new bug that it seems GLFW has introduced.
this->width = width == 0 ? 1 : width;
this->height = height == 0 ? 1 : height;
onResize.emit(this->width, this->height);
}
void BackBuffer::setClearColor(const struct Color color) {
this->clearColor = color;
}
void BackBuffer::clear(const int32_t clearFlags) {
glClearColor(clearColor.r, clearColor.g, clearColor.b, 1.0f);
assertNoGLError();
GLbitfield mask = 0;
if((clearFlags & RENDER_TARGET_CLEAR_COLOR) == RENDER_TARGET_CLEAR_COLOR) {
mask |= GL_COLOR_BUFFER_BIT;
}
if((clearFlags & RENDER_TARGET_CLEAR_DEPTH) == RENDER_TARGET_CLEAR_DEPTH) {
mask |= GL_DEPTH_BUFFER_BIT;
}
glClear(mask);
assertNoGLError();
}
void BackBuffer::bind() {
#if DAWN_OPENGL_FRAMEBUFFERS
glBindFramebuffer(GL_FRAMEBUFFER, 0);
assertNoGLError();
#endif
glViewport(0, 0, (GLsizei)this->width, (GLsizei)this->height);
assertNoGLError();
}

View File

@ -1,44 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/Color.hpp"
#include "display/RenderTarget.hpp"
namespace Dawn {
class BackBuffer final : public RenderTarget {
private:
float_t width = 1;
float_t height = 1;
struct Color clearColor = COLOR_CORNFLOWER_BLUE;
public:
float_t scale = 1.0f;
/**
* Construct the back buffer render target.
*/
BackBuffer();
float_t getScale() override;
float_t getWidth() override;
float_t getHeight() override;
void setClearColor(const struct Color color) override;
void clear(const int32_t) override;
void bind() override;
/**
* Requests to modify the viewport directly. This is mostly to be called
* by whatever is setting the window/display resolution, so that the
* backbuffer can keep track of what the viewport size is. This should
* also be DPI aware, e.g. "4k @ 2xDPI, resulting in a 1080p equiv" should
* still call this method with 3840, 2160.
*
* @param width New width of the back buffer.
* @param height New height of the back buffer.
*/
void setSize(const float_t width, const float_t height);
};
}

View File

@ -1,20 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Color.cpp
BackBuffer.cpp
Texture.cpp
RenderManager.cpp
)
# Subdirs
# add_subdirectory(mesh)
if(DAWN_OPENGL_SHADERS EQUAL TRUE)
message(FATAL_ERROR "DAWN_OPENGL_SHADERS: ${DAWN_OPENGL_SHADERS}")
add_subdirectory(shader)
endif()

View File

@ -1,84 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
#include "error/assert.hpp"
#include "util/string.hpp"
using namespace Dawn;
struct Color Color::fromString(const std::string str) {
// Convert to lowercase
auto lower = stringToLowercase(str);
if(stringIncludes(lower, "cornflower")) {
return COLOR_CORNFLOWER_BLUE;
} else if(stringIncludes(lower, "magenta")) {
return COLOR_MAGENTA;
} else if(stringIncludes(lower, "white")) {
return COLOR_WHITE;
} else if(stringIncludes(lower, "black")) {
return COLOR_BLACK;
} else if(stringIncludes(lower, "red")) {
return COLOR_RED;
} else if(stringIncludes(lower, "green")) {
return COLOR_GREEN;
} else if(stringIncludes(lower, "blue")) {
return COLOR_BLUE;
} else if(stringIncludes(lower, "transparent")) {
return COLOR_TRANSPARENT;
}
// Hex code?
if(lower[0] == '#') {
// Remove the hash
lower = lower.substr(1);
// Convert to RGB
if(lower.length() == 3) {
// Convert to 6 digit hex
lower = lower[0] + lower[0] + lower[1] + lower[1] + lower[2] + lower[2];
}
// Convert to RGB
return {
(float_t)std::stoi(lower.substr(0, 2), nullptr, 16) / 255.0f,
(float_t)std::stoi(lower.substr(2, 2), nullptr, 16) / 255.0f,
(float_t)std::stoi(lower.substr(4, 2), nullptr, 16) / 255.0f,
1.0f
};
}
// Split by comma
auto splitByComma = stringSplit(str, ",");
if(splitByComma.size() == 3) {
// RGB
return {
(float_t)std::stof(splitByComma[0]),
(float_t)std::stof(splitByComma[1]),
(float_t)std::stof(splitByComma[2]),
1.0f
};
} else if(splitByComma.size() == 4) {
// RGBA
return {
(float_t)std::stof(splitByComma[0]),
(float_t)std::stof(splitByComma[1]),
(float_t)std::stof(splitByComma[2]),
(float_t)std::stof(splitByComma[3])
};
}
// TODO: Parse other kinds of colors
assertUnreachable("Failed to find a color match for %s", str);
return {};
}

View File

@ -1,89 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct ColorU8 {
uint8_t r, g, b, a;
};
struct Color final {
/**
* Returns a color from a string.
*
* @param str String to parse.
* @return Color parsed.
*/
static struct Color fromString(const std::string str);
float_t r, g, b, a;
const struct Color& operator = (const struct Color &val) {
this->r = val.r;
this->g = val.g;
this->b = val.b;
this->a = val.a;
return *this;
}
struct Color operator * (const float_t &x) {
return {
r * x,
g * x,
b * x,
a * x
};
}
struct Color operator - (const struct Color &color) {
return {
r - color.r,
g - color.g,
b - color.b,
a - color.a
};
}
struct Color operator + (const struct Color &color) {
return {
r + color.r,
g + color.g,
b + color.b,
a + color.a
};
}
const bool_t operator == (const struct Color &other) {
return r == other.r && g == other.g && b == other.b && a == other.a;
}
operator struct ColorU8() const {
return {
(uint8_t)(r * 255),
(uint8_t)(g * 255),
(uint8_t)(b * 255),
(uint8_t)(a * 255)
};
}
};
#define COLOR_DEF(r,g,b,a) { r, g, b, a }
#define COLOR_WHITE COLOR_DEF(1.0f, 1.0f, 1.0f, 1.0f)
#define COLOR_RED COLOR_DEF(1.0f, 0, 0, 1.0f)
#define COLOR_GREEN COLOR_DEF(0, 1.0f, 0, 1.0f)
#define COLOR_BLUE COLOR_DEF(0, 0, 1.0f, 1.0f)
#define COLOR_BLACK COLOR_DEF(0, 0, 0, 1.0f)
#define COLOR_MAGENTA COLOR_DEF(1.0f, 0, 1.0f, 1.0f)
#define COLOR_DARK_GREY COLOR_DEF(0.2f, 0.2f, 0.2f, 1.0f)
#define COLOR_LIGHT_GREY COLOR_DEF(0.8f, 0.8f, 0.8f, 1.0f)
#define COLOR_CORNFLOWER_BLUE COLOR_DEF(0.4f, 0.6f, 0.9f, 1.0f)
#define COLOR_WHITE_TRANSPARENT COLOR_DEF(1.0f, 1.0f, 1.0f, 0.0f)
#define COLOR_BLACK_TRANSPARENT COLOR_DEF(0.0f, 0.0f, 0.0f, 0.0f)
#define COLOR_YELLOW COLOR_DEF(1.0f, 1.0f, 0.0f, 1.0f)
#define COLOR_CYAN COLOR_DEF(0.0f, 1.0f, 1.0f, 1.0f)
#define COLOR_TRANSPARENT COLOR_WHITE_TRANSPARENT
}

View File

@ -1,29 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "RenderManager.hpp"
#include "game/Game.hpp"
using namespace Dawn;
RenderManager::RenderManager() {
}
void RenderManager::init(const Game &game) {
backBuffer = std::make_shared<BackBuffer>();
backBuffer->setClearColor(COLOR_CORNFLOWER_BLUE);
}
void RenderManager::update(const Game &game) {
backBuffer->bind();
backBuffer->clear(RENDER_TARGET_CLEAR_COLOR | RENDER_TARGET_CLEAR_DEPTH);
}
std::shared_ptr<BackBuffer> RenderManager::getBackBufferRenderTarget() {
return backBuffer;
}
RenderManager::~RenderManager() {
}

View File

@ -1,59 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "display/RenderTarget.hpp"
#include "display/BackBuffer.hpp"
#if DAWN_OPENGL_SHADERS
#include "display/shader/ShaderManager.hpp"
#endif
namespace Dawn {
class Game;
class RenderManager {
private:
std::shared_ptr<BackBuffer> backBuffer = nullptr;
public:
#if DAWN_OPENGL_SHADERS
ShaderManager shaderManager;
#endif
/**
* Creates a render manager.
*/
RenderManager();
/**
* Initializes the render manager, called by the game during the initial
* set up of the engine.
*
* @param game Game that requested the render manager to initialize.
*/
void init(const Game &game);
/**
* Performs an update/tick of the render manager. This would be the game
* asking the RenderManager to do the rendering.
*/
void update(const Game &game);
/**
* Returns the back buffer render target. This is the render target that
* is used to render to the screen.
*
* @return The back buffer render target.
*/
std::shared_ptr<BackBuffer> getBackBufferRenderTarget();
/**
* Destroys the render manager.
*/
~RenderManager();
};
}

View File

@ -1,71 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "event/Event.hpp"
#define RENDER_TARGET_CLEAR_COLOR (1 << 0)
#define RENDER_TARGET_CLEAR_DEPTH (1 << 1)
namespace Dawn {
class RenderTarget {
public:
Event<float_t, float_t> onResize;
/**
* Return the width of the render target.
*
* @return The width of the render target.
*/
virtual float_t getWidth() = 0;
/**
* Return the height of the render target.
*
* @return The height of the render target.
*/
virtual float_t getHeight() = 0;
/**
* Returns the scale (as in pixel density) of the render target. This is
* typically 1.0f, but on high DPI displays this may be 2.0f or higher.
*
* @return The scale of the render target.
*/
virtual float_t getScale() = 0;
/**
* Sets the clear color of the render target when the clear method for
* the color buffer is requested.
*
* @param color Color to use for the clear operation.
*/
virtual void setClearColor(const struct Color color) = 0;
/**
* Request the existing data in the render target to be cleared out. We
* typically assume the render target can support multiple buffer types,
* so you can opt to only clear certain buffer types.
*
* @param clearFlags Flags to request what is going to be cleared.
*/
virtual void clear(const int32_t clearFlags) = 0;
/**
* Bind the render target for rendering to. The proceeding render requests
* will want to render to this render target directly. In future I may
* see if we can have multiple render targets bound at once to make this
* operation perform faster.
*/
virtual void bind() = 0;
/**
* Destroys the render target.
*/
virtual ~RenderTarget() {
}
};
}

View File

@ -1,172 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "error/assert.hpp"
#include "error/assertgl.hpp"
#include "Texture.hpp"
using namespace Dawn;
void Texture::bind(const uint8_t slot) {
assertTrue(this->id != -1, "Texture is not ready!");
glActiveTexture(GL_TEXTURE0 + slot);
assertNoGLError();
glBindTexture(GL_TEXTURE_2D, this->id);
assertNoGLError();
this->updateTextureProperties();
}
int32_t Texture::getWidth() {
return this->width;
}
int32_t Texture::getHeight() {
return this->height;
}
bool_t Texture::isReady() {
return this->id != -1;
}
void Texture::setSize(
const int32_t width,
const int32_t height,
const enum TextureFormat format,
const enum TextureDataFormat dataFormat
) {
if(this->id != -1) {
glDeleteTextures(1, &this->id);
assertNoGLError();
this->id = -1;
}
GLint maxSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
assertTrue(width > 0 && width <= maxSize, "Width is out of bounds!");
assertTrue(height > 0 && height <= maxSize, "Height is out of bounds!");
this->width = width;
this->height = height;
this->format = format;
this->dataFormat = dataFormat;
glGenTextures(1, &this->id);
assertNoGLError();
if(this->id <= 0) assertUnreachable("Texture generation failed!");
// Initialize the texture to blank
glActiveTexture(GL_TEXTURE0);
assertNoGLError();
this->bufferRaw(NULL);
}
void Texture::updateTextureProperties() {
auto setWrapMode = [](GLenum axis, enum TextureWrapMode wm) {
glTexParameteri(GL_TEXTURE_2D, axis, (GLint)wm);
assertNoGLError();
};
setWrapMode(GL_TEXTURE_WRAP_S, this->wrapModeX);
setWrapMode(GL_TEXTURE_WRAP_T, this->wrapModeY);
auto setFilterMode = [](
GLenum minMag,
enum TextureFilterMode filter,
enum TextureFilterMode mapFilterMode
) {
switch(filter) {
case TextureFilterMode::NEAREST: {
glTexParameteri(GL_TEXTURE_2D, minMag, GL_NEAREST);
break;
}
case TextureFilterMode::LINEAR: {
glTexParameteri(GL_TEXTURE_2D, minMag, GL_LINEAR);
break;
}
default: {
assertUnreachable("Unknown filter mode!");
}
}
assertNoGLError();
};
setFilterMode(
GL_TEXTURE_MIN_FILTER, this->filterModeMin, this->mipMapFilterModeMin
);
setFilterMode(
GL_TEXTURE_MAG_FILTER, this->filterModeMag, this->mipMapFilterModeMag
);
}
void Texture::bufferRaw(const void *data) {
assertTrue(this->id != -1, "Texture is not ready!");
GLenum format = (GLenum)this->format;
GLenum dataFormat;
switch(this->dataFormat) {
case TextureDataFormat::UNSIGNED_BYTE:
dataFormat = GL_UNSIGNED_BYTE;
break;
case TextureDataFormat::FLOAT:
dataFormat = GL_FLOAT;
break;
default:
assertUnreachable("Unknown texture data format!");
}
glBindTexture(GL_TEXTURE_2D, this->id);
assertNoGLError();
glTexImage2D(
GL_TEXTURE_2D, 0, format,
this->width, this->height,
0, format, dataFormat, data
);
assertNoGLError();
#if DAWN_OPENGL_MIPMAPS
glGenerateMipmap(GL_TEXTURE_2D);
assertNoGLError();
#endif
}
void Texture::buffer(const struct ColorU8 pixels[]) {
assertTrue(
this->dataFormat == TextureDataFormat::UNSIGNED_BYTE,
"Texture data format must be unsigned byte!"
);
this->bufferRaw((void*)pixels);
}
void Texture::buffer(const struct Color pixels[]) {
std::cout << "Correct buffer" << std::endl;
assertTrue(
this->dataFormat == TextureDataFormat::FLOAT,
"Texture data format must be float!"
);
assertTrue(
this->format == TextureFormat::RGBA,
"Texture format must be RGBA!"
);
this->bufferRaw((void*)pixels);
}
void Texture::buffer(const uint8_t pixels[]) {
assertTrue(
this->dataFormat == TextureDataFormat::UNSIGNED_BYTE,
"Texture data format must be unsigned byte!"
);
this->bufferRaw((void*)pixels);
}
Texture::~Texture() {
if(this->id != -1) {
glDeleteTextures(1, &this->id);
assertNoGLError();
}
}

View File

@ -1,135 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnopengl.hpp"
#include "display/Color.hpp"
namespace Dawn {
class TextureRenderTarget;
typedef GLuint textureslot_t;
enum class TextureFormat {
R = GL_RED,
#ifdef GL_RG
RG = GL_RG,
#endif
RGB = GL_RGB,
RGBA = GL_RGBA
};
enum class TextureWrapMode {
REPEAT = GL_REPEAT,
MIRRORED_REPEAT = GL_MIRRORED_REPEAT,
CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
#ifdef GL_CLAMP_TO_BORDER
CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER
#endif
};
enum class TextureFilterMode {
NEAREST = 0,
LINEAR = 1
};
enum class TextureDataFormat {
UNSIGNED_BYTE = sizeof(uint8_t),
FLOAT = sizeof(float_t)
};
class Texture {
private:
int32_t width = -1;
int32_t height = -1;
GLuint id = -1;
enum TextureFormat format;
enum TextureDataFormat dataFormat;
void updateTextureProperties();
void bufferRaw(const void *data);
public:
enum TextureWrapMode wrapModeX = TextureWrapMode::REPEAT;
enum TextureWrapMode wrapModeY = TextureWrapMode::REPEAT;
enum TextureFilterMode filterModeMin = TextureFilterMode::NEAREST;
enum TextureFilterMode filterModeMag = TextureFilterMode::NEAREST;
enum TextureFilterMode mipMapFilterModeMin = TextureFilterMode::NEAREST;
enum TextureFilterMode mipMapFilterModeMag = TextureFilterMode::NEAREST;
/**
* Returns the width of the texture.
*
* @return Width of the texture.
*/
int32_t getWidth();
/**
* Returns the height of the texture.
*
* @return Height of the texture.
*/
int32_t getHeight();
/**
* Initializes a texture.
*
* @param width Width of the texture (in pixels).
* @param height Height of the texture (in pixels).
* @param format Data format of the texture to use.
* @param dataFormat Data format of the texture to use.
*/
void setSize(
const int32_t width,
const int32_t height,
const enum TextureFormat format,
const enum TextureDataFormat dataForat
);
/**
* Returns true only when the texture has been loaded, sized and put on
* the gpu for rendering.
*
* @return True if ready, otherwise false.
*/
bool_t isReady();
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
void buffer(const struct ColorU8 pixels[]);
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
void buffer(const struct Color pixels[]);
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
*/
void buffer(const uint8_t pixels[]);
/**
* Binds the texture to the given slot (for use by the shaders).
*
* @param slot Slot to bind to.
*/
void bind(const uint8_t slot);
/*
* Destructs and disposes the texture off the GPU.
*/
~Texture();
};
}

View File

@ -1,12 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
CubeMesh.cpp
Mesh.cpp
QuadMesh.cpp
)

View File

@ -1,70 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "CubeMesh.hpp"
using namespace Dawn;
void CubeMesh::buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec3 pos,
const glm::vec3 size,
const int32_t verticeStart,
const int32_t indiceStart
) {
glm::vec3 positions[CUBE_VERTICE_COUNT] = {
pos,
glm::vec3(pos.x+size.x, pos.y, pos.z),
glm::vec3(pos.x, pos.y+size.y, pos.z),
glm::vec3(pos.x+size.x, pos.y+size.y, pos.z),
glm::vec3(pos.x, pos.y, pos.z+size.z),
glm::vec3(pos.x+size.x, pos.y, pos.z+size.z),
glm::vec3(pos.x, pos.y+size.y, pos.z+size.z),
pos + size
};
glm::vec2 coordinates[CUBE_VERTICE_COUNT] = {
glm::vec2(0, 0),
glm::vec2(1, 0),
glm::vec2(0, 1),
glm::vec2(1, 1),
glm::vec2(0, 0),
glm::vec2(1, 0),
glm::vec2(0, 1),
glm::vec2(1, 1)
};
int32_t indices[CUBE_INDICE_COUNT] = {
// Back
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3,
// Right
verticeStart + 1, verticeStart + 5, verticeStart + 7,
verticeStart + 1, verticeStart + 3, verticeStart + 7,
// Left
verticeStart + 4, verticeStart, verticeStart + 2,
verticeStart + 4, verticeStart + 6, verticeStart + 2,
// Front
verticeStart + 5, verticeStart + 4, verticeStart + 6,
verticeStart + 5, verticeStart + 7, verticeStart + 6,
// Top
verticeStart + 7, verticeStart + 2, verticeStart + 6,
verticeStart + 7, verticeStart + 3, verticeStart + 2,
// Bottom
verticeStart + 1, verticeStart, verticeStart + 4,
verticeStart + 1, verticeStart + 4, verticeStart + 5
};
mesh->bufferPositions(verticeStart, positions, CUBE_VERTICE_COUNT);
mesh->bufferCoordinates(verticeStart, coordinates, CUBE_VERTICE_COUNT);
mesh->bufferIndices(indiceStart, indices, CUBE_INDICE_COUNT);
}

View File

@ -1,30 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#define CUBE_VERTICE_COUNT 8
#define CUBE_INDICE_COUNT 36
namespace Dawn {
class CubeMesh {
public:
/**
* Buffers cube mesh vertices and indices into the given mesh.
*
* @param size The size of the cube.
* @param verticeStart The starting index of the vertices.
* @param indiceStart The starting index of the indices.
*/
static void buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec3 pos,
const glm::vec3 size,
const int32_t verticeStart,
const int32_t indiceStart
);
};
}

View File

@ -1,232 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "error/assert.hpp"
#include "error/assertgl.hpp"
#include "display/mesh/Mesh.hpp"
using namespace Dawn;
void Mesh::createBuffers(
const int32_t verticeCount,
const int32_t indiceCount
) {
assertTrue(verticeCount > 0, "Vertice count must be greater than zero.");
assertTrue(indiceCount > 0, "Indice count must be greater than zero.");
// Can we re-use the buffers?
if(
verticeCount <= this->verticeCount &&
indiceCount <= this->indiceCount
) return;
this->disposeBuffers();
this->verticeCount = verticeCount;
this->indiceCount = indiceCount;
auto sizePos = sizeof(glm::vec3) * verticeCount;
auto sizeInds = sizeof(int32_t) * indiceCount;
auto sizeCoords = sizeof(glm::vec2) * verticeCount;
// Generate vertex array, I don't think I need to do this tbh.
glGenVertexArrays(1, &this->vertexArray);
assertNoGLError();
glBindVertexArray(this->vertexArray);
assertNoGLError();
// Create some buffers, one for the vertex data, one for the indices
GLuint buffer[2];
glGenBuffers(2, buffer);
assertNoGLError();
this->vertexBuffer = buffer[0];
if(this->vertexBuffer < 0) assertUnreachable("Can't make vertex buffer");
this->indexBuffer = buffer[1];
if(this->indexBuffer < 0) assertUnreachable("Can't make index buffer");
// Buffer an empty set of data then buffer each component
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
assertNoGLError();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
assertNoGLError();
glBufferData(GL_ARRAY_BUFFER, sizePos+sizeCoords, 0, GL_DYNAMIC_DRAW);
assertNoGLError();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeInds, 0, GL_DYNAMIC_DRAW);
assertNoGLError();
// Setup the attrib pointers
size_t offset = 0;
glVertexAttribPointer(
0, sizeof(glm::vec3) / sizeof(float_t),
GL_FLOAT, GL_FALSE,
0, (void *)offset
);
assertNoGLError();
glEnableVertexAttribArray(0);
assertNoGLError();
offset += sizePos;
glVertexAttribPointer(
1, sizeof(glm::vec2) / sizeof(float_t),
GL_FLOAT, GL_FALSE,
0, (void *)offset
);
assertNoGLError();
glEnableVertexAttribArray(1);
assertNoGLError();
}
void Mesh::disposeBuffers() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
assertNoGLError();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
assertNoGLError();
if(this->vertexBuffer != -1) {
glDeleteBuffers(1, &this->vertexBuffer);
assertNoGLError();
this->vertexBuffer = -1;
this->verticeCount = -1;
}
if(this->indexBuffer != -1) {
glDeleteBuffers(1, &this->indexBuffer);
assertNoGLError();
this->indexBuffer = -1;
this->indiceCount = -1;
}
if(this->vertexArray) {
glDeleteVertexArrays(1, &this->vertexArray);
assertNoGLError();
this->vertexArray = -1;
}
}
void Mesh::bufferPositions(
const int32_t pos,
const glm::vec3 positions[],
const int32_t len
) {
assertNotNull(positions, "Positions cannot be null");
assertTrue(pos >= 0 && pos < verticeCount, "Position must be within range");
assertTrue(pos+len <= verticeCount, "Position + Length must be within range");
assertTrue(len > 0, "Length must be greater than zero");
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
assertNoGLError();
glBufferSubData(
GL_ARRAY_BUFFER,
sizeof(glm::vec3) * pos,
sizeof(glm::vec3) * len,
(void*)positions
);
assertNoGLError();
}
void Mesh::bufferCoordinates(
const int32_t pos,
const glm::vec2 coordinates[],
const int32_t len
) {
assertNotNull(coordinates, "Coordinates cannot be null");
assertTrue(pos >= 0 && pos < verticeCount, "Position must be within range");
assertTrue(pos+len <= verticeCount, "Position + Length must be within range");
assertTrue(len > 0, "Length must be greater than zero");
auto offsetCoordinates = (
(sizeof(glm::vec3) * this->verticeCount) +
(sizeof(glm::vec2) * pos)
);
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
assertNoGLError();
glBufferSubData(
GL_ARRAY_BUFFER,
offsetCoordinates,
sizeof(glm::vec2) * len,
(void*)coordinates
);
assertNoGLError();
}
void Mesh::bufferIndices(
const int32_t pos,
const int32_t indices[],
const int32_t len
) {
assertNotNull(indices, "Indices cannot be null");
assertTrue(pos >= 0 && pos < indiceCount, "Position must be within range");
assertTrue(pos+len <= indiceCount, "Position + Length must be within range");
assertTrue(len > 0, "Length must be greater than zero");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
assertNoGLError();
glBufferSubData(
GL_ELEMENT_ARRAY_BUFFER,
sizeof(int32_t) * pos,
sizeof(int32_t) * len,
(void*)indices
);
assertNoGLError();
}
void Mesh::draw(
const enum MeshDrawMode drawMode,
const int32_t start,
const int32_t count
) {
if(
count == 0 ||
this->vertexBuffer == -1 ||
this->indexBuffer == -1
) return;
int32_t drawCount = count;
if(count == -1) drawCount = this->indiceCount;
// Re-Bind the buffers
glBindVertexArray(this->vertexArray);
assertNoGLError();
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
assertNoGLError();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
assertNoGLError();
// Re-Calculate the attrib pointers.
size_t offset = 0;
glVertexAttribPointer(
0, sizeof(glm::vec3) / sizeof(float_t),
GL_FLOAT, GL_FALSE,
0, (void *)offset
);
assertNoGLError();
glEnableVertexAttribArray(0);
assertNoGLError();
offset += sizeof(glm::vec3) * this->verticeCount;
glVertexAttribPointer(
1, sizeof(glm::vec2) / sizeof(float_t),
GL_FLOAT, GL_FALSE,
0, (void *)offset
);
assertNoGLError();
glEnableVertexAttribArray(1);
assertNoGLError();
// Render the elements.
glDrawElements(
drawMode,
drawCount,
GL_UNSIGNED_INT,
(void *)(sizeof(int32_t) * start)
);
assertNoGLError();
}
Mesh::~Mesh() {
this->disposeBuffers();
}

View File

@ -1,107 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "dawnopengl.hpp"
namespace Dawn {
enum MeshDrawMode {
TRIANGLES = GL_TRIANGLES,
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
TRIANGLE_FAN = GL_TRIANGLE_FAN,
LINES = GL_LINES,
POINTS = GL_POINTS,
LINE_STRIP = GL_LINE_STRIP
};
class Mesh {
protected:
GLuint vertexBuffer = -1;
GLuint indexBuffer = -1;
GLuint vertexArray = -1;
/** How many vertices are in the mesh */
int32_t verticeCount = -1;
/** How many indices are in the mesh */
int32_t indiceCount = -1;
public:
/**
* Create a new set of buffers for the mesh to use.
*
* @param verticeCount How many Vertices will this buffer support.
* @param indiceCount How many Indices will this buffer support.
*/
void createBuffers(
const int32_t verticeCount,
const int32_t indiceCount
);
/**
* Cleanup the buffers on a given mesh. This is useful if you intend to
* expand the count of vertices your mesh supports.
*/
void disposeBuffers();
/**
* Write vertice positions to the mesh.
*
* @param pos Position, within the buffer, to write to.
* @param positions Array of positions to write.
* @param len How many positions are in the array.
*/
void bufferPositions(
const int32_t pos,
const glm::vec3 positions[],
const int32_t len
);
/**
* Write vertice coordinates to the mesh.
*
* @param pos Position, within the buffer, to write to.
* @param coordinates Array of coordinates to write.
* @param len How many coordinates are in the array.
*/
void bufferCoordinates(
const int32_t pos,
const glm::vec2 coordinates[],
const int32_t len
);
/**
* Write indices to the mesh.
*
* @param pos Position, within the buffer, to write to.
* @param indices Array of indices to write.
* @param len How many indices are in the array.
*/
void bufferIndices(
const int32_t pos,
const int32_t indices[],
const int32_t len
);
/**
* Draw a primitive. Primitives are drawn by their indices.
*
* @param drawMode Which drawing mode to use to draw the primitive.
* @param start Start indice (index) to draw.
* @param count Count of indices to draw. Use -1 to draw all.
*/
void draw(
const enum MeshDrawMode drawMode,
const int32_t start,
const int32_t count
);
/**
* Cleanup a previously initiated mesh.
*/
~Mesh();
};
}

View File

@ -1,72 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "QuadMesh.hpp"
using namespace Dawn;
void QuadMesh::buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const float_t depth
) {
glm::vec3 vertices[QUAD_VERTICE_COUNT] = {
glm::vec3(positions.x, positions.y, depth),
glm::vec3(positions.z, positions.y, depth),
glm::vec3(positions.x, positions.w, depth),
glm::vec3(positions.z, positions.w, depth)
};
glm::vec2 coords[QUAD_VERTICE_COUNT] = {
glm::vec2(coordinates.x, coordinates.y),
glm::vec2(coordinates.z, coordinates.y),
glm::vec2(coordinates.x, coordinates.w),
glm::vec2(coordinates.z, coordinates.w)
};
int32_t indices[QUAD_INDICE_COUNT] = {
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3
};
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
mesh->bufferCoordinates(verticeStart, coords, QUAD_VERTICE_COUNT);
mesh->bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
}
void QuadMesh::bufferWithIndex(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const int32_t indexOffset
) {
glm::vec3 vertices[QUAD_VERTICE_COUNT] = {
glm::vec3(positions.x, positions.y, indexOffset),
glm::vec3(positions.z, positions.y, indexOffset + 1),
glm::vec3(positions.x, positions.w, indexOffset + 2),
glm::vec3(positions.z, positions.w, indexOffset + 3)
};
glm::vec2 coords[QUAD_VERTICE_COUNT] = {
glm::vec2(coordinates.x, coordinates.y),
glm::vec2(coordinates.z, coordinates.y),
glm::vec2(coordinates.x, coordinates.w),
glm::vec2(coordinates.z, coordinates.w)
};
int32_t indices[QUAD_INDICE_COUNT] = {
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3
};
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
mesh->bufferCoordinates(verticeStart, coords, QUAD_VERTICE_COUNT);
mesh->bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
}

View File

@ -1,55 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#define QUAD_VERTICE_COUNT 4
#define QUAD_INDICE_COUNT 6
namespace Dawn {
class QuadMesh {
public:
/**
* Buffers quad mesh vertices and indices into the given mesh.
*
* @param mesh The mesh to buffer into.
* @param positions The positions of the vertices.
* @param coordinates The coordinates of the vertices.
* @param verticeStart The starting index of the vertices.
* @param indiceStart The starting index of the indices.
* @param depth The depth of the vertices (Z coordinate).
*/
static void buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const float_t depth = 0.0f
);
/**
* Buffers quad mesh vertices and indices into the given mesh. This will
* store the index of the vertice in the Z component, allowing you to find
* which vertex ID you are rendering in your shader.
*
* @param mesh The mesh to buffer into.
* @param positions The positions of the vertices.
* @param coordinates The coordinates of the vertices.
* @param verticeStart The starting index of the vertices.
* @param indiceStart The starting index of the indices.
* @param indexOffset The offset to add to the index of each vertex.
*/
static void bufferWithIndex(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 positions,
const glm::vec4 coordinates,
const int32_t verticeStart,
const int32_t indiceStart,
const int32_t indexOffset = 0
);
};
}

View File

@ -1,13 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Shader.cpp
ShaderStage.cpp
SimpleTexturedShader.cpp
ShaderParameter.cpp
)

View File

@ -1,43 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Shader.hpp"
using namespace Dawn;
size_t shaderParameterTypeGetSize(const enum ShaderParameterType type) {
switch(type) {
case ShaderParameterType::VEC2:
return sizeof(glm::vec2);
case ShaderParameterType::VEC3:
return sizeof(glm::vec3);
case ShaderParameterType::VEC4:
return sizeof(glm::vec4);
case ShaderParameterType::MAT3:
return sizeof(glm::mat3);
case ShaderParameterType::MAT4:
return sizeof(glm::mat4);
case ShaderParameterType::COLOR:
return sizeof(struct Color);
case ShaderParameterType::FLOAT:
return sizeof(float);
case ShaderParameterType::INT:
return sizeof(int32_t);
case ShaderParameterType::TEXTURE:
return sizeof(shadertexturebinding_t);
default:
assertUnreachable("Unknown ShaderParameterType");
return 0;
};
}

View File

@ -1,271 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/ShaderStage.hpp"
#include "error/assert.hpp"
#include "error/assertgl.hpp"
#include "display/Color.hpp"
#include "display/Texture.hpp"
#include "ShaderParameter.hpp"
#include "ShaderStructure.hpp"
namespace Dawn {
typedef GLuint shadertexturebinding_t;
enum class ShaderOpenGLVariant {
GLSL_330_CORE
};
class ShaderBase {
};
template<typename T>
class Shader : public ShaderBase {
private:
std::vector<std::shared_ptr<ShaderStage>> stages;
std::vector<struct ShaderParameter> parameters;
std::vector<struct IShaderStructure> structures;
enum ShaderOpenGLVariant variant;
GLuint shaderProgram = -1;
protected:
T data;
/**
* Overridable function to get the stages for the shader.
*
* @param variant The variant of the shader to use.
* @param rel The relative data to use.
* @param stages The stages to add to.
* @param parameters The parameters to add to.
* @param structures The structures to add to.
*/
virtual void getStages(
const enum ShaderOpenGLVariant variant,
const T *rel,
std::vector<std::shared_ptr<ShaderStage>> &stages,
std::vector<struct ShaderParameter> &parameters,
std::vector<struct IShaderStructure> &structures
) = 0;
public:
/**
* Returns the currently uploaded data on the Shader.
*
* @return The uploaded data.
*/
T getData() {
return data;
}
/**
* Sets the entire data to be uploaded.
*
* @param data Data to be uploaded.
*/
void setData(const T data) {
this->data = data;
}
/**
* Initializes the shader, this needs to be called before the shader can
* be used.
*/
void init() {
// Determine which kind of OpenGL shader to use.
variant = ShaderOpenGLVariant::GLSL_330_CORE;
// Now get the stages
T dummy;
this->getStages(
variant,
&dummy,
stages,
parameters,
structures
);
// Create the shader program
shaderProgram = glCreateProgram();
assertNoGLError();
// Attach all the stages
for(auto stage : stages) {
glAttachShader(shaderProgram, stage->id);
assertNoGLError();
}
// Link and verify the program
glLinkProgram(shaderProgram);
assertNoGLError();
GLint status;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
assertNoGLError();
assertTrue(status == GL_TRUE, "Failed to link shader program.");
// Map parameters correctly.
std::for_each(
parameters.begin(),
parameters.end(),
[&](struct ShaderParameter &param) {
// Correct offset
param.offset = param.offset - (size_t)(&dummy);
param.location = glGetUniformLocation(
shaderProgram,
param.name.c_str()
);
assertNoGLError();
assertTrue(
param.location != -1,
"Failed to get location for parameter %s.",
param.name.c_str()
);
}
);
// Map structures
std::for_each(
structures.begin(),
structures.end(),
[&](struct IShaderStructure &structure) {
structure.offset = structure.offset - (size_t)(&dummy);
structure.location = glGetUniformBlockIndex(
shaderProgram,
structure.structureName.c_str()
);
assertNoGLError();
assertTrue(
structure.location != -1,
"Failed to get location for structure %s.",
structure.structureName.c_str()
);
// Create the buffer
glGenBuffers(1, &structure.buffer);
}
);
this->bind();
}
/**
* Binds the shader as the current one, does not upload any data, somewhat
* relies on something else uploading the data.
*/
void bind() {
glUseProgram(shaderProgram);
assertNoGLError();
}
/**
* Uploads the data to the GPU.
*/
void upload() {
switch(this->variant) {
case ShaderOpenGLVariant::GLSL_330_CORE:
for(auto param : parameters) {
void *value = (void*)(
((size_t)&this->data) + param.offset
);
switch(param.type) {
case ShaderParameterType::MAT4: {
glm::mat4 *matrix = (glm::mat4 *)value;
if(param.count != 1) {
assertUnreachable("I haven't implemented multiple mat4s");
}
glUniformMatrix4fv(
param.location, 1, GL_FALSE, glm::value_ptr(*matrix)
);
break;
}
case ShaderParameterType::COLOR: {
auto color = (Color *)value;
glUniform4fv(
param.location,
param.count,
(GLfloat*)value
);
break;
}
case ShaderParameterType::BOOLEAN: {
glUniform1iv(param.location, param.count, (GLint*)value);
break;
}
case ShaderParameterType::TEXTURE: {
glUniform1iv(param.location, param.count, (GLint*)value);
break;
}
default: {
assertUnreachable("Unsupported ShaderParameterType");
}
}
assertNoGLError();
}
break;
default:
assertUnreachable("Unsupported ShaderOpenGLVariant");
}
// Upload structures
for(auto structure : structures) {
switch(structure.structureType) {
case ShaderOpenGLStructureType::STD140: {
// Upload the data
glBindBuffer(GL_UNIFORM_BUFFER, structure.buffer);
assertNoGLError();
glBindBufferBase(GL_UNIFORM_BUFFER, structure.location, structure.buffer);
assertNoGLError();
glBufferData(
GL_UNIFORM_BUFFER,
structure.size * structure.count,
(void*)((size_t)&this->data + (size_t)structure.offset),
GL_STATIC_DRAW
);
assertNoGLError();
break;
}
default:
assertUnreachable("Unsupported ShaderOpenGLStructureType");
}
}
}
/**
* Disposes of the shader.
*/
~Shader() {
// Delete the structures
for(auto structure : structures) {
assertTrue(structure.buffer != -1, "Invalid buffer.");
glDeleteBuffers(1, &structure.buffer);
assertNoGLError();
}
// Delete the shader program
glDeleteProgram(shaderProgram);
assertNoGLError();
}
};
/**
* Returns the size of the ShaderParameterType.
*
* @param type The type to get the size of.
* @return Size of the type.
*/
size_t shaderParameterTypeGetSize(const enum Dawn::ShaderParameterType type);
}

View File

@ -1,45 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/Shader.hpp"
namespace Dawn {
class ShaderManager {
private:
std::vector<std::shared_ptr<ShaderBase>> shaders;
public:
/**
* Retreives an instance of the shader from the shader manager. If the
* shader does not exist it will be created.
*
* @tparam T Type of shader to retreive.
* @return Shader instance.
*/
template<class T>
std::shared_ptr<T> getShader() {
auto itShaders = shaders.begin();
while(itShaders != shaders.end()) {
// auto shader = itShaders->lock();
// if(!shader) {
// itShaders = shaders.erase(itShaders);
// continue;
// }
// std::shared_ptr<T> casted = std::dynamic_pointer_cast<T>(shader);
auto shader = *itShaders;
std::shared_ptr<T> casted = std::dynamic_pointer_cast<T>(shader);
if(casted) return casted;
itShaders++;
}
auto newShader = std::make_shared<T>();
shaders.push_back(newShader);
newShader->init();
return newShader;
}
};
}

View File

@ -1,20 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "ShaderParameter.hpp"
using namespace Dawn;
ShaderParameter::ShaderParameter(
const std::string &name,
const void *offset,
const enum ShaderParameterType type,
const size_t count
) {
this->name = name;
this->offset = (size_t)offset;
this->type = type;
this->count = count;
}

View File

@ -1,46 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "dawnopengl.hpp"
namespace Dawn {
enum class ShaderParameterType {
VEC2,
VEC3,
VEC4,
MAT3,
MAT4,
COLOR,
FLOAT,
INT,
TEXTURE,
BOOLEAN
};
struct ShaderParameter {
std::string name;
size_t offset;
enum ShaderParameterType type;
size_t count;
GLint location = -1;
/**
* Construct a new shader parameter.
*
* @param name Name of the parameter within the shader.
* @param offset Offset, relative to the structure of the data.
* @param type Type of the parameter.
* @param count How many elements in the array (if multiple).
*/
ShaderParameter(
const std::string &name,
const void *offset,
const enum ShaderParameterType type,
const size_t count = 1
);
};
}

View File

@ -1,69 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "error/assertgl.hpp"
#include "error/assert.hpp"
#include "ShaderStage.hpp"
using namespace Dawn;
ShaderStage::ShaderStage(
const enum ShaderStageType type,
const std::string source
) : type(type) {
// Get OpenGL Shader Type
GLenum shaderType;
switch(this->type) {
case ShaderStageType::VERTEX:
shaderType = GL_VERTEX_SHADER;
break;
case ShaderStageType::FRAGMENT:
shaderType = GL_FRAGMENT_SHADER;
break;
// case ShaderStageType::COMPUTE:
// shaderType = GL_COMPUTE;
// break;
default:
assertUnreachable("Unknown ShaderStageType");
}
// Initialize the shader
this->id = glCreateShader(shaderType);
assertNoGLError();
// Compile the shader
auto cSource = source.c_str();
glShaderSource(this->id, 1, &cSource, NULL);
assertNoGLError();
glCompileShader(this->id);
assertNoGLError();
// Validate
GLint status;
glGetShaderiv(this->id, GL_COMPILE_STATUS, &status);
assertNoGLError();
if(!status) {
// Failed to compile
GLint logLength;
glGetShaderiv(this->id, GL_INFO_LOG_LENGTH, &logLength);
assertNoGLError();
GLchar *log = new GLchar[logLength];
glGetShaderInfoLog(this->id, logLength, NULL, log);
assertNoGLError();
assertUnreachable("Failed to compile shader stage %i:\n%s", type, log);
}
}
ShaderStage::~ShaderStage() {
if(this->id != -1) {
glDeleteShader(this->id);
assertNoGLError();
}
}

View File

@ -1,35 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "dawnopengl.hpp"
namespace Dawn {
enum class ShaderStageType {
VERTEX,
FRAGMENT,
// COMPUTE
};
class ShaderStage {
public:
GLuint id = -1;
const enum ShaderStageType type;
/**
* Constructs a new ShaderStage.
*
* @param type The type of shader this is.
* @param source The source code to compile.
*/
ShaderStage(const enum ShaderStageType type, const std::string source);
/**
* Disposes of the shader stage.
*/
~ShaderStage();
};
}

View File

@ -1,95 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma ocne
#include "display/shader/ShaderParameter.hpp"
namespace Dawn {
enum class ShaderOpenGLStructureType {
STD140
};
struct IShaderStructure {
std::string structureName;
size_t offset;
enum ShaderOpenGLStructureType structureType;
size_t size;
size_t count;
std::vector<struct ShaderParameter> parameters;
GLint location = -1;
GLuint buffer = -1;
};
template<typename T>
struct ShaderStructure final : public IShaderStructure {
public:
/**
* Constructs a new shader structure. Shader structures allow for larger
* amounts/volumes of data to be passed to the shader in a single call.
* Ideally I wouldn't really need this as I wanted the entire shader to
* basically be a single large structure, but OpenGL doesn't support that
* so I have to do this instead.
*
* @param structureName Structure name within the shader.
* @param offset Offset, within the data structure, that this structure
* starts at.
* @param structureType The type of structure data format to use.
* @param getParameters A callback that, when invoked, will populate the
* parameters vector with the parameters for this
* structure.
*/
ShaderStructure(
const std::string &structureName,
const void *offset,
const enum ShaderOpenGLStructureType structureType,
std::function<
void(const T&, std::vector<struct ShaderParameter>&)
> getParameters,
size_t count = 1
) {
this->structureName = structureName;
this->offset = (size_t)offset;
this->structureType = structureType;
this->size = sizeof(T);
this->count = count;
this->parameters = std::vector<struct ShaderParameter>();
T dummy;
getParameters(dummy, this->parameters);
// Update offsets.
auto itParams = this->parameters.begin();
while(itParams != this->parameters.end()) {
struct ShaderParameter &param = *itParams;
param.offset -= (size_t)(&dummy);
// Check for non-aligned OpenGL structures.
if(param.offset % sizeof(glm::vec4) != 0) {
assertUnreachable(
"%s%s%s",
"Non-aligned OpenGL structure detected on param ",
param.name.c_str(),
"!\nEnsure you have padded correctly."
);
}
if(
itParams == (this->parameters.end() - 1) &&
count > 1 &&
(sizeof(T) % sizeof(glm::vec4)) != 0
) {
assertUnreachable(
"%s%s%s",
"Non-aligned OpenGL structure detected on last element in array structure on param ",
param.name.c_str(),
"!\nEnsure you have padded correctly."
);
}
++itParams;
}
}
};
}

View File

@ -1,100 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "display/shader/SimpleTexturedShader.hpp"
using namespace Dawn;
void SimpleTexturedShader::getStages(
const enum ShaderOpenGLVariant variant,
const struct SimpleTexturedShaderData *rel,
std::vector<std::shared_ptr<ShaderStage>> &stages,
std::vector<struct ShaderParameter> &parameters,
std::vector<struct IShaderStructure> &structures
) {
// Stages
std::shared_ptr<ShaderStage> vertex;
std::shared_ptr<ShaderStage> fragment;
switch(variant) {
case ShaderOpenGLVariant::GLSL_330_CORE:
vertex = std::make_shared<ShaderStage>(
ShaderStageType::VERTEX,
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 aTexCoord;\n"
"uniform mat4 u_Projection;\n"
"uniform mat4 u_View;\n"
"uniform mat4 u_Model;\n"
"out vec2 o_TextCoord;\n"
"void main() {\n"
"gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\n"
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
"}"
);
fragment = std::make_shared<ShaderStage>(
ShaderStageType::FRAGMENT,
"#version 330 core\n"
"in vec2 o_TextCoord;\n"
"out vec4 o_Color;\n"
"uniform vec4 u_Color;\n"
"uniform bool u_HasTexture;\n"
"uniform sampler2D u_Texture;\n"
"void main() {\n"
"if(u_HasTexture) {\n"
"o_Color = texture(u_Texture, o_TextCoord) * u_Color;\n"
"} else {\n"
"o_Color = u_Color;"
"}\n"
"}\n"
);
break;
default:
assertUnreachable("Unsupported ShaderOpenGLVariant");
}
// Add stages
stages.push_back(vertex);
stages.push_back(fragment);
// Parameters
parameters.push_back(ShaderParameter(
"u_Projection",
&rel->projection,
ShaderParameterType::MAT4
));
parameters.push_back(ShaderParameter(
"u_View",
&rel->view,
ShaderParameterType::MAT4
));
parameters.push_back(ShaderParameter(
"u_Model",
&rel->model,
ShaderParameterType::MAT4
));
parameters.push_back(ShaderParameter(
"u_Color",
&rel->color,
ShaderParameterType::COLOR
));
parameters.push_back(ShaderParameter(
"u_HasTexture",
&rel->hasTexture,
ShaderParameterType::BOOLEAN
));
parameters.push_back(ShaderParameter(
"u_Texture",
&rel->texture,
ShaderParameterType::TEXTURE
));
}

View File

@ -1,29 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/Shader.hpp"
namespace Dawn {
struct SimpleTexturedShaderData {
glm::mat4 projection;
glm::mat4 view;
glm::mat4 model;
struct Color color = COLOR_WHITE;
bool hasTexture = false;
shadertexturebinding_t texture = 0;
};
class SimpleTexturedShader : public Shader<SimpleTexturedShaderData> {
protected:
void getStages(
const enum ShaderOpenGLVariant variant,
const struct SimpleTexturedShaderData *rel,
std::vector<std::shared_ptr<ShaderStage>> &stages,
std::vector<struct ShaderParameter> &parameters,
std::vector<struct IShaderStructure> &structures
) override;
};
}

View File

@ -1,11 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
assertgl.cpp
erroropengl.cpp
)

View File

@ -1,61 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assertgl.hpp"
#include "error/assert.hpp"
#include "dawnopengl.hpp"
void assertNotGLErrorCheck(const char *file, int32_t line) {
GLenum errorCode;
std::string fileString = file;
std::string error = "GL Error";
int32_t errorCount = 0;
while((errorCode = glGetError()) != GL_NO_ERROR) {
errorCount++;
switch (errorCode) {
case GL_INVALID_ENUM:
error += "\nINVALID_ENUM";
break;
case GL_INVALID_VALUE:
error += "\nINVALID_VALUE";
break;
case GL_INVALID_OPERATION:
error += "\nINVALID_OPERATION";
break;
case GL_STACK_OVERFLOW:
error += "\nSTACK_OVERFLOW";
break;
case GL_STACK_UNDERFLOW:
error += "\nSTACK_UNDERFLOW";
break;
case GL_OUT_OF_MEMORY:
error += "\nOUT_OF_MEMORY";
break;
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION
case GL_INVALID_FRAMEBUFFER_OPERATION:
error += "\nINVALID_FRAMEBUFFER_OPERATION";
break;
#endif
default:
error += "\nUNKNOWN GL ERROR ERROR";
break;
}
error += " (" + std::to_string(errorCode) + ")";
}
if(errorCount != 0) {
error += "\n" + std::string(file) + " (" + std::to_string(line) + ")";
assertUnreachable(error.c_str());
}
}

View File

@ -1,20 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
/**
* Asserts that there are no OpenGL errors.
*
* @param file The file the assertion is being made in.
* @param line The line the assertion is being made in.
*/
void assertNotGLErrorCheck(const char *file, int32_t line);
/**
* Asserts that there are no OpenGL errors.
*/
#define assertNoGLError() assertNotGLErrorCheck(__FILE__, __LINE__)

View File

@ -1,58 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "erroropengl.hpp"
void errorCheckOpenGL() {
std::stringstream buffer;
GLenum errorCode;
int32_t errorCount = 0;
while((errorCode = glGetError()) != GL_NO_ERROR) {
errorCount++;
switch (errorCode) {
case GL_INVALID_ENUM:
buffer << "INVALID_ENUM" << std::endl;
break;
case GL_INVALID_VALUE:
buffer << "INVALID_VALUE" << std::endl;
break;
case GL_INVALID_OPERATION:
buffer << "INVALID_OPERATION" << std::endl;
break;
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION
case GL_INVALID_FRAMEBUFFER_OPERATION:
buffer << "INVALID_FRAMEBUFFER_OPERATION" << std::endl;
break;
#endif
case GL_OUT_OF_MEMORY:
buffer << "OUT_OF_MEMORY" << std::endl;
break;
case GL_STACK_UNDERFLOW:
buffer << "STACK_UNDERFLOW" << std::endl;
break;
case GL_STACK_OVERFLOW:
buffer << "STACK_OVERFLOW" << std::endl;
break;
default:
buffer << "UNKNOWN" << std::endl;
break;
}
buffer << "(Error Code: " << errorCode << ")" << std::endl;
}
if(errorCount > 0) {
throw std::runtime_error("OpenGL Error(s) Found: " + buffer.str());
}
}

View File

@ -1,13 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "dawnopengl.hpp"
/**
* Checks for OpenGL errors. Throws an exception if an error is found.
*/
void errorCheckOpenGL();

View File

@ -1,37 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libraries
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
m
c
psputility
pspdebug
pspge
pspdisplay
pspctrl
pspsdk
pspuser
psprtc
pspvfpu
GL
)
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
main.cpp
)
# Subdirs
add_subdirectory(error)
add_subdirectory(host)

View File

@ -1,10 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
error.cpp
)

View File

@ -1,31 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "error/error.hpp"
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
void errorMessageBox(const std::u8string &message) {
// c8string to cstring
std::string messageStr = (
message.length() > 0 ?
std::string(message.cbegin(), message.cend()) :
std::string()
);
// Print Hello World! on a debug screen on a loop
pspDebugScreenInit();
while(1) {
pspDebugScreenSetXY(0, 0);
pspDebugScreenPrintf(messageStr.c_str());
sceDisplayWaitVblankStart();
}
}
void errorLog(const std::string &message) {
std::cerr << message << std::endl;
}

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