port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

View File

@@ -0,0 +1,431 @@
#include "stdafx.h"
#include "IResourceFactory.h"
#include "GeometryBuffer.h"
GeometryBuffer::GeometryBuffer(IEngine& argEngine)
: m_Engine(argEngine)
, m_VertexBuffer(NULL)
, m_IndexBuffer(NULL)
, m_InputElementDesc(NULL)
, m_VertexCount(0)
, m_VertexElementSize(0)
, m_IndexCount(0)
, m_VertexOffset(0)
, m_VertexDataMapped(false)
, m_IndexDataMapped(false)
, m_RawVertexData_(NULL)
, m_RawIndexData(NULL)
, m_PrimitiveTopology(PrimitiveTopology::TriangleList)
, m_IndexOffset(0)
, m_UsableIndexCount(0)
{
m_Commands.push_back(new Command(this, CommandFlags::None, SetIndexBufferCommandType, 1));
m_Commands.push_back(new Command(this, CommandFlags::None, SetVertexBufferCommandType, 0));
m_Commands.push_back(new Command(this, CommandFlags::EndChain | CommandFlags::Unique, DrawGeometryCommandType, 6));
}
GeometryBuffer::~GeometryBuffer()
{
this->Uninitialize();
m_Engine.get_ResourceFactory().DeleteGeometryBuffer(*const_cast<GeometryBuffer*>(this), true);
}
void GeometryBuffer::Uninitialize()
{
if (m_Engine.get_EngineStates().LastIndexBufferProvider == this)
m_Engine.get_EngineStates().LastIndexBufferProvider = NULL;
if (m_Engine.get_EngineStates().LastVertexBufferProvider == this)
m_Engine.get_EngineStates().LastVertexBufferProvider = NULL;
this->DeleteVertexData();
this->DeleteIndexData();
}
void GeometryBuffer::SetVertexData(uint32 argVertexCount, uint32 argVertexElementSize, void* a_VertexData_, const std::vector<VertexElement>& argVertexElements, bool argNeedsDynamicAccess)
{
this->DeleteVertexData();
D3D10_BUFFER_DESC desc;
desc.Usage = argNeedsDynamicAccess ? D3D10_USAGE_DYNAMIC : D3D10_USAGE_DEFAULT;
desc.ByteWidth = argVertexElementSize * argVertexCount;
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = argNeedsDynamicAccess ? D3D10_CPU_ACCESS_WRITE : 0;
desc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = a_VertexData_;
if (S_OK != m_Engine.get_DX10Device().CreateBuffer(&desc, &initData, &m_VertexBuffer))
{
throw L"GeometryBuffer: Unable to create vertex buffer.";
}
m_VertexCount = argVertexCount;
m_VertexElementSize = argVertexElementSize;
m_VertexElements = argVertexElements;
m_RawVertexData_ = new char[argVertexElementSize * argVertexCount];
::memcpy(m_RawVertexData_, a_VertexData_, argVertexElementSize * argVertexCount);
if (m_InputElementDesc == NULL)
{
if (!m_VertexElements.empty())
{
m_InputElementDesc = new D3D10_INPUT_ELEMENT_DESC[m_VertexElements.size()];
for (uint32 i = 0; i < m_VertexElements.size(); ++i)
{
D3D10_INPUT_ELEMENT_DESC desc;
VertexElement& element = m_VertexElements[i];
desc.AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT;
desc.Format = (DXGI_FORMAT)element.m_ElementFormat;
desc.InputSlot = 0; // should this be a parameter too?
desc.InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;
desc.InstanceDataStepRate = 0;
desc.SemanticIndex = element.m_NameIndex;
desc.SemanticName = element.m_SemanticName.c_str();
m_InputElementDesc[i] = desc;
}
}
}
}
void GeometryBuffer::DeleteVertexData()
{
if (m_VertexBuffer != NULL)
m_Engine.get_DX10Device().ClearState();
m_VertexElements.clear();
if (m_VertexBuffer != NULL)
m_VertexBuffer->Release();
m_VertexBuffer = NULL;
m_VertexCount = 0;
m_VertexElementSize = 0;
m_VertexDataMapped = false;
if (m_RawVertexData_ != NULL)
delete [] m_RawVertexData_;
m_RawVertexData_ = NULL;
if (m_InputElementDesc != NULL)
delete [] m_InputElementDesc;
m_InputElementDesc = NULL;
}
void GeometryBuffer::SetIndexData(uint32 argIndexCount, uint32* aui_IndexData_, bool argNeedsDynamicAccess)
{
this->DeleteIndexData();
D3D10_BUFFER_DESC desc;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.ByteWidth = sizeof(uint32) * argIndexCount;
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = argNeedsDynamicAccess ? D3D10_CPU_ACCESS_WRITE : 0;
desc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = aui_IndexData_;
initData.SysMemPitch = 0;
initData.SysMemSlicePitch = 0;
if (S_OK != m_Engine.get_DX10Device().CreateBuffer(&desc, &initData, &m_IndexBuffer))
{
throw L"GeometryBuffer: Unable to create index buffer.";
}
m_IndexCount = argIndexCount;
m_UsableIndexCount = argIndexCount;
m_IndexOffset = 0;
m_RawIndexData = new uint32[m_IndexCount];
::memcpy(m_RawIndexData, aui_IndexData_, sizeof(uint32) * m_IndexCount);
}
void GeometryBuffer::DeleteIndexData()
{
if (m_IndexBuffer != NULL)
m_Engine.get_DX10Device().ClearState();
if (m_IndexBuffer != NULL)
m_IndexBuffer->Release();
m_IndexBuffer = NULL;
if (m_RawIndexData != NULL)
delete [] m_RawIndexData;
m_RawIndexData = NULL;
m_IndexCount = 0;
while (!m_VertexLayoutsPerShaderAndPass.empty())
{
while (!m_VertexLayoutsPerShaderAndPass.begin()->second.empty())
{
m_VertexLayoutsPerShaderAndPass.begin()->second.back()->Release();
m_VertexLayoutsPerShaderAndPass.begin()->second.pop_back();
}
m_VertexLayoutsPerShaderAndPass.erase(m_VertexLayoutsPerShaderAndPass.begin());
}
}
void* GeometryBuffer::MapVertexBuffer(DataAccessMode::Enumeration argAccessMode)
{
if (m_VertexBuffer == NULL)
{
throw L"GeometryBuffer: Access forbidden until resource has been initialized.";
}
if (m_VertexDataMapped)
{
throw L"GeometryBuffer: Only one access to the vertex buffer at one time possible.";
}
void* dataPointer = NULL;
if (S_OK != m_VertexBuffer->Map((D3D10_MAP)argAccessMode, 0, &dataPointer))
{
throw L"GeometryBuffer: Access to the vertex buffer was not successfull.";
}
m_VertexDataMapped = true;
return dataPointer;
}
void GeometryBuffer::UnmapVertexBuffer()
{
if (m_VertexBuffer == NULL)
{
throw L"GeometryBuffer: Access forbidden until resource has been initialized.";
}
if (!m_VertexDataMapped)
{
throw L"GeometryBuffer: No access was done ending the access to the vertex buffer is not possible.";
}
m_VertexBuffer->Unmap();
m_VertexDataMapped = false;
}
uint32* GeometryBuffer::MapIndexBuffer(DataAccessMode::Enumeration argAccessMode)
{
if (m_IndexBuffer == NULL)
{
throw L"GeometryBuffer: Access forbidden until resource has been initialized.";
}
if (m_IndexDataMapped)
{
throw L"GeometryBuffer: Only one access to the index buffer at one time possible.";
}
void* dataPointer = NULL;
if (S_OK != m_IndexBuffer->Map((D3D10_MAP)argAccessMode, 0, &dataPointer))
{
throw L"GeometryBuffer: Access to the index buffer was not successfull.";
}
m_IndexDataMapped = true;
return (uint32*)dataPointer;
}
void GeometryBuffer::UnmapIndexBuffer()
{
if (m_IndexBuffer == NULL)
{
throw L"GeometryBuffer: Access forbidden until resource has been initialized.";
}
if (!m_IndexDataMapped)
{
throw L"GeometryBuffer: No access was done ending the access to the index buffer is not possible.";
}
m_IndexBuffer->Unmap();
m_IndexDataMapped = false;
}
void GeometryBuffer::ConvertToAdjacency()
{
switch (m_PrimitiveTopology)
{
case PrimitiveTopology::LineList:
case PrimitiveTopology::LineStrip:
case PrimitiveTopology::TriangleList:
case PrimitiveTopology::TriangleStrip:
break;
default:
return;
}
D3D10_INPUT_ELEMENT_DESC inputLayout[2] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "END", 0, DXGI_FORMAT_R8_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
inputLayout[1].AlignedByteOffset = m_VertexElementSize - 1;
// create the mesh
uint32 numVertices = m_VertexCount;
uint32 numIndices = m_IndexCount;
uint32 Options = D3DX10_MESH_32_BIT;
ID3DX10Mesh* mesh = NULL;
if (S_OK != D3DX10CreateMesh(&m_Engine.get_DX10Device(),
inputLayout,
2,
inputLayout[0].SemanticName,
numVertices,
numIndices / 3,
Options,
&mesh ) )
{
throw L"GeometryBuffer: Unable to create temp. mesh for adjacency data generation.";
}
//set the VB
mesh->SetVertexData(0, (void*)m_RawVertexData_);
//set the IB
mesh->SetIndexData((void*)m_RawIndexData, numIndices);
//generate adjacency
const float epsilon = 0.0f;
mesh->GenerateAdjacencyAndPointReps(epsilon);
//generate adjacency indices
mesh->GenerateGSAdjacency();
//get the adjacency data out of the mesh
ID3DX10MeshBuffer* indexBufferMesh = NULL;
unsigned char* adjIndices = NULL;
SIZE_T Size = 0;
if(S_OK != mesh->GetIndexBuffer(&indexBufferMesh))
{
throw L"GeometryBuffer: Unable to retrive indexdata for adjacency data generation.";
}
if(S_OK != indexBufferMesh->Map((void**)&adjIndices, &Size))
{
throw L"GeometryBuffer: Unable to map indexdata for adjacency data generation.";
}
this->SetIndexData((uint32)Size/sizeof(uint32), (uint32*)adjIndices, false);
//cleanup
indexBufferMesh->Unmap();
indexBufferMesh->Release();
mesh->Release();
switch (m_PrimitiveTopology)
{
case PrimitiveTopology::LineList:
this->set_PrimitiveTopology(PrimitiveTopology::LineListAdjacency);
break;
case PrimitiveTopology::LineStrip:
this->set_PrimitiveTopology(PrimitiveTopology::LineStripAdjacency);
break;
case PrimitiveTopology::TriangleList:
this->set_PrimitiveTopology(PrimitiveTopology::TriangleListAdjacency);
break;
case PrimitiveTopology::TriangleStrip:
this->set_PrimitiveTopology(PrimitiveTopology::TriangleStripAdjacency);
break;
}
}
CommandExecuteResult::Enumeration GeometryBuffer::ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon)
{
ID3D10Device& device = m_Engine.get_DX10Device();
if (argCommandType == GeometryBuffer::SetIndexBufferCommandType)
{
if (m_Engine.get_EngineStates().LastIndexBufferProvider != this)
{
device.IASetIndexBuffer(m_IndexBuffer, DXGI_FORMAT_R32_UINT, m_IndexOffset);
m_Engine.get_EngineStates().LastIndexBufferProvider = this;
}
}
else if (argCommandType == GeometryBuffer::SetVertexBufferCommandType)
{
if (m_Engine.get_EngineStates().LastVertexBufferProvider != this)
{
device.IASetVertexBuffers(0, 1, &m_VertexBuffer, &m_VertexElementSize, &m_VertexOffset);
device.IASetPrimitiveTopology((D3D10_PRIMITIVE_TOPOLOGY)m_PrimitiveTopology);
m_Engine.get_EngineStates().LastVertexBufferProvider = this;
}
}
else if (argCommandType == GeometryBuffer::DrawGeometryCommandType)
{
if (m_Engine.get_EngineStates().LastShader == NULL)
std::wcout << std::red << "GeometryBuffer could not render without a valid shader." << std::white << std::endl;
else if (m_Engine.get_EngineStates().LastVertexBufferProvider == NULL)
std::wcout << std::red << "GeometryBuffer could not render without a valid vertex buffer." << std::white << std::endl;
else
this->Render(*m_Engine.get_EngineStates().LastShader);
}
return CommandExecuteResult::None;
}
void GeometryBuffer::Render(IShader& argShader)
{
if (m_VertexElements.empty())
return;
uint32 currentPass = argShader.get_CurrentRenderPass();
ID3D10EffectPass* currentEffectPass = argShader.get_DX10Technique()->GetPassByIndex(currentPass);
ID3D10InputLayout* vertexLayout = NULL;
tk_VertexLayoutsPerShaderAndPass::iterator found = m_VertexLayoutsPerShaderAndPass.find(&argShader);
if (found != m_VertexLayoutsPerShaderAndPass.end() && found->second.size() > currentPass)
{
vertexLayout = found->second[currentPass];
}
else
{
D3D10_PASS_DESC passDesc;
currentEffectPass->GetDesc(&passDesc);
if (S_OK == m_Engine.get_DX10Device().CreateInputLayout(m_InputElementDesc, m_VertexElements.size(), passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize, &vertexLayout ))
{
if (found == m_VertexLayoutsPerShaderAndPass.end())
{
std::vector<ID3D10InputLayout*> val;
val.push_back(vertexLayout);
m_VertexLayoutsPerShaderAndPass[&argShader] = val;
}
else
found->second.push_back(vertexLayout);
}
}
if (vertexLayout != NULL)
{
currentEffectPass->Apply(0);
m_Engine.get_DX10Device().IASetInputLayout(vertexLayout);
if (m_IndexBuffer == NULL)
m_Engine.get_DX10Device().Draw(m_VertexCount, 0);
else
m_Engine.get_DX10Device().DrawIndexed(m_UsableIndexCount, m_IndexOffset, 0);
}
}

