Move stuff to files
This commit is contained in:
parent
24db7d8413
commit
482a42ad07
|
@ -7,6 +7,10 @@
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#ifndef offsetof2
|
||||||
|
#define offsetof2(type, member) size_t(uintptr_t(&((type*)0)->member))
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace orange
|
namespace orange
|
||||||
{
|
{
|
||||||
template <typename Signature>
|
template <typename Signature>
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Variant.h>
|
||||||
|
#include <Orange/Graphics/Vertex.h>
|
||||||
|
#include <Orange/Math/AABB.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
struct MeshVertexData
|
||||||
|
{
|
||||||
|
MeshVertexData(MeshVertexType type)
|
||||||
|
: vertexType(type)
|
||||||
|
{
|
||||||
|
switch(vertexType)
|
||||||
|
{
|
||||||
|
case MeshVertexType::Static:
|
||||||
|
vertices.Construct<Vector<StaticVertex>>();
|
||||||
|
break;
|
||||||
|
case MeshVertexType::Skinned:
|
||||||
|
vertices.Construct<Vector<SkinnedVertex>>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<StaticVertex>& GetStaticVertices()
|
||||||
|
{
|
||||||
|
Assert(vertexType == MeshVertexType::Static);
|
||||||
|
return vertices.Get<Vector<StaticVertex>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<SkinnedVertex>& GetSkinnedVertices()
|
||||||
|
{
|
||||||
|
Assert(vertexType == MeshVertexType::Skinned);
|
||||||
|
return vertices.Get<Vector<SkinnedVertex>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferView View()
|
||||||
|
{
|
||||||
|
switch(vertexType)
|
||||||
|
{
|
||||||
|
case MeshVertexType::Static:
|
||||||
|
return GetStaticVertices();
|
||||||
|
break;
|
||||||
|
case MeshVertexType::Skinned:
|
||||||
|
return GetSkinnedVertices();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return BufferView{ nullptr, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t VertexCount() const
|
||||||
|
{
|
||||||
|
// Type doesn't matter here, just want to grab m_size.
|
||||||
|
return uint32_t(vertices.Get<Vector<uint8_t>>().Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshVertexType vertexType;
|
||||||
|
Variant<Vector<StaticVertex>, Vector<SkinnedVertex>> vertices;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MeshData
|
||||||
|
{
|
||||||
|
MeshData(MeshVertexType type)
|
||||||
|
: vertexData{ type } {}
|
||||||
|
|
||||||
|
MeshVertexData vertexData;
|
||||||
|
Vector<uint16_t> indices;
|
||||||
|
AABB bounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<MeshData> ParseOBJ(StringView buffer);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Core/Array.h>
|
||||||
|
#include <Orange/Core/Log.h>
|
||||||
|
#include <Orange/Core/Result.h>
|
||||||
|
#include <Orange/Core/Traits.h>
|
||||||
|
#include <Orange/Core/Vector.h>
|
||||||
|
#include <Orange/Math/Vector.h>
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
enum class MeshVertexType
|
||||||
|
{
|
||||||
|
Static,
|
||||||
|
Skinned,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StaticVertex
|
||||||
|
{
|
||||||
|
vec3 pos;
|
||||||
|
vec2 uv;
|
||||||
|
vec3 normal;
|
||||||
|
//vec3 tangent;
|
||||||
|
|
||||||
|
static constexpr VkVertexInputAttributeDescription Attributes[] =
|
||||||
|
{
|
||||||
|
{ .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, pos)) },
|
||||||
|
{ .location = 1, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, uv)) },
|
||||||
|
{ .location = 2, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, normal)) },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator == (const StaticVertex& other) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
pos == other.pos &&
|
||||||
|
uv == other.uv &&
|
||||||
|
normal == other.normal;// &&
|
||||||
|
//tangent == other.tangent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SkinnedVertex : public StaticVertex
|
||||||
|
{
|
||||||
|
static constexpr uint32_t MaxVertexWeights = 4;
|
||||||
|
|
||||||
|
bool operator == (const SkinnedVertex& other) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
pos == other.pos &&
|
||||||
|
uv == other.uv &&
|
||||||
|
normal == other.normal &&
|
||||||
|
//tangent == other.tangent &&
|
||||||
|
boneIndices == other.boneIndices &&
|
||||||
|
boneWeights == other.boneWeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<uint8_t, MaxVertexWeights> boneIndices;
|
||||||
|
Array<uint8_t, MaxVertexWeights> boneWeights;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Math/Vector.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
struct AABB
|
||||||
|
{
|
||||||
|
vec3 min;
|
||||||
|
vec3 max;
|
||||||
|
|
||||||
|
void Extend(vec3 pos)
|
||||||
|
{
|
||||||
|
min = Min(pos, min);
|
||||||
|
max = Max(pos, max);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Orange/Math/Vector.h>
|
#include <Orange/Math/Matrix.h>
|
||||||
#include <Orange/Math/Angle.h>
|
#include <Orange/Math/Angle.h>
|
||||||
#include <Orange/Math/Basic.h>
|
#include <Orange/Math/Basic.h>
|
||||||
|
|
||||||
|
|
|
@ -279,12 +279,12 @@ namespace orange
|
||||||
constexpr vec4 operator"" _vec4(long double value) { return vec4{static_cast<float>(value)}; }
|
constexpr vec4 operator"" _vec4(long double value) { return vec4{static_cast<float>(value)}; }
|
||||||
constexpr vec4 operator"" _vec4(unsigned long long value) { return vec4{static_cast<float>(value)}; }
|
constexpr vec4 operator"" _vec4(unsigned long long value) { return vec4{static_cast<float>(value)}; }
|
||||||
|
|
||||||
float cross(const vec2& a, const vec2& b)
|
constexpr float cross(const vec2& a, const vec2& b)
|
||||||
{
|
{
|
||||||
return a.x * b.y - b.x * a.y;
|
return a.x * b.y - b.x * a.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 cross(const vec3& a, const vec3& b)
|
constexpr vec3 cross(const vec3& a, const vec3& b)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,250 +1,26 @@
|
||||||
#include <Orange/Core/Array.h>
|
#include <Orange/Core/Array.h>
|
||||||
#include <Orange/Core/Vector.h>
|
|
||||||
#include "Orange/Core/Span.h"
|
|
||||||
#include <Orange/Core/Result.h>
|
|
||||||
#include <Orange/Core/FileSystem.h>
|
#include <Orange/Core/FileSystem.h>
|
||||||
#include <Orange/Math/Vector.h>
|
#include <Orange/Core/Result.h>
|
||||||
|
#include <Orange/Core/Span.h>
|
||||||
|
#include <Orange/Core/Time.h>
|
||||||
|
#include <Orange/Core/Variant.h>
|
||||||
|
#include <Orange/Core/Vector.h>
|
||||||
|
#include <Orange/Graphics/Camera.h>
|
||||||
|
#include <Orange/Graphics/Mesh.h>
|
||||||
#include <Orange/Math/Matrix.h>
|
#include <Orange/Math/Matrix.h>
|
||||||
#include <Orange/Math/Transformation.h>
|
#include <Orange/Math/Transformation.h>
|
||||||
#include <Orange/Core/Parse.h>
|
#include <Orange/Math/Vector.h>
|
||||||
#include <Orange/Core/Variant.h>
|
|
||||||
#include <Orange/Core/Time.h>
|
|
||||||
|
|
||||||
#include <Orange/Render/Window.h>
|
|
||||||
#include <Orange/Render/RenderContext.h>
|
#include <Orange/Render/RenderContext.h>
|
||||||
#include <Orange/Render/Swapchain.h>
|
#include <Orange/Render/Swapchain.h>
|
||||||
#include <Orange/Render/VulkanHelpers.h>
|
#include <Orange/Render/VulkanHelpers.h>
|
||||||
|
#include <Orange/Render/Window.h>
|
||||||
#include <Orange/Graphics/Camera.h>
|
|
||||||
|
|
||||||
#include <vs_Mesh.h>
|
#include <vs_Mesh.h>
|
||||||
|
#include <vs_Fullscreen.h>
|
||||||
#include <fs_DebugVertColor.h>
|
#include <fs_DebugVertColor.h>
|
||||||
|
|
||||||
using namespace orange;
|
using namespace orange;
|
||||||
|
|
||||||
struct AABB
|
|
||||||
{
|
|
||||||
vec3 min;
|
|
||||||
vec3 max;
|
|
||||||
|
|
||||||
void Extend(vec3 pos)
|
|
||||||
{
|
|
||||||
min = Min(pos, min);
|
|
||||||
max = Max(pos, max);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class MeshVertexType
|
|
||||||
{
|
|
||||||
Static,
|
|
||||||
Skinned,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef offsetof2
|
|
||||||
#define offsetof2(type, member) size_t(uintptr_t(&((type*)0)->member))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct StaticVertex
|
|
||||||
{
|
|
||||||
vec3 pos;
|
|
||||||
vec2 uv;
|
|
||||||
vec3 normal;
|
|
||||||
//vec3 tangent;
|
|
||||||
|
|
||||||
static constexpr VkVertexInputAttributeDescription Attributes[] =
|
|
||||||
{
|
|
||||||
{ .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, pos)) },
|
|
||||||
{ .location = 1, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, uv)) },
|
|
||||||
{ .location = 2, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, normal)) },
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator == (const StaticVertex& other) const
|
|
||||||
{
|
|
||||||
return pos == other.pos &&
|
|
||||||
uv == other.uv &&
|
|
||||||
normal == other.normal;// &&
|
|
||||||
//tangent == other.tangent;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SkinnedVertex : public StaticVertex
|
|
||||||
{
|
|
||||||
static constexpr uint32_t MaxVertexWeights = 4;
|
|
||||||
|
|
||||||
bool operator == (const SkinnedVertex& other) const
|
|
||||||
{
|
|
||||||
return pos == other.pos &&
|
|
||||||
uv == other.uv &&
|
|
||||||
normal == other.normal &&
|
|
||||||
//tangent == other.tangent &&
|
|
||||||
boneIndices == other.boneIndices &&
|
|
||||||
boneWeights == other.boneWeights;
|
|
||||||
}
|
|
||||||
|
|
||||||
Array<uint8_t, MaxVertexWeights> boneIndices;
|
|
||||||
Array<uint8_t, MaxVertexWeights> boneWeights;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MeshVertexData
|
|
||||||
{
|
|
||||||
MeshVertexData(MeshVertexType type)
|
|
||||||
: vertexType(type)
|
|
||||||
{
|
|
||||||
switch(vertexType)
|
|
||||||
{
|
|
||||||
case MeshVertexType::Static:
|
|
||||||
vertices.Construct<Vector<StaticVertex>>();
|
|
||||||
break;
|
|
||||||
case MeshVertexType::Skinned:
|
|
||||||
vertices.Construct<Vector<SkinnedVertex>>();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<StaticVertex>& GetStaticVertices()
|
|
||||||
{
|
|
||||||
Assert(vertexType == MeshVertexType::Static);
|
|
||||||
return vertices.Get<Vector<StaticVertex>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<SkinnedVertex>& GetSkinnedVertices()
|
|
||||||
{
|
|
||||||
Assert(vertexType == MeshVertexType::Skinned);
|
|
||||||
return vertices.Get<Vector<SkinnedVertex>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferView View()
|
|
||||||
{
|
|
||||||
switch(vertexType)
|
|
||||||
{
|
|
||||||
case MeshVertexType::Static:
|
|
||||||
return GetStaticVertices();
|
|
||||||
break;
|
|
||||||
case MeshVertexType::Skinned:
|
|
||||||
return GetSkinnedVertices();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return BufferView{ nullptr, 0 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t VertexCount() const
|
|
||||||
{
|
|
||||||
// Type doesn't matter here, just want to grab m_size.
|
|
||||||
return uint32_t(vertices.Get<Vector<uint8_t>>().Size());
|
|
||||||
}
|
|
||||||
|
|
||||||
MeshVertexType vertexType;
|
|
||||||
Variant<Vector<StaticVertex>, Vector<SkinnedVertex>> vertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MeshData
|
|
||||||
{
|
|
||||||
MeshData(MeshVertexType type)
|
|
||||||
: vertexData{ type } {}
|
|
||||||
|
|
||||||
MeshVertexData vertexData;
|
|
||||||
Vector<uint16_t> indices;
|
|
||||||
AABB bounds;
|
|
||||||
};
|
|
||||||
|
|
||||||
Result<MeshData> ParseOBJ(StringView buffer)
|
|
||||||
{
|
|
||||||
MeshData data{ MeshVertexType::Static };
|
|
||||||
|
|
||||||
Vector<vec3> positions;
|
|
||||||
Vector<vec2> uvs;
|
|
||||||
Vector<vec3> normals;
|
|
||||||
|
|
||||||
const char* obj = buffer.data;
|
|
||||||
const char* end = buffer.data + buffer.size;
|
|
||||||
while (obj != end)
|
|
||||||
{
|
|
||||||
SmallVector<char, 8> element;
|
|
||||||
stream::ReadString(obj, end, " #\n", element);
|
|
||||||
|
|
||||||
if (element == "v" || element == "vt" || element == "vn")
|
|
||||||
{
|
|
||||||
float vtx[3]{};
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
stream::ConsumeSpace(obj, end);
|
|
||||||
if (auto r_float = stream::Parse<float>(obj, end))
|
|
||||||
vtx[i] = *r_float;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element == "v")
|
|
||||||
positions.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
|
||||||
else if (element == "vt")
|
|
||||||
uvs.EmplaceBack(vtx[0], vtx[1]);
|
|
||||||
else if (element == "vn")
|
|
||||||
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
|
||||||
}
|
|
||||||
else if (element == "g" || element == "o")
|
|
||||||
{
|
|
||||||
stream::ConsumeSpace(obj, end);
|
|
||||||
SmallVector<char, 32> name;
|
|
||||||
stream::ReadString(obj, end, " #\n", name);
|
|
||||||
|
|
||||||
name.PushBack('\0');
|
|
||||||
if (element == "g")
|
|
||||||
log::info("Group name: %s", name.Data());
|
|
||||||
else
|
|
||||||
log::info("Object name: %s", name.Data());
|
|
||||||
}
|
|
||||||
else if (element == "f")
|
|
||||||
{
|
|
||||||
int32_t indices[3][3]{};
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
stream::ConsumeSpace(obj, end);
|
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
indices[i][j] = -1;
|
|
||||||
|
|
||||||
if (j == 0 || stream::Consume(obj, end, "/"))
|
|
||||||
{
|
|
||||||
if (auto r_int = stream::Parse<uint32_t>(obj, end))
|
|
||||||
indices[i][j] = *r_int - 1; // OBJ indexing starts at one.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
StaticVertex vertex =
|
|
||||||
{
|
|
||||||
.pos = indices[i][0] != -1 ? positions[indices[i][0]] : vec3{},
|
|
||||||
.uv = indices[i][1] != -1 ? uvs [indices[i][1]] : vec2{},
|
|
||||||
.normal = indices[i][2] != -1 ? normals [indices[i][2]] : vec3{},
|
|
||||||
};
|
|
||||||
|
|
||||||
auto& vertices = data.vertexData.GetStaticVertices();
|
|
||||||
|
|
||||||
size_t vertexIdx = vertices.FindIdx(vertex);
|
|
||||||
if (vertexIdx == vertices.InvalidIdx)
|
|
||||||
{
|
|
||||||
data.bounds.Extend(vertex.pos);
|
|
||||||
vertexIdx = vertices.PushBack(vertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(vertexIdx < UINT16_MAX);
|
|
||||||
data.indices.PushBack(uint16_t(vertexIdx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!element.Empty())
|
|
||||||
{
|
|
||||||
element.PushBack('\0');
|
|
||||||
log::info("Unknown element: %s", element.Data());
|
|
||||||
}
|
|
||||||
|
|
||||||
stream::AdvancePast(obj, end, "\n");
|
|
||||||
};
|
|
||||||
|
|
||||||
return Result<MeshData>::Success(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
(void)argc; (void)argv;
|
(void)argc; (void)argv;
|
||||||
|
@ -732,7 +508,7 @@ int main(int argc, char** argv)
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
|
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
|
||||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
.clearValue = { .color = { .float32 = { 1.0f, 0.5f, 0.0f, 1.0f } } },
|
.clearValue = { .color = { .float32 = { 1.0f, 1.0f, 1.0f, 1.0f } } },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Orange/Graphics/Mesh.h>
|
||||||
|
|
||||||
|
#include <Orange/Core/Parse.h>
|
||||||
|
|
||||||
|
namespace orange
|
||||||
|
{
|
||||||
|
Result<MeshData> ParseOBJ(StringView buffer)
|
||||||
|
{
|
||||||
|
MeshData data{ MeshVertexType::Static };
|
||||||
|
|
||||||
|
Vector<vec3> positions;
|
||||||
|
Vector<vec2> uvs;
|
||||||
|
Vector<vec3> normals;
|
||||||
|
|
||||||
|
const char* obj = buffer.data;
|
||||||
|
const char* end = buffer.data + buffer.size;
|
||||||
|
while (obj != end)
|
||||||
|
{
|
||||||
|
SmallVector<char, 8> element;
|
||||||
|
stream::ReadString(obj, end, " #\n", element);
|
||||||
|
|
||||||
|
if (element == "v" || element == "vt" || element == "vn")
|
||||||
|
{
|
||||||
|
float vtx[3]{};
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
stream::ConsumeSpace(obj, end);
|
||||||
|
if (auto r_float = stream::Parse<float>(obj, end))
|
||||||
|
vtx[i] = *r_float;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element == "v")
|
||||||
|
positions.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
||||||
|
else if (element == "vt")
|
||||||
|
uvs.EmplaceBack(vtx[0], vtx[1]);
|
||||||
|
else if (element == "vn")
|
||||||
|
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
|
||||||
|
}
|
||||||
|
else if (element == "g" || element == "o")
|
||||||
|
{
|
||||||
|
stream::ConsumeSpace(obj, end);
|
||||||
|
SmallVector<char, 32> name;
|
||||||
|
stream::ReadString(obj, end, " #\n", name);
|
||||||
|
|
||||||
|
name.PushBack('\0');
|
||||||
|
if (element == "g")
|
||||||
|
log::info("Group name: %s", name.Data());
|
||||||
|
else
|
||||||
|
log::info("Object name: %s", name.Data());
|
||||||
|
}
|
||||||
|
else if (element == "f")
|
||||||
|
{
|
||||||
|
int32_t indices[3][3]{};
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
stream::ConsumeSpace(obj, end);
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
indices[i][j] = -1;
|
||||||
|
|
||||||
|
if (j == 0 || stream::Consume(obj, end, "/"))
|
||||||
|
{
|
||||||
|
if (auto r_int = stream::Parse<uint32_t>(obj, end))
|
||||||
|
indices[i][j] = *r_int - 1; // OBJ indexing starts at one.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
StaticVertex vertex =
|
||||||
|
{
|
||||||
|
.pos = indices[i][0] != -1 ? positions[indices[i][0]] : vec3{},
|
||||||
|
.uv = indices[i][1] != -1 ? uvs [indices[i][1]] : vec2{},
|
||||||
|
.normal = indices[i][2] != -1 ? normals [indices[i][2]] : vec3{},
|
||||||
|
};
|
||||||
|
|
||||||
|
auto& vertices = data.vertexData.GetStaticVertices();
|
||||||
|
|
||||||
|
size_t vertexIdx = vertices.FindIdx(vertex);
|
||||||
|
if (vertexIdx == vertices.InvalidIdx)
|
||||||
|
{
|
||||||
|
data.bounds.Extend(vertex.pos);
|
||||||
|
vertexIdx = vertices.PushBack(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(vertexIdx < UINT16_MAX);
|
||||||
|
data.indices.PushBack(uint16_t(vertexIdx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!element.Empty())
|
||||||
|
{
|
||||||
|
element.PushBack('\0');
|
||||||
|
log::info("Unknown element: %s", element.Data());
|
||||||
|
}
|
||||||
|
|
||||||
|
stream::AdvancePast(obj, end, "\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
return Result<MeshData>::Success(data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 1) out vec2 o_texcoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 coord = vec2(
|
||||||
|
float(gl_VertexIndex & 2),
|
||||||
|
float(gl_VertexIndex & 1) * 2.0f);
|
||||||
|
|
||||||
|
o_texcoord = coord;
|
||||||
|
gl_Position = vec4(-1.0f + 2.0f * coord, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
vec2 positions[3] = vec2[]
|
|
||||||
(
|
|
||||||
vec2( 0.0, -0.5),
|
|
||||||
vec2( 0.5, 0.5),
|
|
||||||
vec2(-0.5, 0.5)
|
|
||||||
);
|
|
||||||
|
|
||||||
vec3 colors[3] = vec3[]
|
|
||||||
(
|
|
||||||
vec3(1.0, 0.0, 0.0),
|
|
||||||
vec3(0.0, 1.0, 0.0),
|
|
||||||
vec3(0.0, 0.0, 1.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
|
||||||
outColor = vec4(colors[gl_VertexIndex], 1.0);
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
orange_shaders = glsl_generator.process([
|
orange_shaders = glsl_generator.process([
|
||||||
'Render/Shaders/fs_DebugVertColor.frag',
|
'Render/Shaders/fs_DebugVertColor.frag',
|
||||||
'Render/Shaders/vs_Triangle.vert',
|
'Render/Shaders/vs_Fullscreen.vert',
|
||||||
'Render/Shaders/vs_Mesh.vert',
|
'Render/Shaders/vs_Mesh.vert',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ orange_src = files([
|
||||||
'Core/Filesystem.cpp',
|
'Core/Filesystem.cpp',
|
||||||
'Core/Log.cpp',
|
'Core/Log.cpp',
|
||||||
|
|
||||||
|
'Graphics/Mesh.cpp',
|
||||||
|
|
||||||
'Render/Input.cpp',
|
'Render/Input.cpp',
|
||||||
'Render/RenderContext_Init.cpp',
|
'Render/RenderContext_Init.cpp',
|
||||||
'Render/RenderContext_Util.cpp',
|
'Render/RenderContext_Util.cpp',
|
||||||
|
|
Loading…
Reference in New Issue