Initial commit
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