This commit is contained in:
Dmitry 2020-09-02 14:21:05 +03:00
parent d6d07e7883
commit dc4373dee7
210 changed files with 17289 additions and 7531 deletions

View File

@ -15,7 +15,7 @@
<ProjectGuid>{53923514-84B2-4B78-889A-8709C6BFA3A5}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>RendererDirect3D12</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

View File

@ -17,6 +17,7 @@ void GeometryD3D12::Init(RcGeometryDesc desc)
{
VERUS_INIT();
_name = desc._name;
_dynBindingsMask = desc._dynBindingsMask;
_32BitIndices = desc._32BitIndices;
@ -102,6 +103,7 @@ void GeometryD3D12::CreateVertexBuffer(int count, int binding)
&vb._pMaAllocation,
IID_PPV_ARGS(&vb._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_UPLOAD), hr=" << VERUS_HR(hr);
vb._pBuffer->SetName(_C(Str::Utf8ToWide(_name + " (Dynamic VB, " + std::to_string(binding) + ")")));
VERUS_FOR(i, BaseRenderer::s_ringBufferSize)
{
@ -122,6 +124,7 @@ void GeometryD3D12::CreateVertexBuffer(int count, int binding)
&vb._pMaAllocation,
IID_PPV_ARGS(&vb._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_DEFAULT), hr=" << VERUS_HR(hr);
vb._pBuffer->SetName(_C(Str::Utf8ToWide(_name + " (VB, " + std::to_string(binding) + ")")));
vb._bufferView[0].BufferLocation = vb._pBuffer->GetGPUVirtualAddress();
vb._bufferView[0].SizeInBytes = Utils::Cast32(vb._bufferSize);
@ -129,7 +132,7 @@ void GeometryD3D12::CreateVertexBuffer(int count, int binding)
}
}
void GeometryD3D12::UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB)
void GeometryD3D12::UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset)
{
VERUS_QREF_RENDERER;
VERUS_QREF_RENDERER_D3D12;
@ -138,12 +141,14 @@ void GeometryD3D12::UpdateVertexBuffer(const void* p, int binding, PBaseCommandB
if (((_instBindingsMask | _dynBindingsMask) >> binding) & 0x1)
{
auto& vb = _vVertexBuffers[binding];
const int elementSize = _vStrides[binding];
size = size ? size * elementSize : vb._bufferSize;
CD3DX12_RANGE readRange(0, 0);
void* pData = nullptr;
if (FAILED(hr = vb._pBuffer->Map(0, &readRange, &pData)))
throw VERUS_RUNTIME_ERROR << "Map(), hr=" << VERUS_HR(hr);
BYTE* pMappedData = static_cast<BYTE*>(pData) + pRendererD3D12->GetRingBufferIndex() * vb._bufferSize;
memcpy(pMappedData, p, vb._bufferSize);
memcpy(pMappedData + offset * elementSize, p, size);
vb._pBuffer->Unmap(0, nullptr);
}
else
@ -167,6 +172,7 @@ void GeometryD3D12::UpdateVertexBuffer(const void* p, int binding, PBaseCommandB
&svb._pMaAllocation,
IID_PPV_ARGS(&svb._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_UPLOAD), hr=" << VERUS_HR(hr);
vb._pBuffer->SetName(_C(Str::Utf8ToWide(_name + " (Staging VB, " + std::to_string(binding) + ")")));
}
if (!pCB)
@ -202,66 +208,107 @@ void GeometryD3D12::CreateIndexBuffer(int count)
const int elementSize = _32BitIndices ? sizeof(UINT32) : sizeof(UINT16);
_indexBuffer._bufferSize = count * elementSize;
D3D12MA::ALLOCATION_DESC allocDesc = {};
allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
if (FAILED(hr = pRendererD3D12->GetMaAllocator()->CreateResource(
&allocDesc,
&CD3DX12_RESOURCE_DESC::Buffer(_indexBuffer._bufferSize),
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
&_indexBuffer._pMaAllocation,
IID_PPV_ARGS(&_indexBuffer._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_DEFAULT), hr=" << VERUS_HR(hr);
if ((_dynBindingsMask >> 31) & 0x1)
{
D3D12MA::ALLOCATION_DESC allocDesc = {};
allocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD;
if (FAILED(hr = pRendererD3D12->GetMaAllocator()->CreateResource(
&allocDesc,
&CD3DX12_RESOURCE_DESC::Buffer(_indexBuffer._bufferSize * BaseRenderer::s_ringBufferSize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
&_indexBuffer._pMaAllocation,
IID_PPV_ARGS(&_indexBuffer._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_UPLOAD), hr=" << VERUS_HR(hr);
_indexBuffer._pBuffer->SetName(_C(Str::Utf8ToWide(_name + " (Dynamic IB)")));
_indexBufferView.BufferLocation = _indexBuffer._pBuffer->GetGPUVirtualAddress();
_indexBufferView.SizeInBytes = Utils::Cast32(_indexBuffer._bufferSize);
_indexBufferView.Format = _32BitIndices ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
VERUS_FOR(i, BaseRenderer::s_ringBufferSize)
{
_indexBufferView[i].BufferLocation = _indexBuffer._pBuffer->GetGPUVirtualAddress() + i * _indexBuffer._bufferSize;
_indexBufferView[i].SizeInBytes = Utils::Cast32(_indexBuffer._bufferSize);
_indexBufferView[i].Format = _32BitIndices ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
}
}
else
{
D3D12MA::ALLOCATION_DESC allocDesc = {};
allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
if (FAILED(hr = pRendererD3D12->GetMaAllocator()->CreateResource(
&allocDesc,
&CD3DX12_RESOURCE_DESC::Buffer(_indexBuffer._bufferSize),
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
&_indexBuffer._pMaAllocation,
IID_PPV_ARGS(&_indexBuffer._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_DEFAULT), hr=" << VERUS_HR(hr);
_indexBuffer._pBuffer->SetName(_C(Str::Utf8ToWide(_name + " (IB)")));
_indexBufferView[0].BufferLocation = _indexBuffer._pBuffer->GetGPUVirtualAddress();
_indexBufferView[0].SizeInBytes = Utils::Cast32(_indexBuffer._bufferSize);
_indexBufferView[0].Format = _32BitIndices ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
}
}
void GeometryD3D12::UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB)
void GeometryD3D12::UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset)
{
VERUS_QREF_RENDERER;
VERUS_QREF_RENDERER_D3D12;
HRESULT hr = 0;
bool revertState = true;
if (!_stagingIndexBuffer._pBuffer)
if ((_dynBindingsMask >> 31) & 0x1)
{
revertState = false;
D3D12MA::ALLOCATION_DESC allocDesc = {};
allocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD;
if (FAILED(hr = pRendererD3D12->GetMaAllocator()->CreateResource(
&allocDesc,
&CD3DX12_RESOURCE_DESC::Buffer(_indexBuffer._bufferSize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
&_stagingIndexBuffer._pMaAllocation,
IID_PPV_ARGS(&_stagingIndexBuffer._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_UPLOAD), hr=" << VERUS_HR(hr);
const int elementSize = _32BitIndices ? sizeof(UINT32) : sizeof(UINT16);
size = size ? size * elementSize : _indexBuffer._bufferSize;
CD3DX12_RANGE readRange(0, 0);
void* pData = nullptr;
if (FAILED(hr = _indexBuffer._pBuffer->Map(0, &readRange, &pData)))
throw VERUS_RUNTIME_ERROR << "Map(), hr=" << VERUS_HR(hr);
BYTE* pMappedData = static_cast<BYTE*>(pData) + pRendererD3D12->GetRingBufferIndex() * _indexBuffer._bufferSize;
memcpy(pMappedData + offset * elementSize, p, size);
_indexBuffer._pBuffer->Unmap(0, nullptr);
}
if (!pCB)
pCB = renderer.GetCommandBuffer().Get();
auto pCmdList = static_cast<PCommandBufferD3D12>(pCB)->GetD3DGraphicsCommandList();
if (revertState)
else
{
bool revertState = true;
if (!_stagingIndexBuffer._pBuffer)
{
revertState = false;
D3D12MA::ALLOCATION_DESC allocDesc = {};
allocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD;
if (FAILED(hr = pRendererD3D12->GetMaAllocator()->CreateResource(
&allocDesc,
&CD3DX12_RESOURCE_DESC::Buffer(_indexBuffer._bufferSize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
&_stagingIndexBuffer._pMaAllocation,
IID_PPV_ARGS(&_stagingIndexBuffer._pBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_UPLOAD), hr=" << VERUS_HR(hr);
_stagingIndexBuffer._pBuffer->SetName(_C(Str::Utf8ToWide(_name + " (Staging IB)")));
}
if (!pCB)
pCB = renderer.GetCommandBuffer().Get();
auto pCmdList = static_cast<PCommandBufferD3D12>(pCB)->GetD3DGraphicsCommandList();
if (revertState)
{
const CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
_indexBuffer._pBuffer.Get(), D3D12_RESOURCE_STATE_INDEX_BUFFER, D3D12_RESOURCE_STATE_COPY_DEST);
pCmdList->ResourceBarrier(1, &barrier);
}
D3D12_SUBRESOURCE_DATA sd = {};
sd.pData = p;
sd.RowPitch = _indexBuffer._bufferSize;
sd.SlicePitch = sd.RowPitch;
UpdateSubresources<1>(pCmdList,
_indexBuffer._pBuffer.Get(),
_stagingIndexBuffer._pBuffer.Get(),
0, 0, 1, &sd);
const CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
_indexBuffer._pBuffer.Get(), D3D12_RESOURCE_STATE_INDEX_BUFFER, D3D12_RESOURCE_STATE_COPY_DEST);
_indexBuffer._pBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER);
pCmdList->ResourceBarrier(1, &barrier);
}
D3D12_SUBRESOURCE_DATA sd = {};
sd.pData = p;
sd.RowPitch = _indexBuffer._bufferSize;
sd.SlicePitch = sd.RowPitch;
UpdateSubresources<1>(pCmdList,
_indexBuffer._pBuffer.Get(),
_stagingIndexBuffer._pBuffer.Get(),
0, 0, 1, &sd);
const CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
_indexBuffer._pBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER);
pCmdList->ResourceBarrier(1, &barrier);
Schedule();
Schedule();
}
}
Continue GeometryD3D12::Scheduled_Update()
@ -323,5 +370,11 @@ const D3D12_VERTEX_BUFFER_VIEW* GeometryD3D12::GetD3DVertexBufferView(int bindin
const D3D12_INDEX_BUFFER_VIEW* GeometryD3D12::GetD3DIndexBufferView() const
{
return &_indexBufferView;
if ((_dynBindingsMask >> 31) & 0x1)
{
VERUS_QREF_RENDERER_D3D12;
return &_indexBufferView[pRendererD3D12->GetRingBufferIndex()];
}
else
return &_indexBufferView[0];
}

View File

@ -18,7 +18,7 @@ namespace verus
BufferEx _indexBuffer;
Vector<BufferEx> _vStagingVertexBuffers;
BufferEx _stagingIndexBuffer;
D3D12_INDEX_BUFFER_VIEW _indexBufferView;
D3D12_INDEX_BUFFER_VIEW _indexBufferView[BaseRenderer::s_ringBufferSize] = {};
Vector<D3D12_INPUT_ELEMENT_DESC> _vInputElementDesc;
Vector<int> _vStrides;
@ -30,10 +30,10 @@ namespace verus
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual Continue Scheduled_Update() override;

View File

@ -180,6 +180,7 @@ void PipelineD3D12::Init(RcPipelineDesc desc)
if (FAILED(hr = pRendererD3D12->GetD3DDevice()->CreateGraphicsPipelineState(&gpsDesc, IID_PPV_ARGS(&_pPipelineState))))
throw VERUS_RUNTIME_ERROR << "CreateGraphicsPipelineState(), hr=" << VERUS_HR(hr);
_pPipelineState->SetName(_C(Str::Utf8ToWide(String("PipelineState (") + _C(shader.GetSourceName()) + ", " + desc._shaderBranch + ")")));
}
void PipelineD3D12::Done()
@ -209,6 +210,7 @@ void PipelineD3D12::InitCompute(RcPipelineDesc desc)
if (FAILED(hr = pRendererD3D12->GetD3DDevice()->CreateComputePipelineState(&cpsDesc, IID_PPV_ARGS(&_pPipelineState))))
throw VERUS_RUNTIME_ERROR << "CreateComputePipelineState(), hr=" << VERUS_HR(hr);
_pPipelineState->SetName(_C(Str::Utf8ToWide(String("PipelineState (") + _C(shader.GetSourceName()) + ", " + desc._shaderBranch + ")")));
}
D3D12_SHADER_BYTECODE PipelineD3D12::ToBytecode(ID3DBlob* pBlob)

View File

@ -45,6 +45,7 @@ void ShaderD3D12::Init(CSZ source, CSZ sourceName, CSZ* branches)
VERUS_QREF_CONST_SETTINGS;
HRESULT hr = 0;
_sourceName = sourceName;
const size_t len = strlen(source);
ShaderInclude inc;
const String version = "5_1";
@ -230,6 +231,7 @@ void ShaderD3D12::CreateDescriptorSet(int setNumber, const void* pSrc, int size,
&dsd._pMaAllocation,
IID_PPV_ARGS(&dsd._pConstantBuffer))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_UPLOAD), hr=" << VERUS_HR(hr);
dsd._pConstantBuffer->SetName(_C(Str::Utf8ToWide("Shader.ConstantBuffer (" + _sourceName + ", set=" + std::to_string(setNumber) + ")")));
const int count = dsd._capacity * BaseRenderer::s_ringBufferSize;
dsd._dhDynamicOffsets.Create(pRendererD3D12->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, count);
@ -383,6 +385,7 @@ void ShaderD3D12::CreatePipelineLayout()
}
if (FAILED(hr = pRendererD3D12->GetD3DDevice()->CreateRootSignature(0, pRootSignatureBlob->GetBufferPointer(), pRootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&_pRootSignature))))
throw VERUS_RUNTIME_ERROR << "CreateRootSignature(), hr=" << VERUS_HR(hr);
_pRootSignature->SetName(_C(Str::Utf8ToWide("RootSignature (" + _sourceName + ")")));
}
CSHandle ShaderD3D12::BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il, const int* pMips)

View File

@ -21,6 +21,8 @@ void TextureD3D12::Init(RcTextureDesc desc)
HRESULT hr = 0;
_initAtFrame = renderer.GetFrameCount();
if (desc._name)
_name = desc._name;
_size = Vector4(
float(desc._width),
float(desc._height),
@ -47,7 +49,11 @@ void TextureD3D12::Init(RcTextureDesc desc)
if (renderTarget)
resDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
if (depthFormat)
{
resDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
if (!depthSampled)
resDesc.Flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
}
D3D12_RESOURCE_STATES initialResourceState = ToNativeImageLayout(_mainLayout);
D3D12_CLEAR_VALUE clearValue = {};
@ -71,6 +77,7 @@ void TextureD3D12::Init(RcTextureDesc desc)
&_resource._pMaAllocation,
IID_PPV_ARGS(&_resource._pResource))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_DEFAULT), hr=" << VERUS_HR(hr);
_resource._pResource->SetName(_C(Str::Utf8ToWide(_name)));
if (_desc._flags & TextureDesc::Flags::generateMips)
{
@ -80,7 +87,7 @@ void TextureD3D12::Init(RcTextureDesc desc)
resDescUAV.Width = Math::Max(1, _desc._width >> 1);
resDescUAV.Height = Math::Max(1, _desc._height >> 1);
resDescUAV.MipLevels = uavMipLevels;
resDescUAV.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
resDescUAV.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
// sRGB cannot be used with UAV:
switch (resDescUAV.Format)
{
@ -98,6 +105,7 @@ void TextureD3D12::Init(RcTextureDesc desc)
&_uaResource._pMaAllocation,
IID_PPV_ARGS(&_uaResource._pResource))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_DEFAULT), hr=" << VERUS_HR(hr);
_uaResource._pResource->SetName(_C(Str::Utf8ToWide(_name + " (UAV)")));
_dhUAV.Create(pRendererD3D12->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, uavMipLevels);
VERUS_FOR(i, uavMipLevels)
@ -130,6 +138,7 @@ void TextureD3D12::Init(RcTextureDesc desc)
&x._pMaAllocation,
IID_PPV_ARGS(&x._pResource))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_READBACK), hr=" << VERUS_HR(hr);
x._pResource->SetName(_C(Str::Utf8ToWide(_name + " (Readback)")));
}
}
@ -225,6 +234,7 @@ void TextureD3D12::UpdateSubresource(const void* p, int mipLevel, int arrayLayer
&sb._pMaAllocation,
IID_PPV_ARGS(&sb._pResource))))
throw VERUS_RUNTIME_ERROR << "CreateResource(D3D12_HEAP_TYPE_UPLOAD), hr=" << VERUS_HR(hr);
sb._pResource->SetName(_C(Str::Utf8ToWide(_name + " (Staging)")));
}
if (!pCB)

View File

@ -37,8 +37,6 @@
// DirectX data
static ID3D12Device* g_pd3dDevice = NULL;
static ID3D10Blob* g_pVertexShaderBlob = NULL;
static ID3D10Blob* g_pPixelShaderBlob = NULL;
static ID3D12RootSignature* g_pRootSignature = NULL;
static ID3D12PipelineState* g_pPipelineState = NULL;
static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN;
@ -361,7 +359,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
hr = cmdList->Close();
IM_ASSERT(SUCCEEDED(hr));
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*) &cmdList);
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
hr = cmdQueue->Signal(fence, 1);
IM_ASSERT(SUCCEEDED(hr));
@ -473,6 +471,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
psoDesc.SampleDesc.Count = 1;
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
ID3DBlob* vertexShaderBlob;
ID3DBlob* pixelShaderBlob;
// Create the vertex shader
{
static const char* vertexShader =
@ -503,13 +504,13 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
return output;\
}";
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL);
if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return false;
psoDesc.VS = { g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize() };
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vertexShaderBlob, NULL)))
return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() };
// Create the input layout
static D3D12_INPUT_ELEMENT_DESC local_layout[] = {
static D3D12_INPUT_ELEMENT_DESC local_layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
@ -535,10 +536,12 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
return out_col; \
}";
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL);
if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return false;
psoDesc.PS = { g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize() };
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &pixelShaderBlob, NULL)))
{
vertexShaderBlob->Release();
return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
}
psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() };
}
// Create the blending setup
@ -583,7 +586,10 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
desc.BackFace = desc.FrontFace;
}
if (g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState)) != S_OK)
HRESULT result_pipeline_state = g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState));
vertexShaderBlob->Release();
pixelShaderBlob->Release();
if (result_pipeline_state != S_OK)
return false;
ImGui_ImplDX12_CreateFontsTexture();
@ -596,8 +602,6 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
if (!g_pd3dDevice)
return;
SafeRelease(g_pVertexShaderBlob);
SafeRelease(g_pPixelShaderBlob);
SafeRelease(g_pRootSignature);
SafeRelease(g_pPipelineState);
SafeRelease(g_pFontTextureResource);

View File

@ -15,7 +15,7 @@
<ProjectGuid>{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>RendererVulkan</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

View File

@ -134,7 +134,7 @@ void CommandBufferVulkan::BindIndexBuffer(GeometryPtr geo)
{
auto& geoVulkan = static_cast<RGeometryVulkan>(*geo);
VkBuffer buffer = geoVulkan.GetVkIndexBuffer();
VkDeviceSize offset = 0;
VkDeviceSize offset = geoVulkan.GetVkIndexBufferOffset();
vkCmdBindIndexBuffer(GetVkCommandBuffer(), buffer, offset, geoVulkan.Has32BitIndices() ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16);
}

View File

@ -109,7 +109,7 @@ void GeometryVulkan::CreateVertexBuffer(int count, int binding)
}
}
void GeometryVulkan::UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB)
void GeometryVulkan::UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset)
{
VERUS_QREF_RENDERER_VULKAN;
VkResult res = VK_SUCCESS;
@ -117,11 +117,13 @@ void GeometryVulkan::UpdateVertexBuffer(const void* p, int binding, PBaseCommand
if (((_instBindingsMask | _dynBindingsMask) >> binding) & 0x1)
{
auto& vb = _vVertexBuffers[binding];
const int elementSize = _vStrides[binding];
size = size ? size * elementSize : vb._bufferSize;
void* pData = nullptr;
if (VK_SUCCESS != (res = vmaMapMemory(pRendererVulkan->GetVmaAllocator(), vb._vmaAllocation, &pData)))
throw VERUS_RECOVERABLE << "vmaMapMemory(), res=" << res;
BYTE* pMappedData = static_cast<BYTE*>(pData) + pRendererVulkan->GetRingBufferIndex() * vb._bufferSize;
memcpy(pMappedData, p, vb._bufferSize);
memcpy(pMappedData + offset * elementSize, p, size);
vmaUnmapMemory(pRendererVulkan->GetVmaAllocator(), vb._vmaAllocation);
}
else
@ -156,30 +158,52 @@ void GeometryVulkan::CreateIndexBuffer(int count)
const int elementSize = _32BitIndices ? sizeof(UINT32) : sizeof(UINT16);
_indexBuffer._bufferSize = count * elementSize;
pRendererVulkan->CreateBuffer(_indexBuffer._bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY,
_indexBuffer._buffer, _indexBuffer._vmaAllocation);
if ((_dynBindingsMask >> 31) & 0x1)
{
pRendererVulkan->CreateBuffer(_indexBuffer._bufferSize * BaseRenderer::s_ringBufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU,
_indexBuffer._buffer, _indexBuffer._vmaAllocation);
}
else
{
pRendererVulkan->CreateBuffer(_indexBuffer._bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY,
_indexBuffer._buffer, _indexBuffer._vmaAllocation);
}
}
void GeometryVulkan::UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB)
void GeometryVulkan::UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset)
{
VERUS_QREF_RENDERER_VULKAN;
VkResult res = VK_SUCCESS;
if (VK_NULL_HANDLE == _stagingIndexBuffer._buffer)
if ((_dynBindingsMask >> 31) & 0x1)
{
pRendererVulkan->CreateBuffer(_indexBuffer._bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY,
_stagingIndexBuffer._buffer, _stagingIndexBuffer._vmaAllocation);
const int elementSize = _32BitIndices ? sizeof(UINT32) : sizeof(UINT16);
size = size ? size * elementSize : _indexBuffer._bufferSize;
void* pData = nullptr;
if (VK_SUCCESS != (res = vmaMapMemory(pRendererVulkan->GetVmaAllocator(), _indexBuffer._vmaAllocation, &pData)))
throw VERUS_RECOVERABLE << "vmaMapMemory(), res=" << res;
BYTE* pMappedData = static_cast<BYTE*>(pData) + pRendererVulkan->GetRingBufferIndex() * _indexBuffer._bufferSize;
memcpy(pMappedData + offset * elementSize, p, size);
vmaUnmapMemory(pRendererVulkan->GetVmaAllocator(), _indexBuffer._vmaAllocation);
}
else
{
if (VK_NULL_HANDLE == _stagingIndexBuffer._buffer)
{
pRendererVulkan->CreateBuffer(_indexBuffer._bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY,
_stagingIndexBuffer._buffer, _stagingIndexBuffer._vmaAllocation);
}
void* pData = nullptr;
if (VK_SUCCESS != (res = vmaMapMemory(pRendererVulkan->GetVmaAllocator(), _stagingIndexBuffer._vmaAllocation, &pData)))
throw VERUS_RECOVERABLE << "vmaMapMemory(), res=" << res;
memcpy(pData, p, _indexBuffer._bufferSize);
vmaUnmapMemory(pRendererVulkan->GetVmaAllocator(), _stagingIndexBuffer._vmaAllocation);
void* pData = nullptr;
if (VK_SUCCESS != (res = vmaMapMemory(pRendererVulkan->GetVmaAllocator(), _stagingIndexBuffer._vmaAllocation, &pData)))
throw VERUS_RECOVERABLE << "vmaMapMemory(), res=" << res;
memcpy(pData, p, _indexBuffer._bufferSize);
vmaUnmapMemory(pRendererVulkan->GetVmaAllocator(), _stagingIndexBuffer._vmaAllocation);
pRendererVulkan->CopyBuffer(_stagingIndexBuffer._buffer, _indexBuffer._buffer, _indexBuffer._bufferSize, pCB);
pRendererVulkan->CopyBuffer(_stagingIndexBuffer._buffer, _indexBuffer._buffer, _indexBuffer._bufferSize, pCB);
Schedule();
Schedule();
}
}
Continue GeometryVulkan::Scheduled_Update()
@ -257,3 +281,14 @@ VkDeviceSize GeometryVulkan::GetVkVertexBufferOffset(int binding) const
else
return 0;
}
VkDeviceSize GeometryVulkan::GetVkIndexBufferOffset() const
{
if ((_dynBindingsMask >> 31) & 0x1)
{
VERUS_QREF_RENDERER_VULKAN;
return pRendererVulkan->GetRingBufferIndex() * _indexBuffer._bufferSize;
}
else
return 0;
}

View File

@ -29,10 +29,10 @@ namespace verus
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual Continue Scheduled_Update() override;
@ -47,6 +47,7 @@ namespace verus
VkBuffer GetVkVertexBuffer(int binding) const { return _vVertexBuffers[binding]._buffer; }
VkBuffer GetVkIndexBuffer() const { return _indexBuffer._buffer; }
VkDeviceSize GetVkVertexBufferOffset(int binding) const;
VkDeviceSize GetVkIndexBufferOffset() const;
};
VERUS_TYPEDEFS(GeometryVulkan);
}

View File

@ -30,7 +30,7 @@ static void DestroyDebugUtilsMessengerEXT(
CSZ RendererVulkan::s_requiredValidationLayers[] =
{
"VK_LAYER_LUNARG_standard_validation"
"VK_LAYER_KHRONOS_validation"
};
CSZ RendererVulkan::s_requiredDeviceExtensions[] =

View File

@ -22,6 +22,8 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2020-05-04: Vulkan: Fixed crash if initial frame has no vertices.
// 2020-04-26: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData didn't have vertices.
// 2019-08-01: Vulkan: Added support for specifying multisample count. Set ImGui_ImplVulkan_InitInfo::MSAASamples to one of the VkSampleCountFlagBits values to use, default is non-multisampled as before.
// 2019-05-29: Vulkan: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: Vulkan: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
@ -219,7 +221,7 @@ static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, ui
VkPhysicalDeviceMemoryProperties prop;
vkGetPhysicalDeviceMemoryProperties(v->PhysicalDevice, &prop);
for (uint32_t i = 0; i < prop.memoryTypeCount; i++)
if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<<i))
if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1 << i))
return i;
return 0xFFFFFFFF; // Unable to find memoryType
}
@ -274,6 +276,7 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkCommandBu
}
// Bind Vertex And Index Buffer:
if (draw_data->TotalVtxCount > 0)
{
VkBuffer vertex_buffers[1] = { rb->VertexBuffer };
VkDeviceSize vertex_offset[1] = { 0 };
@ -314,7 +317,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0)
if (fb_width <= 0 || fb_height <= 0)
return;
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
@ -332,21 +335,20 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
wrb->Index = (wrb->Index + 1) % wrb->Count;
ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index];
VkResult err;
// Create or resize the vertex/index buffers
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size)
CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
// Upload vertex/index data into a single contiguous GPU buffer
if (draw_data->TotalVtxCount > 0)
{
// Create or resize the vertex/index buffers
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size)
CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
// Upload vertex/index data into a single contiguous GPU buffer
ImDrawVert* vtx_dst = NULL;
ImDrawIdx* idx_dst = NULL;
err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst));
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst));
check_vk_result(err);
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst));
check_vk_result(err);
@ -440,7 +442,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
size_t upload_size = width*height*4*sizeof(char);
size_t upload_size = width * height * 4 * sizeof(char);
VkResult err;
@ -997,6 +999,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
{
VkResult err;
VkSwapchainKHR old_swapchain = wd->Swapchain;
wd->Swapchain = NULL;
err = vkDeviceWaitIdle(device);
check_vk_result(err);
@ -1153,7 +1156,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
}
}
void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count)
// Create or resize window
void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count)
{
(void)instance;
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count);