View File

@@ -0,0 +1,79 @@
#pragma once
#include "IEngine.h"
#include "IGeometryBuffer.h"
#include "IShader.h"
#include "../Commands/CommandUserBase.h"
class GeometryBuffer
: public IGeometryBuffer
, public CommandUserBase
{
protected:
static const unsigned char SetIndexBufferCommandType = 0;
static const unsigned char SetVertexBufferCommandType = 1;
static const unsigned char DrawGeometryCommandType = 2;
public:
GeometryBuffer(IEngine& argEngine);
virtual ~GeometryBuffer();
virtual void Uninitialize();
virtual void SetVertexData(uint32 argVertexCount, uint32 argVertexElementSize, void* a_VertexData_, const std::vector<VertexElement>& argVertexElements, bool argNeedsDynamicAccess);
virtual void DeleteVertexData();
virtual void SetIndexData(uint32 argIndexCount, uint32* aui_IndexData_, bool argNeedsDynamicAccess);
virtual void DeleteIndexData();
virtual void* MapVertexBuffer(DataAccessMode::Enumeration argAccessMode);
virtual void UnmapVertexBuffer();
virtual uint32* MapIndexBuffer(DataAccessMode::Enumeration argAccessMode);
virtual void UnmapIndexBuffer();
virtual uint32 get_IndexBufferOffset() const { return m_IndexOffset; }
virtual void set_IndexBufferOffset(uint32 argValue) { m_IndexOffset = argValue; }
virtual uint32 get_IndexBufferUsableLength() const { return m_UsableIndexCount; }
virtual void set_IndexBufferUsableLength(uint32 argValue) { m_UsableIndexCount = argValue; }
virtual uint32 get_IndexBufferLength() const { return m_IndexCount; }
virtual uint32 get_VertexBufferLength() const { return m_VertexCount; }
virtual PrimitiveTopology::Enumeration get_PrimitiveTopology() const { return m_PrimitiveTopology; }
virtual void set_PrimitiveTopology(PrimitiveTopology::Enumeration argValue) { m_PrimitiveTopology = argValue; }
virtual void ConvertToAdjacency();
// ICommandUser
virtual CommandExecuteResult::Enumeration ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon);
virtual string8 get_UserName() const { return "GeometryBuffer"; }
protected:
void Render(IShader& argShader);
protected:
IEngine& m_Engine;
uint32 m_IndexCount;
uint32 m_IndexOffset;
uint32 m_UsableIndexCount;
ID3D10Buffer* m_IndexBuffer;
uint32* m_RawIndexData;
uint32 m_VertexOffset;
uint32 m_VertexCount;
uint32 m_VertexElementSize;
ID3D10Buffer* m_VertexBuffer;
void* m_RawVertexData_;
bool m_VertexDataMapped;
bool m_IndexDataMapped;
PrimitiveTopology::Enumeration m_PrimitiveTopology;
std::vector<VertexElement> m_VertexElements;
D3D10_INPUT_ELEMENT_DESC* m_InputElementDesc;
typedef std::map<IShader*, std::vector<ID3D10InputLayout*> > tk_VertexLayoutsPerShaderAndPass;
tk_VertexLayoutsPerShaderAndPass m_VertexLayoutsPerShaderAndPass;
};