diff options
Diffstat (limited to 'examples/hello-world/main.cpp')
| -rw-r--r-- | examples/hello-world/main.cpp | 102 |
1 files changed, 89 insertions, 13 deletions
diff --git a/examples/hello-world/main.cpp b/examples/hello-world/main.cpp index 49fe2ec67..f0ea3eb2a 100644 --- a/examples/hello-world/main.cpp +++ b/examples/hello-world/main.cpp @@ -201,6 +201,7 @@ gfx::Result loadShaderProgram( // int gWindowWidth = 1024; int gWindowHeight = 768; +const uint32_t kSwapchainImageCount = 2; // We will define global variables for the various platform and // graphics API objects that our application needs: @@ -213,10 +214,10 @@ gfx::ApplicationContext* gAppContext; gfx::Window* gWindow; Slang::ComPtr<gfx::IRenderer> gRenderer; -//ComPtr<gfx::IShaderObjectLayout> gRootLayout; ComPtr<gfx::IPipelineState> gPipelineState; ComPtr<gfx::IShaderObject> gRootObject; - +ComPtr<gfx::ISwapchain> gSwapchain; +List<ComPtr<gfx::IFramebuffer>> gFramebuffers; ComPtr<gfx::IBufferResource> gVertexBuffer; // Now that we've covered the function that actually loads and @@ -242,9 +243,7 @@ Slang::Result initialize() // IRenderer::Desc rendererDesc = {}; rendererDesc.rendererType = gfx::RendererType::DirectX11; - rendererDesc.width = gWindowWidth; - rendererDesc.height = gWindowHeight; - gfx::Result res = gfxCreateRenderer(&rendererDesc, getPlatformWindowHandle(gWindow), gRenderer.writeRef()); + gfx::Result res = gfxCreateRenderer(&rendererDesc, gRenderer.writeRef()); if(SLANG_FAILED(res)) return res; // Now we will create objects needed to configur the "input assembler" @@ -311,15 +310,76 @@ Slang::Result initialize() SLANG_RETURN_ON_FAIL(gRenderer->createRootShaderObject(shaderProgram, rootObject.writeRef())); gRootObject = rootObject; + // Create swapchain and framebuffers. + gfx::ISwapchain::Desc swapchainDesc = {}; + swapchainDesc.format = gfx::Format::RGBA_Unorm_UInt8; + swapchainDesc.width = gWindowWidth; + swapchainDesc.height = gWindowHeight; + swapchainDesc.imageCount = kSwapchainImageCount; + gSwapchain = gRenderer->createSwapchain( + swapchainDesc, gfx::WindowHandle::FromHwnd(getPlatformWindowHandle(gWindow))); + + IFramebufferLayout::AttachmentLayout renderTargetLayout = {gSwapchain->getDesc().format, 1}; + IFramebufferLayout::AttachmentLayout depthLayout = {gfx::Format::D_Float32, 1}; + IFramebufferLayout::Desc framebufferLayoutDesc; + framebufferLayoutDesc.renderTargetCount = 1; + framebufferLayoutDesc.renderTargets = &renderTargetLayout; + framebufferLayoutDesc.depthStencil = &depthLayout; + ComPtr<IFramebufferLayout> framebufferLayout; + SLANG_RETURN_ON_FAIL( + gRenderer->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef())); + + for (uint32_t i = 0; i < kSwapchainImageCount; i++) + { + gfx::ITextureResource::Desc depthBufferDesc; + depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); + depthBufferDesc.init2D( + gfx::IResource::Type::Texture2D, + gfx::Format::D_Float32, + gSwapchain->getDesc().width, + gSwapchain->getDesc().height, + 0); + + ComPtr<gfx::ITextureResource> depthBufferResource = gRenderer->createTextureResource( + gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); + ComPtr<gfx::ITextureResource> colorBuffer; + gSwapchain->getImage(i, colorBuffer.writeRef()); + + gfx::IResourceView::Desc colorBufferViewDesc; + memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); + colorBufferViewDesc.format = gSwapchain->getDesc().format; + colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; + colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget; + ComPtr<gfx::IResourceView> rtv = + gRenderer->createTextureView(colorBuffer.get(), colorBufferViewDesc); + + gfx::IResourceView::Desc depthBufferViewDesc; + memset(&depthBufferViewDesc, 0, sizeof(depthBufferViewDesc)); + depthBufferViewDesc.format = gfx::Format::D_Float32; + depthBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; + depthBufferViewDesc.type = gfx::IResourceView::Type::DepthStencil; + ComPtr<gfx::IResourceView> dsv = + gRenderer->createTextureView(depthBufferResource.get(), depthBufferViewDesc); + + gfx::IFramebuffer::Desc framebufferDesc; + framebufferDesc.renderTargetCount = 1; + framebufferDesc.depthStencilView = dsv.get(); + framebufferDesc.renderTargetViews = rtv.readRef(); + framebufferDesc.layout = framebufferLayout; + ComPtr<gfx::IFramebuffer> frameBuffer = gRenderer->createFramebuffer(framebufferDesc); + gFramebuffers.add(frameBuffer); + } + // Following the D3D12/Vulkan style of API, we need a pipeline state object // (PSO) to encapsulate the configuration of the overall graphics pipeline. // GraphicsPipelineStateDesc desc; desc.inputLayout = inputLayout; desc.program = shaderProgram; - desc.renderTargetCount = 1; + desc.framebufferLayout = framebufferLayout; auto pipelineState = gRenderer->createGraphicsPipelineState(desc); - if(!pipelineState) return SLANG_FAIL; + if (!pipelineState) + return SLANG_FAIL; gPipelineState = pipelineState; @@ -338,6 +398,17 @@ Slang::Result initialize() // void renderFrame() { + gRenderer->beginFrame(); + uint32_t frameBufferIndex = gSwapchain->acquireNextImage(); + gRenderer->setFramebuffer(gFramebuffers[frameBufferIndex]); + + gfx::Viewport viewport = {}; + viewport.maxZ = 1.0f; + viewport.extentX = (float)gWindowWidth; + viewport.extentY = (float)gWindowHeight; + gRenderer->setViewportAndScissor(viewport); + + // We start by clearing our framebuffer, which only has a color target. // static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; @@ -349,13 +420,15 @@ void renderFrame() // basis, even though the data that is loaded does not change // per-frame (we always use an identity matrix). // - static const float kIdentity[] = + float identityMatrix[] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }; + gfxGetIdentityProjection(gfxGetProjectionStyle(gRenderer->getRendererType()), identityMatrix); + // // We know that `gRootObject` is a root shader object created // from our program, and that it is set up to hold values for @@ -390,7 +463,7 @@ void renderFrame() // Once we have formed a cursor that "points" at the // model-view projection matrix, we can set its data directly. // - rootCursor["Uniforms"]["modelViewProjection"].setData(kIdentity, sizeof(kIdentity)); + rootCursor["Uniforms"]["modelViewProjection"].setData(identityMatrix, sizeof(identityMatrix)); // // Some readers might be concerned about the performance o // the above operations because of the use of strings. For @@ -427,14 +500,17 @@ void renderFrame() // With that, we are done drawing for one frame, and ready for the next. // - gRenderer->presentFrame(); + gRenderer->makeSwapchainImagePresentable(gSwapchain); + + gRenderer->endFrame(); + + gSwapchain->present(); } void finalize() { - // All of our graphics API objects are reference-counted, - // so there isn't any additional cleanup work that needs - // to be done in this simple example. + gRenderer->waitForGpu(); + destroyWindow(gWindow); } }; |