View File

@ -72,7 +72,7 @@ struct ImGui_ImplVulkanH_Frame;
struct ImGui_ImplVulkanH_Window;
// Helpers
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator);
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);

View File

@ -3,8 +3,8 @@
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<IncludePath>C:\Compressonator_3.2.4691\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-2.89\src;C:\Home\Middleware\bullet3-2.89\Extras;C:\Home\Middleware\DevIL-Windows-SDK-1.8.0\include;C:\Home\Middleware\libogg-1.3.4\include;C:\Home\Middleware\libvorbis-1.3.6\include;C:\Home\Middleware\openal-soft-1.20.1-bin\include;C:\Home\Middleware\SDL2-2.0.12\include;C:\VulkanSDK\1.2.148.1\Include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Compressonator_3.2.4691\lib\VS2017\x64;C:\Home\Middleware\bullet3-2.89\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\DevIL-Windows-SDK-1.8.0\lib\x64\Release;C:\Home\Middleware\libogg-1.3.4\lib;C:\Home\Middleware\libvorbis-1.3.6\lib2;C:\Home\Middleware\openal-soft-1.20.1-bin\libs\Win64;C:\Home\Middleware\SDL2-2.0.12\lib\x64;C:\VulkanSDK\1.2.148.1\Lib;$(LibraryPath)</LibraryPath>
<IncludePath>C:\Compressonator_3.2.4691\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-2.89\src;C:\Home\Middleware\bullet3-2.89\Extras;C:\Home\Middleware\DevIL-Windows-SDK-1.8.0\include;C:\Home\Middleware\libogg-1.3.4\include;C:\Home\Middleware\libvorbis-1.3.7\include;C:\Home\Middleware\openal-soft-1.20.1-bin\include;C:\Home\Middleware\SDL2-2.0.12\include;C:\VulkanSDK\1.2.148.1\Include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Compressonator_3.2.4691\lib\VS2017\x64;C:\Home\Middleware\bullet3-2.89\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\DevIL-Windows-SDK-1.8.0\lib\x64\Release;C:\Home\Middleware\libogg-1.3.4\lib;C:\Home\Middleware\libvorbis-1.3.7\lib2;C:\Home\Middleware\openal-soft-1.20.1-bin\libs\Win64;C:\Home\Middleware\SDL2-2.0.12\lib\x64;C:\VulkanSDK\1.2.148.1\Lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup />
<ItemGroup />

View File

@ -15,7 +15,7 @@
<ProjectGuid>{B154D670-E4B1-4D8A-885C-69546A5BD833}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Verus</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@ -133,6 +133,7 @@
<ClInclude Include="src\Effects\Bloom.h" />
<ClInclude Include="src\Effects\Blur.h" />
<ClInclude Include="src\Effects\Effects.h" />
<ClInclude Include="src\Effects\Particles.h" />
<ClInclude Include="src\Effects\Ssao.h" />
<ClInclude Include="src\Extra\Extra.h" />
<ClInclude Include="src\Extra\FileParser.h" />
@ -317,6 +318,7 @@
<ClCompile Include="src\Effects\Bloom.cpp" />
<ClCompile Include="src\Effects\Blur.cpp" />
<ClCompile Include="src\Effects\Effects.cpp" />
<ClCompile Include="src\Effects\Particles.cpp" />
<ClCompile Include="src\Effects\Ssao.cpp" />
<ClCompile Include="src\Extra\Extra.cpp" />
<ClCompile Include="src\Extra\FileParser.cpp" />
@ -764,6 +766,22 @@
<FileType>Document</FileType>
</None>
</ItemGroup>
<ItemGroup>
<None Include="src\Shaders\SimpleForest.hlsl">
<FileType>Document</FileType>
</None>
<None Include="src\Shaders\SimpleForest.inc.hlsl">
<FileType>Document</FileType>
</None>
</ItemGroup>
<ItemGroup>
<None Include="src\Shaders\Particles.hlsl">
<FileType>Document</FileType>
</None>
<None Include="src\Shaders\Particles.inc.hlsl">
<FileType>Document</FileType>
</None>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -669,6 +669,9 @@
<ClInclude Include="src\Scene\SceneNodes\Types.h">
<Filter>src\Scene\SceneNodes</Filter>
</ClInclude>
<ClInclude Include="src\Effects\Particles.h">
<Filter>src\Effects</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\CGI\BaseGeometry.cpp">
@ -1136,6 +1139,9 @@
<ClCompile Include="src\Scene\SceneNodes\TransformGizmo.cpp">
<Filter>src\Scene\SceneNodes</Filter>
</ClCompile>
<ClCompile Include="src\Effects\Particles.cpp">
<Filter>src\Effects</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="src\Shaders\Lib.hlsl">
@ -1276,6 +1282,24 @@
<None Include="src\Shaders\DS_BakeSprites.inc.hlsl">
<Filter>src\Shaders</Filter>
</None>
<None Include="src\Shaders\DS_Forest.hlsl">
<Filter>src\Shaders</Filter>
</None>
<None Include="src\Shaders\DS_Forest.inc.hlsl">
<Filter>src\Shaders</Filter>
</None>
<None Include="src\Shaders\SimpleForest.hlsl">
<Filter>src\Shaders</Filter>
</None>
<None Include="src\Shaders\SimpleForest.inc.hlsl">
<Filter>src\Shaders</Filter>
</None>
<None Include="src\Shaders\Particles.hlsl">
<Filter>src\Shaders</Filter>
</None>
<None Include="src\Shaders\Particles.inc.hlsl">
<Filter>src\Shaders</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Natvis Include="src\ThirdParty\pugixml-1.10\pugixml.natvis">
@ -1288,12 +1312,4 @@
<Filter>src\ThirdParty\imgui</Filter>
</Natvis>
</ItemGroup>
<ItemGroup>
<FxCompile Include="src\Shaders\DS_Forest.hlsl">
<Filter>src\Shaders</Filter>
</FxCompile>
<FxCompile Include="src\Shaders\DS_Forest.inc.hlsl">
<Filter>src\Shaders</Filter>
</FxCompile>
</ItemGroup>
</Project>

View File

@ -276,7 +276,7 @@ void StreamPlayer::ThreadProc()
{
D::Log::I().Write(e.what(), e.GetThreadID(), e.GetFile(), e.GetLine(), D::Log::Severity::error);
}
catch (const std::exception & e)
catch (const std::exception& e)
{
VERUS_LOG_ERROR(e.what());
}
@ -338,3 +338,8 @@ void StreamPlayer::Mute()
{
_fade.Set(0, 0);
}
void StreamPlayer::SetGain(float gain)
{
_gain = gain;
}

View File

@ -75,6 +75,7 @@ namespace verus
void FadeIn(float time);
void FadeOut(float time);
void Mute();
void SetGain(float gain);
};
VERUS_TYPEDEFS(StreamPlayer);
}

View File

@ -40,7 +40,7 @@ namespace verus
virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout,
Range<int> mipLevels, int arrayLayer = 0) = 0;
virtual void Draw(int vertexCount, int instanceCount, int firstVertex = 0, int firstInstance = 0) = 0;
virtual void Draw(int vertexCount, int instanceCount = 1, int firstVertex = 0, int firstInstance = 0) = 0;
virtual void DrawIndexed(int indexCount, int instanceCount = 1, int firstIndex = 0, int vertexOffset = 0, int firstInstance = 0) = 0;
virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ = 1) = 0;

View File

@ -8,7 +8,8 @@ namespace verus
struct GeometryDesc
{
PcVertexInputAttrDesc _pVertexInputAttrDesc;
CSZ _name = nullptr;
PcVertexInputAttrDesc _pVertexInputAttrDesc = nullptr;
const int* _pStrides = nullptr;
UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false;
@ -18,6 +19,7 @@ namespace verus
class BaseGeometry : public Object, public Scheduled
{
protected:
String _name;
UINT32 _instBindingsMask = 0;
UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false;
@ -30,10 +32,10 @@ namespace verus
virtual void Done() = 0;
virtual void CreateVertexBuffer(int count, int binding) = 0;
virtual void UpdateVertexBuffer(const void* p, int binding, BaseCommandBuffer* pCB = nullptr) = 0;
virtual void UpdateVertexBuffer(const void* p, int binding, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
virtual void CreateIndexBuffer(int count) = 0;
virtual void UpdateIndexBuffer(const void* p, BaseCommandBuffer* pCB = nullptr) = 0;
virtual void UpdateIndexBuffer(const void* p, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
static int GetVertexInputAttrDescCount(PcVertexInputAttrDesc p);
static int GetBindingCount(PcVertexInputAttrDesc p);

View File

@ -33,8 +33,9 @@ namespace verus
};
protected:
String _sourceName;
CSZ* _ignoreList = nullptr;
bool _saveCompiled = false;
bool _saveCompiled = false;
BaseShader() = default;
virtual ~BaseShader() = default;
@ -63,6 +64,8 @@ namespace verus
virtual void BeginBindDescriptors() = 0;
virtual void EndBindDescriptors() = 0;
Str GetSourceName() const { return _C(_sourceName); }
void SetIgnoreList(CSZ* list) { _ignoreList = list; }
bool IsInIgnoreList(CSZ name) const;

View File

@ -43,6 +43,7 @@ namespace verus
Vector4 _clearValue = Vector4(0);
PcSamplerDesc _pSamplerDesc = nullptr;
CSZ _name = nullptr;
CSZ _url = nullptr;
CSZ* _urls = nullptr;
Format _format = Format::unormR8G8B8A8;

View File

@ -25,6 +25,7 @@ void DebugDraw::Init()
_shader->CreatePipelineLayout();
GeometryDesc geoDesc;
geoDesc._name = "DebugDraw.Geo";
const VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, _pos), ViaType::floats, 3, ViaUsage::position, 0},

View File

@ -183,6 +183,7 @@ void DeferredShading::InitGBuffers(int w, int h)
// GB0:
texDesc._clearValue = Vector4(0);
texDesc._name = "DeferredShading.GBuffer0";
texDesc._format = Format::srgbR8G8B8A8;
texDesc._width = w;
texDesc._height = h;
@ -191,6 +192,7 @@ void DeferredShading::InitGBuffers(int w, int h)
// GB1:
texDesc._clearValue = Vector4(0);
texDesc._name = "DeferredShading.GBuffer1";
texDesc._format = Format::unormR10G10B10A2;
texDesc._width = w;
texDesc._height = h;
@ -199,6 +201,7 @@ void DeferredShading::InitGBuffers(int w, int h)
// GB2:
texDesc._clearValue = Vector4(0);
texDesc._name = "DeferredShading.GBuffer2";
texDesc._format = Format::unormR8G8B8A8;
texDesc._width = w;
texDesc._height = h;
@ -316,9 +319,13 @@ void DeferredShading::OnSwapChainResized(bool init, bool done)
texDesc._width = renderer.GetSwapChainWidth();
texDesc._height = renderer.GetSwapChainHeight();
texDesc._flags = TextureDesc::Flags::colorAttachment;
texDesc._name = "DeferredShading.LightAccDiff";
_tex[TEX_LIGHT_ACC_DIFF].Init(texDesc);
texDesc._name = "DeferredShading.LightAccSpec";
_tex[TEX_LIGHT_ACC_SPEC].Init(texDesc);
texDesc._name = "DeferredShading.ComposedA";
_tex[TEX_COMPOSED_A].Init(texDesc);
texDesc._name = "DeferredShading.ComposedB";
_tex[TEX_COMPOSED_B].Init(texDesc);
_fbh = renderer->CreateFramebuffer(_rph,
@ -577,7 +584,7 @@ void DeferredShading::EndAmbientOcclusion()
renderer.GetCommandBuffer()->EndRenderPass();
}
void DeferredShading::BeginCompose()
void DeferredShading::BeginCompose(RcVector4 bgColor)
{
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
@ -593,6 +600,7 @@ void DeferredShading::BeginCompose()
s_ubComposeFS._matInvV = sm.GetCamera()->GetMatrixVi().UniformBufferFormat();
s_ubComposeFS._matInvVP = matInvVP.UniformBufferFormat();
s_ubComposeFS._ambientColor_exposure = float4(atmo.GetAmbientColor().GLM(), renderer.GetExposure());
s_ubComposeFS._backgroundColor = bgColor.GLM();
s_ubComposeFS._fogColor = Vector4(atmo.GetFogColor(), atmo.GetFogDensity()).GLM();
s_ubComposeFS._zNearFarEx = sm.GetCamera()->GetZNearFarEx().GLM();
s_ubComposeFS._waterDiffColorShallow = float4(water.GetDiffuseColorShallow().GLM(), water.GetFogDensity());
@ -630,7 +638,7 @@ void DeferredShading::EndCompose()
renderer.GetCommandBuffer()->EndRenderPass();
}
void DeferredShading::ToneMapping(RcVector4 bgColor)
void DeferredShading::ToneMapping()
{
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
@ -642,7 +650,6 @@ void DeferredShading::ToneMapping(RcVector4 bgColor)
s_ubComposeVS._matV = Math::ToUVMatrix().UniformBufferFormat();
s_ubComposeFS._matInvV = sm.GetCamera()->GetMatrixVi().UniformBufferFormat();
s_ubComposeFS._ambientColor_exposure = float4(atmo.GetAmbientColor().GLM(), renderer.GetExposure());
s_ubComposeFS._backgroundColor = bgColor.GLM();
s_ubComposeFS._fogColor = Vector4(0.5f, 0.5f, 0.5f, 0.002f).GLM();
s_ubComposeFS._zNearFarEx = sm.GetCamera()->GetZNearFarEx().GLM();

View File

@ -123,9 +123,9 @@ namespace verus
void EndLightingPass();
void BeginAmbientOcclusion();
void EndAmbientOcclusion();
void BeginCompose();
void BeginCompose(RcVector4 bgColor = Vector4(0));
void EndCompose();
void ToneMapping(RcVector4 bgColor = Vector4(0));
void ToneMapping();
static bool IsLightUrl(CSZ url);
void OnNewLightType(CommandBufferPtr cb, LightType type, bool wireframe = false);

View File

@ -97,6 +97,7 @@ void Renderer::Init(PRendererDelegate pDelegate)
{});
GeometryDesc geoDesc;
geoDesc._name = "Renderer.Geo";
const VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, _pos), ViaType::floats, 2, ViaUsage::position, 0},
@ -175,6 +176,7 @@ void Renderer::Done()
_geoQuad.Done();
_commandBuffer.Done();
Effects::Particles::DoneStatic();
Scene::Forest::DoneStatic();
Scene::Grass::DoneStatic();
Scene::Terrain::DoneStatic();
@ -277,6 +279,7 @@ void Renderer::OnSwapChainResized(bool init, bool done)
TextureDesc texDesc;
if (settings._screenOffscreenDraw)
{
texDesc._name = "Renderer.OffscreenColor";
texDesc._format = Format::srgbB8G8R8A8;
texDesc._width = _swapChainWidth;
texDesc._height = _swapChainHeight;
@ -287,6 +290,7 @@ void Renderer::OnSwapChainResized(bool init, bool done)
}
texDesc.Reset();
texDesc._clearValue = Vector4(1);
texDesc._name = "Renderer.DepthStencil";
texDesc._format = Format::unormD24uintS8;
texDesc._width = _swapChainWidth;
texDesc._height = _swapChainHeight;
@ -315,7 +319,7 @@ void Renderer::DrawQuad(PBaseCommandBuffer pCB)
if (!pCB)
pCB = _commandBuffer.Get();
pCB->BindVertexBuffers(_geoQuad);
pCB->Draw(4, 1);
pCB->Draw(4);
}
void Renderer::DrawOffscreenColor(PBaseCommandBuffer pCB, bool endRenderPass)
@ -339,7 +343,7 @@ void Renderer::DrawOffscreenColor(PBaseCommandBuffer pCB, bool endRenderPass)
pCB->BindDescriptors(_shader[SHADER_QUAD], 0);
pCB->BindDescriptors(_shader[SHADER_QUAD], 1, _cshOffscreenColor);
_shader[SHADER_QUAD]->EndBindDescriptors();
pCB->Draw(4, 1);
pCB->Draw(4);
if (endRenderPass)
pCB->EndRenderPass();

View File

@ -78,6 +78,7 @@ void Bloom::OnSwapChainResized()
const int w = renderer.GetSwapChainWidth() / 2;
const int h = renderer.GetSwapChainHeight() / 2;
CGI::TextureDesc texDesc;
texDesc._name = "Bloom.Pong";
texDesc._format = CGI::Format::srgbR8G8B8A8;
texDesc._width = w;
texDesc._height = h;
@ -113,7 +114,7 @@ void Bloom::Generate()
s_ubBloomGodRaysFS._splitRanges = atmo.GetShadowMap().GetSplitRanges().GLM();
s_ubBloomGodRaysFS._dirToSun = float4(atmo.GetDirToSun().GLM(), 0);
s_ubBloomGodRaysFS._sunColor = float4(atmo.GetSunColor().GLM(), 0);
s_ubBloomGodRaysFS._eyePos = float4(atmo.GetEyePosition().GLM(), 0);
s_ubBloomGodRaysFS._eyePos = float4(sm.GetMainCamera()->GetEyePosition().GLM(), 0);
cb->PipelineImageMemoryBarrier(renderer.GetTexDepthStencil(), CGI::ImageLayout::depthStencilAttachment, CGI::ImageLayout::depthStencilReadOnly, 0);
cb->BeginRenderPass(_rph, _fbh, { _tex[TEX_PING]->GetClearValue() });

View File

@ -136,6 +136,7 @@ void Blur::OnSwapChainResized()
const int swapChainHalfHeight = renderer.GetSwapChainHeight() / 2;
CGI::TextureDesc texDesc;
texDesc._name = "Blur.Tex";
texDesc._format = CGI::Format::srgbR8G8B8A8;
texDesc._width = swapChainWidth;
texDesc._height = swapChainHeight;

View File

