template project, first version
This commit is contained in:
793
DirectXTK/Src/GeometricPrimitive.cpp
Normal file
793
DirectXTK/Src/GeometricPrimitive.cpp
Normal file
@@ -0,0 +1,793 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: GeometricPrimitive.cpp
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
// PARTICULAR PURPOSE.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// http://go.microsoft.com/fwlink/?LinkId=248929
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "pch.h"
|
||||
#include "GeometricPrimitive.h"
|
||||
#include "Effects.h"
|
||||
#include "CommonStates.h"
|
||||
#include "DirectXHelpers.h"
|
||||
#include "SharedResourcePool.h"
|
||||
#include "Geometry.h"
|
||||
|
||||
using namespace DirectX;
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
// Helper for creating a D3D vertex or index buffer.
|
||||
template<typename T>
|
||||
static void CreateBuffer(_In_ ID3D11Device* device, T const& data, D3D11_BIND_FLAG bindFlags, _Outptr_ ID3D11Buffer** pBuffer)
|
||||
{
|
||||
assert(pBuffer != 0);
|
||||
|
||||
D3D11_BUFFER_DESC bufferDesc = {};
|
||||
|
||||
bufferDesc.ByteWidth = (UINT)data.size() * sizeof(typename T::value_type);
|
||||
bufferDesc.BindFlags = bindFlags;
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA dataDesc = {};
|
||||
|
||||
dataDesc.pSysMem = data.data();
|
||||
|
||||
ThrowIfFailed(
|
||||
device->CreateBuffer(&bufferDesc, &dataDesc, pBuffer)
|
||||
);
|
||||
|
||||
_Analysis_assume_(*pBuffer != 0);
|
||||
|
||||
SetDebugObjectName(*pBuffer, "DirectXTK:GeometricPrimitive");
|
||||
}
|
||||
|
||||
|
||||
// Helper for creating a D3D input layout.
|
||||
void CreateInputLayout(_In_ ID3D11Device* device, IEffect* effect, _Outptr_ ID3D11InputLayout** pInputLayout)
|
||||
{
|
||||
assert(pInputLayout != 0);
|
||||
|
||||
void const* shaderByteCode;
|
||||
size_t byteCodeLength;
|
||||
|
||||
effect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);
|
||||
|
||||
ThrowIfFailed(
|
||||
device->CreateInputLayout(VertexPositionNormalTexture::InputElements,
|
||||
VertexPositionNormalTexture::InputElementCount,
|
||||
shaderByteCode, byteCodeLength,
|
||||
pInputLayout)
|
||||
);
|
||||
|
||||
_Analysis_assume_(*pInputLayout != 0);
|
||||
|
||||
SetDebugObjectName(*pInputLayout, "DirectXTK:GeometricPrimitive");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Internal GeometricPrimitive implementation class.
|
||||
class GeometricPrimitive::Impl
|
||||
{
|
||||
public:
|
||||
void Initialize(_In_ ID3D11DeviceContext* deviceContext, const VertexCollection& vertices, const IndexCollection& indices);
|
||||
|
||||
void XM_CALLCONV Draw(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, FXMVECTOR color, _In_opt_ ID3D11ShaderResourceView* texture, bool wireframe, std::function<void()>& setCustomState) const;
|
||||
|
||||
void Draw(_In_ IEffect* effect, _In_ ID3D11InputLayout* inputLayout, bool alpha, bool wireframe, std::function<void()>& setCustomState) const;
|
||||
|
||||
void CreateInputLayout(_In_ IEffect* effect, _Outptr_ ID3D11InputLayout** inputLayout) const;
|
||||
|
||||
private:
|
||||
ComPtr<ID3D11Buffer> mVertexBuffer;
|
||||
ComPtr<ID3D11Buffer> mIndexBuffer;
|
||||
|
||||
UINT mIndexCount;
|
||||
|
||||
// Only one of these helpers is allocated per D3D device context, even if there are multiple GeometricPrimitive instances.
|
||||
class SharedResources
|
||||
{
|
||||
public:
|
||||
SharedResources(_In_ ID3D11DeviceContext* deviceContext);
|
||||
|
||||
void PrepareForRendering(bool alpha, bool wireframe) const;
|
||||
|
||||
ComPtr<ID3D11DeviceContext> deviceContext;
|
||||
std::unique_ptr<BasicEffect> effect;
|
||||
|
||||
ComPtr<ID3D11InputLayout> inputLayoutTextured;
|
||||
ComPtr<ID3D11InputLayout> inputLayoutUntextured;
|
||||
|
||||
std::unique_ptr<CommonStates> stateObjects;
|
||||
};
|
||||
|
||||
|
||||
// Per-device-context data.
|
||||
std::shared_ptr<SharedResources> mResources;
|
||||
|
||||
static SharedResourcePool<ID3D11DeviceContext*, SharedResources> sharedResourcesPool;
|
||||
};
|
||||
|
||||
|
||||
// Global pool of per-device-context GeometricPrimitive resources.
|
||||
SharedResourcePool<ID3D11DeviceContext*, GeometricPrimitive::Impl::SharedResources> GeometricPrimitive::Impl::sharedResourcesPool;
|
||||
|
||||
|
||||
// Per-device-context constructor.
|
||||
GeometricPrimitive::Impl::SharedResources::SharedResources(_In_ ID3D11DeviceContext* deviceContext)
|
||||
: deviceContext(deviceContext)
|
||||
{
|
||||
ComPtr<ID3D11Device> device;
|
||||
deviceContext->GetDevice(&device);
|
||||
|
||||
// Create the BasicEffect.
|
||||
effect = std::make_unique<BasicEffect>(device.Get());
|
||||
|
||||
effect->EnableDefaultLighting();
|
||||
|
||||
// Create state objects.
|
||||
stateObjects = std::make_unique<CommonStates>(device.Get());
|
||||
|
||||
// Create input layouts.
|
||||
effect->SetTextureEnabled(true);
|
||||
::CreateInputLayout(device.Get(), effect.get(), &inputLayoutTextured);
|
||||
|
||||
effect->SetTextureEnabled(false);
|
||||
::CreateInputLayout(device.Get(), effect.get(), &inputLayoutUntextured);
|
||||
}
|
||||
|
||||
|
||||
// Sets up D3D device state ready for drawing a primitive.
|
||||
void GeometricPrimitive::Impl::SharedResources::PrepareForRendering(bool alpha, bool wireframe) const
|
||||
{
|
||||
// Set the blend and depth stencil state.
|
||||
ID3D11BlendState* blendState;
|
||||
ID3D11DepthStencilState* depthStencilState;
|
||||
|
||||
if (alpha)
|
||||
{
|
||||
// Alpha blended rendering.
|
||||
blendState = stateObjects->AlphaBlend();
|
||||
depthStencilState = stateObjects->DepthRead();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Opaque rendering.
|
||||
blendState = stateObjects->Opaque();
|
||||
depthStencilState = stateObjects->DepthDefault();
|
||||
}
|
||||
|
||||
deviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFFF);
|
||||
deviceContext->OMSetDepthStencilState(depthStencilState, 0);
|
||||
|
||||
// Set the rasterizer state.
|
||||
if (wireframe)
|
||||
deviceContext->RSSetState(stateObjects->Wireframe());
|
||||
else
|
||||
deviceContext->RSSetState(stateObjects->CullCounterClockwise());
|
||||
|
||||
ID3D11SamplerState* samplerState = stateObjects->LinearWrap();
|
||||
|
||||
deviceContext->PSSetSamplers(0, 1, &samplerState);
|
||||
}
|
||||
|
||||
|
||||
// Initializes a geometric primitive instance that will draw the specified vertex and index data.
|
||||
_Use_decl_annotations_
|
||||
void GeometricPrimitive::Impl::Initialize(ID3D11DeviceContext* deviceContext, const VertexCollection& vertices, const IndexCollection& indices)
|
||||
{
|
||||
if (vertices.size() >= USHRT_MAX)
|
||||
throw std::exception("Too many vertices for 16-bit index buffer");
|
||||
|
||||
mResources = sharedResourcesPool.DemandCreate(deviceContext);
|
||||
|
||||
ComPtr<ID3D11Device> device;
|
||||
deviceContext->GetDevice(&device);
|
||||
|
||||
CreateBuffer(device.Get(), vertices, D3D11_BIND_VERTEX_BUFFER, &mVertexBuffer);
|
||||
CreateBuffer(device.Get(), indices, D3D11_BIND_INDEX_BUFFER, &mIndexBuffer);
|
||||
|
||||
mIndexCount = static_cast<UINT>(indices.size());
|
||||
}
|
||||
|
||||
|
||||
// Draws the primitive.
|
||||
_Use_decl_annotations_
|
||||
void XM_CALLCONV GeometricPrimitive::Impl::Draw(
|
||||
FXMMATRIX world,
|
||||
CXMMATRIX view,
|
||||
CXMMATRIX projection,
|
||||
FXMVECTOR color,
|
||||
ID3D11ShaderResourceView* texture,
|
||||
bool wireframe,
|
||||
std::function<void()>& setCustomState) const
|
||||
{
|
||||
assert(mResources != 0);
|
||||
auto effect = mResources->effect.get();
|
||||
assert(effect != 0);
|
||||
|
||||
ID3D11InputLayout *inputLayout;
|
||||
if (texture)
|
||||
{
|
||||
effect->SetTextureEnabled(true);
|
||||
effect->SetTexture(texture);
|
||||
|
||||
inputLayout = mResources->inputLayoutTextured.Get();
|
||||
}
|
||||
else
|
||||
{
|
||||
effect->SetTextureEnabled(false);
|
||||
|
||||
inputLayout = mResources->inputLayoutUntextured.Get();
|
||||
}
|
||||
|
||||
// Set effect parameters.
|
||||
effect->SetMatrices(world, view, projection);
|
||||
|
||||
effect->SetColorAndAlpha(color);
|
||||
|
||||
float alpha = XMVectorGetW(color);
|
||||
Draw(effect, inputLayout, (alpha < 1.f), wireframe, setCustomState);
|
||||
}
|
||||
|
||||
|
||||
// Draw the primitive using a custom effect.
|
||||
_Use_decl_annotations_
|
||||
void GeometricPrimitive::Impl::Draw(
|
||||
IEffect* effect,
|
||||
ID3D11InputLayout* inputLayout,
|
||||
bool alpha,
|
||||
bool wireframe,
|
||||
std::function<void()>& setCustomState) const
|
||||
{
|
||||
assert(mResources != 0);
|
||||
auto deviceContext = mResources->deviceContext.Get();
|
||||
assert(deviceContext != 0);
|
||||
|
||||
// Set state objects.
|
||||
mResources->PrepareForRendering(alpha, wireframe);
|
||||
|
||||
// Set input layout.
|
||||
assert(inputLayout != 0);
|
||||
deviceContext->IASetInputLayout(inputLayout);
|
||||
|
||||
// Activate our shaders, constant buffers, texture, etc.
|
||||
assert(effect != 0);
|
||||
effect->Apply(deviceContext);
|
||||
|
||||
// Set the vertex and index buffer.
|
||||
auto vertexBuffer = mVertexBuffer.Get();
|
||||
UINT vertexStride = sizeof(VertexPositionNormalTexture);
|
||||
UINT vertexOffset = 0;
|
||||
|
||||
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
|
||||
|
||||
deviceContext->IASetIndexBuffer(mIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);
|
||||
|
||||
// Hook lets the caller replace our shaders or state settings with whatever else they see fit.
|
||||
if (setCustomState)
|
||||
{
|
||||
setCustomState();
|
||||
}
|
||||
|
||||
// Draw the primitive.
|
||||
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
deviceContext->DrawIndexed(mIndexCount, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
// Create input layout for drawing with a custom effect.
|
||||
_Use_decl_annotations_
|
||||
void GeometricPrimitive::Impl::CreateInputLayout(IEffect* effect, ID3D11InputLayout** inputLayout) const
|
||||
{
|
||||
assert(effect != 0);
|
||||
assert(inputLayout != 0);
|
||||
|
||||
assert(mResources != 0);
|
||||
auto deviceContext = mResources->deviceContext.Get();
|
||||
assert(deviceContext != 0);
|
||||
|
||||
ComPtr<ID3D11Device> device;
|
||||
deviceContext->GetDevice(&device);
|
||||
|
||||
::CreateInputLayout(device.Get(), effect, inputLayout);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// GeometricPrimitive
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Constructor.
|
||||
GeometricPrimitive::GeometricPrimitive()
|
||||
: pImpl(new Impl())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Destructor.
|
||||
GeometricPrimitive::~GeometricPrimitive()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Public entrypoints.
|
||||
_Use_decl_annotations_
|
||||
void XM_CALLCONV GeometricPrimitive::Draw(
|
||||
FXMMATRIX world,
|
||||
CXMMATRIX view,
|
||||
CXMMATRIX projection,
|
||||
FXMVECTOR color,
|
||||
ID3D11ShaderResourceView* texture,
|
||||
bool wireframe,
|
||||
std::function<void()> setCustomState) const
|
||||
{
|
||||
pImpl->Draw(world, view, projection, color, texture, wireframe, setCustomState);
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_
|
||||
void GeometricPrimitive::Draw(
|
||||
IEffect* effect,
|
||||
ID3D11InputLayout* inputLayout,
|
||||
bool alpha,
|
||||
bool wireframe,
|
||||
std::function<void()> setCustomState) const
|
||||
{
|
||||
pImpl->Draw(effect, inputLayout, alpha, wireframe, setCustomState);
|
||||
}
|
||||
|
||||
|
||||
_Use_decl_annotations_
|
||||
void GeometricPrimitive::CreateInputLayout(IEffect* effect, ID3D11InputLayout** inputLayout) const
|
||||
{
|
||||
pImpl->CreateInputLayout(effect, inputLayout);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Cube (aka a Hexahedron) or Box
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateCube(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeBox(vertices, indices, XMFLOAT3(size, size, size), rhcoords, false);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateCube(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeBox(vertices, indices, XMFLOAT3(size, size, size), rhcoords, false);
|
||||
}
|
||||
|
||||
|
||||
// Creates a box primitive.
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateBox(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
const XMFLOAT3& size,
|
||||
bool rhcoords,
|
||||
bool invertn)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeBox(vertices, indices, size, rhcoords, invertn);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateBox(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
const XMFLOAT3& size,
|
||||
bool rhcoords,
|
||||
bool invertn)
|
||||
{
|
||||
ComputeBox(vertices, indices, size, rhcoords, invertn);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Sphere
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateSphere(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float diameter,
|
||||
size_t tessellation,
|
||||
bool rhcoords,
|
||||
bool invertn)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeSphere(vertices, indices, diameter, tessellation, rhcoords, invertn);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateSphere(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float diameter,
|
||||
size_t tessellation,
|
||||
bool rhcoords,
|
||||
bool invertn)
|
||||
{
|
||||
ComputeSphere(vertices, indices, diameter, tessellation, rhcoords, invertn);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Geodesic sphere
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateGeoSphere(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float diameter,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeGeoSphere(vertices, indices, diameter, tessellation, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateGeoSphere(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float diameter,
|
||||
size_t tessellation, bool rhcoords)
|
||||
{
|
||||
ComputeGeoSphere(vertices, indices, diameter, tessellation, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Cylinder / Cone
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Creates a cylinder primitive.
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateCylinder(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float height,
|
||||
float diameter,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeCylinder(vertices, indices, height, diameter, tessellation, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateCylinder(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float height,
|
||||
float diameter,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeCylinder(vertices, indices, height, diameter, tessellation, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
// Creates a cone primitive.
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateCone(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float diameter,
|
||||
float height,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeCone(vertices, indices, diameter, height, tessellation, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateCone(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float diameter,
|
||||
float height,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeCone(vertices, indices, diameter, height, tessellation, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Torus
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateTorus(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float diameter,
|
||||
float thickness,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeTorus(vertices, indices, diameter, thickness, tessellation, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateTorus(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float diameter,
|
||||
float thickness,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeTorus(vertices, indices, diameter, thickness, tessellation, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Tetrahedron
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateTetrahedron(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeTetrahedron(vertices, indices, size, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateTetrahedron(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeTetrahedron(vertices, indices, size, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Octahedron
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateOctahedron(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeOctahedron(vertices, indices, size, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateOctahedron(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeOctahedron(vertices, indices, size, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Dodecahedron
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateDodecahedron(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeDodecahedron(vertices, indices, size, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateDodecahedron(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeDodecahedron(vertices, indices, size, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Icosahedron
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateIcosahedron(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeIcosahedron(vertices, indices, size, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateIcosahedron(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float size,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeIcosahedron(vertices, indices, size, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Teapot
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateTeapot(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
float size,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
VertexCollection vertices;
|
||||
IndexCollection indices;
|
||||
ComputeTeapot(vertices, indices, size, tessellation, rhcoords);
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void GeometricPrimitive::CreateTeapot(
|
||||
std::vector<VertexPositionNormalTexture>& vertices,
|
||||
std::vector<uint16_t>& indices,
|
||||
float size,
|
||||
size_t tessellation,
|
||||
bool rhcoords)
|
||||
{
|
||||
ComputeTeapot(vertices, indices, size, tessellation, rhcoords);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Custom
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateCustom(
|
||||
ID3D11DeviceContext* deviceContext,
|
||||
const std::vector<VertexPositionNormalTexture>& vertices,
|
||||
const std::vector<uint16_t>& indices)
|
||||
{
|
||||
// Extra validation
|
||||
if (vertices.empty() || indices.empty())
|
||||
throw std::exception("Requires both vertices and indices");
|
||||
|
||||
if (indices.size() % 3)
|
||||
throw std::exception("Expected triangular faces");
|
||||
|
||||
size_t nVerts = vertices.size();
|
||||
if (nVerts >= USHRT_MAX)
|
||||
throw std::exception("Too many vertices for 16-bit index buffer");
|
||||
|
||||
for (auto it = indices.cbegin(); it != indices.cend(); ++it)
|
||||
{
|
||||
if (*it >= nVerts)
|
||||
{
|
||||
throw std::exception("Index not in vertices list");
|
||||
}
|
||||
}
|
||||
|
||||
// Create the primitive object.
|
||||
std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
|
||||
|
||||
primitive->pImpl->Initialize(deviceContext, vertices, indices);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
Reference in New Issue
Block a user