Initial commit
This commit is contained in:
commit
4e86a20238
|
@ -0,0 +1,3 @@
|
||||||
|
build
|
||||||
|
.cache
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Types.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
template <size_t Length, size_t Alignment>
|
||||||
|
struct AlignedStorage
|
||||||
|
{
|
||||||
|
alignas(Alignment) unsigned char data[Length];
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Result.h>
|
||||||
|
|
||||||
|
namespace orange::fs
|
||||||
|
{
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
//Result<File>
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Types.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
constexpr uint32_t HashString(const char* s, size_t count)
|
||||||
|
{
|
||||||
|
return ((count ? HashString(s, count - 1) : 2166136261u) ^ s[count]) * 16777619u;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr uint32_t operator"" _hash(const char* s, size_t count)
|
||||||
|
{
|
||||||
|
return HashString(s, count);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
#define Assert(...)
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Log.h>
|
||||||
|
#include <Orange/Core/AlignedStorage.h>
|
||||||
|
#include <Orange/Core/Traits.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
enum class BasicErrorCode : int32_t
|
||||||
|
{
|
||||||
|
Invalid = -1,
|
||||||
|
Failed = -2,
|
||||||
|
|
||||||
|
Success = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename ErrorCode = BasicErrorCode>
|
||||||
|
class Result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~Result() { Destroy(); }
|
||||||
|
|
||||||
|
T* Get()
|
||||||
|
{
|
||||||
|
Assert(IsSuccess());
|
||||||
|
if (!IsSuccess())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &RefUnsafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* Get() const
|
||||||
|
{
|
||||||
|
Assert(IsSuccess());
|
||||||
|
if (!IsSuccess())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &RefUnsafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSuccess() const { return static_cast<int32_t>(m_error) >= 0; }
|
||||||
|
|
||||||
|
operator bool() const { return IsSuccess(); }
|
||||||
|
|
||||||
|
T* operator ->() { return Get(); }
|
||||||
|
const T* operator ->() const { return Get(); }
|
||||||
|
|
||||||
|
T& operator *() { return *Get(); }
|
||||||
|
const T& operator *() const { return *Get(); }
|
||||||
|
protected:
|
||||||
|
Result() = default;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
T& Create(Args&&... args)
|
||||||
|
{
|
||||||
|
Assert(!m_created);
|
||||||
|
m_created = true;
|
||||||
|
new(&m_data) T(Forward<Args>(args)...);
|
||||||
|
return RefUnsafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destroy()
|
||||||
|
{
|
||||||
|
if (m_created)
|
||||||
|
{
|
||||||
|
RefUnsafe().~T();
|
||||||
|
m_created = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result& Error(ErrorCode code) { m_error = code; return *this; }
|
||||||
|
Result& Success() { m_error = ErrorCode::Success; return *this; }
|
||||||
|
|
||||||
|
T& RefUnsafe() { return *reinterpret_cast< T*>(&m_data); }
|
||||||
|
const T& RefUnsafe() const { return *reinterpret_cast<const T*>(&m_data); }
|
||||||
|
|
||||||
|
friend T;
|
||||||
|
AlignedStorage<sizeof(T), alignof(T)> m_data;
|
||||||
|
ErrorCode m_error = ErrorCode::Invalid;
|
||||||
|
bool m_created = false;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/AlignedStorage.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
template <typename T, size_t N>
|
||||||
|
class SmallVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
SmallVector() {}
|
||||||
|
SmallVector(size_t size) { Resize(size); }
|
||||||
|
|
||||||
|
SmallVector (const SmallVector&) = delete;
|
||||||
|
SmallVector& operator = (const SmallVector&) = delete;
|
||||||
|
|
||||||
|
~SmallVector()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_size; i++)
|
||||||
|
Ptr(i)->~T();
|
||||||
|
|
||||||
|
if (m_capacity > N)
|
||||||
|
delete[] u.m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Size() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reserve(size_t n)
|
||||||
|
{
|
||||||
|
n = PickCapacity(n);
|
||||||
|
|
||||||
|
if (n <= m_capacity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Storage* data = new Storage[n];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
new (&data[i]) T(Move(*Ptr(i)));
|
||||||
|
Ptr(i)->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_capacity > N)
|
||||||
|
delete[] u.m_ptr;
|
||||||
|
|
||||||
|
m_capacity = n;
|
||||||
|
u.m_ptr = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* Data() const { return Ptr(0); }
|
||||||
|
T* Data() { return Ptr(0); }
|
||||||
|
|
||||||
|
void Resize(size_t n)
|
||||||
|
{
|
||||||
|
Reserve(n);
|
||||||
|
|
||||||
|
for (size_t i = n; i < m_size; i++)
|
||||||
|
Ptr(i)->~T();
|
||||||
|
|
||||||
|
for (size_t i = m_size; i < n; i++)
|
||||||
|
new (Ptr(i)) T();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushBack(const T& object)
|
||||||
|
{
|
||||||
|
Reserve(m_size + 1);
|
||||||
|
new (Ptr(m_size++)) T(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushBack(T&& object)
|
||||||
|
{
|
||||||
|
Reserve(m_size + 1);
|
||||||
|
new (Ptr(m_size++)) T(Move(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void EmplaceBack(Args... args)
|
||||||
|
{
|
||||||
|
Reserve(m_size + 1);
|
||||||
|
new (Ptr(m_size++)) T(Forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Erase(size_t idx)
|
||||||
|
{
|
||||||
|
Ptr(idx)->~T();
|
||||||
|
|
||||||
|
for (size_t i = idx; i < m_size - 1; i++)
|
||||||
|
{
|
||||||
|
new (Ptr(i)) T(Move(*Ptr(i + 1)));
|
||||||
|
Ptr(i + 1)->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopBack()
|
||||||
|
{
|
||||||
|
Ptr(--m_size)->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator [] (size_t idx) { return *Ptr(idx); }
|
||||||
|
const T& operator [] (size_t idx) const { return *Ptr(idx); }
|
||||||
|
|
||||||
|
T& front() { return *Ptr(0); }
|
||||||
|
const T& front() const { return *Ptr(0); }
|
||||||
|
|
||||||
|
T& back() { return *Ptr(m_size - 1); }
|
||||||
|
const T& back() const { return *Ptr(m_size - 1); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
using Storage = AlignedStorage<sizeof(T), alignof(T)>;
|
||||||
|
|
||||||
|
size_t m_capacity = N;
|
||||||
|
size_t m_size = 0;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
Storage* m_ptr;
|
||||||
|
Storage m_data[sizeof(T) * N];
|
||||||
|
} u;
|
||||||
|
|
||||||
|
size_t PickCapacity(size_t n) {
|
||||||
|
size_t capacity = m_capacity;
|
||||||
|
|
||||||
|
while (capacity < n)
|
||||||
|
capacity *= 2;
|
||||||
|
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* Ptr(size_t idx) {
|
||||||
|
return m_capacity == N
|
||||||
|
? reinterpret_cast<T*>(&u.m_data[idx])
|
||||||
|
: reinterpret_cast<T*>(&u.m_ptr[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* Ptr(size_t idx) const
|
||||||
|
{
|
||||||
|
return m_capacity == N
|
||||||
|
? reinterpret_cast<const T*>(&u.m_data[idx])
|
||||||
|
: reinterpret_cast<const T*>(&u.m_ptr[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Types.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct Span
|
||||||
|
{
|
||||||
|
Span(T* data, size_t size) : data(data), size(size) {}
|
||||||
|
|
||||||
|
template <size_t Count>
|
||||||
|
Span(T (&array)[Count]) : data(array), size(Count) {}
|
||||||
|
|
||||||
|
explicit Span(T* data) : data(data), size(1) {}
|
||||||
|
explicit Span(T& data) : data(&data), size(1) {}
|
||||||
|
|
||||||
|
T& operator [] (size_t idx) { return data[idx]; }
|
||||||
|
const T& operator [] (size_t idx) const { return data[idx]; }
|
||||||
|
|
||||||
|
bool IsEmpty() const { return size == 0; }
|
||||||
|
|
||||||
|
T& front() { return *data[idx]; }
|
||||||
|
const T& front() const { return *data[idx]; }
|
||||||
|
|
||||||
|
T& back() { return *data[size - 1]; }
|
||||||
|
const T& back() const { return *data[size - 1]; }
|
||||||
|
|
||||||
|
T* data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
struct FalseType { static constexpr bool Value = false; };
|
||||||
|
struct TrueType { static constexpr bool Value = true; };
|
||||||
|
|
||||||
|
template <typename T> struct IsLValueReference : FalseType {};
|
||||||
|
template <typename T> struct IsLValueReference<T&> : TrueType {};
|
||||||
|
|
||||||
|
template <typename T> struct RemoveReference_ { using Type = T; };
|
||||||
|
template <typename T> struct RemoveReference_<T&> { using Type = T; };
|
||||||
|
template <typename T> struct RemoveReference_<T&&> { using Type = T; };
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using RemoveReference = typename RemoveReference_<T>::Type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T&& Forward(RemoveReference<T>& t) { return static_cast<T&&>(t); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T&& Forward(RemoveReference<T>&& t)
|
||||||
|
{
|
||||||
|
static_assert(!IsLValueReference<T>::Value, "Can not forward an rvalue as an lvalue.");
|
||||||
|
return static_cast<T&&>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr RemoveReference<T>&& Move(T&& arg)
|
||||||
|
{
|
||||||
|
return static_cast<RemoveReference<T>&&>(arg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
|
@ -0,0 +1,109 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Types.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
class Quake2BSP
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Quake2BSP(const void* data, size_t size);
|
||||||
|
private:
|
||||||
|
static constexpr uint32_t LumpCount = 19;
|
||||||
|
static constexpr uint32_t MaxLightmapStyles = 4;
|
||||||
|
|
||||||
|
struct LumpType
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Entities,
|
||||||
|
Planes,
|
||||||
|
Vertices,
|
||||||
|
Visibility,
|
||||||
|
Nodes,
|
||||||
|
TextureInfo,
|
||||||
|
Faces,
|
||||||
|
Lightmaps,
|
||||||
|
Leaves,
|
||||||
|
LeafFaceTable,
|
||||||
|
LeafBrushTable,
|
||||||
|
Edges,
|
||||||
|
FaceEdgeTable,
|
||||||
|
Models,
|
||||||
|
Brushes,
|
||||||
|
BrushSides,
|
||||||
|
Pop,
|
||||||
|
Areas,
|
||||||
|
AreaPortals,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LumpPointer
|
||||||
|
{
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSPHeader
|
||||||
|
{
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t version;
|
||||||
|
|
||||||
|
LumpPointer lumps[LumpCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSPFace
|
||||||
|
{
|
||||||
|
uint16_t plane;
|
||||||
|
uint16_t planeSide;
|
||||||
|
|
||||||
|
uint32_t firstEdge;
|
||||||
|
uint16_t numEdges;
|
||||||
|
|
||||||
|
uint16_t textureInfoIdx;
|
||||||
|
|
||||||
|
uint8_t lightmapStyles[MaxLightmapStyles];
|
||||||
|
uint32_t lightmapOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSPPlane
|
||||||
|
{
|
||||||
|
float normal[3];
|
||||||
|
float distance;
|
||||||
|
uint32_t type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSPNode
|
||||||
|
{
|
||||||
|
uint32_t plane;
|
||||||
|
|
||||||
|
int32_t frontChild;
|
||||||
|
int32_t backChild;
|
||||||
|
|
||||||
|
int16_t bboxMins[3];
|
||||||
|
int16_t bboxMaxs[3];
|
||||||
|
|
||||||
|
uint16_t firstLeafFace;
|
||||||
|
uint16_t numLeafFaces;
|
||||||
|
|
||||||
|
uint16_t firstLeafBrush;
|
||||||
|
uint16_t numLeafBrushes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSPTexInfo
|
||||||
|
{
|
||||||
|
float uAxis[3];
|
||||||
|
float uOffset;
|
||||||
|
|
||||||
|
float vAxis[3];
|
||||||
|
float vOffset;
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
char textureName[32];
|
||||||
|
|
||||||
|
uint32_t nextTexInfo;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Result.h>
|
||||||
|
#include <Orange/Render/Renderer.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
class ForwardRenderer : public Renderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~ForwardRenderer() = default;
|
||||||
|
|
||||||
|
static Result<ForwardRenderer> create(SDL_Window* window, const char* name)
|
||||||
|
{
|
||||||
|
Result<ForwardRenderer> result;
|
||||||
|
|
||||||
|
ForwardRenderer& renderer = result.Create();
|
||||||
|
|
||||||
|
if ((renderer.m_instance = createInstance(window, name)) == VK_NULL_HANDLE)
|
||||||
|
return result.Error(BasicErrorCode::Failed);
|
||||||
|
|
||||||
|
return result.Success();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
friend Result<ForwardRenderer>;
|
||||||
|
ForwardRenderer() = default;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Types.h>
|
||||||
|
#include <Orange/Core/SmallVector.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_vulkan.h>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
|
||||||
|
class Renderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~Renderer() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Renderer() = default;
|
||||||
|
|
||||||
|
static VkInstance createInstance(SDL_Window* window, const char* name)
|
||||||
|
{
|
||||||
|
uint32_t instanceExtensionCount = {};
|
||||||
|
if (SDL_Vulkan_GetInstanceExtensions(window, &instanceExtensionCount, nullptr) != SDL_TRUE)
|
||||||
|
{
|
||||||
|
//std::cerr << "Failed to get SDL instance extension count.\n";
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallVector<const char *, 8> instanceExtensions{ instanceExtensionCount };
|
||||||
|
if (SDL_Vulkan_GetInstanceExtensions(window, &instanceExtensionCount, instanceExtensions.Data()) != SDL_TRUE)
|
||||||
|
{
|
||||||
|
//std::cerr << "Failed to get SDL instance extensions.\n";
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkApplicationInfo appInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||||
|
.pApplicationName = name,
|
||||||
|
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
|
||||||
|
.pEngineName = "Orange",
|
||||||
|
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
|
||||||
|
.apiVersion = VK_API_VERSION_1_3,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkInstanceCreateInfo instanceInfo =
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||||
|
.pApplicationInfo = &appInfo,
|
||||||
|
.enabledExtensionCount = instanceExtensionCount,
|
||||||
|
.ppEnabledExtensionNames = instanceExtensions.Data(),
|
||||||
|
};
|
||||||
|
|
||||||
|
VkResult result = VK_SUCCESS;
|
||||||
|
VkInstance instance;
|
||||||
|
if ((result = vkCreateInstance(&instanceInfo, nullptr, &instance)) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
//std::cerr << "Failed to create Vulkan instance.\n";
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkInstance m_instance = VK_NULL_HANDLE;
|
||||||
|
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
|
||||||
|
VkDevice m_device = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
project('orange', ['cpp'], version : '0.0.1', meson_version : '>= 0.49', default_options : [
|
||||||
|
'warning_level=2',
|
||||||
|
'c_std=c11',
|
||||||
|
'cpp_std=c++20'
|
||||||
|
])
|
||||||
|
|
||||||
|
orange_compiler = meson.get_compiler('cpp')
|
||||||
|
add_project_arguments(orange_compiler.get_supported_arguments([
|
||||||
|
'-Wno-missing-field-initializers',
|
||||||
|
]), language : 'cpp')
|
||||||
|
|
||||||
|
orange_include = include_directories(['include'])
|
||||||
|
sdl2_dep = dependency('SDL2')
|
||||||
|
vulkan_dep = dependency('vulkan') # get rid of me!
|
||||||
|
|
||||||
|
subdir('src')
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include <Orange/Core/Result.h>
|
||||||
|
#include <Orange/Render/ForwardRenderer.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
executable('BSPViewer', 'BSPViewer.cpp',
|
||||||
|
dependencies : [sdl2_dep, vulkan_dep],
|
||||||
|
include_directories : [orange_include])
|
|
@ -0,0 +1 @@
|
||||||
|
subdir('Tools')
|
|
@ -0,0 +1 @@
|
||||||
|
subdir('Apps')
|
Loading…
Reference in New Issue