@ -3,6 +3,7 @@
#include "Blur.h"
#include "Bloom.h"
#include "Ssao.h"
#include "Particles.h"
namespace verus
{

View File

@ -0,0 +1,753 @@
#include "verus.h"
using namespace verus;
using namespace verus::Effects;
CGI::ShaderPwn Particles::s_shader;
CGI::PipelinePwns<Particles::PIPE_COUNT> Particles::s_pipe;
Particles::UB_ParticlesVS Particles::s_ubParticlesVS;
Particles::UB_ParticlesFS Particles::s_ubParticlesFS;
Particles::Particles()
{
VERUS_CT_ASSERT(32 == sizeof(Vertex));
}
Particles::~Particles()
{
Done();
}
void Particles::InitStatic()
{
s_shader.Init("[Shaders]:Particles.hlsl");
s_shader->CreateDescriptorSet(0, &s_ubParticlesVS, sizeof(s_ubParticlesVS), 100, {}, CGI::ShaderStageFlags::vs);
s_shader->CreateDescriptorSet(1, &s_ubParticlesFS, sizeof(s_ubParticlesFS), 100,
{
CGI::Sampler::aniso
}, CGI::ShaderStageFlags::fs);
s_shader->CreatePipelineLayout();
}
void Particles::DoneStatic()
{
s_pipe.Done();
s_shader.Done();
}
void Particles::Init(CSZ url)
{
VERUS_INIT();
VERUS_QREF_RENDERER;
_url = url;
Vector<BYTE> vData;
IO::FileSystem::LoadResource(url, vData, IO::FileSystem::LoadDesc(true));
pugi::xml_document doc;
const pugi::xml_parse_result result = doc.load_buffer_inplace(vData.data(), vData.size());
if (!result)
throw VERUS_RECOVERABLE << "load_buffer_inplace(), " << result.description();
pugi::xml_node root = doc.first_child();
_capacity = root.child("capacity").text().as_int();
if (auto node = root.child("type"))
{
Str type = node.text().as_string();
if (type == "none") _billboardType = BillboardType::none;
else if (type == "screen-vplane") _billboardType = BillboardType::screenViewplaneOriented;
else if (type == "screen-vpoint") _billboardType = BillboardType::screenViewpointOriented;
else if (type == "world-vplane") _billboardType = BillboardType::worldViewplaneOriented;
else if (type == "world-vpoint") _billboardType = BillboardType::worldViewpointOriented;
else if (type == "axial") _billboardType = BillboardType::axial;
else
{
VERUS_RT_FAIL("Invalid particle type.");
}
}
if (auto node = root.child("texture"))
_tex.Init(node.text().as_string());
if (auto node = root.child("tilesetSize"))
{
_tilesetX = node.attribute("x").as_int(_tilesetX);
_tilesetY = node.attribute("y").as_int(_tilesetY);
_tilesetSize = Vector4(
static_cast<float>(_tilesetX),
static_cast<float>(_tilesetY),
1.f / _tilesetX,
1.f / _tilesetY);
}
if (auto node = root.child("lifeTime"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetLifeTime(mn, mx);
}
if (auto node = root.child("speed"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetSpeed(mn, mx);
}
if (auto node = root.child("beginAdditive"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetBeginAdditive(mn, mx);
}
if (auto node = root.child("endAdditive"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetEndAdditive(mn, mx);
}
if (auto node = root.child("beginColor"))
{
Vector4 mn, mx;
mn.FromColorString(node.attribute("min").as_string());
mx.FromColorString(node.attribute("max").as_string());
SetBeginColor(mn, mx);
}
if (auto node = root.child("endColor"))
{
Vector4 mn, mx;
mn.FromColorString(node.attribute("min").as_string());
mx.FromColorString(node.attribute("max").as_string());
SetEndColor(mn, mx);
}
if (auto node = root.child("beginSize"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetBeginSize(mn, mx);
}
if (auto node = root.child("endSize"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetEndSize(mn, mx);
}
if (auto node = root.child("beginSpin"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetBeginSpin(mn, mx);
}
if (auto node = root.child("endSpin"))
{
const float mn = node.attribute("min").as_float();
const float mx = node.attribute("max").as_float();
SetEndSpin(mn, mx);
}
_brightness = root.child("brightness").text().as_float(_brightness);
_bounceStrength = root.child("bounce").text().as_float(_bounceStrength);
_gravityStrength = root.child("gravity").text().as_float(_gravityStrength);
_windStrength = root.child("wind").text().as_float(_windStrength);
_collide = root.child("collide").text().as_bool(_collide);
_decal = root.child("decal").text().as_bool(_decal);
_particlesPerSecond = root.child("particlesPerSecond").text().as_float(_particlesPerSecond);
_zone = root.child("zone").text().as_float(_zone);
_vParticles.resize(_capacity);
if (BillboardType::none == _billboardType) // Use point sprites?
{
_vVB.resize(_capacity);
CGI::GeometryDesc geoDesc;
geoDesc._name = "Particles.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, pos), /**/CGI::ViaType::floats, 4, CGI::ViaUsage::position, 0},
{0, offsetof(Vertex, tc0), /**/CGI::ViaType::floats, 2, CGI::ViaUsage::texCoord, 0},
{0, offsetof(Vertex, color), /**/CGI::ViaType::ubytes, 4, CGI::ViaUsage::color, 0},
{0, offsetof(Vertex, psize), /**/CGI::ViaType::floats, 1, CGI::ViaUsage::psize, 0},
CGI::VertexInputAttrDesc::End()
};
geoDesc._pVertexInputAttrDesc = viaDesc;
const int strides[] = { sizeof(Vertex), 0 };
geoDesc._pStrides = strides;
geoDesc._dynBindingsMask = 0x1;
_geo.Init(geoDesc);
_geo->CreateVertexBuffer(_capacity, 0);
if (!s_pipe[PIPE_MAIN])
{
CGI::PipelineDesc pipeDesc(_geo, s_shader, "#", renderer.GetDS().GetRenderPassHandle_ExtraCompose());
pipeDesc._colorAttachBlendEqs[0] = VERUS_COLOR_BLEND_PA;
pipeDesc._topology = CGI::PrimitiveTopology::pointList;
pipeDesc._depthWriteEnable = false;
s_pipe[PIPE_MAIN].Init(pipeDesc);
}
}
else // Use billboards?
{
_capacity = Math::Min(_capacity * 4, 65536) / 4;
_vVB.resize(_capacity * 4); // Each sprite has 4 vertices.
_indexCount = _capacity * 6;
_vIB.resize(_indexCount);
CGI::GeometryDesc geoDesc;
geoDesc._name = "Particles.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, pos), /**/CGI::ViaType::floats, 4, CGI::ViaUsage::position, 0},
{0, offsetof(Vertex, tc0), /**/CGI::ViaType::floats, 2, CGI::ViaUsage::texCoord, 0},
{0, offsetof(Vertex, color), /**/CGI::ViaType::ubytes, 4, CGI::ViaUsage::color, 0},
{0, offsetof(Vertex, psize), /**/CGI::ViaType::floats, 1, CGI::ViaUsage::psize, 0},
CGI::VertexInputAttrDesc::End()
};
geoDesc._pVertexInputAttrDesc = viaDesc;
const int strides[] = { sizeof(Vertex), 0 };
geoDesc._pStrides = strides;
geoDesc._dynBindingsMask = 0x1 | (1 << 31);
_geo.Init(geoDesc);
_geo->CreateVertexBuffer(_capacity * 4, 0);
_geo->CreateIndexBuffer(_indexCount);
if (!s_pipe[PIPE_BILLBOARDS])
{
CGI::PipelineDesc pipeDesc(_geo, s_shader, "#Billboards", renderer.GetDS().GetRenderPassHandle_ExtraCompose());
pipeDesc._colorAttachBlendEqs[0] = VERUS_COLOR_BLEND_PA;
pipeDesc._depthWriteEnable = false;
s_pipe[PIPE_BILLBOARDS].Init(pipeDesc);
}
}
_ratio = static_cast<float>(_tilesetY) / static_cast<float>(_tilesetX);
}
void Particles::Done()
{
VERUS_DONE(Particles);
}
void Particles::Update()
{
VERUS_UPDATE_ONCE_CHECK;
_drawCount = 0;
if (!_csh.IsSet())
{
if (_tex->IsLoaded())
_csh = s_shader->BindDescriptorSetTextures(1, { _tex });
else
return;
}
VERUS_QREF_TIMER;
Vector3 wind = Vector3(0);
if (Scene::Atmosphere::IsValidSingleton())
{
VERUS_QREF_ATMO;
wind = atmo.GetWindVelocity();
}
if (BillboardType::none == _billboardType)
{
VERUS_FOR(i, _capacity)
{
if (_vParticles[i]._timeLeft >= 0)
{
_vParticles[i]._timeLeft -= dt;
if (_vParticles[i]._timeLeft < 0)
{
_vParticles[i]._timeLeft = -1;
continue;
}
if (_pDelegate)
{
Vector3 up, normal;
Transform3 matrix;
_pDelegate->Particles_OnUpdate(*this, i, _vParticles[i], up, normal, matrix);
}
else
{
Point3 hitPoint;
Vector3 hitNormal;
TimeCorrectedVerletIntegration(_vParticles[i], hitPoint, hitNormal);
const float t = glm::quadraticEaseInOut(1 - _vParticles[i]._timeLeft * _vParticles[i]._invTotalTime);
const Vector4 color = VMath::lerp(t, _vParticles[i]._beginColor, _vParticles[i]._endColor);
const float size = Math::Lerp(_vParticles[i]._beginSize, _vParticles[i]._endSize, t);
const float additive = Math::Lerp(_vParticles[i]._beginAdditive, _vParticles[i]._endAdditive, t);
PushPointSprite(i, color, size, additive);
}
}
}
if (_drawCount)
_geo->UpdateVertexBuffer(_vVB.data(), 0, nullptr, _drawCount);
}
else // Billboards:
{
VERUS_QREF_SM;
Scene::PCamera pCam = sm.GetCamera();
Vector3 normal = pCam->GetFrontDirection();
Vector3 up(0, 1, 0);
switch (_billboardType)
{
case BillboardType::screenViewplaneOriented:
case BillboardType::screenViewpointOriented:
{
up = pCam->GetUpDirection();
}
break;
case BillboardType::worldViewplaneOriented:
case BillboardType::worldViewpointOriented:
{
up = Vector3(0, 1, 0);
const Vector3 right = VMath::cross(up, normal);
normal = VMath::normalizeApprox(VMath::cross(right, up));
}
break;
}
Matrix3 matAim3;
matAim3.AimZ(normal, &up);
Transform3 matAim(matAim3, Vector3(0));
VERUS_FOR(i, _capacity)
{
if (_vParticles[i]._timeLeft >= 0)
{
_vParticles[i]._timeLeft -= dt;
if (_vParticles[i]._timeLeft < 0)
{
_vParticles[i]._timeLeft = -1;
continue;
}
if (_pDelegate)
{
_pDelegate->Particles_OnUpdate(*this, i, _vParticles[i], up, normal, matAim);
}
else
{
if (!_decal)
{
Point3 hitPoint;
Vector3 hitNormal;
TimeCorrectedVerletIntegration(_vParticles[i], hitPoint, hitNormal);
}
const float t = glm::quadraticEaseInOut(1 - _vParticles[i]._timeLeft * _vParticles[i]._invTotalTime);
const Vector4 color = VMath::lerp(t, _vParticles[i]._beginColor, _vParticles[i]._endColor);
const float size = Math::Lerp(_vParticles[i]._beginSize, _vParticles[i]._endSize, t);
const float spin = Math::Lerp(_vParticles[i]._beginSpin, _vParticles[i]._endSpin, t);
const float additive = Math::Lerp(_vParticles[i]._beginAdditive, _vParticles[i]._endAdditive, t);
if (BillboardType::axial == _billboardType && _decal)
normal = _vParticles[i]._velocity;
const Transform3 matW = GetBillboardMatrix(i, size, spin, up, normal, matAim);
PushBillboard(i, color, matW, additive);
}
}
}
if (_drawCount)
{
_geo->UpdateVertexBuffer(_vVB.data(), 0, nullptr, _drawCount * 4);
_geo->UpdateIndexBuffer(_vIB.data(), nullptr, _drawCount * 6);
}
}
}
void Particles::Draw()
{
VERUS_UPDATE_ONCE_CHECK_DRAW;
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
if (!_drawCount)
return;
auto cb = renderer.GetCommandBuffer();
s_ubParticlesVS._matP = sm.GetCamera()->GetMatrixP().UniformBufferFormat();
s_ubParticlesVS._matWVP = sm.GetCamera()->GetMatrixVP().UniformBufferFormat();
s_ubParticlesVS._viewportSize = cb->GetViewportSize().GLM();
s_ubParticlesVS._brightness.x = _brightness;
s_ubParticlesFS._tilesetSize = _tilesetSize.GLM();
switch (_billboardType)
{
case BillboardType::none:
cb->BindPipeline(s_pipe[PIPE_MAIN]);
break;
default:
cb->BindPipeline(s_pipe[PIPE_BILLBOARDS]);
}
cb->BindVertexBuffers(_geo);
if (BillboardType::none != _billboardType)
cb->BindIndexBuffer(_geo);
s_shader->BeginBindDescriptors();
cb->BindDescriptors(s_shader, 0);
cb->BindDescriptors(s_shader, 1, _csh);
if (BillboardType::none == _billboardType)
cb->Draw(_drawCount);
else
cb->DrawIndexed(_drawCount * 6);
s_shader->EndBindDescriptors();
}
void Particles::GetLifeTime(float& mn, float& mx) const
{
mn = _lifeTimeRange.getX();
mx = _lifeTimeRange.getY();
}
void Particles::SetLifeTime(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_lifeTimeRange = Vector3(mn, mx, mx - mn);
}
void Particles::GetSpeed(float& mn, float& mx) const
{
mn = _speedRange.getX();
mx = _speedRange.getY();
}
void Particles::SetSpeed(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_speedRange = Vector3(mn, mx, mx - mn);
}
void Particles::GetBeginAdditive(float& mn, float& mx) const
{
mn = _beginAdditiveRange.getX();
mx = _beginAdditiveRange.getY();
}
void Particles::SetBeginAdditive(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_beginAdditiveRange = Vector3(mn, mx, mx - mn);
}
void Particles::GetBeginColor(RVector4 mn, RVector4 mx) const
{
mn = _beginColorMin;
mx = _beginColorMin + _beginColorDelta;
}
void Particles::SetBeginColor(RcVector4 mn, RcVector4 mx)
{
_beginColorMin = mn;
_beginColorDelta = mx - mn;
}
void Particles::GetEndColor(RVector4 mn, RVector4 mx) const
{
mn = _endColorMin;
mx = _endColorMin + _endColorDelta;
}
void Particles::SetEndColor(RcVector4 mn, RcVector4 mx)
{
_endColorMin = mn;
_endColorDelta = mx - mn;
}
void Particles::GetEndAdditive(float& mn, float& mx) const
{
mn = _endAdditiveRange.getX();
mx = _endAdditiveRange.getY();
}
void Particles::SetEndAdditive(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_endAdditiveRange = Vector3(mn, mx, mx - mn);
}
void Particles::GetBeginSize(float& mn, float& mx) const
{
mn = _beginSizeRange.getX();
mx = _beginSizeRange.getY();
}
void Particles::SetBeginSize(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_beginSizeRange = Vector3(mn, mx, mx - mn);
}
void Particles::GetEndSize(float& mn, float& mx) const
{
mn = _endSizeRange.getX();
mx = _endSizeRange.getY();
}
void Particles::SetEndSize(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_endSizeRange = Vector3(mn, mx, mx - mn);
}
void Particles::GetBeginSpin(float& mn, float& mx) const
{
mn = _beginSpinRange.getX();
mx = _beginSpinRange.getY();
}
void Particles::SetBeginSpin(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_beginSpinRange = Vector3(mn, mx, mx - mn);
}
void Particles::GetEndSpin(float& mn, float& mx) const
{
mn = _endSpinRange.getX();
mx = _endSpinRange.getY();
}
void Particles::SetEndSpin(float mn, float mx)
{
VERUS_RT_ASSERT(mx <= mx);
_endSpinRange = Vector3(mn, mx, mx - mn);
}
int Particles::Add(RcPoint3 pos, RcVector3 dir, float scale, PcVector4 pUserColor, void* pUser)
{
VERUS_QREF_UTILS;
VERUS_QREF_TIMER;
Vector3 wind = Vector3(0);
if (Scene::Atmosphere::IsValidSingleton())
{
VERUS_QREF_ATMO;
wind = atmo.GetWindVelocity();
}
const Vector3 accel = _gravity * _gravityStrength + wind * _windStrength;
RRandom random = utils.GetRandom();
RParticle particle = _vParticles[_addAt];
particle._pUser = pUser;
const int index = _addAt;
const int tilesetX = random.Next() % _tilesetX;
const int tilesetY = random.Next() % _tilesetY;
const float lifeTime = scale * (_lifeTimeRange.getX() + _lifeTimeRange.getZ() * random.NextFloat());
if (_decal)
{
particle._position = pos;
particle._prevPosition = pos;
particle._velocity = dir;
}
else
{
const float zone = (_pUserZone ? *_pUserZone : _zone) * scale;
const Point3 posZone = pos + ((zone > 0) ? Vector3(glm::ballRand(zone)) : Vector3(0));
particle._position = posZone;
particle._velocity = dir * (scale * (_speedRange.getX() + _speedRange.getZ() * random.NextFloat()));
particle._prevPosition = posZone - particle._velocity * dt - accel * (0.5f * timer.GetDeltaTimeSq());
}
particle._tcOffset = Vector4(tilesetX * _tilesetSize.getZ(), tilesetY * _tilesetSize.getW());
particle._invTotalTime = 1 / lifeTime;
particle._timeLeft = lifeTime;
particle._beginAdditive = _beginAdditiveRange.getX() + _beginAdditiveRange.getZ() * random.NextFloat();
particle._endAdditive = _endAdditiveRange.getX() + _endAdditiveRange.getZ() * random.NextFloat();
particle._beginColor = _beginColorMin + _beginColorDelta * random.NextFloat();
particle._endColor = _endColorMin + _endColorDelta * random.NextFloat();
if (pUserColor)
{
particle._beginColor = VMath::mulPerElem(particle._beginColor, *pUserColor);
particle._endColor = VMath::mulPerElem(particle._endColor, *pUserColor);
}
particle._beginSize = scale * (_beginSizeRange.getX() + _beginSizeRange.getZ() * random.NextFloat());
particle._endSize = scale * (_endSizeRange.getX() + _endSizeRange.getZ() * random.NextFloat());
particle._beginSpin = scale * (_beginSpinRange.getX() + _beginSpinRange.getZ() * random.NextFloat());
particle._endSpin = scale * (_endSpinRange.getX() + _endSpinRange.getZ() * random.NextFloat());
if (_decal)
particle._endSpin = particle._beginSpin;
_addAt++;
_addAt %= _capacity;
return index;
}
void Particles::AddFlow(RcPoint3 pos, RcVector3 dirOffset, float scale, PcVector4 pUserColor, float* pUserFlowRemainder, float intensity)
{
if (!_flowEnabled)
return;
VERUS_QREF_TIMER;
float& flowRemainder = pUserFlowRemainder ? *pUserFlowRemainder : _flowRemainder;
flowRemainder += _particlesPerSecond * dt * intensity;
int count = static_cast<int>(flowRemainder);
if (count)
flowRemainder = fmod(flowRemainder, 1.f);
VERUS_FOR(i, count)
{
const Vector3 dir = VMath::normalizeApprox(Vector3(glm::ballRand(1.f)) + dirOffset);
Add(pos, dir, scale, pUserColor);
}
}
bool Particles::TimeCorrectedVerletIntegration(RParticle particle, RPoint3 point, RVector3 normal)
{
VERUS_QREF_TIMER;
bool hit = false;
Vector3 wind = Vector3(0);
if (Scene::Atmosphere::IsValidSingleton())
{
VERUS_QREF_ATMO;
wind = atmo.GetWindVelocity();
}
const Vector3 accel = _gravity * _gravityStrength + wind * _windStrength;
const Point3 posCurrent = particle._position;
particle._position += (posCurrent - particle._prevPosition) * timer.GetVerletValue() + accel * timer.GetDeltaTimeSq();
particle._prevPosition = posCurrent;
particle._velocity = (particle._position - posCurrent) * timer.GetDeltaTimeInv();
if (_collide)
{
VERUS_QREF_SM;
if (sm.RayCastingTest(particle._prevPosition, particle._position, nullptr, &point, &normal))
{
hit = true;
particle._velocity = particle._velocity.Reflect(normal) * _bounceStrength;
particle._prevPosition = point;
particle._position = point + particle._velocity * timer.GetDeltaTime();
}
}
if (BillboardType::axial == _billboardType && !_decal)
particle._axis = VMath::normalizeApprox(particle._velocity);
return hit;
}
bool Particles::EulerIntegration(RParticle particle, RPoint3 point, RVector3 normal)
{
return false;
}
void Particles::PushPointSprite(int index, RcVector4 color, float size, float additive)
{
_vVB[_drawCount].pos.x = _vParticles[index]._position.getX();
_vVB[_drawCount].pos.y = _vParticles[index]._position.getY();
_vVB[_drawCount].pos.z = _vParticles[index]._position.getZ();
_vVB[_drawCount].pos.w = additive;
_vVB[_drawCount].tc0.x = _vParticles[index]._tcOffset.getX();
_vVB[_drawCount].tc0.y = _vParticles[index]._tcOffset.getY();
_vVB[_drawCount].color = color.ToColor();
_vVB[_drawCount].psize = size;
_drawCount++;
}
void Particles::PushBillboard(int index, RcVector4 color, RcTransform3 matW, float additive)
{
Point3 pos[4] =
{
Point3(+0.5f, +0.5f),
Point3(-0.5f, +0.5f),
Point3(-0.5f, -0.5f),
Point3(+0.5f, -0.5f)
};
static const Vector4 tc[4] =
{
Vector4(1, 0),
Vector4(0, 0),
Vector4(0, 1),
Vector4(1, 1)
};
VERUS_FOR(i, 4)
pos[i] = matW * pos[i];
const int vertexOffset = _drawCount << 2;
VERUS_FOR(i, 4)
{
RVertex vertex = _vVB[vertexOffset + i];
vertex.pos.x = pos[i].getX();
vertex.pos.y = pos[i].getY();
vertex.pos.z = pos[i].getZ();
vertex.pos.w = additive;
vertex.tc0[0] = tc[i].getX() * _tilesetSize.getZ() + _vParticles[index]._tcOffset.getX();
vertex.tc0[1] = tc[i].getY() * _tilesetSize.getW() + _vParticles[index]._tcOffset.getY();
vertex.color = color.ToColor();
vertex.psize = 1;
}
const int indexOffset = _drawCount * 6;
_vIB[indexOffset + 0] = vertexOffset + 0;
_vIB[indexOffset + 1] = vertexOffset + 2;
_vIB[indexOffset + 2] = vertexOffset + 1;
_vIB[indexOffset + 3] = vertexOffset + 0;
_vIB[indexOffset + 4] = vertexOffset + 3;
_vIB[indexOffset + 5] = vertexOffset + 2;
_drawCount++;
}
Transform3 Particles::GetBillboardMatrix(int index, float size, float spin, RcVector3 up, RcVector3 normal, RTransform3 matAim)
{
Vector3 up2(up), normal2(normal);
switch (_billboardType)
{
case BillboardType::screenViewpointOriented:
{
}
break;
case BillboardType::worldViewpointOriented:
{
}
break;
case BillboardType::axial:
{
if (_decal)
{
Matrix3 matAim3;
matAim3.AimZ(-normal2, &up2);
matAim = Transform3(matAim3, Vector3(0));
}
else
{
up2 = _vParticles[index]._axis;
const Vector3 right = VMath::cross(up2, normal2);
normal2 = VMath::normalizeApprox(VMath::cross(right, up2));
Matrix3 matAim3;
matAim3.AimZ(normal2, &up2);
matAim = Transform3(matAim3, Vector3(0));
}
}
break;
}
return Transform3::translation(Vector3(_vParticles[index]._position)) * matAim *
Transform3(VMath::appendScale(Matrix3::rotationZ(spin), Vector3(size * _ratio, size, 0)), Vector3(0));
}

View File

@ -0,0 +1,186 @@
#pragma once
namespace verus
{
namespace Effects
{
enum class BillboardType : int
{
none,
screenViewplaneOriented,
screenViewpointOriented,
worldViewplaneOriented,
worldViewpointOriented,
axial
};
class Particle
{
public:
Point3 _position = Point3(0);
Point3 _prevPosition = Point3(0);
Vector3 _velocity = Vector3(0, 1, 0);
Vector3 _axis = Vector3(0, 1, 0);
Vector4 _tcOffset = Vector4(0);
Vector4 _beginColor = Vector4::Replicate(1);
Vector4 _endColor = Vector4::Replicate(1);
void* _pUser = nullptr;
float _invTotalTime = 0;
float _timeLeft = -1;
float _beginAdditive = 0;
float _endAdditive = 0;
float _beginSize = 0;
float _endSize = 0;
float _beginSpin = 0;
float _endSpin = 0;
};
VERUS_TYPEDEFS(Particle);
class Particles;
class ParticlesDelegate
{
public:
virtual void Particles_OnUpdate(Particles& particles, int index, RParticle particle,
RVector3 up, RVector3 normal, RTransform3 matAim) = 0;
};
VERUS_TYPEDEFS(ParticlesDelegate);
class Particles : public Object
{
#include "../Shaders/Particles.inc.hlsl"
enum PIPE
{
PIPE_MAIN,
PIPE_BILLBOARDS,
PIPE_COUNT
};
struct Vertex
{
glm::vec4 pos;
glm::vec2 tc0;
UINT32 color;
float psize;
};
VERUS_TYPEDEFS(Vertex);
static CGI::ShaderPwn s_shader;
static CGI::PipelinePwns<PIPE_COUNT> s_pipe;
static UB_ParticlesVS s_ubParticlesVS;
static UB_ParticlesFS s_ubParticlesFS;
Vector4 _tilesetSize = Vector4::Replicate(1);
Vector3 _lifeTimeRange = Vector3(0, 1, 1);
Vector3 _speedRange = Vector3(0, 1, 1);
Vector3 _beginAdditiveRange = Vector3(0);
Vector3 _endAdditiveRange = Vector3(0);
Vector4 _beginColorMin = Vector4(0);
Vector4 _beginColorDelta = Vector4(0);
Vector4 _endColorMin = Vector4(0);
Vector4 _endColorDelta = Vector4(0);
Vector3 _beginSizeRange = Vector3(0, 1, 1);
Vector3 _endSizeRange = Vector3(0, 1, 1);
Vector3 _beginSpinRange = Vector3(0, 1, 1);
Vector3 _endSpinRange = Vector3(0, 1, 1);
Vector3 _gravity = Vector3(0, -9.8f, 0);
String _url;
Vector<Particle> _vParticles;
Vector<Vertex> _vVB;
Vector<UINT16> _vIB;
CGI::GeometryPwn _geo;
CGI::TexturePwn _tex;
CGI::CSHandle _csh;
PParticlesDelegate _pDelegate = nullptr;
const float* _pUserZone = nullptr;
BillboardType _billboardType = BillboardType::none;
int _tilesetX = 0;
int _tilesetY = 0;
int _indexCount = 0;
int _capacity = 0;
int _addAt = 0;
int _drawCount = 0;
float _ratio = 1;
float _brightness = 1;
float _bounceStrength = 0.5f;
float _gravityStrength = 1;
float _windStrength = 0;
float _flowRemainder = 0;
float _particlesPerSecond = 0;
float _zone = 0;
bool _collide = false;
bool _decal = false;
bool _flowEnabled = true;
public:
Particles();
~Particles();
static void InitStatic();
static void DoneStatic();
void Init(CSZ url);
void Done();
void Update(); // Call this after adding particles!
void Draw();
Str GetUrl() const { return _C(_url); }
int GetTilesetX() const { return _tilesetX; }
int GetTilesetY() const { return _tilesetY; }
int GetCapacity() const { return _capacity; }
int GetDrawCount() const { return _drawCount; }
PParticlesDelegate SetDelegate(PParticlesDelegate p) { return Utils::Swap(_pDelegate, p); }
void SetUserZone(const float* pZone) { _pUserZone = pZone; }
void GetLifeTime(float& mn, float& mx) const;
void SetLifeTime(float mn, float mx);
void GetSpeed(float& mn, float& mx) const;
void SetSpeed(float mn, float mx);
void GetBeginAdditive(float& mn, float& mx) const;
void SetBeginAdditive(float mn, float mx);
void GetBeginColor(RVector4 mn, RVector4 mx) const;
void SetBeginColor(RcVector4 mn, RcVector4 mx);
void GetEndColor(RVector4 mn, RVector4 mx) const;
void SetEndColor(RcVector4 mn, RcVector4 mx);
void GetEndAdditive(float& mn, float& mx) const;
void SetEndAdditive(float mn, float mx);
void GetBeginSize(float& mn, float& mx) const;
void SetBeginSize(float mn, float mx);
void GetEndSize(float& mn, float& mx) const;
void SetEndSize(float mn, float mx);
void GetBeginSpin(float& mn, float& mx) const;
void SetBeginSpin(float mn, float mx);
void GetEndSpin(float& mn, float& mx) const;
void SetEndSpin(float mn, float mx);
float GetBrightness() const { return _brightness; }
void SetBrightness(float value) { _brightness = value; }
float GetBounce() const { return _bounceStrength; }
void SetBounce(float value) { _bounceStrength = value; }
float GetGravity() const { return _gravityStrength; }
void SetGravity(float value) { _gravityStrength = value; }
float GetWind() const { return _windStrength; }
void SetWind(float value) { _windStrength = value; }
float GetParticlesPerSecond() const { return _particlesPerSecond; }
void SetParticlesPerSecond(float value) { _particlesPerSecond = value; }
float GetZone() const { return _zone; }
void SetZone(float value) { _zone = value; }
int Add(RcPoint3 pos, RcVector3 dir,
float scale = 1, PcVector4 pUserColor = nullptr, void* pUser = nullptr);
void AddFlow(RcPoint3 pos, RcVector3 dirOffset,
float scale = 1, PcVector4 pUserColor = nullptr, float* pUserFlowRemainder = nullptr, float intensity = 1);
bool IsFlowEnabled() const { return _flowEnabled; }
void EnableFlow(bool b = true) { _flowEnabled = b; }
bool TimeCorrectedVerletIntegration(RParticle particle, RPoint3 point, RVector3 normal);
bool EulerIntegration(RParticle particle, RPoint3 point, RVector3 normal);
void PushPointSprite(int index, RcVector4 color, float size, float additive);
void PushBillboard(int index, RcVector4 color, RcTransform3 matW, float additive);
Transform3 GetBillboardMatrix(int index, float size, float spin, RcVector3 up, RcVector3 normal, RTransform3 matAim);
};
VERUS_TYPEDEFS(Particles);
}
}

View File

@ -40,6 +40,7 @@ void Ssao::Init()
}
CGI::TextureDesc texDesc;
texDesc._name = "Ssao.RandNormals";
texDesc._format = CGI::Format::unormR8G8B8A8;
texDesc._width = 4;
texDesc._height = 4;
@ -68,6 +69,7 @@ void Ssao::OnSwapChainResized()
}
{
CGI::TextureDesc texDesc;
texDesc._name = "Ssao.GenAO";
texDesc._format = CGI::Format::unormR8;
texDesc._width = renderer.GetSwapChainWidth();
texDesc._height = renderer.GetSwapChainHeight();

View File

@ -37,9 +37,7 @@ void Font::Init(CSZ url)
VERUS_INIT();
VERUS_QREF_RENDERER;
CGI::TextureDesc texDesc;
texDesc._url = url;
_tex.Init(texDesc);
_tex.Init(url);
String xmlUrl(url);
Str::ReplaceExtension(xmlUrl, ".xml");
@ -96,6 +94,7 @@ void Font::Init(CSZ url)
}
CGI::GeometryDesc geoDesc;
geoDesc._name = "Font.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, _x), CGI::ViaType::floats, 2, CGI::ViaUsage::position, 0},

View File

@ -27,6 +27,7 @@ void ViewManager::Init(bool hasCursor, bool canDebug)
{
CGI::TextureDesc texDesc;
texDesc._name = "ViewManager.Dummy";
texDesc._format = CGI::Format::unormR8G8B8A8;
texDesc._width = 8;
texDesc._height = 8;
@ -36,11 +37,7 @@ void ViewManager::Init(bool hasCursor, bool canDebug)
_cshDefault = _shader->BindDescriptorSetTextures(1, { _tex[TEX_DUMMY] });
if (canDebug)
{
CGI::TextureDesc texDesc;
texDesc._url = "[Textures]:UI/Debug.dds";
_tex[TEX_DEBUG].Init(texDesc);
}
_tex[TEX_DEBUG].Init("[Textures]:UI/Debug.dds");
if (hasCursor)
_cursor.Init();

View File

@ -431,4 +431,7 @@ void Convert::Test()
const Vector<BYTE> vMd5 = ToMd5(vBin);
const String md5 = ToMd5String(vBin);
VERUS_RT_ASSERT(md5 == "C84AAFD3D09E719514977BF3624F4D85");
const double someNum = fast_atof("1.097");
VERUS_RT_ASSERT(1.097 == someNum);
}

View File

@ -78,8 +78,8 @@ void EngineInit::Init(Input::PKeyMapperDelegate pKeyMapperDelegate, CGI::Rendere
}
// Static init:
//if (_makeEffects)
// Effects::CParticles::InitStatic();
if (_makeEffects)
Effects::Particles::InitStatic();
if (_makeGUI)
GUI::Font::InitStatic();
if (_makeScene)

View File

@ -49,7 +49,7 @@ namespace verus
return *it;
}
int FindIndex(TValue* p)
int FindStoredIndex(TValue* p) const
{
int index = 0;
for (const auto& x : _list)
@ -65,6 +65,28 @@ namespace verus
{
return static_cast<int>(_list.size());
}
void MoveStoredUp(int index)
{
if (index <= 0)
return;
auto it = _list.begin();
std::advance(it, index);
auto itTo = it;
itTo--;
_list.splice(itTo, _list, it);
}
void MoveStoredDown(int index)
{
if (index + 1 >= _list.size())
return;
auto it = _list.begin();
std::advance(it, index);
auto itTo = it;
itTo++;
itTo++;
_list.splice(itTo, _list, it);
}
};
template<typename TKey, typename TValue>

View File

@ -499,7 +499,7 @@ void FileSystem::SaveImage(CSZ pathname, const UINT32* p, int w, int h, bool ups
ilTexImage(w, h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, (void*)p);
Vector<BYTE> v;
v.resize(w * h * 8);
ilSaveL(type, v.data(), v.size());
ilSaveL(type, v.data(), Utils::Cast32(v.size()));
const ILuint sizeOut = ilGetLumpPos();
IO::File file;
if (file.Open(pathname, "wb"))

View File

@ -79,8 +79,8 @@ void QuadtreeIntegral::Done()
void QuadtreeIntegral::AllocNodes()
{
const int maxDepth = Math::HighestBit(_mapSide / _limit);
const int depthCount = maxDepth + 1;
_maxDepth = Math::HighestBit(_mapSide / _limit);
const int depthCount = _maxDepth + 1;
_nodeCount = 0;
VERUS_FOR(i, depthCount)
_nodeCount += (1 << i) * (1 << i);
@ -90,7 +90,6 @@ void QuadtreeIntegral::AllocNodes()
void QuadtreeIntegral::InitNodes(int currentNode, int depth)
{
RNode node = _vNodes[currentNode];
const int maxDepth = Math::HighestBit(_mapSide / _limit);
if (!currentNode)
{
node.PrepareMinMax(_mapSide / 2);
@ -127,7 +126,7 @@ void QuadtreeIntegral::InitNodes(int currentNode, int depth)
node.PrepareOffsetIJ(_mapSide >> 1);
node.PrepareBounds2D();
if (depth < maxDepth)
if (depth < _maxDepth)
{
VERUS_FOR(i, 4)
{
@ -151,8 +150,10 @@ void QuadtreeIntegral::InitNodes(int currentNode, int depth)
node.SetSphere(node.GetBounds().GetSphere());
}
void QuadtreeIntegral::TraverseVisible(int currentNode)
void QuadtreeIntegral::TraverseVisible(int currentNode, int depth)
{
VERUS_QREF_SM;
if (!currentNode)
{
_testCount = 0;
@ -161,7 +162,22 @@ void QuadtreeIntegral::TraverseVisible(int currentNode)
_testCount++;
if (Relation::outside == Scene::SceneManager::I().GetCamera()->GetFrustum().ContainsAabb(_vNodes[currentNode].GetBounds()))
bool testFrustum = true;
if (_distCoarseMode && depth + 2 >= _maxDepth)
{
RcPoint3 eyePos = sm.GetMainCamera()->GetEyePosition();
RcPoint3 nodePos = _vNodes[currentNode].GetSphere().GetCenter();
const float distSq = VMath::distSqr(eyePos, nodePos);
if (_maxDepth == depth && distSq >= 500 * 500.f)
testFrustum = false;
else if (_maxDepth == depth + 1 && distSq >= 1000 * 1000.f)
testFrustum = false;
else if (_maxDepth == depth + 2 && distSq >= 1500 * 1500.f && (currentNode & 0x1))
testFrustum = false;
}
RFrustum frustum = sm.GetCamera()->GetFrustum();
if (testFrustum && Relation::outside == frustum.ContainsAabb(_vNodes[currentNode].GetBounds()))
return;
// Yes, it is visible:
@ -170,7 +186,7 @@ void QuadtreeIntegral::TraverseVisible(int currentNode)
VERUS_FOR(i, 4)
{
const int childIndex = Node::GetChildIndex(currentNode, i);
TraverseVisible(childIndex);
TraverseVisible(childIndex, depth + 1);
}
}
else // Smallest node -> update it:

View File

@ -53,6 +53,8 @@ namespace verus
int _passedTestCount = 0;
int _limit = 0;
int _mapSide = 0;
int _maxDepth = 0;
bool _distCoarseMode = false;
public:
QuadtreeIntegral();
@ -61,12 +63,14 @@ namespace verus
void Init(int mapSide, int limit, PQuadtreeIntegralDelegate p, float fattenBy = 0.5f);
void Done();
void SetDistCoarseMode(bool b) { _distCoarseMode = b; }
void SetDelegate(PQuadtreeIntegralDelegate p) { _pDelegate = p; }
VERUS_P(void AllocNodes());
VERUS_P(void InitNodes(int currentNode = 0, int depth = 0));
void TraverseVisible(int currentNode = 0);
void TraverseVisible(int currentNode = 0, int depth = 0);
int GetTestCount() const { return _testCount; }
int GetPassedTestCount() const { return _passedTestCount; }

View File

@ -142,16 +142,18 @@ void Atmosphere::UpdateWind()
Stabilize(_wind._accel, Vector3(0), 1.1f - 0.6f * baseWindStrength);
Stabilize(_wind._velocity, _wind._baseVelocity, 2 - 0.5f * baseWindStrength);
//static bool null = false;
//if (timer.IsEventEvery(2000))
// null = !null;
//_wind._velocity = null ? Vector3(0) : Vector3(4, 0, 0);
_wind._speed = VMath::length(_wind._velocity);
if (_wind._speed >= VERUS_FLOAT_THRESHOLD)
_wind._direction = _wind._velocity / _wind._speed;
else
_wind._direction = Vector3(1, 0, 0);
const float angle = Math::Clamp<float>(_wind._speed * (1 / 80.f), 0, VERUS_PI * 0.25f);
const Vector3 axis = VMath::cross(Vector3(0, 1, 0), _wind._velocity);
if (VMath::lengthSqr(axis) >= VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
_wind._matPlantBending = Matrix3::rotation(angle, VMath::normalizeApprox(axis));
else
_wind._matPlantBending = Matrix3::identity();
}
void Atmosphere::Update()
@ -216,9 +218,9 @@ void Atmosphere::Update()
const float cloudScaleFog = 1 - 0.9f * _clouds._cloudiness * cloudinessSq;
const float cloudScaleSun = 1 - 0.999f * _clouds._cloudiness * cloudinessSq;
float color[3];
GetColor(208, color, 1); _ambientColor = Vector3::MakeFromPointer(color) * (GetMagnitude(60000, 40000, 10) * cloudScaleAmb);
GetColor(208, color, 1); _ambientColor = Vector3::MakeFromPointer(color) * (GetMagnitude(50000, 30000, 1) * cloudScaleAmb);
GetColor(100, color, 1); _fog._color = Vector3::MakeFromPointer(color) * (GetMagnitude(30000, 2000, 1) * cloudScaleFog);
GetColor(240, color, 1); _sun._color = Vector3::MakeFromPointer(color) * (GetMagnitude(85000, 20000, 1) * cloudScaleSun);
GetColor(240, color, 1); _sun._color = Vector3::MakeFromPointer(color) * (GetMagnitude(80000, 10000, 1) * cloudScaleSun);
glm::vec3 ambientColor = _ambientColor.GLM();
glm::vec3 fogColor = _fog._color.GLM();
@ -308,7 +310,7 @@ void Atmosphere::DrawSky(bool reflection)
cb->BindDescriptors(_shader, 2);
cb->BindDescriptors(_shader, 3);
_shader->EndBindDescriptors();
cb->Draw(4, 1);
cb->Draw(4);
}
// </Sun>
@ -327,7 +329,7 @@ void Atmosphere::DrawSky(bool reflection)
cb->BindDescriptors(_shader, 2);
cb->BindDescriptors(_shader, 3);
_shader->EndBindDescriptors();
cb->Draw(4, 1);
cb->Draw(4);
}
// </Moon>
@ -395,6 +397,11 @@ float Atmosphere::GetSunAlpha() const
return _sun._alpha;
}
RcMatrix3 Atmosphere::GetPlantBendingMatrix() const
{
return _wind._matPlantBending;
}
RcVector3 Atmosphere::GetBaseWindVelocity() const
{
return _wind._baseVelocity;
@ -422,7 +429,7 @@ float Atmosphere::GetWindSpeed() const
void Atmosphere::BeginShadow(int split)
{
_shadowMap.Begin(_sun._dirTo, 1, 0, split);
_shadowMap.Begin(_sun._dirTo, split);
}
void Atmosphere::EndShadow(int split)
@ -430,26 +437,10 @@ void Atmosphere::EndShadow(int split)
_shadowMap.End(split);
}
RcPoint3 Atmosphere::GetEyePosition(PVector3 pDirFront)
{
VERUS_QREF_SM;
if (_shadowMap.GetSceneCamera())
{
if (pDirFront)
*pDirFront = _shadowMap.GetSceneCamera()->GetFrontDirection();
return _shadowMap.GetSceneCamera()->GetEyePosition();
}
else
{
if (pDirFront)
*pDirFront = sm.GetCamera()->GetFrontDirection();
return sm.GetCamera()->GetEyePosition();
}
}
void Atmosphere::CreateCelestialBodyMesh()
{
CGI::GeometryDesc geoDesc;
geoDesc._name = "Atmosphere.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, _pos), CGI::ViaType::floats, 3, CGI::ViaUsage::position, 0},

View File

@ -64,6 +64,7 @@ namespace verus
struct Wind
{
Matrix3 _matPlantBending = Matrix3::identity();
Vector3 _baseVelocity = Vector3(4, 0, 0);
Vector3 _velocity = Vector3(4, 0, 0);
Vector3 _accel = Vector3(0);
@ -136,6 +137,7 @@ namespace verus
float GetSunAlpha() const;
// Wind:
RcMatrix3 GetPlantBendingMatrix() const;
RcVector3 GetBaseWindVelocity() const;
void SetBaseWindVelocity(RcVector3 v);
RcVector3 GetWindVelocity() const;
@ -147,8 +149,6 @@ namespace verus
void EndShadow(int split);
RCascadedShadowMap GetShadowMap() { return _shadowMap; }
RcPoint3 GetEyePosition(PVector3 pDirFront = nullptr);
void CreateCelestialBodyMesh();
};
VERUS_TYPEDEFS(Atmosphere);

View File

@ -3,9 +3,11 @@
using namespace verus;
using namespace verus::Scene;
CGI::ShaderPwn Forest::s_shader;
Forest::UB_ForestVS Forest::s_ubForestVS;
Forest::UB_ForestFS Forest::s_ubForestFS;
CGI::ShaderPwns<Forest::SHADER_COUNT> Forest::s_shader;
Forest::UB_ForestVS Forest::s_ubForestVS;
Forest::UB_ForestFS Forest::s_ubForestFS;
Forest::UB_SimpleForestVS Forest::s_ubSimpleForestVS;
Forest::UB_SimpleForestFS Forest::s_ubSimpleForestFS;
// Forest::Plant:
@ -28,15 +30,26 @@ Forest::~Forest()
void Forest::InitStatic()
{
s_shader.Init("[Shaders]:DS_Forest.hlsl");
s_shader->CreateDescriptorSet(0, &s_ubForestVS, sizeof(s_ubForestVS), 100, {}, CGI::ShaderStageFlags::vs_hs_ds_fs);
s_shader->CreateDescriptorSet(1, &s_ubForestFS, sizeof(s_ubForestFS), 100,
s_shader[SHADER_MAIN].Init("[Shaders]:DS_Forest.hlsl");
s_shader[SHADER_MAIN]->CreateDescriptorSet(0, &s_ubForestVS, sizeof(s_ubForestVS), 100, {}, CGI::ShaderStageFlags::vs);
s_shader[SHADER_MAIN]->CreateDescriptorSet(1, &s_ubForestFS, sizeof(s_ubForestFS), 100,
{
CGI::Sampler::aniso,
CGI::Sampler::aniso,
CGI::Sampler::aniso
CGI::Sampler::linearMipL,
CGI::Sampler::linearMipL,
CGI::Sampler::linearMipL
}, CGI::ShaderStageFlags::fs);
s_shader->CreatePipelineLayout();
s_shader[SHADER_MAIN]->CreatePipelineLayout();
s_shader[SHADER_SIMPLE].Init("[Shaders]:SimpleForest.hlsl");
s_shader[SHADER_SIMPLE]->CreateDescriptorSet(0, &s_ubSimpleForestVS, sizeof(s_ubSimpleForestVS), 100, {}, CGI::ShaderStageFlags::vs);
s_shader[SHADER_SIMPLE]->CreateDescriptorSet(1, &s_ubSimpleForestFS, sizeof(s_ubSimpleForestFS), 100,
{
CGI::Sampler::linearMipN,
CGI::Sampler::linearMipN,
CGI::Sampler::linearMipN,
CGI::Sampler::shadow
}, CGI::ShaderStageFlags::fs);
s_shader[SHADER_SIMPLE]->CreatePipelineLayout();
}
void Forest::DoneStatic()
@ -50,14 +63,7 @@ void Forest::Init(PTerrain pTerrain)
_pTerrain = pTerrain;
_octree.SetDelegate(this);
const float hf = _pTerrain->GetMapSide() * 0.5f;
Math::Bounds bounds;
bounds.Set(
Vector3(-hf, -hf, -hf),
Vector3(+hf, +hf, +hf));
const Vector3 limit(hf / 6, hf / 6, hf / 6);
_octree.Init(bounds, limit);
OnTerrainModified();
const Scatter::TypeDesc id[] =
{
@ -72,6 +78,7 @@ void Forest::Init(PTerrain pTerrain)
};
_scatter.Init(32, SCATTER_TYPE_COUNT, id, 19201);
_scatter.SetDelegate(this);
_scatter.SetMaxDist(_maxDist * 1.25f);
_vPlants.reserve(16);
_vLayerPlants.reserve(16);
@ -80,6 +87,11 @@ void Forest::Init(PTerrain pTerrain)
void Forest::Done()
{
for (auto& plant : _vPlants)
{
s_shader[SHADER_SIMPLE]->FreeDescriptorSet(plant._cshSimple);
s_shader[SHADER_MAIN]->FreeDescriptorSet(plant._csh);
}
VERUS_DONE(Forest);
}
@ -95,6 +107,10 @@ void Forest::Update()
return;
VERUS_UPDATE_ONCE_CHECK;
VERUS_QREF_TIMER;
_phaseY = glm::fract(_phaseY + dt * 0.37f);
_phaseXZ = glm::fract(_phaseXZ + dt * 1.49f);
if (!_async_initPlants)
{
_async_initPlants = true;
@ -127,7 +143,7 @@ void Forest::Update()
_maxSizeAll = plant._maxSize;
_pTerrain->FattenQuadtreeNodesBy(_maxSizeAll);
}
plant._aoSize = plant._mesh.GetBounds().GetAverageSize() * 1.7f;
plant._aoSize = plant._mesh.GetBounds().GetAverageSize() * 1.5f;
}
if (!plant._tex[0] && plant._mesh.IsLoaded() && plant._material->IsLoaded())
@ -139,12 +155,20 @@ void Forest::Update()
plant._tex[Plant::TEX_GBUFFER_1] && plant._tex[Plant::TEX_GBUFFER_1]->IsLoaded() &&
plant._tex[Plant::TEX_GBUFFER_2] && plant._tex[Plant::TEX_GBUFFER_2]->IsLoaded())
{
plant._csh = s_shader->BindDescriptorSetTextures(1,
plant._csh = s_shader[SHADER_MAIN]->BindDescriptorSetTextures(1,
{
plant._tex[Plant::TEX_GBUFFER_0],
plant._tex[Plant::TEX_GBUFFER_1],
plant._tex[Plant::TEX_GBUFFER_2]
});
VERUS_QREF_ATMO;
plant._cshSimple = s_shader[SHADER_SIMPLE]->BindDescriptorSetTextures(1,
{
plant._tex[Plant::TEX_GBUFFER_0],
plant._tex[Plant::TEX_GBUFFER_1],
plant._tex[Plant::TEX_GBUFFER_2],
atmo.GetShadowMap().GetTexture()
});
}
}
}
@ -178,11 +202,11 @@ void Forest::Update()
{
for (auto& bc : plant._vBakedChunks)
{
Math::Bounds bounds;
for (auto& s : bc._vSprites)
bounds.Include(s._pos);
bounds.FattenBy(plant.GetSize());
_octree.BindClient(Math::Octree::Client(bounds, &bc));
bc._bounds.Include(s._pos);
bc._bounds.FattenBy(plant.GetSize());
_octree.BindClient(Math::Octree::Client(bc._bounds, &bc));
bc._bounds.FattenBy(10); // For shadow map.
if (!bc._vSprites.empty())
memcpy(&vVB[vertCount], bc._vSprites.data(), bc._vSprites.size() * sizeof(Vertex));
@ -191,6 +215,7 @@ void Forest::Update()
}
CGI::GeometryDesc geoDesc;
geoDesc._name = "Forest.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, _pos), CGI::ViaType::floats, 3, CGI::ViaUsage::position, 0},
@ -204,11 +229,12 @@ void Forest::Update()
_geo->CreateVertexBuffer(vertCount, 0);
_geo->UpdateVertexBuffer(vVB.data(), 0);
VERUS_QREF_RENDERER;
VERUS_QREF_ATMO;
VERUS_QREF_RENDERER;
VERUS_QREF_WATER;
{
CGI::PipelineDesc pipeDesc(_geo, s_shader, "#", renderer.GetDS().GetRenderPassHandle());
CGI::PipelineDesc pipeDesc(_geo, s_shader[SHADER_MAIN], "#", renderer.GetDS().GetRenderPassHandle());
pipeDesc._colorAttachBlendEqs[0] = VERUS_COLOR_BLEND_OFF;
pipeDesc._colorAttachBlendEqs[1] = VERUS_COLOR_BLEND_OFF;
pipeDesc._colorAttachBlendEqs[2] = VERUS_COLOR_BLEND_OFF;
@ -216,16 +242,25 @@ void Forest::Update()
_pipe[PIPE_MAIN].Init(pipeDesc);
}
{
CGI::PipelineDesc pipeDesc(_geo, s_shader, "#Depth", atmo.GetShadowMap().GetRenderPassHandle());
CGI::PipelineDesc pipeDesc(_geo, s_shader[SHADER_MAIN], "#Depth", atmo.GetShadowMap().GetRenderPassHandle());
pipeDesc._colorAttachBlendEqs[0] = "";
pipeDesc._topology = CGI::PrimitiveTopology::pointList;
_pipe[PIPE_DEPTH].Init(pipeDesc);
}
{
CGI::PipelineDesc pipeDesc(_geo, s_shader[SHADER_SIMPLE], "#", water.GetRenderPassHandle());
pipeDesc._colorAttachBlendEqs[0] = VERUS_COLOR_BLEND_OFF;
pipeDesc._rasterizationState._cullMode = CGI::CullMode::none;
pipeDesc._topology = CGI::PrimitiveTopology::pointList;
_pipe[PIPE_REFLECTION].Init(pipeDesc);
}
}
}
UpdateCollision();
}
void Forest::Layout()
void Forest::Layout(bool reflection)
{
if (!IsInitialized())
return;
@ -239,30 +274,24 @@ void Forest::Layout()
bc._visible = false;
{
const float zFarWas = sm.GetCamera()->GetZFar();
const float zFarWas = sm.GetMainCamera()->GetZFar();
const bool drawingDepth = Scene::SceneManager::IsDrawingDepth(DrawDepth::automatic);
if (drawingDepth)
if (!reflection)
{
const int csmSplit = Atmosphere::I().GetShadowMap().GetCurrentSplit();
if (!csmSplit)
return;
sm.GetMainCamera()->SetFrustumFar(_maxDist);
Math::RQuadtreeIntegral qt = _pTerrain->GetQuadtree();
qt.SetDelegate(&_scatter);
qt.TraverseVisible();
qt.SetDelegate(_pTerrain);
}
else
sm.GetCamera()->SetFrustumFar(_maxDist);
Math::RQuadtreeIntegral qt = _pTerrain->GetQuadtree();
qt.SetDelegate(&_scatter);
qt.TraverseVisible();
qt.SetDelegate(_pTerrain);
sm.GetMainCamera()->SetFrustumFar(1000);
_octree.TraverseVisible(sm.GetMainCamera()->GetFrustum());
if (drawingDepth)
_octree.TraverseVisible(sm.GetCamera()->GetFrustum());
sm.GetCamera()->SetFrustumFar(_maxDist * 8);
if (!drawingDepth)
_octree.TraverseVisible(sm.GetCamera()->GetFrustum());
sm.GetMainCamera()->SetFrustumFar(zFarWas);
sm.GetCamera()->SetFrustumFar(zFarWas);
if (reflection)
return;
}
const float tessDistSq = _tessDist * _tessDist;
@ -293,8 +322,11 @@ void Forest::DrawModels(bool allowTess)
if (!_visibleCount)
return;
VERUS_QREF_RENDERER;
VERUS_QREF_ATMO;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_RENDERER;
const Transform3 trBending = Transform3(atmo.GetPlantBendingMatrix(), Vector3(0));
PMesh pMesh = nullptr;
MaterialPtr material;
@ -346,6 +378,8 @@ void Forest::DrawModels(bool allowTess)
pMesh->BindPipelineInstanced(cb, 1 == bindPipelineStage, true);
pMesh->UpdateUniformBufferPerFrame(1 / (_tessDist - 10));
cb->BindDescriptors(shader, 0);
pMesh->UpdateUniformBufferPerObject(trBending, Vector4(_phaseY, _phaseXZ));
cb->BindDescriptors(shader, 4);
}
else if (1 == bindPipelineStage && !nextTess)
{
@ -353,6 +387,8 @@ void Forest::DrawModels(bool allowTess)
pMesh->BindPipelineInstanced(cb, false, true);
pMesh->UpdateUniformBufferPerFrame();
cb->BindDescriptors(shader, 0);
pMesh->UpdateUniformBufferPerObject(trBending, Vector4(_phaseY, _phaseXZ));
cb->BindDescriptors(shader, 4);
}
}
tess = nextTess;
@ -371,7 +407,7 @@ void Forest::DrawModels(bool allowTess)
{
const Transform3 matW = VMath::appendScale(Transform3(drawPlant._basis * Matrix3::rotationY(drawPlant._angle),
Vector3(drawPlant._pos + drawPlant._pushBack)), Vector3::Replicate(drawPlant._scale));
pMesh->PushInstance(matW, Vector4(Vector3(drawPlant._pos), 1));
pMesh->PushInstance(matW, Vector4(Vector3(drawPlant._pos), drawPlant._windBending));
}
}
shader->EndBindDescriptors();
@ -384,7 +420,6 @@ void Forest::DrawSprites()
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
VERUS_QREF_ATMO;
const bool drawingDepth = Scene::SceneManager::IsDrawingDepth(DrawDepth::automatic);
@ -392,26 +427,26 @@ void Forest::DrawSprites()
s_ubForestVS._matP = sm.GetCamera()->GetMatrixP().UniformBufferFormat();
s_ubForestVS._matWVP = sm.GetCamera()->GetMatrixVP().UniformBufferFormat();
s_ubForestVS._viewportSize = renderer.GetCommandBuffer()->GetViewportSize().GLM();
s_ubForestVS._viewportSize = cb->GetViewportSize().GLM();
s_ubForestVS._eyePos = float4(sm.GetCamera()->GetEyePosition().GLM(), 0);
s_ubForestVS._eyePosScreen = float4(atmo.GetEyePosition().GLM(), 0);
s_ubForestVS._eyePosScreen = float4(sm.GetMainCamera()->GetEyePosition().GLM(), 0);
cb->BindPipeline(_pipe[drawingDepth ? PIPE_DEPTH : PIPE_MAIN]);
cb->BindVertexBuffers(_geo);
s_shader->BeginBindDescriptors();
cb->BindDescriptors(s_shader, 0);
s_shader[SHADER_MAIN]->BeginBindDescriptors();
cb->BindDescriptors(s_shader[SHADER_MAIN], 0);
for (auto& plant : _vPlants)
{
if (!plant._csh.IsSet())
continue;
cb->BindDescriptors(s_shader, 1, plant._csh);
cb->BindDescriptors(s_shader[SHADER_MAIN], 1, plant._csh);
for (auto& bc : plant._vBakedChunks)
{
if (bc._visible)
cb->Draw(bc._vSprites.size(), 1, bc._vbOffset);
cb->Draw(Utils::Cast32(bc._vSprites.size()), 1, bc._vbOffset);
}
}
s_shader->EndBindDescriptors();
s_shader[SHADER_MAIN]->EndBindDescriptors();
}
void Forest::DrawAO()
@ -419,8 +454,8 @@ void Forest::DrawAO()
if (!_visibleCount)
return;
VERUS_QREF_RENDERER;
VERUS_QREF_HELPERS;
VERUS_QREF_RENDERER;
CGI::LightType type = CGI::LightType::none;
PMesh pMesh = nullptr;
@ -479,6 +514,157 @@ void Forest::DrawAO()
}
}
void Forest::DrawReflection()
{
if (!_geo)
return;
VERUS_QREF_ATMO;
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
VERUS_QREF_WATER;
auto cb = renderer.GetCommandBuffer();
s_ubSimpleForestVS._matP = sm.GetCamera()->GetMatrixP().UniformBufferFormat();
s_ubSimpleForestVS._matWVP = sm.GetCamera()->GetMatrixVP().UniformBufferFormat();
s_ubSimpleForestVS._viewportSize = renderer.GetCommandBuffer()->GetViewportSize().GLM();
s_ubSimpleForestVS._eyePos = float4(sm.GetCamera()->GetEyePosition().GLM(), 0);
s_ubSimpleForestVS._eyePosScreen = float4(sm.GetMainCamera()->GetEyePosition().GLM(), 0);
s_ubSimpleForestVS._pointSpriteScale = float4(1, water.IsUnderwater() ? 1 : -1, 0, 0);
s_ubSimpleForestFS._matInvV = sm.GetCamera()->GetMatrixVi().UniformBufferFormat();
s_ubSimpleForestFS._ambientColor = float4(atmo.GetAmbientColor().GLM(), 0);
s_ubSimpleForestFS._fogColor = Vector4(atmo.GetFogColor(), atmo.GetFogDensity()).GLM();
s_ubSimpleForestFS._dirToSun = float4(atmo.GetDirToSun().GLM(), 0);
s_ubSimpleForestFS._sunColor = float4(atmo.GetSunColor().GLM(), 0);
s_ubSimpleForestFS._matSunShadow = atmo.GetShadowMap().GetShadowMatrix(0).UniformBufferFormat();
s_ubSimpleForestFS._matSunShadowCSM1 = atmo.GetShadowMap().GetShadowMatrix(1).UniformBufferFormat();
s_ubSimpleForestFS._matSunShadowCSM2 = atmo.GetShadowMap().GetShadowMatrix(2).UniformBufferFormat();
s_ubSimpleForestFS._matSunShadowCSM3 = atmo.GetShadowMap().GetShadowMatrix(3).UniformBufferFormat();
memcpy(&s_ubSimpleForestFS._shadowConfig, &atmo.GetShadowMap().GetConfig(), sizeof(s_ubSimpleForestFS._shadowConfig));
s_ubSimpleForestFS._splitRanges = atmo.GetShadowMap().GetSplitRanges().GLM();
cb->BindPipeline(_pipe[PIPE_REFLECTION]);
cb->BindVertexBuffers(_geo);
s_shader[SHADER_SIMPLE]->BeginBindDescriptors();
cb->BindDescriptors(s_shader[SHADER_SIMPLE], 0);
for (auto& plant : _vPlants)
{
if (!plant._cshSimple.IsSet())
continue;
cb->BindDescriptors(s_shader[SHADER_SIMPLE], 1, plant._cshSimple);
for (auto& bc : plant._vBakedChunks)
{
if (bc._visible)
cb->Draw(Utils::Cast32(bc._vSprites.size()), 1, bc._vbOffset);
}
}
s_shader[SHADER_SIMPLE]->EndBindDescriptors();
}
void Forest::UpdateCollision()
{
VERUS_QREF_BULLET;
for (auto& plant : _vPlants)
{
for (auto& rigidBody : plant._vRigidBodies)
{
if (rigidBody._pBody)
{
bullet.GetWorld()->removeRigidBody(rigidBody._pBody);
delete rigidBody._pBody->getMotionState();
delete rigidBody._pBody;
}
if (rigidBody._pScaledShape)
{
delete rigidBody._pScaledShape;
}
}
plant._vRigidBodies.clear();
}
const int half = _pTerrain->GetMapSide() / 2;
VERUS_FOR(i, 32)
{
VERUS_FOR(j, 32)
{
const int ij[] = { i, j };
Scatter::RcInstance instance = _scatter.GetInstanceAt(ij);
const int type = instance._type;
if (type >= 0)
{
VERUS_QREF_SM;
const int layer = _pTerrain->GetMainLayerAt(ij);
if (layer >= _vLayerPlants.size())
continue;
const int plantIndex = _vLayerPlants[layer]._plants[type];
if (plantIndex < 0)
continue;
RPlant plant = _vPlants[plantIndex];
if (!plant._mesh.IsLoaded())
continue;
if (_pTerrain->GetNormalAt(ij)[1] < plant._allowedNormal)
continue;
const float h = _pTerrain->GetHeightAt(ij);
int ij4[2] = { ij[0], ij[1] };
float h4[4];
h4[0] = h;
ij4[0]++; h4[1] = _pTerrain->GetHeightAt(ij4);
ij4[1]++; h4[2] = _pTerrain->GetHeightAt(ij4);
ij4[0]--; h4[3] = _pTerrain->GetHeightAt(ij4);
const float hMin = *std::min_element(h4 + 0, h4 + 4);
const int xOffset = ij[1] & ~0xF;
const int zOffset = ij[0] & ~0xF;
const float scale = plant._vScales[instance._rand % plant._vScales.size()];
const Point3 pos(
xOffset - half + instance._x,
hMin,
zOffset - half + instance._z);
StaticRigidBody staticRigidBody;
const Matrix3 matBasis = _pTerrain->GetBasisAt(ij);
const Transform3 matW = Transform3(matBasis * Matrix3::rotationY(instance._angle), Vector3(pos));
staticRigidBody._pScaledShape = new btScaledBvhTriangleMeshShape(plant._mesh.GetShape(), btVector3(scale, scale, scale));
staticRigidBody._pBody = bullet.AddNewRigidBody(0, matW.Bullet(), staticRigidBody._pScaledShape);
plant._vRigidBodies.push_back(staticRigidBody);
}
}
}
}
void Forest::OnTerrainModified()
{
VERUS_QREF_RENDERER;
renderer->WaitIdle();
for (auto& plant : _vPlants)
plant._maxSize = 0;
_octree.Done();
_octree.SetDelegate(this);
const float hf = _pTerrain->GetMapSide() * 0.5f;
Math::Bounds bounds;
bounds.Set(
Vector3(-hf, -hf, -hf),
Vector3(+hf, +hf, +hf));
const Vector3 limit(hf / 6, hf / 6, hf / 6);
_octree.Init(bounds, limit);
_pipe.Done();
_geo.Done();
}
void Forest::SetLayer(int layer, RcLayerDesc desc)
{
if (_vLayerPlants.size() < layer + 1)
@ -504,6 +690,7 @@ void Forest::SetLayer(int layer, RcLayerDesc desc)
plant._url = plantDesc._url;
plant._alignToNormal = plantDesc._alignToNormal;
plant._maxScale = plantDesc._maxScale;
plant._windBending = plantDesc._windBending;
plant._allowedNormal = plantDesc._allowedNormal;
const float ds = plantDesc._maxScale - plantDesc._minScale;
const int count = 64;
@ -528,9 +715,9 @@ int Forest::FindPlant(CSZ url) const
void Forest::BakeChunks(RPlant plant)
{
const int chunkSide = 128;
const int side = _pTerrain->GetMapSide() / chunkSide;
const int side = 8;
const int half = _pTerrain->GetMapSide() / 2;
const int chunkSide = _pTerrain->GetMapSide() / side;
auto BakeChunk = [this, side, half, chunkSide](int ic, int jc, RPlant plant)
{
@ -571,18 +758,26 @@ void Forest::BakeChunks(RPlant plant)
const int xOffset = ij[1] & ~0xF;
const int zOffset = ij[0] & ~0xF;
const float psize = plant.GetSize() * plant._vScales[instance._rand % plant._vScales.size()] * _margin;
Vertex v;
v._pos = glm::vec3(
const float scale = plant._vScales[instance._rand % plant._vScales.size()];
const float psize = plant.GetSize() * scale * _margin;
const Point3 pos(
xOffset - half + instance._x,
hMin - psize * 0.05f,
hMin,
zOffset - half + instance._z);
Vertex v;
v._pos = pos.GLM();
v._tc[0] = Math::Clamp<int>(static_cast<int>(psize * 500), 0, SHRT_MAX);
v._tc[1] = Math::Clamp<int>(static_cast<int>(instance._angle * SHRT_MAX / VERUS_2PI), 0, SHRT_MAX);
v._pos.y += psize * 0.5f / _margin;
v._pos.y += psize * 0.5f / _margin - psize * 0.05f;
if (!bc._vSprites.capacity())
bc._vSprites.reserve(256);
bc._vSprites.push_back(v);
//VERUS_QREF_BULLET;
//const Matrix3 matBasis = _pTerrain->GetBasisAt(ij);
//const Transform3 matW = Transform3(matBasis * Matrix3::rotationY(instance._angle), Vector3(pos));
//btScaledBvhTriangleMeshShape* pScaledShape = new btScaledBvhTriangleMeshShape(plant._mesh.GetShape(), btVector3(scale, scale, scale));
//bullet.AddNewRigidBody(0, matW.Bullet(), pScaledShape);
}
}
}
@ -590,6 +785,7 @@ void Forest::BakeChunks(RPlant plant)
}
};
plant._vBakedChunks.clear();
plant._vBakedChunks.resize(side * side);
VERUS_FOR(i, side)
{
@ -648,7 +844,7 @@ void Forest::BakeSprite(RPlant plant, CSZ url)
CGI::RP::Attachment("GBuffer0", CGI::Format::srgbR8G8B8A8).LoadOpClear().Layout(CGI::ImageLayout::fsReadOnly),
CGI::RP::Attachment("GBuffer1", CGI::Format::unormR10G10B10A2).LoadOpClear().Layout(CGI::ImageLayout::fsReadOnly),
CGI::RP::Attachment("GBuffer2", CGI::Format::unormR8G8B8A8).LoadOpClear().Layout(CGI::ImageLayout::fsReadOnly),
CGI::RP::Attachment("Depth", CGI::Format::unormD24uintS8).LoadOpClear().Layout(CGI::ImageLayout::depthStencilAttachment, CGI::ImageLayout::depthStencilReadOnly),
CGI::RP::Attachment("Depth", CGI::Format::unormD24uintS8).LoadOpClear().Layout(CGI::ImageLayout::depthStencilAttachment),
},
{
CGI::RP::Subpass("Sp0").Color(
@ -820,7 +1016,7 @@ void Forest::Scatter_AddInstance(const int ij[2], int type, float x, float z, fl
if (_visibleCount == _vDrawPlants.size())
return;
VERUS_QREF_ATMO;
VERUS_QREF_SM;
const int layer = _pTerrain->GetMainLayerAt(ij);
if (layer >= _vLayerPlants.size())
@ -831,7 +1027,7 @@ void Forest::Scatter_AddInstance(const int ij[2], int type, float x, float z, fl
const float h = _pTerrain->GetHeightAt(ij);
Point3 pos(x, h, z);
RcPoint3 eyePos = atmo.GetEyePosition();
RcPoint3 eyePos = sm.GetMainCamera()->GetEyePosition();
const float distSq = VMath::distSqr(eyePos, pos);
const float maxDistSq = _maxDist * _maxDist;
if (distSq >= maxDistSq)
@ -859,13 +1055,14 @@ void Forest::Scatter_AddInstance(const int ij[2], int type, float x, float z, fl
if (Scene::SceneManager::IsDrawingDepth(DrawDepth::automatic))
{
const float strength = Math::Clamp<float>((1 - distFractionSq) * 1.25f, 0, 1);
matScale = Matrix3::scale(Vector3(strength, 0.5f + 0.5f * strength, strength));
matScale = Matrix3::scale(Vector3::Replicate(0.5f + 0.5f * strength));
}
else
{
const float strength = Math::Clamp<float>((distFractionSq - 0.5f) * 2, 0, 1);
const Point3 center = pos + Vector3(0, plant._maxSize * 0.5f, 0);
pushBack = VMath::normalizeApprox(center - eyePos) * plant._maxSize * strength;
const float maxOffset = Math::Min(plant._maxSize, 5.f);
const Point3 center = pos + Vector3(0, maxOffset * 0.5f, 0);
pushBack = VMath::normalizeApprox(center - eyePos) * maxOffset * strength;
}
DrawPlant drawPlant;
@ -875,13 +1072,15 @@ void Forest::Scatter_AddInstance(const int ij[2], int type, float x, float z, fl
drawPlant._scale = plant._vScales[r % plant._vScales.size()];
drawPlant._angle = angle;
drawPlant._distToEyeSq = distSq;
drawPlant._windBending = (1 - distFractionSq) * plant._windBending;
drawPlant._plantIndex = plantIndex;
_vDrawPlants[_visibleCount++] = drawPlant;
}
Continue Forest::Octree_ProcessNode(void* pToken, void* pUser)
{
VERUS_QREF_SM;
PBakedChunk pBakedChunk = static_cast<PBakedChunk>(pToken);
pBakedChunk->_visible = true;
pBakedChunk->_visible = sm.GetMainCamera()->GetFrustum().ContainsAabb(pBakedChunk->_bounds) != Relation::outside;
return Continue::yes;
}

View File

@ -7,11 +7,20 @@ namespace verus
class Forest : public Object, public ScatterDelegate, public Math::OctreeDelegate
{
#include "../Shaders/DS_Forest.inc.hlsl"
#include "../Shaders/SimpleForest.inc.hlsl"
enum SHADER
{
SHADER_MAIN,
SHADER_SIMPLE,
SHADER_COUNT
};
enum PIPE
{
PIPE_MAIN,
PIPE_DEPTH,
PIPE_REFLECTION,
PIPE_COUNT
};
@ -40,12 +49,21 @@ namespace verus
class BakedChunk
{
public:
Math::Bounds _bounds;
Vector<Vertex> _vSprites;
int _vbOffset = 0;
bool _visible = false;
};
VERUS_TYPEDEFS(BakedChunk);
class StaticRigidBody
{
public:
btScaledBvhTriangleMeshShape* _pScaledShape = nullptr;
btRigidBody* _pBody = nullptr;
};
VERUS_TYPEDEFS(StaticRigidBody);
class Plant
{
public:
@ -62,11 +80,14 @@ namespace verus
MaterialPwn _material;
CGI::TexturePwns<TEX_COUNT> _tex;
CGI::CSHandle _csh;
CGI::CSHandle _cshSimple;
Vector<BakedChunk> _vBakedChunks;
Vector<StaticRigidBody> _vRigidBodies;
Vector<float> _vScales;
float _alignToNormal = 1;
float _maxScale = 0;
float _maxSize = 0;
float _windBending = 1;
float _aoSize = 1;
char _allowedNormal = 116;
@ -95,13 +116,16 @@ namespace verus
float _scale = 1;
float _angle = 0;
float _distToEyeSq = 0;
float _windBending = 0;
int _plantIndex = 0;
};
VERUS_TYPEDEFS(DrawPlant);
static CGI::ShaderPwn s_shader;
static UB_ForestVS s_ubForestVS;
static UB_ForestFS s_ubForestFS;
static CGI::ShaderPwns<SHADER_COUNT> s_shader;
static UB_ForestVS s_ubForestVS;
static UB_ForestFS s_ubForestFS;
static UB_SimpleForestVS s_ubSimpleForestVS;
static UB_SimpleForestFS s_ubSimpleForestFS;
PTerrain _pTerrain = nullptr;
CGI::GeometryPwn _geo;
@ -115,6 +139,8 @@ namespace verus
float _maxDist = 100;
float _tessDist = 50;
float _maxSizeAll = 0;
float _phaseY = 0;
float _phaseXZ = 0;
int _capacity = 4000;
int _visibleCount = 0;
bool _async_initPlants = false;
@ -127,14 +153,16 @@ namespace verus
float _alignToNormal = 1;
float _minScale = 0.5f;
float _maxScale = 1.5f;
float _windBending = 1;
char _allowedNormal = 116;
void Set(CSZ url, float alignToNormal = 1, float minScale = 0.5f, float maxScale = 1.5f, char allowedNormal = 116)
void Set(CSZ url, float alignToNormal = 1, float minScale = 0.5f, float maxScale = 1.5f, float windBending = 1, char allowedNormal = 116)
{
_url = url;
_alignToNormal = alignToNormal;
_minScale = minScale;
_maxScale = maxScale;
_windBending = windBending;
_allowedNormal = allowedNormal;
}
};
@ -160,13 +188,17 @@ namespace verus
void ResetInstanceCount();
void Update();
void Layout();
void Layout(bool reflection = false);
void Draw(bool allowTess = true);
VERUS_P(void DrawModels(bool allowTess));
VERUS_P(void DrawSprites());
void DrawAO();
void DrawReflection();
void UpdateCollision();
PTerrain SetTerrain(PTerrain p) { return Utils::Swap(_pTerrain, p); }
void OnTerrainModified();
void SetLayer(int layer, RcLayerDesc desc);
VERUS_P(int FindPlant(CSZ url) const);

View File

@ -84,6 +84,7 @@ void Grass::Init(RTerrain terrain)
_vInstanceBuffer.resize(maxInstances);
CGI::GeometryDesc geoDesc;
geoDesc._name = "Grass.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{ 0, offsetof(Vertex, _pos), CGI::ViaType::shorts, 4, CGI::ViaUsage::position, 0},
@ -124,6 +125,7 @@ void Grass::Init(RTerrain terrain)
_vTextureSubresData.resize(texW * texH);
CGI::TextureDesc texDesc;
texDesc._name = "Grass.Tex";
texDesc._format = CGI::Format::srgbR8G8B8A8;
texDesc._width = texW;
texDesc._height = texH;
@ -209,7 +211,6 @@ void Grass::Draw()
if (!_visiblePatchCount)
return;
VERUS_QREF_ATMO;
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
VERUS_RT_ASSERT(_pTerrain->GetMapSide() == _mapSide);
@ -228,7 +229,7 @@ void Grass::Draw()
s_ubGrassVS._phase_mapSideInv_bushMask.x = _phase;
s_ubGrassVS._phase_mapSideInv_bushMask.y = 1.f / _mapSide;
s_ubGrassVS._phase_mapSideInv_bushMask.z = *(float*)&bushMask;
s_ubGrassVS._posEye = float4(atmo.GetEyePosition().GLM(), 0);
s_ubGrassVS._posEye = float4(sm.GetMainCamera()->GetEyePosition().GLM(), 0);
s_ubGrassVS._viewportSize = cb->GetViewportSize().GLM();
s_ubGrassVS._warp_turb = Vector4(_warpSpring.GetOffset(), _turbulence).GLM();
@ -284,9 +285,9 @@ void Grass::Draw()
void Grass::QuadtreeIntegral_ProcessVisibleNode(const short ij[2], RcPoint3 center)
{
VERUS_QREF_ATMO;
VERUS_QREF_SM;
const RcPoint3 eyePos = atmo.GetEyePosition();
const RcPoint3 eyePos = sm.GetMainCamera()->GetEyePosition();
const float distSq = VMath::distSqr(eyePos, center);
if (distSq >= 128 * 128.f)
return;

View File

@ -90,9 +90,9 @@ void Mesh::Draw(RcDrawDesc dd, CGI::CommandBufferPtr cb)
void Mesh::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
{
VERUS_QREF_RENDERER;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_ATMO;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_RENDERER;
if (!settings._gpuTessellation) // Fallback:
{
@ -295,9 +295,8 @@ void Mesh::UpdateUniformBufferPerFrame(float invTessDist)
{
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
VERUS_QREF_ATMO;
RcPoint3 eyePos = atmo.GetEyePosition();
RcPoint3 eyePos = sm.GetMainCamera()->GetEyePosition();
Point3 eyePosWV = sm.GetCamera()->GetMatrixV() * eyePos;
s_ubPerFrame._matV = sm.GetCamera()->GetMatrixV().UniformBufferFormat();
@ -347,6 +346,7 @@ void Mesh::CreateDeviceBuffers()
_bindingsMask = 0;
CGI::GeometryDesc geoDesc;
geoDesc._name = _C(_url);
const CGI::VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(VertexInputBinding0, _pos), CGI::ViaType::shorts, 4, CGI::ViaUsage::position, 0},
@ -463,5 +463,5 @@ bool Mesh::IsInstanceBufferEmpty(bool fromFirstInstance)
void Mesh::UpdateInstanceBuffer()
{
VERUS_RT_ASSERT(!_vInstanceBuffer.empty());
_geo->UpdateVertexBuffer(_vInstanceBuffer.data(), 4);
_geo->UpdateVertexBuffer(&_vInstanceBuffer[_firstInstance], 4, nullptr, GetInstanceCount(true), _firstInstance);
}

View File

@ -81,6 +81,13 @@ void Scatter::Done()
void Scatter::QuadtreeIntegral_ProcessVisibleNode(const short ij[2], RcPoint3 center)
{
VERUS_QREF_SM;
RcPoint3 eyePos = sm.GetMainCamera()->GetEyePosition();
const float distSq = VMath::distSqr(eyePos, center);
if (distSq >= _maxDistSq)
return;
const int mask = _side - 1;
VERUS_FOR(i, 16)
{

View File

@ -29,6 +29,7 @@ namespace verus
private:
PScatterDelegate _pDelegate = nullptr;
Vector<Instance> _vInstances;
float _maxDistSq = FLT_MAX;
int _side = 0;
int _shift = 0;
@ -54,6 +55,8 @@ namespace verus
void Init(int side, int typeCount, PcTypeDesc pTypes, int seed = 192000);
void Done();
void SetMaxDist(float dist) { _maxDistSq = dist * dist; }
PScatterDelegate SetDelegate(PScatterDelegate p) { return Utils::Swap(_pDelegate, p); }
virtual void QuadtreeIntegral_ProcessVisibleNode(const short ij[2], RcPoint3 center) override;

View File

@ -80,15 +80,15 @@ void SceneManager::UpdateParts()
void SceneManager::Layout()
{
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_ATMO;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_SM;
// Allocate enough space:
int countAll = 0;
//countAll += TStorePrefabs::_list.size();
countAll += TStoreBlocks::_list.size();
countAll += TStoreLights::_list.size();
countAll += Utils::Cast32(TStoreBlocks::_list.size());
countAll += Utils::Cast32(TStoreLights::_list.size());
//countAll += TStoreSites::_map.size();
if (_vVisibleNodes.size() != countAll)
_vVisibleNodes.resize(countAll);
@ -233,8 +233,8 @@ void SceneManager::DrawLights()
if (!_visibleCountPerType[+NodeType::light])
return;
VERUS_QREF_RENDERER;
VERUS_QREF_HELPERS;
VERUS_QREF_RENDERER;
CGI::LightType type = CGI::LightType::none;
PMesh pMesh = nullptr;

View File

@ -28,6 +28,7 @@ void ShadowMap::Init(int side)
CGI::TextureDesc texDesc;
texDesc._clearValue = Vector4(1);
texDesc._name = "ShadowMap.Tex";
texDesc._format = CGI::Format::unormD24uintS8;
texDesc._width = _side;
texDesc._height = _side;
@ -47,7 +48,7 @@ void ShadowMap::Done()
VERUS_DONE(ShadowMap);
}
void ShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar)
void ShadowMap::Begin(RcVector3 dirToSun)
{
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
@ -55,13 +56,14 @@ void ShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar)
const Vector3 up(0, 1, 0);
Point3 eye, at;
const float texSizeInMeters = 4096 * 0.005f;
if (0 == zFar)
zFar = 1001;
const float depth = texSizeInMeters * 10;
const float zNear = 1;
const float zFar = zNear + depth;
at = sm.GetCamera()->GetEyePosition() + sm.GetCamera()->GetFrontDirection() * (texSizeInMeters * (1 / 3.f));
if (_snapToTexels)
{
const Matrix4 matToShadowSpace = Matrix4::lookAt(Point3(dirToSun), Point3(0), up);
const Matrix4 matToShadowSpace = Matrix4::lookAt(Point3(0), Point3(-dirToSun), up);
const Matrix4 matFromShadowSpace = VMath::orthoInverse(matToShadowSpace);
const Point3 atPosShadowSpace = (matToShadowSpace * at).getXYZ();
const float texelSizeInMeters = texSizeInMeters / _side;
@ -70,7 +72,7 @@ void ShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar)
atPosShadowSpaceSnapped.setY(atPosShadowSpaceSnapped.getY() - fmod(atPosShadowSpaceSnapped.getY(), texelSizeInMeters));
at = (matFromShadowSpace * atPosShadowSpaceSnapped).getXYZ();
}
eye = at + dirToSun * ((zFar - zNear) * 0.5f);
eye = at + dirToSun * (depth * (2 / 3.f));
// Setup light space camera and use it (used for terrain draw, etc.):
_camera.SetUpDirection(up);
@ -82,69 +84,30 @@ void ShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar)
_camera.SetWidth(texSizeInMeters);
_camera.SetHeight(texSizeInMeters);
_camera.Update();
_pSceneCamera = sm.SetCamera(&_camera);
_pPrevCamera = sm.SetCamera(&_camera);
_config._penumbraScale = (zFar - zNear) * 2;
_config._penumbraScale = depth * 2;
renderer.GetCommandBuffer()->BeginRenderPass(_rph, _fbh,
{
_tex->GetClearValue()
});
_rendering = true;
}
void ShadowMap::BeginLight(RcPoint3 pos, RcPoint3 target, float side)
{
#if 0
VERUS_QREF_RENDERER;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_SM;
const float zFar = 100; // pos.DistanceTo(target)*1.5f;
_camera.SetDirectionUp(Vector3(0, 1, 0));
_camera.MoveAtTo(target);
_camera.MoveEyeTo(pos);
_camera.SetFOV(0);
_camera.SetZNear(0.1f);
_camera.SetZFar(zFar);
_camera.SetWidth(side);
_camera.SetHeight(side);
_camera.Update();
_pSceneCamera = sm.SetCamera(&_camera);
render->SetRenderTargets({ _tex[TEX_COLOR] }, _tex[TEX_DEPTH]);
if (1 == settings._gpuDepthTexture)
{
render->Clear(CGI::CLEAR_ZBUFFER);
}
else
{
render.SetClearColor(Vector4(1, 1, 1, 1));
render->Clear(CGI::CLEAR_ZBUFFER | CGI::CLEAR_TARGET);
}
_rendering = true;
#endif
}
void ShadowMap::End()
{
VERUS_QREF_RENDERER;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_SM;
renderer.GetCommandBuffer()->EndRenderPass();
const Matrix4 m = Math::ToUVMatrix();
_matShadow = m * _camera.GetMatrixVP();
_matShadowDS = _matShadow * _pSceneCamera->GetMatrixVi();
_matShadowDS = _matShadow * _pPrevCamera->GetMatrixVi();
_pSceneCamera = sm.SetCamera(_pSceneCamera);
VERUS_RT_ASSERT(&_camera == _pSceneCamera); // Check camera's integrity.
_pSceneCamera = nullptr;
_rendering = false;
_pPrevCamera = sm.SetCamera(_pPrevCamera);
VERUS_RT_ASSERT(&_camera == _pPrevCamera); // Check camera's integrity.
_pPrevCamera = nullptr;
}
RcMatrix4 ShadowMap::GetShadowMatrix() const
@ -199,6 +162,7 @@ void CascadedShadowMap::Init(int side)
CGI::TextureDesc texDesc;
texDesc._clearValue = Vector4(1);
texDesc._name = "ShadowMap.Tex (CSM)";
texDesc._format = CGI::Format::unormD24uintS8;
texDesc._width = _side;
texDesc._height = _side;
@ -224,11 +188,11 @@ void CascadedShadowMap::Done()
{
}
void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int split)
void CascadedShadowMap::Begin(RcVector3 dirToSun, int split)
{
VERUS_QREF_CONST_SETTINGS;
if (settings._sceneShadowQuality < App::Settings::ShadowQuality::cascaded)
return ShadowMap::Begin(dirToSun, zNear, zFar);
return ShadowMap::Begin(dirToSun);
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
@ -242,14 +206,17 @@ void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int s
float texWidthInMeters, texHeightInMeters, texSizeInMeters;
float zNearFrustum, zFarFrustum;
const float closerToLight = 1500;
const Matrix4 matToLightSpace = Matrix4::lookAt(Point3(0), Point3(-dirToSun), up);
const float maxRange = (settings._sceneShadowQuality >= App::Settings::ShadowQuality::ultra) ? 850.f : 350.f;
const float maxRange = (settings._sceneShadowQuality >= App::Settings::ShadowQuality::ultra) ? 1000.f : 300.f;
const float range = Math::Min<float>(maxRange, cam.GetZFar() - cam.GetZNear()); // Clip terrain, etc.
_camera = cam;
if (0 == _currentSplit)
{
const float depth = Math::Min(range * 10, 10000.f);
const float zNear = 1;
const float zFar = zNear + depth;
_camera.SetZNear(cam.GetZNear());
_camera.SetZFar(cam.GetZNear() + range);
_camera.Update();
@ -261,10 +228,8 @@ void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int s
zNearFrustum);
pos = (VMath::orthoInverse(matToLightSpace) * pos).getXYZ(); // To world space.
eye = pos + dirToSun * closerToLight;
eye = pos + dirToSun * (depth * (2 / 3.f));
at = pos;
if (0 == zFar)
zFar = abs(zFarFrustum - zNearFrustum) + closerToLight;
texWidthInMeters = ceil(frustumBounds.getZ() - frustumBounds.getX() + 2.5f);
texHeightInMeters = ceil(frustumBounds.getW() - frustumBounds.getY() + 2.5f);
@ -284,9 +249,9 @@ void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int s
// Compute split ranges:
_splitRanges = Vector4(
cam.GetZNear() + range * 0.5f * 0.5f,
cam.GetZNear() + range * 0.25f,
cam.GetZNear() + range * 0.25f * 0.25f,
cam.GetZNear() + range * 0.125f * 0.125f,
cam.GetZNear() + range * 0.25f * 0.25f * 0.25f,
cam.GetZNear());
// Default scene camera with the current split range:
@ -320,6 +285,9 @@ void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int s
texWidthInMeters = ceil(frustumBounds.getZ() - frustumBounds.getX() + 2.5f);
texHeightInMeters = ceil(frustumBounds.getW() - frustumBounds.getY() + 2.5f);
texSizeInMeters = Math::Max(texWidthInMeters, texHeightInMeters);
const float depth = Math::Min(texSizeInMeters * 10, 10000.f);
const float zNear = 1;
const float zFar = zNear + depth;
if (_snapToTexels)
{
@ -330,10 +298,8 @@ void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int s
}
pos = (VMath::orthoInverse(matToLightSpace) * pos).getXYZ(); // To world space.
eye = pos + dirToSun * closerToLight;
eye = pos + dirToSun * (depth * (2 / 3.f));
at = pos;
if (0 == zFar)
zFar = _cameraCSM.GetZFar();
_splitRanges.setW(cam.GetZNear() + range);
@ -347,7 +313,7 @@ void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int s
_camera.SetWidth(texSizeInMeters);
_camera.SetHeight(texSizeInMeters);
_camera.Update();
_pSceneCamera = sm.SetCamera(&_camera);
_pPrevCamera = sm.SetCamera(&_camera);
_config._penumbraScale = (zFar - zNear) * 2;
@ -367,8 +333,6 @@ void CascadedShadowMap::Begin(RcVector3 dirToSun, float zNear, float zFar, int s
case 2: renderer.GetCommandBuffer()->SetViewport({ Vector4(0, s, s, s) }); break;
case 3: renderer.GetCommandBuffer()->SetViewport({ Vector4(s, s, s, s) }); break;
}
_rendering = true;
}
void CascadedShadowMap::End(int split)
@ -386,13 +350,13 @@ void CascadedShadowMap::End(int split)
const Matrix4 m = Math::ToUVMatrix();
_matShadowCSM[_currentSplit] = _matOffset[_currentSplit] * m * _camera.GetMatrixVP();
_matShadowCSM_DS[_currentSplit] = _matShadowCSM[_currentSplit] * _pSceneCamera->GetMatrixVi();
_matShadowCSM_DS[_currentSplit] = _matShadowCSM[_currentSplit] * _pPrevCamera->GetMatrixVi();
_pSceneCamera = sm.SetCamera(_pSceneCamera);
VERUS_RT_ASSERT(&_camera == _pSceneCamera); // Check camera's integrity.
_pSceneCamera = nullptr;
_pPrevCamera = sm.SetCamera(_pPrevCamera);
VERUS_RT_ASSERT(&_camera == _pPrevCamera); // Check camera's integrity.
_pPrevCamera = nullptr;
_rendering = false;
_currentSplit = -1;
}
RcMatrix4 CascadedShadowMap::GetShadowMatrix(int split) const

View File

@ -18,16 +18,15 @@ namespace verus
protected:
Matrix4 _matShadow;
Matrix4 _matShadowDS;
Matrix4 _matShadowDS; // For WV positions in Deferred Shading.
Config _config;
CGI::TexturePwn _tex;
Camera _camera;
PCamera _pSceneCamera = nullptr;
PCamera _pPrevCamera = nullptr;
int _side = 0;
CGI::RPHandle _rph;
CGI::FBHandle _fbh;
bool _snapToTexels = true;
bool _rendering = false;
public:
ShadowMap();
@ -37,12 +36,11 @@ namespace verus
void Done();
void SetSnapToTexels(bool b) { _snapToTexels = b; }
bool IsRendering() const { return _rendering; }
bool IsRendering() const { return !!_pPrevCamera; }
CGI::RPHandle GetRenderPassHandle() const { return _rph; }
void Begin(RcVector3 dirToSun, float zNear = 1, float zFar = 0);
void BeginLight(RcPoint3 pos, RcPoint3 target, float side = 10);
void Begin(RcVector3 dirToSun);
void End();
RcMatrix4 GetShadowMatrix() const;
@ -51,15 +49,13 @@ namespace verus
RConfig GetConfig() { return _config; }
CGI::TexturePtr GetTexture() const;
PCamera GetSceneCamera() { return _pSceneCamera; }
};
VERUS_TYPEDEFS(ShadowMap);
class CascadedShadowMap : public ShadowMap
{
Matrix4 _matShadowCSM[4];
Matrix4 _matShadowCSM_DS[4];
Matrix4 _matShadowCSM_DS[4]; // For WV positions in Deferred Shading.
Matrix4 _matOffset[4];
Vector4 _splitRanges = Vector4(0);
Camera _cameraCSM;
@ -72,7 +68,7 @@ namespace verus
void Init(int side);
void Done();
void Begin(RcVector3 dirToSun, float zNear, float zFar, int split);
void Begin(RcVector3 dirToSun, int split);
void End(int split);
RcMatrix4 GetShadowMatrix(int split = 0) const;

View File

@ -420,9 +420,9 @@ void Terrain::DoneStatic()
void Terrain::Init(RcDesc desc)
{
VERUS_INIT();
VERUS_QREF_RENDERER;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_ATMO;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_RENDERER;
if (!Math::IsPowerOfTwo(desc._mapSide))
throw VERUS_RECOVERABLE << "Init(), mapSide must be power of two";
@ -491,6 +491,7 @@ void Terrain::Init(RcDesc desc)
}
}
_vSortedPatchIndices.resize(patchCount);
_vRandomPatchIndices.resize(patchCount);
// Init LODs:
VERUS_FOR(i, VERUS_COUNT_OF(_lods))
@ -517,6 +518,7 @@ void Terrain::Init(RcDesc desc)
_vInstanceBuffer.resize(maxInstances);
CGI::GeometryDesc geoDesc;
geoDesc._name = "Terrain.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{ 0, 0, CGI::ViaType::shorts, 4, CGI::ViaUsage::position, 0},
@ -586,6 +588,7 @@ void Terrain::Init(RcDesc desc)
}
CGI::TextureDesc texDesc;
texDesc._name = "Terrain.Heightmap";
texDesc._format = CGI::Format::floatR16;
texDesc._width = _mapSide;
texDesc._height = _mapSide;
@ -593,16 +596,19 @@ void Terrain::Init(RcDesc desc)
texDesc._flags = CGI::TextureDesc::Flags::anyShaderResource;
_tex[TEX_HEIGHTMAP].Init(texDesc);
texDesc._name = "Terrain.Normals";
texDesc._format = CGI::Format::unormR8G8B8A8;
texDesc._width = _mapSide;
texDesc._height = _mapSide;
texDesc._mipLevels = 0;
texDesc._flags = CGI::TextureDesc::Flags::anyShaderResource | CGI::TextureDesc::Flags::generateMips;
_tex[TEX_NORMALS].Init(texDesc);
texDesc._name = "Terrain.Blend";
texDesc._flags = CGI::TextureDesc::Flags::generateMips;
_tex[TEX_BLEND].Init(texDesc);
texDesc.Reset();
texDesc._name = "Terrain.MainLayer";
texDesc._format = CGI::Format::unormR8;
texDesc._width = _mapSide;
texDesc._height = _mapSide;
@ -675,13 +681,10 @@ void Terrain::ResetInstanceCount()
void Terrain::Layout()
{
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_ATMO;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_SM;
// Reset LOD data:
std::for_each(_vPatches.begin(), _vPatches.end(), [](RTerrainPatch patch) {patch._quadtreeLOD = -1; });
PCamera pPrevCamera = nullptr;
// For CSM we need to create geometry beyond the view frustum (1st slice):
if (settings._sceneShadowQuality >= App::Settings::ShadowQuality::cascaded && atmo.GetShadowMap().IsRendering())
@ -692,6 +695,8 @@ void Terrain::Layout()
}
_visiblePatchCount = 0;
_visibleSortedPatchCount = 0;
_visibleRandomPatchCount = 0;
_quadtree.TraverseVisible();
SortVisiblePatches();
@ -702,10 +707,9 @@ void Terrain::Layout()
void Terrain::Draw(RcDrawDesc dd)
{
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
VERUS_QREF_ATMO;
VERUS_QREF_CONST_SETTINGS;
if (!_visiblePatchCount)
return;
@ -721,7 +725,7 @@ void Terrain::Draw(RcDrawDesc dd)
s_ubTerrainVS._matV = sm.GetCamera()->GetMatrixV().UniformBufferFormat();
s_ubTerrainVS._matVP = sm.GetCamera()->GetMatrixVP().UniformBufferFormat();
s_ubTerrainVS._matP = sm.GetCamera()->GetMatrixP().UniformBufferFormat();
s_ubTerrainVS._eyePos_mapSideInv = float4(atmo.GetEyePosition().GLM(), 0);
s_ubTerrainVS._eyePos_mapSideInv = float4(sm.GetMainCamera()->GetEyePosition().GLM(), 0);
s_ubTerrainVS._eyePos_mapSideInv.w = 1.f / _mapSide;
s_ubTerrainVS._viewportSize = cb->GetViewportSize().GLM();
s_ubTerrainFS._matWV = s_ubTerrainVS._matWV;
@ -810,16 +814,15 @@ void Terrain::Draw(RcDrawDesc dd)
}
s_shader[SHADER_MAIN]->EndBindDescriptors();
_geo->UpdateVertexBuffer(&_vInstanceBuffer[_instanceCount], 1, cb.Get(), _visiblePatchCount, _instanceCount);
_instanceCount += _visiblePatchCount;
_geo->UpdateVertexBuffer(_vInstanceBuffer.data(), 1);
}
void Terrain::DrawReflection()
{
VERUS_QREF_ATMO;
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
VERUS_QREF_ATMO;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_WATER;
if (!_visiblePatchCount)
@ -831,7 +834,7 @@ void Terrain::DrawReflection()
s_ubSimpleTerrainVS._matW = matW.UniformBufferFormat();
s_ubSimpleTerrainVS._matVP = sm.GetCamera()->GetMatrixVP().UniformBufferFormat();
s_ubSimpleTerrainVS._eyePos = float4(atmo.GetEyePosition().GLM(), 0);
s_ubSimpleTerrainVS._eyePos = float4(sm.GetMainCamera()->GetEyePosition().GLM(), 0);
s_ubSimpleTerrainVS._mapSideInv_clipDistanceOffset.x = 1.f / _mapSide;
s_ubSimpleTerrainVS._mapSideInv_clipDistanceOffset.y = static_cast<float>(water.IsUnderwater() ? USHRT_MAX : 0);
VERUS_FOR(i, VERUS_COUNT_OF(_layerData))
@ -908,13 +911,14 @@ void Terrain::DrawReflection()
}
s_shader[SHADER_SIMPLE]->EndBindDescriptors();
_geo->UpdateVertexBuffer(&_vInstanceBuffer[_instanceCount], 1, cb.Get(), _visiblePatchCount, _instanceCount);
_instanceCount += _visiblePatchCount;
_geo->UpdateVertexBuffer(_vInstanceBuffer.data(), 1);
}
void Terrain::SortVisiblePatches()
{
std::sort(_vSortedPatchIndices.begin(), _vSortedPatchIndices.begin() + _visiblePatchCount, [this](int a, int b)
_visiblePatchCount = _visibleSortedPatchCount + _visibleRandomPatchCount;
std::sort(_vSortedPatchIndices.begin(), _vSortedPatchIndices.begin() + _visibleSortedPatchCount, [this](int a, int b)
{
RcTerrainPatch patchA = GetPatch(a);
RcTerrainPatch patchB = GetPatch(b);
@ -924,19 +928,20 @@ void Terrain::SortVisiblePatches()
return patchA._distToCameraSq < patchB._distToCameraSq;
});
if (_visibleRandomPatchCount)
memcpy(&_vSortedPatchIndices[_visibleSortedPatchCount], _vRandomPatchIndices.data(), _visibleRandomPatchCount * sizeof(UINT16));
}
int Terrain::UserPtr_GetType()
{
return 0;
//return +NodeType::terrain;
return +NodeType::terrain;
}
void Terrain::QuadtreeIntegral_ProcessVisibleNode(const short ij[2], RcPoint3 center)
{
VERUS_QREF_ATMO;
VERUS_QREF_SM;
const RcPoint3 posEye = atmo.GetEyePosition();
const RcPoint3 posEye = sm.GetMainCamera()->GetEyePosition();
const Vector3 toCenter = center - posEye;
const float dist = VMath::length(toCenter);
@ -959,7 +964,10 @@ void Terrain::QuadtreeIntegral_ProcessVisibleNode(const short ij[2], RcPoint3 ce
patch._patchHeight = ConvertHeight(center.getY());
patch._quadtreeLOD = lod;
_vSortedPatchIndices[_visiblePatchCount++] = offsetPatch;
if (4 == lod)
_vRandomPatchIndices[_visibleRandomPatchCount++] = offsetPatch;
else
_vSortedPatchIndices[_visibleSortedPatchCount++] = offsetPatch;
}
void Terrain::QuadtreeIntegral_GetHeights(const short ij[2], float height[2])
@ -983,6 +991,7 @@ void Terrain::FattenQuadtreeNodesBy(float x)
_quadtreeFatten = x;
_quadtree.Done();
_quadtree.Init(_mapSide, 16, this, _quadtreeFatten);
_quadtree.SetDistCoarseMode(true);
}
float Terrain::GetHeightAt(const float xz[2]) const
@ -1150,9 +1159,9 @@ void Terrain::LoadLayerTextures()
if (_vLayerUrls.empty())
return;
VERUS_QREF_ATMO;
VERUS_QREF_MM;
VERUS_QREF_RENDERER;
VERUS_QREF_ATMO;
renderer->WaitIdle();
@ -1244,7 +1253,6 @@ void Terrain::UpdateMainLayerAt(const int ij[2])
void Terrain::UpdateHeightmapTexture()
{
VERUS_QREF_RENDERER;
_vHeightmapSubresData.resize(_mapSide * _mapSide);
const int mipLevels = Math::ComputeMipLevels(_mapSide, _mapSide);
VERUS_FOR(lod, mipLevels)
@ -1337,6 +1345,7 @@ void Terrain::OnHeightModified()
{
_quadtree.Done();
_quadtree.Init(_mapSide, 16, this, _quadtreeFatten);
_quadtree.SetDistCoarseMode(true);
UpdateHeightBuffer();
UpdateHeightmapTexture();
@ -1411,9 +1420,6 @@ void Terrain::Serialize(IO::RSeekableStream stream)
void Terrain::Deserialize(IO::RStream stream)
{
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_SM;
char buffer[IO::Stream::s_bufferSize] = {};
Done();

View File

@ -146,6 +146,7 @@ namespace verus
Vector<TerrainPatch> _vPatches;
Vector<TerrainPatch::TBN> _vPatchTBNs;
Vector<UINT16> _vSortedPatchIndices;
Vector<UINT16> _vRandomPatchIndices;
Vector<PerInstanceData> _vInstanceBuffer;
Vector<String> _vLayerUrls;
Vector<short> _vHeightBuffer;
@ -160,6 +161,8 @@ namespace verus
int _indexCount = 0;
int _instanceCount = 0;
int _visiblePatchCount = 0;
int _visibleSortedPatchCount = 0;
int _visibleRandomPatchCount = 0;
CGI::CSHandle _cshVS;
CGI::CSHandle _cshFS;
CGI::CSHandle _cshSimpleVS;

View File

@ -24,7 +24,6 @@ void Water::Init(RTerrain terrain)
VERUS_INIT();
VERUS_QREF_RENDERER;
VERUS_QREF_CONST_SETTINGS;
_pTerrain = &terrain;
@ -74,6 +73,7 @@ void Water::Init(RTerrain terrain)
_indexCount = Utils::Cast32(vIndices.size());
CGI::GeometryDesc geoDesc;
geoDesc._name = "Water.Geo";
const CGI::VertexInputAttrDesc viaDesc[] =
{
{0, offsetof(Vertex, _pos), CGI::ViaType::floats, 4, CGI::ViaUsage::position, 0},
@ -115,9 +115,7 @@ void Water::Init(RTerrain terrain)
texDesc._flags = CGI::TextureDesc::Flags::anyShaderResource;
_tex[TEX_FOAM].Init(texDesc);
texDesc.Reset();
texDesc._url = "[Textures]:Water/Heightmap.FX.dds";
_tex[TEX_SOURCE_HEIGHTMAP].Init(texDesc);
_tex[TEX_SOURCE_HEIGHTMAP].Init("[Textures]:Water/Heightmap.FX.dds");
CGI::SamplerDesc normalsSamplerDesc;
normalsSamplerDesc.SetFilter("ll");
@ -125,12 +123,14 @@ void Water::Init(RTerrain terrain)
normalsSamplerDesc._mipLodBias = 0.5f;
normalsSamplerDesc._minLod = 1;
texDesc.Reset();
texDesc._name = "Water.GenHeightmap";
texDesc._format = CGI::Format::floatR16;
texDesc._width = _genSide;
texDesc._height = _genSide;
texDesc._mipLevels = 0;
texDesc._flags = CGI::TextureDesc::Flags::colorAttachment | CGI::TextureDesc::Flags::anyShaderResource | CGI::TextureDesc::Flags::generateMips;
_tex[TEX_GEN_HEIGHTMAP].Init(texDesc);
texDesc._name = "Water.GenNormals";
texDesc._format = CGI::Format::unormR10G10B10A2;
texDesc._flags = CGI::TextureDesc::Flags::colorAttachment | CGI::TextureDesc::Flags::generateMips;
texDesc._pSamplerDesc = &normalsSamplerDesc;
@ -143,12 +143,14 @@ void Water::Init(RTerrain terrain)
_cshGenNormals = _shader[SHADER_GEN]->BindDescriptorSetTextures(2, { _tex[TEX_GEN_HEIGHTMAP] });
texDesc.Reset();
texDesc._name = "Water.Reflection";
texDesc._format = CGI::Format::floatR11G11B10;
texDesc._width = 1024;
texDesc._height = 512;
texDesc._mipLevels = 0;
texDesc._flags = CGI::TextureDesc::Flags::colorAttachment | CGI::TextureDesc::Flags::generateMips;
_tex[TEX_REFLECTION].Init(texDesc);
texDesc._name = "Water.ReflectionDepth";
texDesc._clearValue = Vector4(1);
texDesc._format = CGI::Format::unormD24uintS8;
texDesc._mipLevels = 1;
@ -197,11 +199,9 @@ void Water::Draw()
{
VERUS_UPDATE_ONCE_CHECK_DRAW;
VERUS_QREF_ATMO;
VERUS_QREF_RENDERER;
VERUS_QREF_SM;
VERUS_QREF_CONST_SETTINGS;
VERUS_QREF_TIMER;
VERUS_QREF_ATMO;
if (!_cshWaterFS.IsSet())
{
@ -279,8 +279,8 @@ void Water::OnSwapChainResized()
if (!_tex[TEX_FOAM]->IsLoaded())
return;
VERUS_QREF_RENDERER;
VERUS_QREF_ATMO;
VERUS_QREF_RENDERER;
_shader[SHADER_MAIN]->FreeDescriptorSet(_cshWaterFS);
_shader[SHADER_MAIN]->FreeDescriptorSet(_cshWaterVS);
@ -309,7 +309,7 @@ void Water::BeginReflection(CGI::PBaseCommandBuffer pCB)
_camera = *sm.GetCamera();
if (!IsUnderwater(_camera.GetEyePosition()))
_camera.EnableReflectionMode();
_pSceneCamera = sm.SetCamera(&_camera);
_pPrevCamera = sm.SetCamera(&_camera);
pCB->BeginRenderPass(_rphReflection, _fbhReflection,
{
@ -328,7 +328,7 @@ void Water::EndReflection(CGI::PBaseCommandBuffer pCB)
pCB->EndRenderPass();
sm.SetCamera(_pSceneCamera);
sm.SetCamera(_pPrevCamera);
_tex[TEX_REFLECTION]->GenerateMips();
}
@ -459,8 +459,8 @@ float Water::PhillipsSpectrum(float k)
bool Water::IsUnderwater() const
{
return _pSceneCamera ?
IsUnderwater(_pSceneCamera->GetEyePosition()) :
return _pPrevCamera ?
IsUnderwater(_pPrevCamera->GetEyePosition()) :
IsUnderwater(SceneManager::I().GetCamera()->GetEyePosition());
}

View File

@ -33,10 +33,6 @@ namespace verus
TEX_GEN_NORMALS,
TEX_REFLECTION,
TEX_REFLECTION_DEPTH,
TEX_REFRACT,
TEX_REFLECT,
TEX_REFLECT_DEPTH,
TEX_COUNT
};
@ -54,8 +50,8 @@ namespace verus
static UB_GenHeightmapFS s_ubGenHeightmapFS;
static UB_GenNormalsFS s_ubGenNormalsFS;
Vector3 _diffuseColorShallow = Vector3(0.02f, 0.42f, 0.52f);
Vector3 _diffuseColorDeep = Vector3(0.01f, 0.01f, 0.06f);
Vector3 _diffuseColorShallow = Vector3(0.02f, 0.4f, 0.5f);
Vector3 _diffuseColorDeep = Vector3(0.01f, 0.01f, 0.05f);
PTerrain _pTerrain = nullptr;
CGI::GeometryPwn _geo;
CGI::ShaderPwns<SHADER_COUNT> _shader;
@ -72,7 +68,7 @@ namespace verus
CGI::RPHandle _rphReflection;
CGI::FBHandle _fbhReflection;
Camera _camera;
PCamera _pSceneCamera = nullptr;
PCamera _pPrevCamera = nullptr;
const int _genSide = 1024;
int _gridWidth = 128;
int _gridHeight = 512;
@ -106,8 +102,6 @@ namespace verus
// Caustics are highlights on ocean floor.
CGI::TexturePtr GetCausticsTexture() const;
PCamera GetSceneCamera() { return _pSceneCamera; }
VERUS_P(void CreateWaterPlane());
static float PhillipsSpectrum(float k);

View File

@ -52,7 +52,7 @@ FSO mainFS(VSO si)
const float4 rawColor = g_tex.SampleLevel(g_sam, si.tc0, 0.0);
const float3 color = rawColor.rgb * g_ubBloomFS._exposure.x;
const float3 bloom = saturate((color - 1.0) * 0.4);
const float3 bloom = saturate((color - 1.0) * 0.3);
#ifdef DEF_GOD_RAYS
const float2 ndcPos = ToNdcPos(si.tc0);

View File

@ -1,6 +1,7 @@
// Copyright (C) 2020, Dmitry Maluev (dmaluev@gmail.com)
#include "Lib.hlsl"
#include "LibColor.hlsl"
#include "LibDeferredShading.hlsl"
#include "LibDepth.hlsl"
#include "Blur.inc.hlsl"
@ -125,13 +126,13 @@ FSO mainAntiAliasingFS(VSO si)
const float rawOriginDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
const float originDepth = ToLinearDepth(rawOriginDepth, g_ubExtraBlurFS._zNearFarEx);
const float4 rawKernelDepths = float4(
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(-2, +0)).r, // L
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+0, -2)).r, // T
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+2, +0)).r, // R
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+0, +2)).r); // B
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(-1, +0)).r, // L
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+0, -1)).r, // T
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+1, +0)).r, // R
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+0, +1)).r); // B
const float4 kernelDepths = ToLinearDepth(rawKernelDepths, g_ubExtraBlurFS._zNearFarEx);
const float minDepth = min(min(kernelDepths[0], kernelDepths[1]), min(kernelDepths[2], kernelDepths[3]));
const float equalize = max(1.0 / originDepth, 0.05);
const float equalize = 1.0 / originDepth;
originDeeper = saturate((originDepth - minDepth) * equalize);
const float4 depthOffsets = abs((originDepth - kernelDepths) * equalize);
depthBasedEdge = saturate(dot(depthOffsets, 1.0));
@ -146,11 +147,11 @@ FSO mainAntiAliasingFS(VSO si)
float normalBasedEdge;
{
const float4 rawNrmLT = float4(
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(-2, +0)).rg,
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+0, -2)).rg);
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(-1, +0)).rg,
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+0, -1)).rg);
const float4 rawNrmRB = float4(
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+2, +0)).rg,
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+0, +2)).rg);
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+1, +0)).rg,
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+0, +1)).rg);
const float4 diffA = rawNrmLT - rawNrmRB;
const float4 diffB = rawNrmLT - rawNrmRB.zwxy;
const float4 dots = float4(
@ -170,10 +171,10 @@ FSO mainAntiAliasingFS(VSO si)
const float omni = max(perp.z * perp.z * perp.z, originDeeper);
const float2 dirs[4] =
{
lerp(perp.xy * +4.0, float2(-0.6, -0.3), omni),
lerp(perp.xy * -2.0, float2(+0.3, -0.6), omni),
lerp(perp.xy * -4.0, float2(-0.3, +0.6), omni),
lerp(perp.xy * +2.0, float2(+0.6, +0.3), omni)
lerp(perp.xy * +4.0, float2(-0.4, -0.2), omni),
lerp(perp.xy * -2.0, float2(+0.2, -0.4), omni),
lerp(perp.xy * -4.0, float2(-0.2, +0.4), omni),
lerp(perp.xy * +2.0, float2(+0.4, +0.2), omni)
};
const float2 offsetScale = g_ubExtraBlurFS._textureSize.zw * max(normalBasedEdge, depthBasedEdge);
const float3 kernelColors[4] =
@ -183,7 +184,15 @@ FSO mainAntiAliasingFS(VSO si)
g_tex.SampleLevel(g_sam, si.tc0 + dirs[2] * offsetScale, 0.0).rgb,
g_tex.SampleLevel(g_sam, si.tc0 + dirs[3] * offsetScale, 0.0).rgb
};
so.color.rgb = (kernelColors[0] + kernelColors[1] + kernelColors[2] + kernelColors[3]) * 0.25;
const float3 sdrKernelColors[4] =
{
ToneMappingReinhard(kernelColors[0] * 0.001),
ToneMappingReinhard(kernelColors[1] * 0.001),
ToneMappingReinhard(kernelColors[2] * 0.001),
ToneMappingReinhard(kernelColors[3] * 0.001)
};
so.color.rgb = (sdrKernelColors[0] + sdrKernelColors[1] + sdrKernelColors[2] + sdrKernelColors[3]) * 0.25;
so.color.rgb = ToneMappingInvReinhard(so.color.rgb) * 1000.0;
so.color.a = 1.0;
return so;

