diff options
| author | Yong He <yonghe@outlook.com> | 2021-04-20 13:17:29 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-20 13:17:29 -0700 |
| commit | 34fba7b5e726136c6eee8a318ab9a75381399c00 (patch) | |
| tree | 39a496c7052256cef9b089b78ab4bd48316571bd /examples/model-viewer/main.cpp | |
| parent | 6bba674f9d732eccc27dcf004611e6a8eb9bc14e (diff) | |
Various fixes to make `model-viewer` example almost working. (#1801)
* Fixing `PseudoPtr` legalization and `gfx` lifetime issues.
* Fixing `model-viewer` example.
This change contains various fixes to bring `model-viewer` example to fully functional. These fixes include:
1. Add `spReflectionTypeLayout_getSubObjectRangeSpaceOffset` function to return the space index for a sub object referenced through a `ParameterBlock` binding.
2. Make sure `D3D12Device` specifies column major matrix order creating a Slang session.
3. Fix `platform::Window::close()` and `platform::Application::quit()`.
4. Fix memory leak during `model-viewer''s model loading.
5. Fix command buffer recording in `model-viewer`.
With these changes, model viewer can now produce an image with a gray cube. The lighting is still incorrect becuase the `gfx` shader object implementation still does not handle "pending layout" resulting from global existential parameters.
* Fix d3d12 root signature creation.
* Use row-major matrix layout in model-viewer
Diffstat (limited to 'examples/model-viewer/main.cpp')
| -rw-r--r-- | examples/model-viewer/main.cpp | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/examples/model-viewer/main.cpp b/examples/model-viewer/main.cpp index 3d7a9fe34..f6aab4c4a 100644 --- a/examples/model-viewer/main.cpp +++ b/examples/model-viewer/main.cpp @@ -212,6 +212,11 @@ RefPtr<Model> loadModel( struct Callbacks : platform::ModelLoader::ICallbacks { RendererContext* context; + // Hold a reference to all material and mesh objects + // created during loading so that they can be properly + // freed. + std::vector<RefPtr<Material>> materials; + std::vector<RefPtr<Mesh>> meshes; void* createMaterial(MaterialData const& data) override { SimpleMaterial* material = new SimpleMaterial(); @@ -219,6 +224,7 @@ RefPtr<Model> loadModel( material->specularColor = data.specularColor; material->specularity = data.specularity; material->createShaderObject(context); + materials.push_back(material); return material; } @@ -228,6 +234,7 @@ RefPtr<Model> loadModel( mesh->firstIndex = data.firstIndex; mesh->indexCount = data.indexCount; mesh->material = (Material*)data.material; + meshes.push_back(mesh); return mesh; } @@ -626,7 +633,6 @@ struct LightEnv : public RefObject // struct ModelViewer : WindowedAppBase { - RendererContext context; // Most of the application state is stored in the list of loaded models, @@ -809,7 +815,9 @@ void renderFrame(int frameIndex) override // glm::mat4x4 identity = glm::mat4x4(1.0f); auto clientRect = getWindow()->getClientRect(); - glm::mat4x4 projection = glm::perspective( + if (clientRect.height == 0) + return; + glm::mat4x4 projection = glm::perspectiveRH_ZO( glm::radians(60.0f), float(clientRect.width) / float(clientRect.height), 0.1f, 1000.0f); @@ -834,6 +842,12 @@ void renderFrame(int frameIndex) override view = glm::translate(view, -cameraPosition); glm::mat4x4 viewProjection = projection * view; + auto deviceInfo = gDevice->getDeviceInfo(); + glm::mat4x4 correctionMatrix; + memcpy(&correctionMatrix, deviceInfo.identityProjectionMatrix, sizeof(float)*16); + viewProjection = correctionMatrix * viewProjection; + // glm uses column-major layout, we need to translate it to row-major. + viewProjection = glm::transpose(viewProjection); auto drawCommandBuffer = gTransientHeaps[frameIndex]->createCommandBuffer(); auto drawCommandEncoder = @@ -848,24 +862,20 @@ void renderFrame(int frameIndex) override // We are only rendering one view, so we can fill in a per-view // shader object once and use it across all draw calls. // + auto viewShaderObject = gDevice->createShaderObject(context.perViewShaderType); { ShaderCursor cursor(viewShaderObject); cursor["viewProjection"].setData(&viewProjection, sizeof(viewProjection)); cursor["eyePosition"].setData(&cameraPosition, sizeof(cameraPosition)); } - // The majority of our rendering logic is handled as a loop // over the models in the scene, and their meshes. // for(auto& model : gModels) { - auto rootObject = drawCommandEncoder->bindPipeline(gPipelineState); - ShaderCursor rootCursor(rootObject); - rootCursor["gViewParams"].setObject(viewShaderObject); drawCommandEncoder->setVertexBuffer(0, model->vertexBuffer, sizeof(Model::Vertex)); drawCommandEncoder->setIndexBuffer(model->indexBuffer, Format::R_UInt32); - // For each model we provide a parameter // block that holds the per-model transformation // parameters, corresponding to the `PerModel` type @@ -879,10 +889,8 @@ void renderFrame(int frameIndex) override cursor["inverseTransposeModelTransform"].setData( &inverseTransposeModelTransform, sizeof(inverseTransposeModelTransform)); } - rootCursor["gModelParams"].setObject(modelShaderObject); auto lightShaderObject = lightEnv->createShaderObject(); - rootCursor["gLightEnv"].setObject(lightShaderObject); // Now we loop over the meshes in the model. // @@ -893,6 +901,13 @@ void renderFrame(int frameIndex) override // for(auto& mesh : model->meshes) { + // Set the pipeline and binding state for drawing each mesh. + auto rootObject = drawCommandEncoder->bindPipeline(gPipelineState); + ShaderCursor rootCursor(rootObject); + rootCursor["gViewParams"].setObject(viewShaderObject); + rootCursor["gModelParams"].setObject(modelShaderObject); + rootCursor["gLightEnv"].setObject(lightShaderObject); + // Each mesh has a material, and each material has its own // parameter block that was created at load time, so we // can just re-use the persistent parameter block for the @@ -911,6 +926,9 @@ void renderFrame(int frameIndex) override drawCommandEncoder->drawIndexed(mesh->indexCount, mesh->firstIndex); } } + drawCommandEncoder->endEncoding(); + drawCommandBuffer->close(); + gQueue->executeCommandBuffer(drawCommandBuffer); gSwapchain->present(); } |
