Files
Seele/src/Engine/Graphics/VertexShaderInput.h
T

163 lines
5.0 KiB
C++
Raw Normal View History

2020-06-02 11:46:18 +02:00
#pragma once
#include "MinimalEngine.h"
#include "GraphicsEnums.h"
#include "GraphicsResources.h"
2020-06-02 11:46:18 +02:00
namespace Seele
{
2020-09-19 14:36:50 +02:00
// Minimal vertex source used for building commands
2020-06-02 11:46:18 +02:00
struct VertexInputStream
{
uint32 streamIndex : 4;
uint32 offset : 28;
Gfx::PVertexBuffer vertexBuffer;
VertexInputStream()
: streamIndex(0), offset(0), vertexBuffer(nullptr)
{
}
VertexInputStream(uint32 streamIndex, uint32 offset, Gfx::PVertexBuffer vertexBuffer)
: streamIndex(streamIndex), offset(offset), vertexBuffer(vertexBuffer)
{
assert(this->streamIndex == streamIndex && this->offset == offset);
}
inline bool operator==(const VertexInputStream &rhs) const
{
if (streamIndex != rhs.streamIndex || offset != rhs.offset || vertexBuffer != rhs.vertexBuffer)
{
return false;
}
return true;
}
inline bool operator!=(const VertexInputStream &rhs) const
{
return !(*this == rhs);
}
};
2020-09-19 14:36:50 +02:00
typedef Array<VertexInputStream> VertexInputStreamArray; //TODO inline allocation
// Typed data source for a vertex factory
struct VertexStreamComponent
{
// Source vertex buffer
Gfx::PVertexBuffer vertexBuffer = nullptr;
// Offset to the start of the vertex buffer fetch
uint32 streamOffset = 0;
// Offset of the data, relative to the beginnning of each element in the vertex buffer
uint32 offset = 0;
// Stride of the data
uint32 stride = 0;
Gfx::SeFormat type = Gfx::SE_FORMAT_UNDEFINED;
VertexStreamComponent()
{}
VertexStreamComponent(const Gfx::PVertexBuffer vertexBuffer, uint32 offset, uint32 stride, Gfx::SeFormat type)
: vertexBuffer(vertexBuffer)
, streamOffset(0)
, offset(offset)
, stride(stride)
, type(type)
{}
VertexStreamComponent(const Gfx::PVertexBuffer vertexBuffer, uint32 streamOffset, uint32 offset, uint32 stride, Gfx::SeFormat type)
: vertexBuffer(vertexBuffer)
, streamOffset(streamOffset)
, offset(offset)
, stride(stride)
, type(type)
{}
};
#define STRUCTMEMBER_VERTEXSTREAMCOMPONENT(vertexBuffer, vertexType, member, memberType) \
VertexStreamComponent(vertexBuffer, offsetof(vertexType, member), sizeof(vertexType), memberType)
class VertexInputType
{
public:
2020-10-03 11:00:10 +02:00
static List<VertexInputType*>& getTypeList();
2020-09-19 14:36:50 +02:00
static VertexInputType* getVertexInputByName(const std::string& name);
VertexInputType(
const char* name,
const char* shaderFilename
);
virtual ~VertexInputType();
const char* getName();
const char* getShaderFilename();
private:
const char* name;
const char* shaderFilename;
static List<VertexInputType*> globalTypeList;
};
#define DECLARE_VERTEX_INPUT_TYPE(inputClass) \
public: \
static VertexInputType staticType; \
virtual VertexInputType* getType() const override;
#define IMPLEMENT_VERTEX_INPUT_TYPE(inputClass, shaderFilename) \
VertexInputType inputClass::staticType( \
#inputClass, \
shaderFilename); \
VertexInputType* inputClass::getType() const { return &staticType; }
2020-06-02 11:46:18 +02:00
2020-06-08 01:44:47 +02:00
struct MeshDescription;
2021-04-01 16:40:14 +02:00
DECLARE_REF(VertexShaderInput)
class VertexShaderInput
2020-06-02 11:46:18 +02:00
{
public:
VertexShaderInput(std::string name);
2020-09-19 14:36:50 +02:00
virtual ~VertexShaderInput();
2021-11-18 12:48:21 +01:00
virtual void init(Gfx::PGraphics);
2020-06-02 11:46:18 +02:00
void getStreams(VertexInputStreamArray& outVertexStreams) const;
void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const;
virtual bool supportsTesselation() { return false; }
2020-09-19 14:36:50 +02:00
virtual VertexInputType* getType() const { return nullptr; }
2020-06-02 11:46:18 +02:00
Gfx::PVertexDeclaration getDeclaration() const {return declaration;}
Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;}
std::string getName() const { return name; }
2020-09-19 14:36:50 +02:00
protected:
2020-10-03 11:00:10 +02:00
Gfx::VertexElement accessStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex);
Gfx::VertexElement accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex);
void initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements);
void initPositionDeclaration(Gfx::PGraphics graphics, const Array<Gfx::VertexElement>& elements);
static List<PVertexShaderInput> registeredInputs;
static std::mutex registeredInputsLock;
Array<Gfx::VertexAttribute> layout;
2020-10-03 11:00:10 +02:00
// internal helper class, basically a VertexInputStream plus stride
struct VertexStream
{
Gfx::PVertexBuffer vertexBuffer = nullptr;
uint8 stride = 0;
uint8 offset = 0;
friend bool operator==(const VertexStream& a, const VertexStream& b)
{
return a.vertexBuffer == b.vertexBuffer &&
a.stride == b.stride &&
a.offset == b.offset;
}
VertexStream()
{
}
};
Array<VertexStream> streams;
Array<VertexStream> positionStreams;
2020-06-02 11:46:18 +02:00
Gfx::PVertexDeclaration declaration;
Gfx::PVertexDeclaration positionDeclaration;
std::string name;
2020-06-02 11:46:18 +02:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(VertexShaderInput)
2020-06-02 11:46:18 +02:00
} // namespace Seele