View File

@ -44,9 +44,6 @@ struct VSO
float4 lightDirWV_invConeDelta : TEXCOORD3;
#endif
float4 color_coneOut : TEXCOORD4;
#ifdef DEF_DIR
float3 dirZenithWV : TEXCOORD5;
#endif
};
#ifdef _VS
@ -68,12 +65,6 @@ VSO mainVS(VSI si)
const float coneIn = g_ubPerObject.a;
#endif
#ifdef DEF_DIR
const float glossScale = 0.5;
#else
const float glossScale = 1.0;
#endif
const matrix matWV = mul(ToFloat4x4(matW), ToFloat4x4(g_ubPerFrame._matV));
const float3x3 matW33 = (float3x3)matW;
@ -100,11 +91,10 @@ VSO mainVS(VSI si)
const float4 posOrigin = float4(0, 0, 0, 1);
so.lightPosWV = mul(posOrigin, matWV).xyz;
#endif
so.color_coneOut = float4(color, glossScale);
so.color_coneOut = float4(color, 0);
#ifdef DEF_DIR
const float3 posUnit = mul(float3(0, 0, 1), matWV33); // Assume no scale in matWV33.
so.lightDirWV_invConeDelta = float4(posUnit, 1);
so.dirZenithWV = mul(float3(0, 1, 0), matV33);
#elif DEF_SPOT
so.lightDirWV_invConeDelta.xyz = normalize(mul(float3(0, 0, 1), matWV33));
const float3 posCone = mul(float3(0, 1, 1), matW33);
@ -145,19 +135,12 @@ DS_ACC_FSO mainFS(VSO si)
// For Dir & Spot: light's direction & cone:
#ifdef DEF_DIR
const float3 lightDirWV = si.lightDirWV_invConeDelta.xyz;
const float3 dirZenithWV = si.dirZenithWV;
#elif DEF_SPOT
const float3 lightDirWV = si.lightDirWV_invConeDelta.xyz;
const float invConeDelta = si.lightDirWV_invConeDelta.w;
const float coneOut = si.color_coneOut.a;
#endif
#ifdef DEF_SPOT
const float glossScale = 0.5;
#else
const float glossScale = si.color_coneOut.a;
#endif
// GBuffer1:
const float depth = VK_SUBPASS_LOAD(g_texDepth, g_samDepth, tc0).r;
const float3 posWV = DS_GetPosition(depth, g_ubPerFrame._matInvP, ndcPos.xy);
@ -188,25 +171,19 @@ DS_ACC_FSO mainFS(VSO si)
const float2 lamScaleBias = DS_GetLamScaleBias(rawGBuffer2);
const float2 metal = DS_GetMetallicity(rawGBuffer2);
const float gloss64 = rawGBuffer2.a * 64.0;
const float gloss64Scaled = gloss64 * glossScale;
// Special:
const float skinMask = emission.y;
const float hairMask = metal.y;
const float eyeMask = saturate(1.0 - gloss64);
const float eyeGloss = 25.0 * glossScale;
const float eyeGloss = 25.0;
const float2 lamScaleBiasWithHair = lerp(lamScaleBias, float2(1, 0.4), hairMask);
const float gloss = lerp(gloss64Scaled * gloss64Scaled * gloss64Scaled, eyeGloss * eyeGloss * eyeGloss, eyeMask);
const float gloss = lerp(gloss64 * gloss64, eyeGloss * eyeGloss, eyeMask);
#ifdef DEF_DIR
const float3 dirToLightWV = -lightDirWV;
const float lightFalloff = 1.0;
const float3 reflectWV = reflect(-dirToEyeWV, normalWV);
const float zenith = dot(dirZenithWV, reflectWV);
const float zenithMask = saturate(zenith * gloss64Scaled * 0.15);
const float3 skyColor = 1.0;
#else
const float3 toLightWV = lightPosWV - posWV;
const float3 dirToLightWV = normalize(toLightWV);
@ -270,22 +247,15 @@ DS_ACC_FSO mainFS(VSO si)
const float3 hdrMaxDiff = hdrLightColorSSS * diffLightMask;
const float3 hdrMaxSpec = hdrLightColorSSS * specLightMask * specHue * FresnelSchlick(spec, maxSpecAdd, litRet.w);
#ifdef DEF_DIR
so.target0.rgb = hdrMaxDiff * litRet.y;
so.target1.rgb = hdrMaxSpec * litRet.z;
#else
so.target0.rgb = hdrMaxDiff * litRet.y;
so.target1.rgb = hdrMaxSpec * litRet.z;
#endif
//so.target0.rgb = max(so.target0.rgb, emission.x);
//so.target1.rgb = min(so.target1.rgb, 1.0 - emission.x);
so.target0.a = 1.0;
so.target1.a = 1.0;
}
#if defined(DEF_OMNI) || defined(DEF_SPOT)
else
{
clip(-1.0);
discard;
}
#endif

