Skip to content

Commit

Permalink
Graphics Utilities: added CreateGeometryPrimitiveBuffers function
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Dec 29, 2024
1 parent 00a8777 commit c3e72f4
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 9 deletions.
20 changes: 11 additions & 9 deletions Common/interface/GeometryPrimitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,21 +142,23 @@ struct GeometryPrimitiveInfo
/// The size of the vertex in bytes.
Uint32 VertexSize DEFAULT_INITIALIZER(0);
};
typedef struct GeometryPrimitiveInfo GeometryPrimitiveInfo;

/// Returns the size of the geometry primitive vertex in bytes.
Uint32 GetGeometryPrimitiveVertexSize(GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlags);

/// Creates a geometry primitive
///
/// \param [in] Attribs Geometry primitive attributes, see Diligent::GeometryPrimitiveAttributes.
/// \param [out] ppVertices Address of the memory location where the pointer to the output vertex data blob will be stored.
/// The vertex components are stored as interleaved floating-point values.
/// For example, if VertexFlags = GEOMETRY_PRIMITIVE_VERTEX_FLAG_POS_NORM, the vertex data will
/// be stored as follows:
/// P0, N0, P1, N1, ..., Pn, Nn.
/// \param [out] ppIndices Address of the memory location where the pointer to the output index data blob will be stored.
/// Index data is stored as 32-bit unsigned integers representing the triangle list.
/// \param [out] pInfo Address of the memory location where the pointer to the output geometry primitive info will be stored.
/// \param [in] Attribs - Geometry primitive attributes, see Diligent::GeometryPrimitiveAttributes.
/// \param [out] ppVertices - Address of the memory location where the pointer to the output vertex data blob will be stored.
/// The vertex components are stored as interleaved floating-point values.
/// For example, if VertexFlags = GEOMETRY_PRIMITIVE_VERTEX_FLAG_POS_NORM, the vertex data will
/// be stored as follows:
/// P0, N0, P1, N1, ..., Pn, Nn.
/// \param [out] ppIndices - Address of the memory location where the pointer to the output index data blob will be stored.
/// Index data is stored as 32-bit unsigned integers representing the triangle list.
/// \param [out] pInfo - A pointer to the structure that will receive information about the created geometry primitive.
/// See Diligent::GeometryPrimitiveInfo.
void DILIGENT_GLOBAL_FUNCTION(CreateGeometryPrimitive)(const GeometryPrimitiveAttributes REF Attribs,
IDataBlob** ppVertices,
IDataBlob** ppIndices,
Expand Down
4 changes: 4 additions & 0 deletions Common/src/GeometryPrimitives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ void CreateGeometryPrimitive(const GeometryPrimitiveAttributes& Attribs,
IDataBlob** ppIndices,
GeometryPrimitiveInfo* pInfo)
{
DEV_CHECK_ERR(ppVertices == nullptr || *ppVertices == nullptr, "*ppVertices is not null which may cause memory leaks");
DEV_CHECK_ERR(ppIndices == nullptr || *ppIndices == nullptr, "*ppIndices is not null which may cause memory leaks");

static_assert(GEOMETRY_PRIMITIVE_TYPE_LAST == 1, "Please update the switch below to handle the new geometry primitive type");
switch (Attribs.Type)
{
case GEOMETRY_PRIMITIVE_TYPE_UNDEFINED:
Expand Down
48 changes: 48 additions & 0 deletions Graphics/GraphicsTools/interface/GraphicsUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "../../GraphicsEngine/interface/Texture.h"
#include "../../GraphicsEngine/interface/Buffer.h"
#include "../../GraphicsEngine/interface/RenderDevice.h"
#include "../../../Common/interface/GeometryPrimitives.h"

DILIGENT_BEGIN_NAMESPACE(Diligent)

Expand Down Expand Up @@ -218,6 +219,53 @@ int64_t DILIGENT_GLOBAL_FUNCTION(GetNativeTextureFormat)(TEXTURE_FORMAT TexForma
/// Returns the texture format for the given native format (e.g. DXGI_FORMAT, VkFormat) and device type.
TEXTURE_FORMAT DILIGENT_GLOBAL_FUNCTION(GetTextureFormatFromNative)(int64_t NativeFormat, enum RENDER_DEVICE_TYPE DeviceType);


/// Geometry primitive buffers creation info
struct GeometryPrimitiveBuffersCreateInfo
{
/// Vertex buffer usage.
USAGE VertexBufferUsage DEFAULT_INITIALIZER(USAGE_DEFAULT);

/// Index buffer usage.
USAGE IndexBufferUsage DEFAULT_INITIALIZER(USAGE_DEFAULT);

/// Vertex buffer bind flags.
BIND_FLAGS VertexBufferBindFlags DEFAULT_INITIALIZER(BIND_VERTEX_BUFFER);

/// Index buffer bind flags.
BIND_FLAGS IndexBufferBindFlags DEFAULT_INITIALIZER(BIND_INDEX_BUFFER);

/// Vertex buffer mode.
BUFFER_MODE VertexBufferMode DEFAULT_INITIALIZER(BUFFER_MODE_UNDEFINED);

/// Index buffer mode.
BUFFER_MODE IndexBufferMode DEFAULT_INITIALIZER(BUFFER_MODE_UNDEFINED);

/// Vertex buffer CPU access flags.
CPU_ACCESS_FLAGS VertexBufferCPUAccessFlags DEFAULT_INITIALIZER(CPU_ACCESS_NONE);

/// Index buffer CPU access flags.
CPU_ACCESS_FLAGS IndexBufferCPUAccessFlags DEFAULT_INITIALIZER(CPU_ACCESS_NONE);
};
typedef struct GeometryPrimitiveBuffersCreateInfo GeometryPrimitiveBuffersCreateInfo;

/// Creates vertex and index buffers for a geometry primitive (see Diligent::CreateGeometryPrimitive)
///
/// \param [in] pDevice - A pointer to the render device that will be used to create the buffers.
/// \param [in] Attribs - Geometry primitive attributes, see Diligent::GeometryPrimitiveAttributes.
/// \param [in] pBufferCI - Optional buffer create info, see Diligent::GeometryPrimitiveBufferCreateInfo.
/// If null, default values are used.
/// \param [out] ppVertices - Address of the memory location where the pointer to the vertex buffer will be stored.
/// \param [out] ppIndices - Address of the memory location where the pointer to the index buffer will be stored.
/// \param [out] pInfo - A pointer to the structure that will receive information about the created geometry primitive.
/// See Diligent::GeometryPrimitiveInfo.
void DILIGENT_GLOBAL_FUNCTION(CreateGeometryPrimitiveBuffers)(IRenderDevice* pDevice,
const GeometryPrimitiveAttributes REF Attribs,
const GeometryPrimitiveBuffersCreateInfo* pBufferCI,
IBuffer** ppVertices,
IBuffer** ppIndices,
GeometryPrimitiveInfo* pInfo DEFAULT_VALUE(nullptr));

#include "../../../Primitives/interface/UndefRefMacro.h"

DILIGENT_END_NAMESPACE // namespace Diligent
81 changes: 81 additions & 0 deletions Graphics/GraphicsTools/src/GraphicsUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <algorithm>
#include <cmath>
#include <limits>
#include <atomic>

#include "GraphicsUtilities.h"
#include "DebugUtilities.hpp"
Expand Down Expand Up @@ -659,6 +660,76 @@ TEXTURE_FORMAT GetTextureFormatFromNative(int64_t NativeFormat, RENDER_DEVICE_TY
}
}

void CreateGeometryPrimitiveBuffers(IRenderDevice* pDevice,
const GeometryPrimitiveAttributes& Attribs,
const GeometryPrimitiveBuffersCreateInfo* pBufferCI,
IBuffer** ppVertices,
IBuffer** ppIndices,
GeometryPrimitiveInfo* pInfo)
{
static_assert(GEOMETRY_PRIMITIVE_TYPE_LAST == 1, "Please handle the new primitive type");

RefCntAutoPtr<IDataBlob> pVertexData;
RefCntAutoPtr<IDataBlob> pIndexData;
CreateGeometryPrimitive(Attribs,
ppVertices != nullptr ? pVertexData.RawDblPtr() : nullptr,
ppIndices != nullptr ? pIndexData.RawDblPtr() : nullptr,
pInfo);

static constexpr GeometryPrimitiveBuffersCreateInfo DefaultCI{};
if (pBufferCI == nullptr)
pBufferCI = &DefaultCI;

const char* PrimTypeStr = "";
switch (Attribs.Type)
{
case GEOMETRY_PRIMITIVE_TYPE_CUBE: PrimTypeStr = "Cube"; break;
default: UNEXPECTED("Unexpected primitive type");
}

static std::atomic<int> PrimCounter{0};
const int PrimId = PrimCounter.fetch_add(1);
if (pVertexData)
{
const std::string Name = std::string{"Geometry primitive "} + std::to_string(PrimId) + " (" + PrimTypeStr + ")";

BufferDesc VBDesc;
VBDesc.Name = Name.c_str();
VBDesc.Size = pVertexData->GetSize();
VBDesc.BindFlags = pBufferCI->VertexBufferBindFlags;
VBDesc.Usage = pBufferCI->VertexBufferUsage;
VBDesc.CPUAccessFlags = pBufferCI->VertexBufferCPUAccessFlags;
VBDesc.Mode = pBufferCI->VertexBufferMode;
if (VBDesc.Mode != BUFFER_MODE_UNDEFINED)
{
VBDesc.ElementByteStride = GetGeometryPrimitiveVertexSize(Attribs.VertexFlags);
}

BufferData VBData{pVertexData->GetDataPtr(), pVertexData->GetSize()};
pDevice->CreateBuffer(VBDesc, &VBData, ppVertices);
}

if (pIndexData)
{
const std::string Name = std::string{"Geometry primitive "} + std::to_string(PrimId) + " (" + PrimTypeStr + ")";

BufferDesc IBDesc;
IBDesc.Name = Name.c_str();
IBDesc.Size = pIndexData->GetSize();
IBDesc.BindFlags = pBufferCI->IndexBufferBindFlags;
IBDesc.Usage = pBufferCI->IndexBufferUsage;
IBDesc.CPUAccessFlags = pBufferCI->IndexBufferCPUAccessFlags;
IBDesc.Mode = pBufferCI->IndexBufferMode;
if (IBDesc.Mode != BUFFER_MODE_UNDEFINED)
{
IBDesc.ElementByteStride = sizeof(Uint32);
}

BufferData IBData{pIndexData->GetDataPtr(), pIndexData->GetSize()};
pDevice->CreateBuffer(IBDesc, &IBData, ppIndices);
}
}

} // namespace Diligent


Expand Down Expand Up @@ -745,4 +816,14 @@ extern "C"
{
return Diligent::GetTextureFormatFromNative(NativeFormat, DeviceType);
}

void Diligent_CreateGeometryPrimitiveBuffers(Diligent::IRenderDevice* pDevice,
const Diligent::GeometryPrimitiveAttributes& Attribs,
const Diligent::GeometryPrimitiveBuffersCreateInfo* pBufferCI,
Diligent::IBuffer** ppVertices,
Diligent::IBuffer** ppIndices,
Diligent::GeometryPrimitiveInfo* pInfo)
{
Diligent::CreateGeometryPrimitiveBuffers(pDevice, Attribs, pBufferCI, ppVertices, ppIndices, pInfo);
}
}

0 comments on commit c3e72f4

Please sign in to comment.