summaryrefslogtreecommitdiff
path: root/tools/gfx
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-01-06 12:58:57 -0800
committerGitHub <noreply@github.com>2021-01-06 12:58:57 -0800
commit92636513abe72d2da0c45f0e2c1235415e0671c3 (patch)
tree234136e9d89006df9d6775e8bcd07e91ae344af7 /tools/gfx
parent706d4f91e269d473c963d31792fb2c8320933c9b (diff)
Refactor GUI/Window utils out of gfx library (#1649)
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'tools/gfx')
-rw-r--r--tools/gfx/cuda/render-cuda.cpp2
-rw-r--r--tools/gfx/d3d/d3d-util.h6
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp2
-rw-r--r--tools/gfx/d3d12/circular-resource-heap-d3d12.h6
-rw-r--r--tools/gfx/d3d12/descriptor-heap-d3d12.h4
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp2
-rw-r--r--tools/gfx/d3d12/resource-d3d12.h2
-rw-r--r--tools/gfx/gui.cpp415
-rw-r--r--tools/gfx/gui.h28
-rw-r--r--tools/gfx/model.cpp564
-rw-r--r--tools/gfx/model.h77
-rw-r--r--tools/gfx/nvapi/nvapi-util.h4
-rw-r--r--tools/gfx/render.h2
-rw-r--r--tools/gfx/vector-math.h15
-rw-r--r--tools/gfx/vulkan/render-vk.cpp2
-rw-r--r--tools/gfx/vulkan/vk-api.cpp2
-rw-r--r--tools/gfx/vulkan/vk-module.h4
-rw-r--r--tools/gfx/vulkan/vk-swap-chain.cpp2
-rw-r--r--tools/gfx/vulkan/vk-swap-chain.h2
-rw-r--r--tools/gfx/window.h122
-rw-r--r--tools/gfx/windows/win-window.cpp398
21 files changed, 20 insertions, 1641 deletions
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp
index cf77e4ef6..f12e8ee89 100644
--- a/tools/gfx/cuda/render-cuda.cpp
+++ b/tools/gfx/cuda/render-cuda.cpp
@@ -4,7 +4,7 @@
#include "../render.h"
#include <cuda.h>
#include <cuda_runtime_api.h>
-#include "../../source/core/slang-std-writers.h"
+#include "core/slang-std-writers.h"
#include "slang.h"
#endif
diff --git a/tools/gfx/d3d/d3d-util.h b/tools/gfx/d3d/d3d-util.h
index fd7a31d3a..37c277832 100644
--- a/tools/gfx/d3d/d3d-util.h
+++ b/tools/gfx/d3d/d3d-util.h
@@ -3,10 +3,10 @@
#include <stdint.h>
-#include "../../slang-com-helper.h"
+#include "slang-com-helper.h"
-#include "../../slang-com-ptr.h"
-#include "../../source/core/slang-list.h"
+#include "slang-com-ptr.h"
+#include "core/slang-list.h"
#include "../flag-combiner.h"
diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp
index 48cf7770d..5c04eccf1 100644
--- a/tools/gfx/d3d11/render-d3d11.cpp
+++ b/tools/gfx/d3d11/render-d3d11.cpp
@@ -16,7 +16,7 @@
//#include <slang.h>
-#include "../../slang-com-ptr.h"
+#include "slang-com-ptr.h"
#include "../flag-combiner.h"
// We will be rendering with Direct3D 11, so we need to include
diff --git a/tools/gfx/d3d12/circular-resource-heap-d3d12.h b/tools/gfx/d3d12/circular-resource-heap-d3d12.h
index bf9f412cf..7eacf9572 100644
--- a/tools/gfx/d3d12/circular-resource-heap-d3d12.h
+++ b/tools/gfx/d3d12/circular-resource-heap-d3d12.h
@@ -1,8 +1,8 @@
#pragma once
-#include "../../slang-com-ptr.h"
-#include "../../source/core/slang-list.h"
-#include "../../source/core/slang-free-list.h"
+#include "slang-com-ptr.h"
+#include "core/slang-list.h"
+#include "core/slang-free-list.h"
#include "resource-d3d12.h"
diff --git a/tools/gfx/d3d12/descriptor-heap-d3d12.h b/tools/gfx/d3d12/descriptor-heap-d3d12.h
index a546395d8..642ff59db 100644
--- a/tools/gfx/d3d12/descriptor-heap-d3d12.h
+++ b/tools/gfx/d3d12/descriptor-heap-d3d12.h
@@ -4,8 +4,8 @@
#include <dxgi.h>
#include <d3d12.h>
-#include "../../slang-com-ptr.h"
-#include "../../source/core/slang-list.h"
+#include "slang-com-ptr.h"
+#include "core/slang-list.h"
namespace gfx {
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index d3f030b88..0376ee304 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -35,7 +35,7 @@ struct ID3D12GraphicsCommandList1 {};
# include "../nvapi/nvapi-include.h"
#endif
-#include "../../slang-com-ptr.h"
+#include "slang-com-ptr.h"
#include "../flag-combiner.h"
#include "resource-d3d12.h"
diff --git a/tools/gfx/d3d12/resource-d3d12.h b/tools/gfx/d3d12/resource-d3d12.h
index 9e3c3262b..7a26854ff 100644
--- a/tools/gfx/d3d12/resource-d3d12.h
+++ b/tools/gfx/d3d12/resource-d3d12.h
@@ -10,7 +10,7 @@
#include <dxgi1_4.h>
#include <d3d12.h>
-#include "../../slang-com-ptr.h"
+#include "slang-com-ptr.h"
#include "../d3d/d3d-util.h"
namespace gfx {
diff --git a/tools/gfx/gui.cpp b/tools/gfx/gui.cpp
deleted file mode 100644
index 8208bd606..000000000
--- a/tools/gfx/gui.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-// gui.cpp
-#include "gui.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#include "external/imgui/examples/imgui_impl_win32.h"
-IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
-#endif
-
-
-namespace gfx {
-
-#ifdef _WIN32
-LRESULT CALLBACK guiWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- LRESULT handled = ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam);
- if(handled) return handled;
- ImGuiIO& io = ImGui::GetIO();
-
- switch( msg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- if(io.WantCaptureMouse) handled = 1;
- break;
-
- case WM_KEYDOWN:
- case WM_KEYUP:
- if(io.WantCaptureKeyboard) handled = 1;
- break;
- }
-
- return handled;
-}
-void setNativeWindowHook(Window* window, WNDPROC proc);
-#endif
-
-
-GUI::GUI(Window* window, Renderer* inRenderer)
- : renderer(inRenderer)
-{
- ImGui::CreateContext();
- ImGuiIO& io = ImGui::GetIO();
-
-#ifdef _WIN32
- ImGui_ImplWin32_Init(getPlatformWindowHandle(window));
-
- setNativeWindowHook(window, &guiWindowProc);
-#endif
-
- // Let's do the initialization work required for our graphics API
- // abstraction layer, so that we can pipe all IMGUI rendering
- // through the same interface as other work.
- //
-
- static const char* shaderCode =
- "cbuffer U { float4x4 mvp; }; \
- Texture2D t; \
- SamplerState s; \
- struct AssembledVertex { \
- float2 pos; \
- float2 uv; \
- float4 col; \
- }; \
- struct CoarseVertex { \
- float4 col; \
- float2 uv; \
- }; \
- struct VSOutput { \
- CoarseVertex cv : U; \
- float4 pos : SV_Position; \
- }; \
- void vertexMain( \
- AssembledVertex i : U, \
- out VSOutput o) \
- { \
- o.cv.col = i.col; \
- o.cv.uv = i.uv; \
- o.pos = mul(mvp, \
- float4(i.pos.xy, 0.f, 1.f)); \
- } \
- float4 fragmentMain( \
- CoarseVertex i : U) \
- : SV_target \
- { \
- return i.col * t.Sample(s, i.uv); \
- } \
- ";
-
- SlangSession* slangSession = spCreateSession(nullptr);
- SlangCompileRequest* slangRequest = spCreateCompileRequest(slangSession);
-
- // TODO: These two lines need to change based on what the target graphics API
- // is, so we need a way for a `Renderer` to pass back its prefeerred code
- // format and profile name...
- //
- int targetIndex = spAddCodeGenTarget(slangRequest, SLANG_DXBC);
- spSetTargetProfile(slangRequest, targetIndex, spFindProfile(slangSession, "sm_4_0"));
-
- int translationUnitIndex = spAddTranslationUnit(slangRequest, SLANG_SOURCE_LANGUAGE_SLANG, nullptr);
- spAddTranslationUnitSourceString(slangRequest, translationUnitIndex, "gui.cpp.slang", shaderCode);
-
- char const* vertexEntryPointName = "vertexMain";
- char const* fragmentEntryPointName = "fragmentMain";
- int vertexIndex = spAddEntryPoint(slangRequest, translationUnitIndex, vertexEntryPointName, SLANG_STAGE_VERTEX);
- int fragmentIndex = spAddEntryPoint(slangRequest, translationUnitIndex, fragmentEntryPointName, SLANG_STAGE_FRAGMENT);
-
- const SlangResult compileRes = spCompile(slangRequest);
- if(auto diagnostics = spGetDiagnosticOutput(slangRequest))
- {
- reportError("%s", diagnostics);
- }
- if(SLANG_FAILED(compileRes))
- {
- spDestroyCompileRequest(slangRequest);
- spDestroySession(slangSession);
- assert(!"unexpected");
- return;
- }
-
- ISlangBlob* vertexShaderBlob = nullptr;
- spGetEntryPointCodeBlob(slangRequest, vertexIndex, 0, &vertexShaderBlob);
-
- ISlangBlob* fragmentShaderBlob = nullptr;
- spGetEntryPointCodeBlob(slangRequest, fragmentIndex, 0, &fragmentShaderBlob);
-
- char const* vertexCode = (char const*) vertexShaderBlob->getBufferPointer();
- char const* vertexCodeEnd = vertexCode + vertexShaderBlob->getBufferSize();
-
- char const* fragmentCode = (char const*) fragmentShaderBlob->getBufferPointer();
- char const* fragmentCodeEnd = fragmentCode + fragmentShaderBlob->getBufferSize();
-
- spDestroyCompileRequest(slangRequest);
- spDestroySession(slangSession);
-
- gfx::ShaderProgram::KernelDesc kernelDescs[] =
- {
- { gfx::StageType::Vertex, vertexCode, vertexCodeEnd },
- { gfx::StageType::Fragment, fragmentCode, fragmentCodeEnd },
- };
-
- gfx::ShaderProgram::Desc programDesc;
- programDesc.pipelineType = gfx::PipelineType::Graphics;
- programDesc.kernels = &kernelDescs[0];
- programDesc.kernelCount = 2;
-
- auto program = renderer->createProgram(programDesc);
-
- vertexShaderBlob->release();
- fragmentShaderBlob->release();
-
- InputElementDesc inputElements[] = {
- {"U", 0, Format::RG_Float32, offsetof(ImDrawVert, pos) },
- {"U", 1, Format::RG_Float32, offsetof(ImDrawVert, uv) },
- {"U", 2, Format::RGBA_Unorm_UInt8, offsetof(ImDrawVert, col) },
- };
- auto inputLayout = renderer->createInputLayout(
- &inputElements[0],
- SLANG_COUNT_OF(inputElements));
-
- //
-
- List<DescriptorSetLayout::SlotRangeDesc> descriptorSetRanges;
- descriptorSetRanges.add(DescriptorSetLayout::SlotRangeDesc(DescriptorSlotType::UniformBuffer));
- descriptorSetRanges.add(DescriptorSetLayout::SlotRangeDesc(DescriptorSlotType::SampledImage));
- descriptorSetRanges.add(DescriptorSetLayout::SlotRangeDesc(DescriptorSlotType::Sampler));
-
- DescriptorSetLayout::Desc descriptorSetLayoutDesc;
- descriptorSetLayoutDesc.slotRangeCount = descriptorSetRanges.getCount();
- descriptorSetLayoutDesc.slotRanges = descriptorSetRanges.getBuffer();
-
- descriptorSetLayout = renderer->createDescriptorSetLayout(descriptorSetLayoutDesc);
-
- List<PipelineLayout::DescriptorSetDesc> pipelineDescriptorSets;
- pipelineDescriptorSets.add(PipelineLayout::DescriptorSetDesc(descriptorSetLayout));
-
- PipelineLayout::Desc pipelineLayoutDesc;
- pipelineLayoutDesc.descriptorSetCount = pipelineDescriptorSets.getCount();
- pipelineLayoutDesc.descriptorSets = pipelineDescriptorSets.getBuffer();
- pipelineLayoutDesc.renderTargetCount = 1;
-
- pipelineLayout = renderer->createPipelineLayout(pipelineLayoutDesc);
-
- TargetBlendDesc targetBlendDesc;
- targetBlendDesc.color.srcFactor = BlendFactor::SrcAlpha;
- targetBlendDesc.color.dstFactor = BlendFactor::InvSrcAlpha;
- targetBlendDesc.alpha.srcFactor = BlendFactor::InvSrcAlpha;
- targetBlendDesc.alpha.dstFactor = BlendFactor::Zero;
-
- GraphicsPipelineStateDesc pipelineDesc;
- pipelineDesc.renderTargetCount = 1;
- pipelineDesc.program = program;
- pipelineDesc.pipelineLayout = pipelineLayout;
- pipelineDesc.inputLayout = inputLayout;
- pipelineDesc.blend.targets = &targetBlendDesc;
- pipelineDesc.blend.targetCount = 1;
- pipelineDesc.rasterizer.cullMode = CullMode::None;
-
- // Set up the pieces of fixed-function state that we care about
- pipelineDesc.depthStencil.depthTestEnable = false;
-
- // TODO: need to set up blending state...
-
- pipelineState = renderer->createGraphicsPipelineState(pipelineDesc);
-
- // Initialize the texture atlas
- unsigned char* pixels;
- int width, height;
- io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
-
- {
- gfx::TextureResource::Desc desc;
- desc.init2D(Resource::Type::Texture2D, Format::RGBA_Unorm_UInt8, width, height, 1);
- desc.setDefaults(Resource::Usage::PixelShaderResource);
-
-
- ptrdiff_t mipRowStrides[] = { ptrdiff_t(width * 4 * sizeof(unsigned char)) };
- void* subResourceData[] = { pixels };
- TextureResource::Data initData;
- initData.mipRowStrides = mipRowStrides;
- initData.numMips = 1;
- initData.numSubResources = 1;
- initData.subResources = subResourceData;
-
- auto texture = renderer->createTextureResource(Resource::Usage::PixelShaderResource, desc, &initData);
-
- gfx::ResourceView::Desc viewDesc;
- viewDesc.format = desc.format;
- viewDesc.type = ResourceView::Type::ShaderResource;
- auto textureView = renderer->createTextureView(texture, viewDesc);
-
- io.Fonts->TexID = (void*) textureView.detach();
- }
-
- {
- SamplerState::Desc desc;
- samplerState = renderer->createSamplerState(desc);
- }
-}
-
-
-
-void GUI::beginFrame()
-{
-#ifdef _WIN32
- ImGui_ImplWin32_NewFrame();
-#endif
- ImGui::NewFrame();
-}
-
-void GUI::endFrame()
-{
- ImGui::Render();
-
- ImDrawData* draw_data = ImGui::GetDrawData();
- auto vertexCount = draw_data->TotalVtxCount;
- auto indexCount = draw_data->TotalIdxCount;
- int commandListCount = draw_data->CmdListsCount;
-
- if(!vertexCount) return;
- if(!indexCount) return;
- if(!commandListCount) return;
-
- // Allocate transient vertex/index buffers to hold the data for this frame.
-
- gfx::BufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.init(vertexCount * sizeof(ImDrawVert));
- vertexBufferDesc.setDefaults(Resource::Usage::VertexBuffer);
- vertexBufferDesc.cpuAccessFlags = Resource::AccessFlag::Write;
- auto vertexBuffer = renderer->createBufferResource(
- Resource::Usage::VertexBuffer,
- vertexBufferDesc);
-
- gfx::BufferResource::Desc indexBufferDesc;
- indexBufferDesc.init(indexCount * sizeof(ImDrawIdx));
- indexBufferDesc.setDefaults(Resource::Usage::IndexBuffer);
- indexBufferDesc.cpuAccessFlags = Resource::AccessFlag::Write;
- auto indexBuffer = renderer->createBufferResource(
- Resource::Usage::IndexBuffer,
- indexBufferDesc);
-
- {
- ImDrawVert* dstVertex = (ImDrawVert*) renderer->map(vertexBuffer, MapFlavor::WriteDiscard);
- ImDrawIdx* dstIndex = (ImDrawIdx*) renderer->map(indexBuffer, MapFlavor::WriteDiscard);
-
- for(int ii = 0; ii < commandListCount; ++ii)
- {
- const ImDrawList* commandList = draw_data->CmdLists[ii];
- memcpy(dstVertex, commandList->VtxBuffer.Data, commandList->VtxBuffer.Size * sizeof(ImDrawVert));
- memcpy(dstIndex, commandList->IdxBuffer.Data, commandList->IdxBuffer.Size * sizeof(ImDrawIdx));
- dstVertex += commandList->VtxBuffer.Size;
- dstIndex += commandList->IdxBuffer.Size;
- }
-
- renderer->unmap(vertexBuffer);
- renderer->unmap(indexBuffer);
- }
-
- // Allocate a transient constant buffer for projection matrix
- gfx::BufferResource::Desc constantBufferDesc;
- constantBufferDesc.init(sizeof(glm::mat4x4));
- constantBufferDesc.setDefaults(Resource::Usage::ConstantBuffer);
- constantBufferDesc.cpuAccessFlags = Resource::AccessFlag::Write;
- auto constantBuffer = renderer->createBufferResource(
- Resource::Usage::ConstantBuffer,
- constantBufferDesc);
-
- {
- glm::mat4x4* dstMVP = (glm::mat4x4*) renderer->map(constantBuffer, MapFlavor::WriteDiscard);
-
- float L = draw_data->DisplayPos.x;
- float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
- float T = draw_data->DisplayPos.y;
- float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
- float mvp[4][4] =
- {
- { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
- { 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.5f, 0.0f },
- { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
- };
- memcpy(dstMVP, mvp, sizeof(mvp));
-
- renderer->unmap(constantBuffer);
- }
-
- gfx::Viewport viewport;
- viewport.originX = 0;
- viewport.originY = 0;
- viewport.extentY = draw_data->DisplaySize.y;
- viewport.extentX = draw_data->DisplaySize.x;
- viewport.extentY = draw_data->DisplaySize.y;
- viewport.minZ = 0;
- viewport.maxZ = 1;
-
- renderer->setViewport(viewport);
-
- auto pipelineType = PipelineType::Graphics;
- renderer->setPipelineState(pipelineType, pipelineState);
-
- renderer->setVertexBuffer(0, vertexBuffer, sizeof(ImDrawVert));
- renderer->setIndexBuffer(indexBuffer, sizeof(ImDrawIdx) == 2 ? Format::R_UInt16 : Format::R_UInt32);
- renderer->setPrimitiveTopology(PrimitiveTopology::TriangleList);
-
- UInt vertexOffset = 0;
- UInt indexOffset = 0;
- ImVec2 pos = draw_data->DisplayPos;
- for(int ii = 0; ii < commandListCount; ++ii)
- {
- auto commandList = draw_data->CmdLists[ii];
- auto commandCount = commandList->CmdBuffer.Size;
- for(int jj = 0; jj < commandCount; jj++)
- {
- auto command = &commandList->CmdBuffer[jj];
- if(auto userCallback = command->UserCallback)
- {
- userCallback(commandList, command);
- }
- else
- {
- ScissorRect rect =
- {
- (Int)(command->ClipRect.x - pos.x),
- (Int)(command->ClipRect.y - pos.y),
- (Int)(command->ClipRect.z - pos.x),
- (Int)(command->ClipRect.w - pos.y)
- };
- renderer->setScissorRect(rect);
-
- // TODO: This should be a dynamic/transient descriptor set...
- auto descriptorSet = renderer->createDescriptorSet(descriptorSetLayout);
- descriptorSet->setConstantBuffer(0, 0, constantBuffer);
- descriptorSet->setResource(1, 0,
- (gfx::ResourceView*) command->TextureId);
- descriptorSet->setSampler(2, 0,
- samplerState);
-
- renderer->setDescriptorSet(
- pipelineType,
- pipelineLayout,
- 0,
- descriptorSet);
-
- renderer->drawIndexed(command->ElemCount, indexOffset, vertexOffset);
- }
- indexOffset += command->ElemCount;
- }
- vertexOffset += commandList->VtxBuffer.Size;
- }
-}
-
-GUI::~GUI()
-{
- auto& io = ImGui::GetIO();
-
- {
- RefPtr<ResourceView> textureView;
- textureView.attach((ResourceView*) io.Fonts->TexID);
- textureView = nullptr;
- }
-
-#ifdef _WIN32
- ImGui_ImplWin32_Shutdown();
-#endif
-
- ImGui::DestroyContext();
-}
-
-} // gfx
-
-#include "external/imgui/imgui.cpp"
-#include "external/imgui/imgui_draw.cpp"
-#ifdef _WIN32
-#include "external/imgui/examples/imgui_impl_win32.cpp"
-#endif
diff --git a/tools/gfx/gui.h b/tools/gfx/gui.h
deleted file mode 100644
index cbec5796f..000000000
--- a/tools/gfx/gui.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// gui.h
-#pragma once
-
-#include "render.h"
-#include "vector-math.h"
-#include "window.h"
-
-#include "external/imgui/imgui.h"
-
-namespace gfx {
-
-struct GUI : RefObject
-{
- GUI(Window* window, Renderer* renderer);
- ~GUI();
-
- void beginFrame();
- void endFrame();
-
-private:
- RefPtr<Renderer> renderer;
- RefPtr<PipelineState> pipelineState;
- RefPtr<DescriptorSetLayout> descriptorSetLayout;
- RefPtr<PipelineLayout> pipelineLayout;
- RefPtr<SamplerState> samplerState;
-};
-
-} // gfx
diff --git a/tools/gfx/model.cpp b/tools/gfx/model.cpp
deleted file mode 100644
index ce176727b..000000000
--- a/tools/gfx/model.cpp
+++ /dev/null
@@ -1,564 +0,0 @@
-// model.cpp
-#include "model.h"
-
-#define TINYOBJLOADER_IMPLEMENTATION
-#include "../../external/tinyobjloader/tiny_obj_loader.h"
-
-#define STB_IMAGE_IMPLEMENTATION
-#include "../../external/stb/stb_image.h"
-
-#define STB_IMAGE_RESIZE_IMPLEMENTATION
-#include "../../external/stb/stb_image_resize.h"
-
-#include "../../external/glm/glm/glm.hpp"
-#include "../../external/glm/glm/gtc/matrix_transform.hpp"
-#include "../../external/glm/glm/gtc/constants.hpp"
-
-#include <memory>
-#include <unordered_map>
-#include <unordered_set>
-
-namespace gfx {
-
-// TinyObj provides a tuple type that bundles up indices, but doesn't
-// provide equality comparison or hashing for that type. We'd like
-// to have a hash function so that we can unique indices.
-//
-// In the simplest case, we could define hashing and operator== operations
-// directly on `tinobj::index_t`, but that would create problems if they
-// revise their API.
-//
-// We will instead define our own wrapper type that supports equality
-// comparisons.
-//
-struct ObjIndexKey
-{
- tinyobj::index_t index;
-};
-
-bool operator==(ObjIndexKey const& left, ObjIndexKey const& right)
-{
- return left.index.vertex_index == right.index.vertex_index
- && left.index.normal_index == right.index.normal_index
- && left.index.texcoord_index == right.index.texcoord_index;
-}
-
-struct Hasher
-{
- template<typename T>
- void add(T const& v)
- {
- state ^= std::hash<T>()(v) + 0x9e3779b9 + (state << 6) + (state >> 2);
- }
- size_t state = 0;
-};
-
-struct SmoothingGroupVertexID
-{
- size_t smoothingGroup;
- size_t positionID;
-};
-bool operator==(SmoothingGroupVertexID const& left, SmoothingGroupVertexID const& right)
-{
- return left.smoothingGroup == right.smoothingGroup
- && left.positionID == right.positionID;
-}
-
-}
-
-namespace std
-{
- template<> struct hash<gfx::ObjIndexKey>
- {
- size_t operator()(gfx::ObjIndexKey const& key) const
- {
- gfx::Hasher hasher;
- hasher.add(key.index.vertex_index);
- hasher.add(key.index.normal_index);
- hasher.add(key.index.texcoord_index);
- return hasher.state;
- }
- };
-
- template<> struct hash<gfx::SmoothingGroupVertexID>
- {
- size_t operator()(gfx::SmoothingGroupVertexID const& id) const
- {
- gfx::Hasher hasher;
- hasher.add(id.smoothingGroup);
- hasher.add(id.positionID);
- return hasher.state;
- }
- };
-}
-
-namespace gfx
-{
-
-RefPtr<TextureResource> loadTextureImage(
- Renderer* renderer,
- char const* path)
-{
- int extentX = 0;
- int extentY = 0;
- int originalChannelCount = 0;
- int requestedChannelCount = 4; // force to 4-component result
- stbi_uc* data = stbi_load(
- path,
- &extentX,
- &extentY,
- &originalChannelCount,
- requestedChannelCount);
- if(!data)
- return nullptr;
-
- int channelCount = requestedChannelCount ? requestedChannelCount : originalChannelCount;
-
- Format format;
- switch(channelCount)
- {
- default:
- return nullptr;
-
- case 4: format = Format::RGBA_Unorm_UInt8;
-
- // TODO: handle other cases here if/when we stop forcing 4-component
- // results when loading the image with stb_image.
- }
-
- std::vector<void*> subresourceInitData;
- std::vector<ptrdiff_t> mipRowStrides;
-
- ptrdiff_t stride = extentX * channelCount * sizeof(stbi_uc);
-
- subresourceInitData.push_back(data);
- mipRowStrides.push_back(stride);
-
- // create down-sampled images for the different mip levels
- bool generateMips = true;
- if(generateMips)
- {
- int prevExtentX = extentX;
- int prevExtentY = extentY;
- stbi_uc* prevData = data;
- int prevStride = int(stride);
-
- for(;;)
- {
- if(prevExtentX == 1 && prevExtentY == 1)
- break;
-
- int newExtentX = prevExtentX / 2;
- int newExtentY = prevExtentY / 2;
-
- if(!newExtentX) newExtentX = 1;
- if(!newExtentY) newExtentY = 1;
-
- stbi_uc* newData = (stbi_uc*) malloc(newExtentX * newExtentY * channelCount * sizeof(stbi_uc));
- int newStride = int(newExtentX * channelCount * sizeof(stbi_uc));
-
- stbir_resize_uint8_srgb(
- prevData, prevExtentX, prevExtentY, prevStride,
- newData, newExtentX, newExtentY, newStride,
- channelCount,
- STBIR_ALPHA_CHANNEL_NONE,
- STBIR_FLAG_ALPHA_PREMULTIPLIED);
-
- subresourceInitData.push_back(newData);
- mipRowStrides.push_back(newStride);
-
- prevExtentX = newExtentX;
- prevExtentY = newExtentY;
- prevData = newData;
- prevStride = newStride;
- }
- }
-
- int mipCount = (int) mipRowStrides.size();
-
- TextureResource::Desc desc;
- desc.init2D(Resource::Type::Texture2D, format, extentX, extentY, mipCount);
-
- TextureResource::Data initData;
- initData.numSubResources = mipCount;
- initData.numMips = mipCount;
- initData.subResources = &subresourceInitData[0];
- initData.mipRowStrides = &mipRowStrides[0];
-
- auto texture = renderer->createTextureResource(
- Resource::Usage::PixelShaderResource,
- desc,
- &initData);
-
- free(data);
-
- return texture;
-}
-
-static std::string makeString(const char* start, const char* end)
-{
- return std::string(start, size_t(end - start));
-}
-
-Result ModelLoader::load(
- char const* inputPath,
- void** outModel)
-{
- // TODO: need to actually allocate/load the data
-
- tinyobj::attrib_t objVertexAttributes;
- std::vector<tinyobj::shape_t> objShapes;
- std::vector<tinyobj::material_t> objMaterials;
-
- std::string baseDir;
- if( auto lastSlash = strrchr(inputPath, '/') )
- {
- baseDir = makeString(inputPath, lastSlash);
- }
-
- std::string diagnostics;
- bool shouldTriangulate = true;
- bool success = tinyobj::LoadObj(
- &objVertexAttributes,
- &objShapes,
- &objMaterials,
- &diagnostics,
- inputPath,
- baseDir.size() ? baseDir.c_str() : nullptr,
- shouldTriangulate);
-
- if(!diagnostics.empty())
- {
- log("%s", diagnostics.c_str());
- }
- if(!success)
- {
- return SLANG_FAIL;
- }
-
- // Translate each material imported by TinyObj into a format that
- // we can actually use for rendering.
- //
- std::vector<void*> materials;
- for(auto& objMaterial : objMaterials)
- {
- MaterialData materialData;
-
- materialData.diffuseColor = glm::vec3(
- objMaterial.diffuse[0],
- objMaterial.diffuse[1],
- objMaterial.diffuse[2]);
-
- materialData.specularColor = glm::vec3(
- objMaterial.specular[0],
- objMaterial.specular[1],
- objMaterial.specular[2]);
-
- materialData.specularity = objMaterial.shininess;
-
- // load any referenced textures here
- if(objMaterial.diffuse_texname.length())
- {
- materialData.diffuseMap = loadTextureImage(
- renderer,
- objMaterial.diffuse_texname.c_str());
- }
-
- auto material = callbacks->createMaterial(materialData);
- materials.push_back(material);
- }
-
- // Flip the winding order on all faces if we are asked to...
- //
- if(loadFlags & LoadFlag::FlipWinding)
- {
- for(auto& objShape : objShapes)
- {
- size_t objIndexCounter = 0;
- size_t objFaceCounter = 0;
- for(auto objFaceVertexCount : objShape.mesh.num_face_vertices)
- {
- size_t beginIndex = objIndexCounter;
- size_t endIndex = beginIndex + objFaceVertexCount;
- objIndexCounter = endIndex;
-
- size_t halfCount = objFaceVertexCount / 2;
- for(size_t ii = 0; ii < halfCount; ++ii)
- {
- std::swap(
- objShape.mesh.indices[beginIndex + ii],
- objShape.mesh.indices[endIndex - (ii + 1)]);
- }
- }
- }
-
- }
-
- // Identify cases where a face has a vertex without a normal, and in that
- // case remember that the given vertex needs to be "smoothed" as part of
- // the smoothing group for that face. Note that it is possible for the
- // same vertex (position) to be part of faces in distinct smoothing groups.
- //
- std::unordered_map<SmoothingGroupVertexID, size_t> smoothedVertexNormals;
- size_t firstSmoothedNormalID = objVertexAttributes.normals.size() / 3;
- size_t flatFaceCounter = 0;
- for(auto& objShape : objShapes)
- {
- size_t objIndexCounter = 0;
- size_t objFaceCounter = 0;
- for(auto objFaceVertexCount : objShape.mesh.num_face_vertices)
- {
- const size_t flatFaceIndex = flatFaceCounter++;
- const size_t objFaceIndex = objFaceCounter++;
- size_t smoothingGroup = objShape.mesh.smoothing_group_ids[objFaceIndex];
- if(!smoothingGroup)
- {
- smoothingGroup = ~flatFaceIndex;
- }
-
- for(size_t objFaceVertex = 0; objFaceVertex < objFaceVertexCount; ++objFaceVertex)
- {
- tinyobj::index_t& objIndex = objShape.mesh.indices[objIndexCounter++];
-
- if(objIndex.normal_index < 0)
- {
- SmoothingGroupVertexID smoothVertexID;
- smoothVertexID.positionID = objIndex.vertex_index;
- smoothVertexID.smoothingGroup = smoothingGroup;
-
- if(smoothedVertexNormals.find(smoothVertexID) == smoothedVertexNormals.end())
- {
- size_t normalID = objVertexAttributes.normals.size() / 3;
- objVertexAttributes.normals.push_back(0);
- objVertexAttributes.normals.push_back(0);
- objVertexAttributes.normals.push_back(0);
-
- smoothedVertexNormals.insert(std::make_pair(smoothVertexID, normalID));
-
- objIndex.normal_index = int(normalID);
- }
- }
- }
- }
- }
- //
- // Having identified which vertices we need to smooth, we will make another
- // pass to compute face normals and apply them to the vertices that belong
- // to the same smoothing group.
- //
- flatFaceCounter = 0;
- for(auto& objShape : objShapes)
- {
- size_t objIndexCounter = 0;
- size_t objFaceCounter = 0;
- for(auto objFaceVertexCount : objShape.mesh.num_face_vertices)
- {
- const size_t flatFaceIndex = flatFaceCounter++;
- const size_t objFaceIndex = objFaceCounter++;
- size_t smoothingGroup = objShape.mesh.smoothing_group_ids[objFaceIndex];
- if(!smoothingGroup)
- {
- smoothingGroup = ~flatFaceIndex;
- }
-
- glm::vec3 faceNormal;
- if(objFaceVertexCount >= 3)
- {
- glm::vec3 v[3];
- for(size_t objFaceVertex = 0; objFaceVertex < 3; ++objFaceVertex)
- {
- tinyobj::index_t objIndex = objShape.mesh.indices[objIndexCounter + objFaceVertex];
- if(objIndex.vertex_index >= 0)
- {
- v[objFaceVertex] = glm::vec3(
- objVertexAttributes.vertices[3 * objIndex.vertex_index + 0],
- objVertexAttributes.vertices[3 * objIndex.vertex_index + 1],
- objVertexAttributes.vertices[3 * objIndex.vertex_index + 2]);
- }
- }
- faceNormal = cross(v[1] - v[0], v[2] - v[0]);
- }
-
- // Add this face normal to any to-be-smoothed vertex on the face.
- for(size_t objFaceVertex = 0; objFaceVertex < objFaceVertexCount; ++objFaceVertex)
- {
- tinyobj::index_t objIndex = objShape.mesh.indices[objIndexCounter++];
-
- SmoothingGroupVertexID smoothVertexID;
- smoothVertexID.positionID = objIndex.vertex_index;
- smoothVertexID.smoothingGroup = smoothingGroup;
-
- auto ii = smoothedVertexNormals.find(smoothVertexID);
- if(ii != smoothedVertexNormals.end())
- {
- size_t normalID = ii->second;
- objVertexAttributes.normals[normalID * 3 + 0] += faceNormal.x;
- objVertexAttributes.normals[normalID * 3 + 1] += faceNormal.y;
- objVertexAttributes.normals[normalID * 3 + 2] += faceNormal.z;
- }
- }
- }
- }
- //
- // Once we've added all contributions from each smoothing group,
- // we can normalize the normals to compute the area-weighted average.
- //
- size_t normalCount = objVertexAttributes.normals.size() / 3;
- for(size_t ii = firstSmoothedNormalID; ii < normalCount; ++ii)
- {
- glm::vec3 normal = glm::vec3(
- objVertexAttributes.normals[3 * ii + 0],
- objVertexAttributes.normals[3 * ii + 1],
- objVertexAttributes.normals[3 * ii + 2]);
-
- normal = normalize(normal);
-
- objVertexAttributes.normals[3 * ii + 0] = normal.x;
- objVertexAttributes.normals[3 * ii + 1] = normal.y;
- objVertexAttributes.normals[3 * ii + 2] = normal.z;
- }
-
- // TODO: we should sort the faces to group faces with
- // the same material ID together, in case they weren't
- // grouped in the original file.
-
- // We need to undo the .obj indexing stuff so that we have
- // standard position/normal/etc. data in a single flat array
-
- std::unordered_map<ObjIndexKey, Index> mapObjIndexToFlatIndex;
- std::vector<Vertex> flatVertices;
- std::vector<Index> flatIndices;
-
- MeshData* currentMesh = nullptr;
- MeshData currentMeshStorage;
-
- std::vector<void*> meshes;
-
- void* defaultMaterial = nullptr;
-
- for(auto& objShape : objShapes)
- {
- size_t objIndexCounter = 0;
- size_t objFaceCounter = 0;
- for(auto objFaceVertexCount : objShape.mesh.num_face_vertices)
- {
- size_t objFaceIndex = objFaceCounter++;
- int faceMaterialID = objShape.mesh.material_ids[objFaceIndex];
- void* faceMaterial = nullptr;
- if( faceMaterialID < 0 )
- {
- if( !defaultMaterial )
- {
- MaterialData defaultMaterialData;
- defaultMaterialData.diffuseColor = glm::vec3(0.5, 0.5, 0.5);
- defaultMaterial = callbacks->createMaterial(defaultMaterialData);
- }
- faceMaterial = defaultMaterial;
- }
- else
- {
- faceMaterial = materials[faceMaterialID];
- }
-
- if(!currentMesh || (faceMaterial != currentMesh->material))
- {
- // finish old mesh.
- if(currentMesh)
- {
- meshes.push_back(callbacks->createMesh(*currentMesh));
- }
-
- // Need to start a new mesh.
- currentMesh = &currentMeshStorage;
- currentMesh->material = faceMaterial;
- currentMesh->firstIndex = (int)flatIndices.size();
- currentMesh->indexCount = 0;
- }
-
- for(size_t objFaceVertex = 0; objFaceVertex < objFaceVertexCount; ++objFaceVertex)
- {
- tinyobj::index_t objIndex = objShape.mesh.indices[objIndexCounter++];
- ObjIndexKey objIndexKey; objIndexKey.index = objIndex;
-
-
- Index flatIndex = Index(-1);
- auto iter = mapObjIndexToFlatIndex.find(objIndexKey);
- if(iter != mapObjIndexToFlatIndex.end())
- {
- flatIndex = iter->second;
- }
- else
- {
- Vertex flatVertex;
- if(objIndex.vertex_index >= 0)
- {
- flatVertex.position = scale * glm::vec3(
- objVertexAttributes.vertices[3 * objIndex.vertex_index + 0],
- objVertexAttributes.vertices[3 * objIndex.vertex_index + 1],
- objVertexAttributes.vertices[3 * objIndex.vertex_index + 2]);
- }
- if(objIndex.normal_index >= 0)
- {
- flatVertex.normal = glm::vec3(
- objVertexAttributes.normals[3 * objIndex.normal_index + 0],
- objVertexAttributes.normals[3 * objIndex.normal_index + 1],
- objVertexAttributes.normals[3 * objIndex.normal_index + 2]);
- }
- if(objIndex.texcoord_index >= 0)
- {
- flatVertex.uv = glm::vec2(
- objVertexAttributes.texcoords[2 * objIndex.texcoord_index + 0],
- objVertexAttributes.texcoords[2 * objIndex.texcoord_index + 1]);
- }
-
- flatIndex = uint32_t(flatVertices.size());
- mapObjIndexToFlatIndex.insert(std::make_pair(objIndexKey, flatIndex));
- flatVertices.push_back(flatVertex);
- }
-
- flatIndices.push_back(flatIndex);
- currentMesh->indexCount++;
- }
- }
- }
-
- // finish last mesh.
- if(currentMesh)
- {
- meshes.push_back(callbacks->createMesh(*currentMesh));
- }
-
- ModelData modelData;
-
- modelData.vertexCount = (int)flatVertices.size();
- modelData.indexCount = (int)flatIndices.size();
-
- modelData.meshCount = int(meshes.size());
- modelData.meshes = meshes.data();
-
- BufferResource::Desc vertexBufferDesc;
- vertexBufferDesc.init(modelData.vertexCount * sizeof(Vertex));
- vertexBufferDesc.setDefaults(Resource::Usage::VertexBuffer);
-
- modelData.vertexBuffer = renderer->createBufferResource(
- Resource::Usage::VertexBuffer,
- vertexBufferDesc,
- flatVertices.data());
- if(!modelData.vertexBuffer) return SLANG_FAIL;
-
- BufferResource::Desc indexBufferDesc;
- indexBufferDesc.init(modelData.indexCount * sizeof(Index));
- vertexBufferDesc.setDefaults(Resource::Usage::IndexBuffer);
-
- modelData.indexBuffer = renderer->createBufferResource(
- Resource::Usage::IndexBuffer,
- indexBufferDesc,
- flatIndices.data());
- if(!modelData.indexBuffer) return SLANG_FAIL;
-
- *outModel = callbacks->createModel(modelData);
-
- return SLANG_OK;
-}
-
-} // gfx
diff --git a/tools/gfx/model.h b/tools/gfx/model.h
deleted file mode 100644
index 17b16510e..000000000
--- a/tools/gfx/model.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// model.h
-#pragma once
-
-#include "render.h"
-#include "vector-math.h"
-
-#include <vector>
-#include <string>
-
-namespace gfx {
-
-struct ModelLoader
-{
- struct MaterialData
- {
- glm::vec3 diffuseColor;
- glm::vec3 specularColor;
- float specularity;
-
- RefPtr<TextureResource> diffuseMap;
- };
-
- struct Vertex
- {
- glm::vec3 position;
- glm::vec3 normal;
- glm::vec2 uv;
- };
-
- typedef uint32_t Index;
-
- struct MeshData
- {
- int firstIndex;
- int indexCount;
-
- void* material;
- };
-
- struct ModelData
- {
- RefPtr<BufferResource> vertexBuffer;
- RefPtr<BufferResource> indexBuffer;
- PrimitiveTopology primitiveTopology;
- int vertexCount;
- int indexCount;
- int meshCount;
- void* const* meshes;
- };
-
- struct ICallbacks
- {
- typedef ModelLoader::MaterialData MaterialData;
- typedef ModelLoader::MeshData MeshData;
- typedef ModelLoader::ModelData ModelData;
-
- virtual void* createMaterial(MaterialData const& data) = 0;
- virtual void* createMesh(MeshData const& data) = 0;
- virtual void* createModel(ModelData const& data) = 0;
- };
-
- typedef uint32_t LoadFlags;
- enum LoadFlag : LoadFlags
- {
- FlipWinding = 1 << 0,
- };
-
- ICallbacks* callbacks = nullptr;
- RefPtr<Renderer> renderer;
- LoadFlags loadFlags = 0;
- float scale = 1.0f;
-
- Result load(char const* inputPath, void** outModel);
-};
-
-
-} // gfx
diff --git a/tools/gfx/nvapi/nvapi-util.h b/tools/gfx/nvapi/nvapi-util.h
index 704f4ede4..0bcab7d36 100644
--- a/tools/gfx/nvapi/nvapi-util.h
+++ b/tools/gfx/nvapi/nvapi-util.h
@@ -1,8 +1,8 @@
// nvapi-util.h
#pragma once
-#include "../../slang-com-helper.h"
-#include "../../slang-com-ptr.h"
+#include "slang-com-helper.h"
+#include "slang-com-ptr.h"
namespace gfx {
diff --git a/tools/gfx/render.h b/tools/gfx/render.h
index fb9e10724..ab9af8afb 100644
--- a/tools/gfx/render.h
+++ b/tools/gfx/render.h
@@ -1,8 +1,6 @@
// render.h
#pragma once
-#include "window.h"
-
//#include "shader-input-layout.h"
#include <float.h>
diff --git a/tools/gfx/vector-math.h b/tools/gfx/vector-math.h
deleted file mode 100644
index e35cb46ac..000000000
--- a/tools/gfx/vector-math.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// vector-math.h
-#pragma once
-
-// We will use the GLM library for our vector math types, just for simplicity.
-
-#include "../../external/glm/glm/glm.hpp"
-#include "../../external/glm/glm/gtc/matrix_transform.hpp"
-#include "../../external/glm/glm/gtc/constants.hpp"
-#include "../../external/glm/glm/gtc/quaternion.hpp"
-
-namespace gfx {
-
-using namespace glm;
-
-} // gfx
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index 0f6e3cdaa..80393904c 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -5,7 +5,7 @@
#include "../render.h"
#include "../render-graphics-common.h"
-#include "../../source/core/slang-smart-pointer.h"
+#include "core/slang-smart-pointer.h"
#include "vk-api.h"
#include "vk-util.h"
diff --git a/tools/gfx/vulkan/vk-api.cpp b/tools/gfx/vulkan/vk-api.cpp
index 50f80aa26..9b51b644c 100644
--- a/tools/gfx/vulkan/vk-api.cpp
+++ b/tools/gfx/vulkan/vk-api.cpp
@@ -1,7 +1,7 @@
// vk-api.cpp
#include "vk-api.h"
-#include "../../source/core/slang-list.h"
+#include "core/slang-list.h"
namespace gfx {
using namespace Slang;
diff --git a/tools/gfx/vulkan/vk-module.h b/tools/gfx/vulkan/vk-module.h
index 4d18823ca..7ddd5da45 100644
--- a/tools/gfx/vulkan/vk-module.h
+++ b/tools/gfx/vulkan/vk-module.h
@@ -1,9 +1,9 @@
// vk-module.h
#pragma once
-#include "../../slang.h"
+#include "slang.h"
-#include "../../slang-com-helper.h"
+#include "slang-com-helper.h"
#if SLANG_WINDOWS_FAMILY
# define VK_USE_PLATFORM_WIN32_KHR 1
diff --git a/tools/gfx/vulkan/vk-swap-chain.cpp b/tools/gfx/vulkan/vk-swap-chain.cpp
index d9b3a495d..21460ce61 100644
--- a/tools/gfx/vulkan/vk-swap-chain.cpp
+++ b/tools/gfx/vulkan/vk-swap-chain.cpp
@@ -3,7 +3,7 @@
#include "vk-util.h"
-#include "../../source/core/slang-list.h"
+#include "core/slang-list.h"
#include <stdlib.h>
#include <stdio.h>
diff --git a/tools/gfx/vulkan/vk-swap-chain.h b/tools/gfx/vulkan/vk-swap-chain.h
index 9b4dfc2c1..893910ea6 100644
--- a/tools/gfx/vulkan/vk-swap-chain.h
+++ b/tools/gfx/vulkan/vk-swap-chain.h
@@ -6,7 +6,7 @@
#include "../render.h"
-#include "../../source/core/slang-list.h"
+#include "core/slang-list.h"
namespace gfx {
diff --git a/tools/gfx/window.h b/tools/gfx/window.h
deleted file mode 100644
index e6f886f42..000000000
--- a/tools/gfx/window.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// window.h
-#pragma once
-
-#include <stdint.h>
-
-namespace gfx {
-
-struct Window;
-
-enum class KeyCode
-{
- Unknown,
-
- // TODO: extend this to cover at least a standard US-English keyboard
-
- A, B, C, D, E, F, G, H, I, J,
- K, L, M, N, O, P, Q, R, S, T,
- U, V, W, X, Y, Z,
-
- Space,
-};
-
-enum class EventCode : uint32_t
-{
- MouseDown,
- MouseUp,
- MouseMoved,
- KeyDown,
- KeyUp,
-};
-
-struct Event
-{
- EventCode code;
- Window* window;
- union
- {
- struct
- {
- float x;
- float y;
- } mouse;
-
- KeyCode key;
- } u;
-};
-
-typedef void (*EventHandler)(Event const&);
-
-struct WindowDesc
-{
- char const* title = nullptr;
- void* userData = nullptr;
- int width = 0;
- int height = 0;
- EventHandler eventHandler = nullptr;
-};
-
-Window* createWindow(WindowDesc const& desc);
-void showWindow(Window* window);
-
-void* getPlatformWindowHandle(Window* window);
-void* getUserData(Window* window);
-
-/// Opaque state provided by platform for a running application.
-typedef struct ApplicationContext ApplicationContext;
-
-/// User-defined application entry-point function.
-typedef void(*ApplicationFunc)(ApplicationContext* context);
-
-/// Dispatch any pending events for application.
-///
-/// @returns `true` if application should keep running.
-bool dispatchEvents(ApplicationContext* context);
-
-/// Exit the application with a given result code
-void exitApplication(ApplicationContext* context, int resultCode);
-
-/// Log a message to an appropriate logging destination.
-void log(char const* message, ...);
-
-/// Report an error to an appropriate logging destination.
-int reportError(char const* message, ...);
-
-uint64_t getCurrentTime();
-
-uint64_t getTimerFrequency();
-
-/// Run an application given the specified callback and command-line arguments.
-int runApplication(
- ApplicationFunc func,
- int argc,
- char const* const* argv);
-
-#define GFX_CONSOLE_MAIN(APPLICATION_ENTRY) \
- int main(int argc, char** argv) { \
- return gfx::runApplication(&(APPLICATION_ENTRY), argc, argv); \
- }
-
-#ifdef _WIN32
-
-int runWindowsApplication(
- ApplicationFunc func,
- void* instance,
- int showCommand);
-
-#define GFX_UI_MAIN(APPLICATION_ENTRY) \
- int __stdcall WinMain( \
- void* instance, \
- void* /* prevInstance */, \
- void* /* commandLine */, \
- int showCommand) { \
- return gfx::runWindowsApplication(&(APPLICATION_ENTRY), instance, showCommand); \
- }
-
-#else
-
-#define GFX_UI_MAIN(APPLICATION_ENTRY) GFX_CONSOLE_MAIN(APPLICATION_ENTRY)
-
-#endif
-
-} // gfx
diff --git a/tools/gfx/windows/win-window.cpp b/tools/gfx/windows/win-window.cpp
deleted file mode 100644
index 45315a27a..000000000
--- a/tools/gfx/windows/win-window.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-// win-window.cpp
-#include "../window.h"
-
-#include <stdio.h>
-
-#ifdef _MSC_VER
-#include <stddef.h>
-#if (_MSC_VER < 1900)
-#define snprintf sprintf_s
-#endif
-#endif
-
-#include <stdint.h>
-
-#if _WIN32
-#include <Windows.h>
-#include <Windowsx.h>
-#else
-#error "The slang-graphics library currently only supports Windows platforms"
-#endif
-
-namespace gfx {
-
-#if _WIN32
-
-struct OSString
-{
- OSString(char const* begin, char const* end)
- {
- _initialize(begin, end - begin);
- }
-
- OSString(char const* begin)
- {
- _initialize(begin, strlen(begin));
- }
-
- ~OSString()
- {
- free(mBegin);
- }
-
- operator WCHAR const*()
- {
- return mBegin;
- }
-
-private:
- WCHAR* mBegin;
- WCHAR* mEnd;
-
- void _initialize(char const* input, size_t inputSize)
- {
- const DWORD dwFlags = 0;
- int outputCodeUnitCount = ::MultiByteToWideChar(CP_UTF8, dwFlags, input, int(inputSize), nullptr, 0);
-
- WCHAR* buffer = (WCHAR*)malloc(sizeof(WCHAR) * (outputCodeUnitCount + 1));
-
- ::MultiByteToWideChar(CP_UTF8, dwFlags, input, int(inputSize), buffer, outputCodeUnitCount);
- buffer[outputCodeUnitCount] = 0;
-
- mBegin = buffer;
- mEnd = buffer + outputCodeUnitCount;
- }
-};
-
-struct ApplicationContext
-{
- HINSTANCE instance;
- int showCommand = SW_SHOWDEFAULT;
- int resultCode = 0;
-};
-
-static uint64_t gTimerFrequency;
-
-
-static void initApplication(ApplicationContext* context)
-{
- LARGE_INTEGER timerFrequency;
- QueryPerformanceFrequency(&timerFrequency);
- gTimerFrequency = timerFrequency.QuadPart;
-}
-
-/// Run an application given the specified callback and command-line arguments.
-int runApplication(
- ApplicationFunc func,
- int argc,
- char const* const* argv)
-{
- ApplicationContext context;
- context.instance = (HINSTANCE) GetModuleHandle(0);
- initApplication(&context);
- func(&context);
- return context.resultCode;
-}
-
-int runWindowsApplication(
- ApplicationFunc func,
- void* instance,
- int showCommand)
-{
- ApplicationContext context;
- context.instance = (HINSTANCE) instance;
- context.showCommand = showCommand;
- initApplication(&context);
- func(&context);
- return context.resultCode;
-}
-
-struct Window
-{
- HWND handle;
- WNDPROC nativeHook;
- EventHandler eventHandler;
- void* userData;
-};
-
-void setNativeWindowHook(Window* window, WNDPROC proc)
-{
- window->nativeHook = proc;
-}
-
-static KeyCode translateKeyCode(int vkey)
-{
- switch( vkey )
- {
- default:
- return KeyCode::Unknown;
-
-#define CASE(FROM, TO) case FROM: return KeyCode::TO;
- CASE('A', A); CASE('B', B); CASE('C', C); CASE('D', D); CASE('E', E);
- CASE('F', F); CASE('G', G); CASE('H', H); CASE('I', I); CASE('J', J);
- CASE('K', K); CASE('L', M); CASE('M', M); CASE('N', N); CASE('O', O);
- CASE('P', P); CASE('Q', Q); CASE('R', R); CASE('S', S); CASE('T', T);
- CASE('U', U); CASE('V', V); CASE('W', W); CASE('X', X); CASE('Y', Y);
- CASE('Z', Z);
-#undef CASE
-
-#define CASE(FROM, TO) case VK_##FROM: return KeyCode::TO;
- CASE(SPACE, Space);
-#undef CASE
- }
-}
-
-static LRESULT CALLBACK windowProc(
- HWND windowHandle,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
-{
- Window* window = (Window*) GetWindowLongPtrW(windowHandle, GWLP_USERDATA);
-
- // Give the installed filter a chance to intercept messages.
- // (This is used for ImGui)
- if( window )
- {
- if(auto nativeHook = window->nativeHook)
- {
- auto result = nativeHook(windowHandle, message, wParam, lParam);
- if(result)
- return result;
- }
- }
-
- auto eventHandler = window ? window->eventHandler : nullptr;
-
- switch (message)
- {
- case WM_CREATE:
- {
- auto createInfo = (CREATESTRUCTW*) lParam;
- window = (Window*) createInfo->lpCreateParams;
- window->handle = windowHandle;
-
- SetWindowLongPtrW(windowHandle, GWLP_USERDATA, (LONG_PTR) window);
- }
- break;
-
- case WM_KEYDOWN:
- case WM_KEYUP:
- {
- int virtualKey = (int) wParam;
- auto keyCode = translateKeyCode(virtualKey);
- if(eventHandler)
- {
- Event event;
- event.window = window;
- event.code = message == WM_KEYDOWN ? EventCode::KeyDown : EventCode::KeyUp;
- event.u.key = keyCode;
- eventHandler(event);
- }
- }
- break;
-
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- {
- if(eventHandler)
- {
- Event event;
- event.window = window;
- event.code = message == WM_LBUTTONDOWN ? EventCode::MouseDown : EventCode::MouseUp;
- event.u.mouse.x = (float) GET_X_LPARAM(lParam);
- event.u.mouse.y = (float) GET_Y_LPARAM(lParam);
- eventHandler(event);
- }
- }
- break;
-
- case WM_MOUSEMOVE:
- {
- if(eventHandler)
- {
- Event event;
- event.window = window;
- event.code = EventCode::MouseMoved;
- event.u.mouse.x = (float) GET_X_LPARAM(lParam);
- event.u.mouse.y = (float) GET_Y_LPARAM(lParam);
- eventHandler(event);
- }
- }
- break;
-
- case WM_CLOSE:
- PostQuitMessage(0);
- return 0;
- }
-
-
- return DefWindowProcW(windowHandle, message, wParam, lParam);
-}
-
-
-static ATOM createWindowClassAtom()
-{
- WNDCLASSEXW windowClassDesc;
- windowClassDesc.cbSize = sizeof(windowClassDesc);
- windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
- windowClassDesc.lpfnWndProc = &windowProc;
- windowClassDesc.cbClsExtra = 0;
- windowClassDesc.cbWndExtra = 0;
- windowClassDesc.hInstance = (HINSTANCE) GetModuleHandle(0);
- windowClassDesc.hIcon = 0;
- windowClassDesc.hCursor = 0;
- windowClassDesc.hbrBackground = 0;
- windowClassDesc.lpszMenuName = 0;
- windowClassDesc.lpszClassName = L"SlangGraphicsWindow";
- windowClassDesc.hIconSm = 0;
- ATOM windowClassAtom = RegisterClassExW(&windowClassDesc);
- return windowClassAtom;
-}
-
-static ATOM getWindowClassAtom()
-{
- static ATOM windowClassAtom = createWindowClassAtom();
- return windowClassAtom;
-}
-
-Window* createWindow(WindowDesc const& desc)
-{
- Window* window = new Window();
- window->handle = nullptr;
- window->nativeHook = nullptr;
- window->eventHandler = desc.eventHandler;
- window->userData = desc.userData;
-
- OSString windowTitle(desc.title);
-
- DWORD windowExtendedStyle = 0;
- DWORD windowStyle = 0;
-
- HINSTANCE instance = (HINSTANCE) GetModuleHandle(0);
-
- HWND windowHandle = CreateWindowExW(
- windowExtendedStyle,
- (LPWSTR) getWindowClassAtom(),
- windowTitle,
- windowStyle,
- 0, 0, // x, y
- desc.width, desc.height,
- NULL, // parent
- NULL, // menu
- instance,
- window);
-
- if(!windowHandle)
- {
- delete window;
- return nullptr;
- }
-
- window->handle = windowHandle;
- return window;
-}
-
-void showWindow(Window* window)
-{
- ShowWindow(window->handle, SW_SHOW);
-}
-
-void* getPlatformWindowHandle(Window* window)
-{
- return window->handle;
-}
-
-void* getUserData(Window* window)
-{
- return window->userData;
-}
-
-bool dispatchEvents(ApplicationContext* context)
-{
- for(;;)
- {
- MSG message;
-
- int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE);
- if (result != 0)
- {
- if (message.message == WM_QUIT)
- {
- context->resultCode = (int)message.wParam;
- return false;
- }
-
- TranslateMessage(&message);
- DispatchMessageW(&message);
- }
- else
- {
- return true;
- }
- }
-
-}
-
-void exitApplication(ApplicationContext* context, int resultCode)
-{
- ExitProcess(resultCode);
-}
-
-void log(char const* message, ...)
-{
- va_list args;
- va_start(args, message);
-
- static const int kBufferSize = 1024;
- char messageBuffer[kBufferSize];
- vsnprintf(messageBuffer, kBufferSize - 1, message, args);
- messageBuffer[kBufferSize - 1] = 0;
-
- va_end(args);
-
- fputs(messageBuffer, stderr);
-
- OSString wideMessageBuffer(messageBuffer);
- OutputDebugStringW(wideMessageBuffer);
-}
-
-int reportError(char const* message, ...)
-{
- va_list args;
- va_start(args, message);
-
- static const int kBufferSize = 1024;
- char messageBuffer[kBufferSize];
- vsnprintf(messageBuffer, kBufferSize - 1, message, args);
- messageBuffer[kBufferSize - 1] = 0;
-
- va_end(args);
-
- fputs(messageBuffer, stderr);
-
- OSString wideMessageBuffer(messageBuffer);
- OutputDebugStringW(wideMessageBuffer);
-
- return 1;
-}
-
-uint64_t getCurrentTime()
-{
- LARGE_INTEGER counter;
- QueryPerformanceCounter(&counter);
- return counter.QuadPart;
-}
-
-uint64_t getTimerFrequency()
-{
- return gTimerFrequency;
-}
-
-#else
-
-// TODO: put an SDL version here
-
-#endif
-
-} // gfx