View File

@ -122,7 +122,7 @@ FSO mainFS(VSO si)
}
else
{
clip(-1.0);
discard;
}
return so;

View File

@ -128,6 +128,12 @@ FSO2 mainFS(VSO si)
so.target0.rgb = lerp(colorWithFog, albedo, floor(rawDepth));
so.target0.a = 1.0;
// <BackgroundColor>
const float2 normalWasSet = ceil(rawGBuffer1.rg);
const float bg = 1.0 - saturate(normalWasSet.r + normalWasSet.g);
so.target0.rgb = lerp(so.target0.rgb, g_ubComposeFS._backgroundColor.rgb, bg * g_ubComposeFS._backgroundColor.a);
// </BackgroundColor>
so.target1 = so.target0;
return so;
@ -143,26 +149,21 @@ FSO mainFS(VSO si)
const float4 rawGBuffer2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.0);
const float4 rawComposed = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0);
const float3 exposedComposed = rawComposed.rgb * g_ubComposeFS._ambientColor_exposure.a;
const float gray = Grayscale(rawComposed.rgb);
const float3 exposedComposed = Desaturate(rawComposed.rgb, saturate(1.0 - gray * 0.03)) * g_ubComposeFS._ambientColor_exposure.a;
so.color.rgb = VerusToneMapping(exposedComposed, 0.5);
so.color.a = 1.0;
// SolidColor (using special value 1.0 for emission):
so.color.rgb = lerp(so.color.rgb, rawGBuffer0.rgb, floor(rawGBuffer1.b));
// <BackgroundColor>
const float2 normalWasSet = ceil(rawGBuffer1.rg);
const float bg = 1.0 - saturate(normalWasSet.r + normalWasSet.g);
so.color.rgb = lerp(so.color.rgb, g_ubComposeFS._backgroundColor.rgb, bg * g_ubComposeFS._backgroundColor.a);
// </BackgroundColor>
const float3 bloom = rawGBuffer2.rgb;
so.color.rgb += bloom * (1.0 - so.color.rgb);
if (false)
{
const float gray = Grayscale(rawComposed.rgb);
so.color.r = saturate((gray - 25.0) * 0.001);
const float gray = dot(rawComposed.rgb, 1.0 / 3.0);
so.color.r = saturate((gray - 2000.0) * 0.001);
so.color.gb *= 0.5;
}

