- Notifications
You must be signed in to change notification settings - Fork0
Experimental early-stage rendering engine for Windows and Linux.
License
anthofoxo/vulpengine
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Vulpengine is an experimental early-stage rendering engine for Windows and Linux. Vulpengine is a general toolset developed by myself used to help myself develop games.
Vulpengine is designed to be used as a static library and git submodule. Add Vulpengine to your submodules withgit submodule add https://github.com/anthofoxo/vulpengine your_submodule_path
.
Vulpengine requires C++20 Support.
Vulpengine requires the following dependencies.
OpenGL 4.5+ is required.Optionally supports:
- GL_ARB_texture_filter_anisotropic (4.6+ Supported)
- GL_EXT_texture_filter_anisotropic
Building Vulpengine is kept simple. Addinclude/vulpengine
to the include paths and add the include paths for all the required libraries.
include/vulpengine
glfw/include
glad/include
Vulpengine supports Windows and Linux.
#define VP_WINDOWS
for Windows builds.#define VP_LINUX
for Linux builds.
If you're building GLFW yourself you will need to generate the xdg headers for wayland. We've bundled a small tool for thisglfw_generate_xdg.sh
.
Vulpengine supports 3 different configurations. If you only havedebug
andrelease
then you can use those.
- For debug builds
#define VP_DEBUG
. - For release builds
#define VP_RELEASE
. - For dist builds
#define VP_DIST
.
Dist is similar to release but with extra debugging tools stripped.
- You should define
GLFW_INCLUDE_NONE
. - Define
VP_ENTRY_WINMAIN
if you're using theWinMain
entrypoint.
Vulpengine supportsspdlog. To enable spdlog support addspdlog/include
to the include paths.
Vulpengine can detect and useTracy if available.
Addtracy/public
to your include paths. Make sure to#define TRACY_ENABLE
too.
Vulpengine can supportRenderDoc detection. RenderDoc installations includerenderdoc_app.h
in the installation directory. Add this directory to the include paths for Vulpengine to detect and enable support for it.
The code below shows how to detect RenderDoc.
If enabled withVP_FEATURE_RDOC_UNSUPPORTED
the parameter may be set totrue
to attempt to inject RenderDoc at startup. While this does works currently, itIS NOT SUPPORTED by the RenderDoc developers and may break.
#include<vulpengine/vp_rdoc.hpp>// Do this before graphics api creationvulpengine::experimental::rdoc::setup(false);
If stb_image is available theImage
class will be available along with helper functions forTexture
creation and upload.
If glm is available, theTransform
andFrustum
features will be enabled.
Once Vulpengine is built. Simply add ourinclude
directory to your include paths.
All Vulpengine headers are prefixed withvp_
to avoid name clashes. You may directly addinclude/vulpengine
if you like.
Vulpengine will define the main entrypoint, so you can't directly use that. This is mainly to perform some backend work to ensure logging will work.
Otherwise no other processing happens and the argments are directly forwarded to the Vulpengine entry point.
#include<vulpengine/vp_entry.hpp>intvulpengine::main(int argc,char* argv[]) {return0;}
Wrap is a simply box type to get around some odd reference semantics when using value types such asstd::optional
andstd::span
.
Wrap is simply defined as:
template<classT>structWrap { T value; };
These utility functions help to easily assist in wrapping reference types.
This takes a reference type and wraps the reference.
This should be treated like astd::move
.This performs astd::move
on the argument and stores the rvalue reference into the wrapper. This is used during resource transfer into Meshes.
Meshes are split into 3 parts. Buffers, Vertex Arrays, and Meshes.Buffers are just OpenGL buffers: Array buffers, element buffers, uniform buffers etc. Vertex arrays are OpenGL vertex arrays. These are constructed with a list of buffers and a list of attributes. Meshes are simple containers to transfer ownership of these resources.
For the example usage assume we have these structs defined:
structVec3f32final {float x, y;};structVertexfinal {Vec3f32 position;};
Vertex positions[] = {{ -0.5f, -0.5f },{0.5f, -0.5f },{0.0f,0.5f }};vulpengine::experimental::Buffer vertexBuffer = {{.content =std::as_bytes(std::span(positions)),.flags = GL_NONE,.label ="Test vertex buffer"// May be omitted}};
vulpengine::experimental::VertexArray vertexArray = {{.buffers = std::array {vulpengine::experimental::VertexArray::BufferInfo {.buffer = vertexBuffer,.offset =0,.stride =sizeof(Vertex),.divisor =0}},.attributes = std::array {vulpengine::experimental::VertexArray::AttributeInfo {.size =2,.type = GL_FLOAT,.relativeoffset =offsetof(Vertex, position),.bindingindex =0,}},// Optionally attach an index buffer// .indexBuffer = vulpengine::experimental::wrap_cref(indexBuffer),.label ="Test vertex array"}};
You'll typically want to transfer all static data into the Mesh, however the Mesh doesn't require ownership of buffers.
vulpengine::experimental::Mesh mesh = {{// usage of std::move is required, this hints to the developer that this takes ownership.vertexArray =std::move(vertexArray),.buffers = std::array {// wrap_rvrefvulpengine::experimental::wrap_rvref(vertexBuffer),vulpengine::experimental::wrap_rvref(indexBuffer),},.mode = GL_TRIANGLES,.count =3,// May be omitted or `GL_NONE` if no index buffer is used..type = GL_UNSIGNED_INT}};