View File

@ -26,7 +26,7 @@ struct VSO
float2 tc0 : TEXCOORD0;
float2 angles : TEXCOORD1;
float4 color : COLOR0;
float2 psize : PSIZE;
float3 psize : PSIZE;
};
#ifdef _VS
@ -40,12 +40,16 @@ VSO mainVS(VSI si)
const float3 toEye = g_ubForestVS._eyePos.xyz - si.pos.xyz;
const float distToScreen = length(g_ubForestVS._eyePosScreen.xyz - si.pos.xyz);
const float nearAlpha = saturate((distToScreen - 60.0) * (1.0 / 30.0));
const float farAlpha = 1.0 - saturate((distToScreen - 900.0) * (1.0 / 100.0));
so.pos = mul(si.pos, g_ubForestVS._matWVP);
so.tc0 = 0.0;
so.color.rgb = RandomColor(si.pos.xz, 0.3, 0.2);
so.color.a = saturate((distToScreen - 60.0) / 30.0);
so.psize = pointSpriteSize * (g_ubForestVS._viewportSize.yx * g_ubForestVS._viewportSize.z) * g_ubForestVS._matP._m11;
so.psize *= ceil(so.color.a); // Hide if too close.
so.color.a = nearAlpha * farAlpha;
so.psize.xy = pointSpriteSize * (g_ubForestVS._viewportSize.yx * g_ubForestVS._viewportSize.z) * g_ubForestVS._matP._m11;
so.psize.xy *= ceil(so.color.a); // Hide if too close.
so.psize.z = saturate(pointSpriteSize * 0.25 - 0.5);
float2 param0 = toEye.xy;
float2 param1 = toEye.zz;
@ -70,7 +74,7 @@ void mainGS(point VSO si[1], inout TriangleStream<VSO> stream)
const float2 center = so.pos.xy;
for (int i = 0; i < 4; ++i)
{
so.pos.xy = center + _POINT_SPRITE_POS_OFFSETS[i] * so.psize;
so.pos.xy = center + _POINT_SPRITE_POS_OFFSETS[i] * so.psize.xy;
so.tc0.xy = _POINT_SPRITE_TEX_COORDS[i];
stream.Append(so);
}
@ -105,7 +109,7 @@ void mainFS(VSO si)
const float alpha = g_texGBuffer1.Sample(g_samGBuffer1, tc).a;
clip(alpha * mask - 0.5);
clip(alpha * mask - 0.53);
}
#else
DS_FSO mainFS(VSO si)
@ -124,9 +128,10 @@ DS_FSO mainFS(VSO si)
so.target2 = rawGBuffer2;
so.target0.rgb *= si.color.rgb;
so.target2.g = lerp(so.target2.g, 0.25, si.tc0.y);
const float lamBiasRatio = 1.0 - ComputeMask(si.tc0, 0.5);
so.target2.g = lerp(so.target2.g, 0.25, lamBiasRatio * lamBiasRatio * si.psize.z);
clip(rawGBuffer1.a * mask - 0.5);
clip(rawGBuffer1.a * mask - 0.53);
return so;
}

View File

@ -204,7 +204,7 @@ DS_FSO mainFS(VSO si)
const float4 rawAlbedo = g_texAlbedo.Sample(g_samAlbedo, tc);
const float3 normal = normalize(si.normal_top.xyz);
const float gray = Grayscale(rawAlbedo.rgb);
const float mask = saturate((gray - 0.25) * 4.0 + 0.25);
const float mask = saturate((gray - 0.25) * 2.0 + 0.2);
const float top = si.normal_top.w;
const float spec = saturate(top * top * (mask + si.tcOffset_phaseShift.z * 0.1));

View File

@ -67,18 +67,16 @@ VSO mainVS(VSI si)
// World matrix, instance data:
#ifdef DEF_INSTANCED
const mataff matW = GetInstMatrix(
mataff matW = GetInstMatrix(
si.matPart0,
si.matPart1,
si.matPart2);
const float4 userColor = si.instData;
#else
const mataff matW = g_ubPerObject._matW;
mataff matW = g_ubPerObject._matW;
const float4 userColor = g_ubPerObject._userColor;
#endif
const matrix matWV = mul(ToFloat4x4(matW), ToFloat4x4(g_ubPerFrame._matV));
// Dequantize:
const float3 intactPos = DequantizeUsingDeq3D(si.pos.xyz, g_ubPerMeshVS._posDeqScale.xyz, g_ubPerMeshVS._posDeqBias.xyz);
const float2 intactTc0 = DequantizeUsingDeq2D(si.tc0.xy, g_ubPerMeshVS._tc0DeqScaleBias.xy, g_ubPerMeshVS._tc0DeqScaleBias.zw);
@ -86,6 +84,7 @@ VSO mainVS(VSI si)
const float3 intactTan = si.tan.xyz;
const float3 intactBin = si.bin.xyz;
float addLamBias = 0.0;
#if defined(DEF_SKINNED) || defined(DEF_ROBOTIC)
const float4 warpMask = float4(
1,
@ -93,10 +92,45 @@ VSO mainVS(VSI si)
si.tan.w,
si.bin.w) * GetWarpScale();
const float3 pos = ApplyWarp(intactPos, g_ubSkeletonVS._vWarpZones, warpMask);
#elif defined(DEF_PLANT)
{
const float3 normPos = NormalizePosition(si.pos.xyz);
const float weightY = saturate(normPos.y * normPos.y - 0.01);
const float3 offsetXYZ = normPos - float3(0.5, 0.8, 0.5);
const float weightXZ = saturate((dot(offsetXYZ.xz, offsetXYZ.xz) - 0.01) * 0.4);
const float phaseShiftY = frac(userColor.x + userColor.z);
const float phaseShiftXZ = frac(phaseShiftY + intactPos.x + intactPos.z);
const float2 bending = (float2(0.7, 0.5) + float2(0.3, 0.5) *
sin((g_ubPerObject._userColor.rg + float2(phaseShiftY, phaseShiftXZ)) * (_PI * 2.0))) * float2(weightY, weightXZ);
const float3x3 matW33 = (float3x3)matW;
const float3x3 matBending = (float3x3)g_ubPerObject._matW;
const float3x3 matBentW33 = mul(matW33, matBending);
const float3x3 matRandW33 = mul(matBending, matW33);
float3x3 matNewW33;
matNewW33[0] = lerp(matW33[0], matBentW33[0], bending.x);
matNewW33[1] = lerp(matW33[1], matBentW33[1], bending.x);
matNewW33[2] = lerp(matW33[2], matBentW33[2], bending.x);
matNewW33[0] = lerp(matNewW33[0], matRandW33[0], bending.y);
matNewW33[1] = lerp(matNewW33[1], matRandW33[1], bending.y);
matNewW33[2] = lerp(matNewW33[2], matRandW33[2], bending.y);
matW = mataff(
lerp(matW33[0], matNewW33[0], userColor.a),
lerp(matW33[1], matNewW33[1], userColor.a),
lerp(matW33[2], matNewW33[2], userColor.a),
matW[3]);
const float weight = 1.0 - saturate(dot(offsetXYZ, offsetXYZ));
addLamBias = (-(weight * weight * weight)) * saturate(userColor.a);
}
const float3 pos = intactPos;
#else
const float3 pos = intactPos;
#endif
const matrix matWV = mul(ToFloat4x4(matW), ToFloat4x4(g_ubPerFrame._matV));
float3 posW;
float3 nrmWV;
float3 tanWV;
@ -157,6 +191,7 @@ VSO mainVS(VSI si)
so.color0 = userColor;
#ifdef DEF_PLANT
so.color0.rgb = RandomColor(userColor.xz, 0.3, 0.2);
so.color0.a = addLamBias;
#endif
#if !defined(DEF_DEPTH) && !defined(DEF_SOLID_COLOR)
so.matTBN0 = float4(tanWV, posW.x);
@ -353,6 +388,9 @@ DS_FSO mainFS(VSO si)
float2 lamScaleBias = mm_lamScaleBias + float2(0, lightPassStrength * 8.0 * mm_lightPass);
lamScaleBias += float2(-0.1, -0.3) * alpha_spec.y + float2(0.1, 0.2); // We bring the noise!
lamScaleBias = lerp(lamScaleBias, float2(1, 0.45), skinAlpha);
#ifdef DEF_PLANT
lamScaleBias.y += si.color0.a;
#endif
// </LambertianScaleBias>
// <RimAlbedo>

View File

@ -150,5 +150,6 @@ float ToWaterDiffuseMask(float height)
float3 ReflectionDimming(float3 hdr, float scale)
{
return lerp(hdr * scale, hdr, saturate(hdr * (1.0 / 65536.0)));
const float gray = dot(hdr, 1.0 / 3.0);
return lerp(hdr * scale, hdr, saturate(gray * (1.0 / 65536.0)));
}

View File

@ -76,6 +76,16 @@ float4 ColorToSRGB(float4 x)
return float4(rgb, x.a);
}
float3 ToneMappingReinhard(float3 x)
{
return x / (1.0 + x);
}
float3 ToneMappingInvReinhard(float3 x)
{
return -x / (x - 1.0);
}
// See: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
float3 ToneMappingACES(float3 x)
{

View File

@ -3,6 +3,8 @@
float3 DequantizeUsingDeq3D(float3 v, float3 scale, float3 bias) { return v * scale + bias; }
float2 DequantizeUsingDeq2D(float2 v, float2 scale, float2 bias) { return v * scale + bias; }
float3 NormalizePosition(float3 v) { return v * (1.0 / 65535.0) + 0.5; }
mataff GetInstMatrix(float4 part0, float4 part1, float4 part2)
{
return mataff(transpose(float3x4(

View File

@ -0,0 +1,83 @@
// Copyright (C) 2020, Dmitry Maluev (dmaluev@gmail.com)
#include "Lib.hlsl"
#include "LibDepth.hlsl"
#include "Particles.inc.hlsl"
ConstantBuffer<UB_ParticlesVS> g_ubParticlesVS : register(b0, space0);
ConstantBuffer<UB_ParticlesFS> g_ubParticlesFS : register(b0, space1);
Texture2D g_tex : register(t1, space1);
SamplerState g_sam : register(s1, space1);
struct VSI
{
VK_LOCATION_POSITION float4 pos : POSITION;
VK_LOCATION(8) float2 tc0 : TEXCOORD0;
VK_LOCATION_COLOR0 float4 color : COLOR0;
VK_LOCATION_PSIZE float psize : PSIZE;
};
struct VSO
{
float4 pos : SV_Position;
float2 tc0 : TEXCOORD0;
float additive : TEXCOORD1;
float4 color0 : COLOR0;
float2 psize : PSIZE;
};
struct FSO
{
float4 color : SV_Target0;
};
#ifdef _VS
VSO mainVS(VSI si)
{
VSO so;
so.pos = mul(float4(si.pos.xyz, 1), g_ubParticlesVS._matWVP);
so.tc0 = si.tc0;
so.additive = si.pos.w;
so.color0 = si.color * float4(g_ubParticlesVS._brightness.xxx, 1);
so.psize = si.psize * (g_ubParticlesVS._viewportSize.yx * g_ubParticlesVS._viewportSize.z) * g_ubParticlesVS._matP._m11;
return so;
}
#endif
#ifdef _GS
[maxvertexcount(4)]
void mainGS(point VSO si[1], inout TriangleStream<VSO> stream)
{
VSO so;
so = si[0];
const float2 center = so.pos.xy;
const float2 tcBias = so.tc0;
for (int i = 0; i < 4; ++i)
{
so.pos.xy = center + _POINT_SPRITE_POS_OFFSETS[i] * so.psize.xy;
so.tc0.xy = _POINT_SPRITE_TEX_COORDS[i] * g_ubParticlesFS._tilesetSize.zw + tcBias;
stream.Append(so);
}
}
#endif
#ifdef _FS
FSO mainFS(VSO si)
{
FSO so;
const float4 rawColor = g_tex.Sample(g_sam, si.tc0);
so.color = rawColor * si.color0;
so.color.a *= 1.0 - si.additive;
return so;
}
#endif
//@main:# (VGF)
//@main:#Billboards

View File

@ -0,0 +1,14 @@
// Copyright (C) 2020, Dmitry Maluev (dmaluev@gmail.com)
VERUS_UBUFFER UB_ParticlesVS
{
matrix _matP;
matrix _matWVP;
float4 _viewportSize;
float4 _brightness;
};
VERUS_UBUFFER UB_ParticlesFS
{
float4 _tilesetSize;
};

View File

@ -0,0 +1,189 @@
// Copyright (C) 2020, Dmitry Maluev (dmaluev@gmail.com)
#include "Lib.hlsl"
#include "LibDeferredShading.hlsl"
#include "LibDepth.hlsl"
#include "LibLighting.hlsl"
#include "SimpleForest.inc.hlsl"
ConstantBuffer<UB_SimpleForestVS> g_ubSimpleForestVS : register(b0, space0);
ConstantBuffer<UB_SimpleForestFS> g_ubSimpleForestFS : register(b0, space1);
Texture2D g_texGBuffer0 : register(t1, space1);
SamplerState g_samGBuffer0 : register(s1, space1);
Texture2D g_texGBuffer1 : register(t2, space1);
SamplerState g_samGBuffer1 : register(s2, space1);
Texture2D g_texGBuffer2 : register(t3, space1);
SamplerState g_samGBuffer2 : register(s3, space1);
Texture2D g_texShadowCmp : register(t4, space1);
SamplerComparisonState g_samShadowCmp : register(s4, space1);
struct VSI
{
VK_LOCATION_POSITION float4 pos : POSITION;
VK_LOCATION(8) int4 tc0 : TEXCOORD0;
};
struct VSO
{
float4 pos : SV_Position;
float2 tc0 : TEXCOORD0;
float2 angles : TEXCOORD1;
float3 dirToEye : TEXCOORD2;
float4 posW_depth : TEXCOORD3;
float4 color : COLOR0;
float4 psize : PSIZE;
float clipDistance : CLIPDIST;
};
struct FSO
{
float4 color : SV_Target0;
};
#ifdef _VS
VSO mainVS(VSI si)
{
VSO so;
const float pointSpriteSize = si.tc0.x / 500.0;
const float angle = si.tc0.y / 32767.0;
const float3 toEye = g_ubSimpleForestVS._eyePos.xyz - si.pos.xyz;
const float distToScreen = length(g_ubSimpleForestVS._eyePosScreen.xyz - si.pos.xyz);
const float farAlpha = 1.0 - saturate((distToScreen - 900.0) * (1.0 / 100.0));
so.pos = mul(si.pos, g_ubSimpleForestVS._matWVP);
so.tc0 = 0.0;
so.dirToEye = toEye;
so.posW_depth = float4(si.pos.xyz, so.pos.z);
so.color.rgb = RandomColor(si.pos.xz, 0.3, 0.2);
so.color.a = farAlpha;
so.psize = (pointSpriteSize * (g_ubSimpleForestVS._viewportSize.yx * g_ubSimpleForestVS._viewportSize.z)).xyxy;
so.psize.xy *= g_ubSimpleForestVS._pointSpriteScale.xy * g_ubSimpleForestVS._matP._m11;
so.clipDistance = 0.0;
float2 param0 = toEye.xy;
float2 param1 = toEye.zz;
param0.y = max(0.0, param0.y); // Only upper hemisphere.
param1.y = length(toEye.xz); // Distance in XZ-plane.
so.angles.xy = (atan2(param0, param1) + _PI) * (0.5 / _PI); // atan2(x, z) and atan2(max(0.0, y), length(toEye.xz)). From 0 to 1.
so.angles.y = (so.angles.y - 0.5) * 4.0; // Choose this quadrant.
so.angles.xy = saturate(so.angles.xy);
so.angles.x = frac(so.angles.x - angle + 0.5); // Turn.
return so;
}
#endif
#ifdef _GS
[maxvertexcount(4)]
void mainGS(point VSO si[1], inout TriangleStream<VSO> stream)
{
VSO so;
so = si[0];
const float2 center = so.pos.xy;
const float2 centerW = so.posW_depth.xy;
for (int i = 0; i < 4; ++i)
{
so.pos.xy = center + _POINT_SPRITE_POS_OFFSETS[i] * so.psize.xy;
so.tc0.xy = _POINT_SPRITE_TEX_COORDS[i];
so.posW_depth.xy = centerW + _POINT_SPRITE_POS_OFFSETS[i] * so.psize.zw;
so.clipDistance = so.posW_depth.y;
stream.Append(so);
}
}
#endif
float2 ComputeTexCoords(float2 tc, float2 angles)
{
const float marginBias = 16.0 / 512.0;
const float marginScale = 1.0 - marginBias * 2.0;
const float2 tcMargin = tc * marginScale + marginBias;
const float2 frameCount = float2(16, 16);
const float2 frameScale = 1.0 / frameCount;
const float2 frameBias = floor(min(angles * frameCount + 0.5, float2(256, frameCount.y - 0.5)));
return (tcMargin + frameBias) * frameScale;
}
float ComputeMask(float2 tc, float alpha)
{
const float2 tcCenter = tc - 0.5;
const float rad = saturate(dot(tcCenter, tcCenter) * 4.0);
return saturate(rad + (alpha * 2.0 - 1.0));
}
#ifdef _FS
FSO mainFS(VSO si)
{
FSO so;
const float3 dirToEye = normalize(si.dirToEye.xyz);
const float depth = si.posW_depth.w;
const float2 tc = ComputeTexCoords(si.tc0, si.angles);
const float mask = ComputeMask(si.tc0, si.color.a);
const float4 rawGBuffer0 = g_texGBuffer0.Sample(g_samGBuffer0, tc);
const float4 rawGBuffer1 = g_texGBuffer1.Sample(g_samGBuffer1, tc);
const float4 rawGBuffer2 = g_texGBuffer2.Sample(g_samGBuffer2, tc);
// GBuffer0:
const float3 albedo = rawGBuffer0.rgb * 0.5;
const float spec = rawGBuffer0.a;
// GBuffer1:
const float3 normalWV = DS_GetNormal(rawGBuffer1);
const float3 normal = mul(normalWV, (float3x3)g_ubSimpleForestFS._matInvV);
const float alpha = rawGBuffer1.a;
// GBuffer2:
const float2 lamScaleBias = DS_GetLamScaleBias(rawGBuffer2);
const float gloss64 = rawGBuffer2.a * 64.0;
const float gloss = gloss64 * gloss64;
// <Shadow>
float shadowMask;
{
float4 config = g_ubSimpleForestFS._shadowConfig;
const float lamBiasMask = saturate(lamScaleBias.y * config.y);
config.y = 1.0 - lamBiasMask; // Keep penumbra blurry.
const float3 posForShadow = AdjustPosForShadow(si.posW_depth.xyz, normal, g_ubSimpleForestFS._dirToSun.xyz, depth);
const float4 tcShadow = ShadowCoords(float4(posForShadow, 1), g_ubSimpleForestFS._matSunShadow, depth);
shadowMask = SimpleShadowMapCSM(
g_texShadowCmp,
g_samShadowCmp,
tcShadow,
config,
g_ubSimpleForestFS._splitRanges,
g_ubSimpleForestFS._matSunShadow,
g_ubSimpleForestFS._matSunShadowCSM1,
g_ubSimpleForestFS._matSunShadowCSM2,
g_ubSimpleForestFS._matSunShadowCSM3);
}
// </Shadow>
const float4 litRet = VerusLit(g_ubSimpleForestFS._dirToSun.xyz, normal, dirToEye,
gloss,
lamScaleBias,
float4(0, 0, 1, 0));
const float3 diffColor = litRet.y * g_ubSimpleForestFS._sunColor.rgb * shadowMask + g_ubSimpleForestFS._ambientColor.rgb;
const float3 specColor = litRet.z * g_ubSimpleForestFS._sunColor.rgb * shadowMask * spec;
so.color.rgb = albedo * diffColor + specColor;
so.color.a = 1.0;
const float fog = ComputeFog(depth, g_ubSimpleForestFS._fogColor.a, si.posW_depth.y);
so.color.rgb = lerp(so.color.rgb, g_ubSimpleForestFS._fogColor.rgb, fog);
clip(alpha * mask * step(0.0, si.clipDistance) - 0.53);
return so;
}
#endif
//@main:# (VGF)

View File

@ -0,0 +1,26 @@
// Copyright (C) 2020, Dmitry Maluev (dmaluev@gmail.com)
VERUS_UBUFFER UB_SimpleForestVS
{
matrix _matP;
matrix _matWVP;
float4 _viewportSize;
float4 _eyePos;
float4 _eyePosScreen;
float4 _pointSpriteScale;
};
VERUS_UBUFFER UB_SimpleForestFS
{
mataff _matInvV;
float4 _ambientColor;
float4 _fogColor;
float4 _dirToSun;
float4 _sunColor;
matrix _matSunShadow;
matrix _matSunShadowCSM1;
matrix _matSunShadowCSM2;
matrix _matSunShadowCSM3;
float4 _shadowConfig;
float4 _splitRanges;
};

View File

@ -153,7 +153,8 @@ FSO mainFS(VSO si)
}
// </Water>
const float gloss = lerp(3.3, 15.0, specStrength) + waterGlossBoost;
const float gloss64 = lerp(3.3, 15.0, specStrength) + waterGlossBoost;
const float gloss = gloss64 * gloss64;
const float3 normal = normalize(si.nrmW);
const float3 dirToEye = normalize(si.dirToEye.xyz);
@ -188,7 +189,7 @@ FSO mainFS(VSO si)
const float3 diffColor = litRet.y * g_ubSimpleTerrainFS._sunColor.rgb * shadowMask + g_ubSimpleTerrainFS._ambientColor.rgb;
const float3 specColor = litRet.z * g_ubSimpleTerrainFS._sunColor.rgb * shadowMask * specStrength;
so.color.rgb = albedo.rgb * 0.5 * diffColor + specColor;
so.color.rgb = (albedo.rgb * 0.5) * diffColor + specColor;
so.color.a = 1.0;
const float fog = ComputeFog(depth, g_ubSimpleTerrainFS._fogColor.a, si.posW_depth.y);

View File

@ -151,7 +151,7 @@ FSO mainFS(VSO si)
const float3 skyColor = rawSky.rgb + rand * lerp(0.001, 0.01, rawSky.rgb); // Dithering.
const float4 rawStars = g_texStars.Sample(g_samStars, si.tcStars);
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * (10.0 + 5.0 * sunBoost);
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * (6.0 + 6.0 * sunBoost);
so.color = float4(skyColor.rgb * hdrScale + rawStars.rgb * 20.0, 1);
#endif

View File

@ -273,7 +273,7 @@ FSO mainFS(VSO si)
{
const float diffuseMask = ToWaterDiffuseMask(landHeight);
planktonColor = lerp(g_ubWaterFS._diffuseColorDeep.rgb, g_ubWaterFS._diffuseColorShallow.rgb, diffuseMask);
planktonColor *= 0.3 + 0.2 * saturate(shade - wave);
planktonColor *= 0.1 + 0.2 * saturate(shade - wave);
refractMask = saturate((diffuseMask - 0.5) * 2.0);
}
// </Plankton>
@ -312,7 +312,7 @@ FSO mainFS(VSO si)
float4(0, 0, 1, 0),
1.0);
const float fresnelTerm = FresnelSchlick(0.03, 0.6 * fresnelDimmer, litRet.w);
const float fresnelTerm = FresnelSchlick(0.03, 0.5 * fresnelDimmer, litRet.w);
const float3 diff = litRet.y * g_ubWaterFS._sunColor.rgb * shadowMask + g_ubWaterFS._ambientColor.rgb;
const float3 diffColorFoam = foamColor.rgb * diff;

View File

@ -1,6 +1,6 @@
#pragma once
// Last updated on 13-Jun-2020
// Last updated on 5-Sep-2020
// Base64 (https://sourceforge.net/projects/libb64/):
#ifdef _WIN32

View File

@ -15,7 +15,7 @@
double fast_atof (const char *p)
{
int frac = 0;
int frac;
double sign, value, scale;
// Skip leading white space, if any.
@ -37,10 +37,8 @@ double fast_atof (const char *p)
// Get digits before decimal point or exponent, if any.
value = 0.0;
while (valid_digit(*p)) {
for (value = 0.0; valid_digit(*p); p += 1) {
value = value * 10.0 + (*p - '0');
p += 1;
}
// Get digits after decimal point, if any.
@ -48,7 +46,6 @@ double fast_atof (const char *p)
if (*p == '.') {
double pow10 = 10.0;
p += 1;
while (valid_digit(*p)) {
value += (*p - '0') / pow10;
pow10 *= 10.0;
@ -58,14 +55,14 @@ double fast_atof (const char *p)
// Handle exponent, if any.
frac = 0;
scale = 1.0;
if ((*p == 'e') || (*p == 'E')) {
unsigned int expon;
p += 1;
// Get sign of exponent, if any.
frac = 0;
p += 1;
if (*p == '-') {
frac = 1;
p += 1;
@ -76,10 +73,8 @@ double fast_atof (const char *p)
// Get digits of exponent, if any.
expon = 0;
while (valid_digit(*p)) {
for (expon = 0; valid_digit(*p); p += 1) {
expon = expon * 10 + (*p - '0');
p += 1;
}
if (expon > 308) expon = 308;

View File

@ -77,5 +77,11 @@ build_script:
test_script:
- ctest -j4 -C %CONFIGURATION%
- cd ..
- ps: |
mkdir build_test_cmake
cd build_test_cmake
cmake ..\test\cmake\ -G "$env:generator" -Dglm_DIR="$env:APPVEYOR_BUILD_FOLDER/cmake/glm/"
- cmake --build . --config %CONFIGURATION% -- /m /v:minimal
deploy: off

View File

@ -33,6 +33,8 @@ CMakeFiles
cmake_install.cmake
install_manifest.txt
*.cmake
!glmConfig.cmake
!glmConfig-version.cmake
# ^ May need to add future .cmake files as exceptions
# Test logs
@ -56,3 +58,4 @@ build*
/.vscode
/CMakeSettings.json
.DS_Store
*.swp

View File

@ -11,6 +11,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_DISABLE_AUTO_DETECTION=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++unknown-release"
@ -23,6 +28,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++98-pure-release"
@ -35,6 +45,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++98-pure-ms-release"
@ -47,6 +62,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++11-pure-release"
@ -59,6 +79,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++11-sse2-release"
@ -71,6 +96,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++14-pure-release"
@ -83,6 +113,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++14-sse3-release"
@ -95,6 +130,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++14-avx-release"
@ -107,6 +147,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++14-avx-debug"
@ -119,6 +164,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++17-pure-release"
@ -131,6 +181,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++17-pure-debug"
@ -143,6 +198,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++17-avx-release"
@ -155,6 +215,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
env:
- MATRIX_EVAL="INFO=C++17-avx-debug"
@ -174,6 +239,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -191,6 +261,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -208,6 +283,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -225,6 +305,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -242,6 +327,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -259,6 +349,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -276,6 +371,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -293,6 +393,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -310,6 +415,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -327,6 +437,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -344,6 +459,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -361,6 +481,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -378,6 +503,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -395,6 +525,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -412,6 +547,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -429,6 +569,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX2=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -447,6 +592,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -465,6 +615,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
addons:
@ -483,11 +638,16 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
dist: bionic
env:
- MATRIX_EVAL="CC=clang-7.0 && INFO=C++17-pure-release"
- MATRIX_EVAL="CC=clang && CXX=clang++ && INFO=C++17-pure-release"
script:
- cmake --version
- mkdir ./build_pure_17_release
@ -495,11 +655,16 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
dist: bionic
env:
- MATRIX_EVAL="CC=clang-7.0 && INFO=C++17-pure-debug"
- MATRIX_EVAL="CC=clang && CXX=clang++ && INFO=C++17-pure-debug"
script:
- cmake --version
- mkdir ./build_pure_17_debug
@ -507,11 +672,16 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
dist: bionic
env:
- MATRIX_EVAL="CC=clang-7.0 && INFO=C++17-sse3-release"
- MATRIX_EVAL="CC=clang && CXX=clang++ && INFO=C++17-sse3-release
script:
- cmake --version
- mkdir ./build_sse3_17_release
@ -519,11 +689,16 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
dist: bionic
env:
- MATRIX_EVAL="CC=clang-7.0 && INFO=C++17-sse3-debug"
- MATRIX_EVAL="CC=clang && CXX=clang++ && INFO=C++17-sse3-debug"
script:
- cmake --version
- mkdir ./build_sse3_17_debug
@ -531,11 +706,16 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
- os: linux
dist: bionic
env:
- MATRIX_EVAL="CC=clang-7.0 && INFO=C++17-ssse3-release"
- MATRIX_EVAL="CC=clang && CXX=clang++ && INFO=C++17-ssse3-release"
script:
- cmake --version
- mkdir ./build_ssse3_17_release
@ -543,6 +723,11 @@ matrix:
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSSE3=ON ..
- cmake -E time cmake --build .
- ctest
- cd $TRAVIS_BUILD_DIR
- mkdir ./build_test_cmake
- cd ./build_test_cmake
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -Dglm_DIR=$TRAVIS_BUILD_DIR/cmake/glm/
- cmake --build .
before_install:
- eval "${MATRIX_EVAL}"

View File

@ -0,0 +1,11 @@
if(${PACKAGE_FIND_VERSION_MAJOR} EQUAL 0)
if (${PACKAGE_FIND_VERSION} VERSION_LESS ${GLM_VERSION})
set(PACKAGE_VERSION_COMPATIBLE 1)
endif()
if(${PACKAGE_FIND_VERSION} VERSION_EQUAL ${GLM_VERSION})
set(PACKAGE_VERSION_EXACT 1)
endif()
else()
set(PACKAGE_VERSION_UNSUITABLE 1)
endif()

View File

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
cmake_policy(VERSION 3.2)
set(GLM_VERSION 0.9.9)
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if (_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Set the old GLM_INCLUDE_DIRS variable for backwards compatibility
set(GLM_INCLUDE_DIRS ${_IMPORT_PREFIX})
add_library(glm::glm INTERFACE IMPORTED)
set_target_properties(glm::glm PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${GLM_INCLUDE_DIRS})
mark_as_advanced(glm_DIR)
set(_IMPORT_PREFIX)

View File

@ -105,7 +105,7 @@ namespace detail
{
GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v)
{
return compute_dot<vec<4, float, Q>, float, true>::call(v, v);
return sqrt(compute_dot<vec<4, float, Q>, float, true>::call(v, v));
}
};
@ -126,9 +126,7 @@ namespace detail
{
#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
float32x4_t v = vmulq_f32(x.data, y.data);
v = vpaddq_f32(v, v);
v = vpaddq_f32(v, v);
return vgetq_lane_f32(v, 0);
return vaddvq_f32(v);
#else // Armv7a with Neon
float32x4_t p = vmulq_f32(x.data, y.data);
float32x2_t v = vpadd_f32(vget_low_f32(p), vget_high_f32(p));

View File

@ -6,9 +6,9 @@
#define GLM_VERSION_MAJOR 0
#define GLM_VERSION_MINOR 9
#define GLM_VERSION_PATCH 9
#define GLM_VERSION_REVISION 7
#define GLM_VERSION 997
#define GLM_VERSION_MESSAGE "GLM: version 0.9.9.7"
#define GLM_VERSION_REVISION 8
#define GLM_VERSION 998
#define GLM_VERSION_MESSAGE "GLM: version 0.9.9.8"
#define GLM_SETUP_INCLUDED GLM_VERSION

View File

@ -485,35 +485,35 @@ namespace glm
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(T scalar, vec<1, T, Q> const& v)
{
return vec<1, T, Q>(
scalar << v.x);
static_cast<T>(scalar << v.x));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2)
{
return vec<1, T, Q>(
v1.x << v2.x);
static_cast<T>(v1.x << v2.x));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v, T scalar)
{
return vec<1, T, Q>(
v.x >> scalar);
static_cast<T>(v.x >> scalar));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(T scalar, vec<1, T, Q> const& v)
{
return vec<1, T, Q>(
scalar >> v.x);
static_cast<T>(scalar >> v.x));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2)
{
return vec<1, T, Q>(
v1.x >> v2.x);
static_cast<T>(v1.x >> v2.x));
}
template<typename T, qualifier Q>

View File

@ -13,6 +13,9 @@
# pragma message("GLM: All extensions included (not recommended)")
#endif//GLM_MESSAGES
#include "./ext/matrix_clip_space.hpp"
#include "./ext/matrix_common.hpp"
#include "./ext/matrix_double2x2.hpp"
#include "./ext/matrix_double2x2_precision.hpp"
#include "./ext/matrix_double2x3.hpp"
@ -51,18 +54,74 @@
#include "./ext/matrix_float4x4.hpp"
#include "./ext/matrix_float4x4_precision.hpp"
#include "./ext/matrix_relational.hpp"
#include "./ext/matrix_int2x2.hpp"
#include "./ext/matrix_int2x2_sized.hpp"
#include "./ext/matrix_int2x3.hpp"
#include "./ext/matrix_int2x3_sized.hpp"
#include "./ext/matrix_int2x4.hpp"
#include "./ext/matrix_int2x4_sized.hpp"
#include "./ext/matrix_int3x2.hpp"
#include "./ext/matrix_int3x2_sized.hpp"
#include "./ext/matrix_int3x3.hpp"
#include "./ext/matrix_int3x3_sized.hpp"
#include "./ext/matrix_int3x4.hpp"
#include "./ext/matrix_int3x4_sized.hpp"
#include "./ext/matrix_int4x2.hpp"
#include "./ext/matrix_int4x2_sized.hpp"
#include "./ext/matrix_int4x3.hpp"
#include "./ext/matrix_int4x3_sized.hpp"
#include "./ext/matrix_int4x4.hpp"
#include "./ext/matrix_int4x4_sized.hpp"
#include "./ext/matrix_uint2x2.hpp"
#include "./ext/matrix_uint2x2_sized.hpp"
#include "./ext/matrix_uint2x3.hpp"
#include "./ext/matrix_uint2x3_sized.hpp"
#include "./ext/matrix_uint2x4.hpp"
#include "./ext/matrix_uint2x4_sized.hpp"
#include "./ext/matrix_uint3x2.hpp"
#include "./ext/matrix_uint3x2_sized.hpp"
#include "./ext/matrix_uint3x3.hpp"
#include "./ext/matrix_uint3x3_sized.hpp"
#include "./ext/matrix_uint3x4.hpp"
#include "./ext/matrix_uint3x4_sized.hpp"
#include "./ext/matrix_uint4x2.hpp"
#include "./ext/matrix_uint4x2_sized.hpp"
#include "./ext/matrix_uint4x3.hpp"
#include "./ext/matrix_uint4x3_sized.hpp"
#include "./ext/matrix_uint4x4.hpp"
#include "./ext/matrix_uint4x4_sized.hpp"
#include "./ext/matrix_projection.hpp"
#include "./ext/matrix_relational.hpp"
#include "./ext/matrix_transform.hpp"
#include "./ext/quaternion_common.hpp"
#include "./ext/quaternion_double.hpp"
#include "./ext/quaternion_double_precision.hpp"
#include "./ext/quaternion_float.hpp"
#include "./ext/quaternion_float_precision.hpp"
#include "./ext/quaternion_exponential.hpp"
#include "./ext/quaternion_geometric.hpp"
#include "./ext/quaternion_relational.hpp"
#include "./ext/quaternion_transform.hpp"
#include "./ext/quaternion_trigonometric.hpp"
#include "./ext/scalar_common.hpp"
#include "./ext/scalar_constants.hpp"
#include "./ext/scalar_int_sized.hpp"
#include "./ext/scalar_integer.hpp"
#include "./ext/scalar_packing.hpp"
#include "./ext/scalar_relational.hpp"
#include "./ext/scalar_ulp.hpp"
#include "./ext/scalar_int_sized.hpp"
#include "./ext/scalar_uint_sized.hpp"
#include "./ext/vector_common.hpp"
#include "./ext/vector_integer.hpp"
#include "./ext/vector_packing.hpp"
#include "./ext/vector_relational.hpp"
#include "./ext/vector_ulp.hpp"
#include "./ext/vector_bool1.hpp"
#include "./ext/vector_bool1_precision.hpp"
@ -92,24 +151,22 @@
#include "./ext/vector_float4_precision.hpp"
#include "./ext/vector_int1.hpp"
#include "./ext/vector_int1_precision.hpp"
#include "./ext/vector_int1_sized.hpp"
#include "./ext/vector_int2.hpp"
#include "./ext/vector_int2_precision.hpp"
#include "./ext/vector_int2_sized.hpp"
#include "./ext/vector_int3.hpp"
#include "./ext/vector_int3_precision.hpp"
#include "./ext/vector_int3_sized.hpp"
#include "./ext/vector_int4.hpp"
#include "./ext/vector_int4_precision.hpp"
#include "./ext/vector_relational.hpp"
#include "./ext/vector_int4_sized.hpp"
#include "./ext/vector_uint1.hpp"
#include "./ext/vector_uint1_precision.hpp"
#include "./ext/vector_uint1_sized.hpp"
#include "./ext/vector_uint2.hpp"
#include "./ext/vector_uint2_precision.hpp"
#include "./ext/vector_uint2_sized.hpp"
#include "./ext/vector_uint3.hpp"
#include "./ext/vector_uint3_precision.hpp"
#include "./ext/vector_uint3_sized.hpp"
#include "./ext/vector_uint4.hpp"
#include "./ext/vector_uint4_precision.hpp"
#include "./ext/vector_uint4_sized.hpp"
#include "./gtc/bitfield.hpp"
#include "./gtc/color_space.hpp"

View File

@ -0,0 +1,38 @@
/// @ref ext_matrix_int2x2
/// @file glm/ext/matrix_int2x2.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int2x2 GLM_EXT_matrix_int2x2
/// @ingroup ext
///
/// Include <glm/ext/matrix_int2x2.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat2x2.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int2x2 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int2x2
/// @{
/// Signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2
typedef mat<2, 2, int, defaultp> imat2x2;
/// Signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2
typedef mat<2, 2, int, defaultp> imat2;
/// @}
}//namespace glm

View File

@ -0,0 +1,70 @@
/// @ref ext_matrix_int2x2_sized
/// @file glm/ext/matrix_int2x2_sized.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int2x2_sized GLM_EXT_matrix_int2x2_sized
/// @ingroup ext
///
/// Include <glm/ext/matrix_int2x2_sized.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat2x2.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int2x2_sized extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int2x2_sized
/// @{
/// 8 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int8, defaultp> i8mat2x2;
/// 16 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int16, defaultp> i16mat2x2;
/// 32 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int32, defaultp> i32mat2x2;
/// 64 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int64, defaultp> i64mat2x2;
/// 8 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int8, defaultp> i8mat2;
/// 16 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int16, defaultp> i16mat2;
/// 32 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int32, defaultp> i32mat2;
/// 64 bit signed integer 2x2 matrix.
///
/// @see ext_matrix_int2x2_sized
typedef mat<2, 2, int64, defaultp> i64mat2;
/// @}
}//namespace glm

View File

@ -0,0 +1,33 @@
/// @ref ext_matrix_int2x3
/// @file glm/ext/matrix_int2x3.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int2x3 GLM_EXT_matrix_int2x3
/// @ingroup ext
///
/// Include <glm/ext/matrix_int2x3.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat2x3.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int2x3 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int2x3
/// @{
/// Signed integer 2x3 matrix.
///
/// @see ext_matrix_int2x3
typedef mat<2, 3, int, defaultp> imat2x3;
/// @}
}//namespace glm

View File

@ -0,0 +1,49 @@
/// @ref ext_matrix_int2x3_sized
/// @file glm/ext/matrix_int2x3_sized.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int2x3_sized GLM_EXT_matrix_int2x3_sized
/// @ingroup ext
///
/// Include <glm/ext/matrix_int2x3_sized.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat2x3.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int2x3_sized extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int2x3_sized
/// @{
/// 8 bit signed integer 2x3 matrix.
///
/// @see ext_matrix_int2x3_sized
typedef mat<2, 3, int8, defaultp> i8mat2x3;
/// 16 bit signed integer 2x3 matrix.
///
/// @see ext_matrix_int2x3_sized
typedef mat<2, 3, int16, defaultp> i16mat2x3;
/// 32 bit signed integer 2x3 matrix.
///
/// @see ext_matrix_int2x3_sized
typedef mat<2, 3, int32, defaultp> i32mat2x3;
/// 64 bit signed integer 2x3 matrix.
///
/// @see ext_matrix_int2x3_sized
typedef mat<2, 3, int64, defaultp> i64mat2x3;
/// @}
}//namespace glm

View File

@ -0,0 +1,33 @@
/// @ref ext_matrix_int2x4
/// @file glm/ext/matrix_int2x4.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int2x4 GLM_EXT_matrix_int2x4
/// @ingroup ext
///
/// Include <glm/ext/matrix_int2x4.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat2x4.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int2x4 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int2x4
/// @{
/// Signed integer 2x4 matrix.
///
/// @see ext_matrix_int2x4
typedef mat<2, 4, int, defaultp> imat2x4;
/// @}
}//namespace glm

View File

@ -0,0 +1,49 @@
/// @ref ext_matrix_int2x4_sized
/// @file glm/ext/matrix_int2x4_sized.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int2x4_sized GLM_EXT_matrix_int2x4_sized
/// @ingroup ext
///
/// Include <glm/ext/matrix_int2x4_sized.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat2x4.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int2x4_sized extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int2x4_sized
/// @{
/// 8 bit signed integer 2x4 matrix.
///
/// @see ext_matrix_int2x4_sized
typedef mat<2, 4, int8, defaultp> i8mat2x4;
/// 16 bit signed integer 2x4 matrix.
///
/// @see ext_matrix_int2x4_sized
typedef mat<2, 4, int16, defaultp> i16mat2x4;
/// 32 bit signed integer 2x4 matrix.
///
/// @see ext_matrix_int2x4_sized
typedef mat<2, 4, int32, defaultp> i32mat2x4;
/// 64 bit signed integer 2x4 matrix.
///
/// @see ext_matrix_int2x4_sized
typedef mat<2, 4, int64, defaultp> i64mat2x4;
/// @}
}//namespace glm

View File

@ -0,0 +1,33 @@
/// @ref ext_matrix_int3x2
/// @file glm/ext/matrix_int3x2.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int3x2 GLM_EXT_matrix_int3x2
/// @ingroup ext
///
/// Include <glm/ext/matrix_int3x2.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat3x2.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int3x2 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int3x2
/// @{
/// Signed integer 3x2 matrix.
///
/// @see ext_matrix_int3x2
typedef mat<3, 2, int, defaultp> imat3x2;
/// @}
}//namespace glm

View File

@ -0,0 +1,49 @@
/// @ref ext_matrix_int3x2_sized
/// @file glm/ext/matrix_int3x2_sized.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int3x2_sized GLM_EXT_matrix_int3x2_sized
/// @ingroup ext
///
/// Include <glm/ext/matrix_int3x2_sized.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat3x2.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int3x2_sized extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int3x2_sized
/// @{
/// 8 bit signed integer 3x2 matrix.
///
/// @see ext_matrix_int3x2_sized
typedef mat<3, 2, int8, defaultp> i8mat3x2;
/// 16 bit signed integer 3x2 matrix.
///
/// @see ext_matrix_int3x2_sized
typedef mat<3, 2, int16, defaultp> i16mat3x2;
/// 32 bit signed integer 3x2 matrix.
///
/// @see ext_matrix_int3x2_sized
typedef mat<3, 2, int32, defaultp> i32mat3x2;
/// 64 bit signed integer 3x2 matrix.
///
/// @see ext_matrix_int3x2_sized
typedef mat<3, 2, int64, defaultp> i64mat3x2;
/// @}
}//namespace glm

View File

@ -0,0 +1,38 @@
/// @ref ext_matrix_int3x3
/// @file glm/ext/matrix_int3x3.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int3x3 GLM_EXT_matrix_int3x3
/// @ingroup ext
///
/// Include <glm/ext/matrix_int3x3.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat3x3.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int3x3 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int3x3
/// @{
/// Signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3
typedef mat<3, 3, int, defaultp> imat3x3;
/// Signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3
typedef mat<3, 3, int, defaultp> imat3;
/// @}
}//namespace glm

View File

@ -0,0 +1,70 @@
/// @ref ext_matrix_int3x3_sized
/// @file glm/ext/matrix_int3x3_sized.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int3x3_sized GLM_EXT_matrix_int3x3_sized
/// @ingroup ext
///
/// Include <glm/ext/matrix_int3x3_sized.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat3x3.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int3x3_sized extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int3x3_sized
/// @{
/// 8 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int8, defaultp> i8mat3x3;
/// 16 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int16, defaultp> i16mat3x3;
/// 32 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int32, defaultp> i32mat3x3;
/// 64 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int64, defaultp> i64mat3x3;
/// 8 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int8, defaultp> i8mat3;
/// 16 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int16, defaultp> i16mat3;
/// 32 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int32, defaultp> i32mat3;
/// 64 bit signed integer 3x3 matrix.
///
/// @see ext_matrix_int3x3_sized
typedef mat<3, 3, int64, defaultp> i64mat3;
/// @}
}//namespace glm

View File

@ -0,0 +1,33 @@
/// @ref ext_matrix_int3x4
/// @file glm/ext/matrix_int3x4.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int3x4 GLM_EXT_matrix_int3x4
/// @ingroup ext
///
/// Include <glm/ext/matrix_int3x4.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat3x4.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int3x4 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int3x4
/// @{
/// Signed integer 3x4 matrix.
///
/// @see ext_matrix_int3x4
typedef mat<3, 4, int, defaultp> imat3x4;
/// @}
}//namespace glm

View File

@ -0,0 +1,49 @@
/// @ref ext_matrix_int3x4_sized
/// @file glm/ext/matrix_int3x2_sized.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int3x4_sized GLM_EXT_matrix_int3x4_sized
/// @ingroup ext
///
/// Include <glm/ext/matrix_int3x4_sized.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat3x4.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int3x4_sized extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int3x4_sized
/// @{
/// 8 bit signed integer 3x4 matrix.
///
/// @see ext_matrix_int3x4_sized
typedef mat<3, 4, int8, defaultp> i8mat3x4;
/// 16 bit signed integer 3x4 matrix.
///
/// @see ext_matrix_int3x4_sized
typedef mat<3, 4, int16, defaultp> i16mat3x4;
/// 32 bit signed integer 3x4 matrix.
///
/// @see ext_matrix_int3x4_sized
typedef mat<3, 4, int32, defaultp> i32mat3x4;
/// 64 bit signed integer 3x4 matrix.
///
/// @see ext_matrix_int3x4_sized
typedef mat<3, 4, int64, defaultp> i64mat3x4;
/// @}
}//namespace glm

View File

@ -0,0 +1,33 @@
/// @ref ext_matrix_int4x2
/// @file glm/ext/matrix_int4x2.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int4x2 GLM_EXT_matrix_int4x2
/// @ingroup ext
///
/// Include <glm/ext/matrix_int4x2.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat4x2.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int4x2 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int4x2
/// @{
/// Signed integer 4x2 matrix.
///
/// @see ext_matrix_int4x2
typedef mat<4, 2, int, defaultp> imat4x2;
/// @}
}//namespace glm

View File

@ -0,0 +1,49 @@
/// @ref ext_matrix_int4x2_sized
/// @file glm/ext/matrix_int4x2_sized.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int4x2_sized GLM_EXT_matrix_int4x2_sized
/// @ingroup ext
///
/// Include <glm/ext/matrix_int4x2_sized.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat4x2.hpp"
#include "../ext/scalar_int_sized.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int4x2_sized extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int4x2_sized
/// @{
/// 8 bit signed integer 4x2 matrix.
///
/// @see ext_matrix_int4x2_sized
typedef mat<4, 2, int8, defaultp> i8mat4x2;
/// 16 bit signed integer 4x2 matrix.
///
/// @see ext_matrix_int4x2_sized
typedef mat<4, 2, int16, defaultp> i16mat4x2;
/// 32 bit signed integer 4x2 matrix.
///
/// @see ext_matrix_int4x2_sized
typedef mat<4, 2, int32, defaultp> i32mat4x2;
/// 64 bit signed integer 4x2 matrix.
///
/// @see ext_matrix_int4x2_sized
typedef mat<4, 2, int64, defaultp> i64mat4x2;
/// @}
}//namespace glm

View File

@ -0,0 +1,33 @@
/// @ref ext_matrix_int4x3
/// @file glm/ext/matrix_int4x3.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_matrix_int4x3 GLM_EXT_matrix_int4x3
/// @ingroup ext
///
/// Include <glm/ext/matrix_int4x3.hpp> to use the features of this extension.
///
/// Defines a number of matrices with integer types.
#pragma once
// Dependency:
#include "../mat4x3.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_matrix_int4x3 extension included")
#endif
namespace glm
{
/// @addtogroup ext_matrix_int4x3
/// @{
/// Signed integer 4x3 matrix.
///
/// @see ext_matrix_int4x3
typedef mat<4, 3, int, defaultp> imat4x3;
/// @}
}//namespace glm

Some files were not shown because too many files have changed in this diff Show More