Oculus Rift DK2 C++ SDK深度缓冲问题求助(SDK 1.20.0/VS2013)
Hey there, I’ve been exactly where you are—trying to build a stripped-down 3D engine for the DK2 using the SuperMinimal sample as a base, since RoomTiny is way overcomplicated for simple use cases. Let’s walk through fixing the depth buffer issue and adding multi-color vertex support step by step.
1. Enable Depth Buffer Support
SuperMinimal skips depth buffers entirely to keep things minimal, so we need to add a depth swap chain alongside the color chain.
Step 1.1: Create the Depth Texture Swap Chain
First, define a depth swap chain descriptor (similar to the color one) and create it with the SDK:
ovrTextureSwapChainDesc depthDesc = {}; depthDesc.Type = ovrTexture_2D; depthDesc.ArraySize = 2; // One buffer per eye depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; // Standard 24-bit depth + 8-bit stencil depthDesc.Width = ovr_GetFovTextureSize(Session, eye, Fov, 1.0f).w; depthDesc.Height = ovr_GetFovTextureSize(Session, eye, Fov, 1.0f).h; depthDesc.MipLevels = 1; depthDesc.SampleCount = 1; depthDesc.StaticImage = ovrFalse; depthDesc.MiscFlags = ovrTextureMisc_DepthStencil; depthDesc.BindFlags = ovrTextureBind_DepthStencil; ovrTextureSwapChain DepthSwapChain = nullptr; ovr_CreateTextureSwapChainDX(Session, d3dDevice, &depthDesc, &DepthSwapChain);
Note: Always use ovr_GetFovTextureSize to get the correct per-eye resolution for your DK2 (it’s 1080x1920 per eye) instead of hardcoding values—this keeps things future-proof.
Step 1.2: Set Up Depth Stencil State
Configure Direct3D to use depth testing by creating a depth stencil state and binding it before rendering:
D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {}; depthStencilDesc.DepthEnable = TRUE; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; // Standard "closer objects obscure farther ones" logic ID3D11DepthStencilState* depthState = nullptr; d3dDevice->CreateDepthStencilState(&depthStencilDesc, &depthState); d3dContext->OMSetDepthStencilState(depthState, 0);
2. Add Multi-Color Vertex Support
SuperMinimal uses a barebones vertex structure with only position data—let’s expand that and update the pipeline.
Step 2.1: Update the Vertex Structure
Modify your vertex struct to include color data:
struct Vertex { XMFLOAT3 Position; XMFLOAT4 Color; };
Step 2.2: Update Input Layout & Shaders
You’ll need to update the input layout to recognize the color component, and adjust your shaders to pass the color through to the pixel shader.
Vertex Shader (HLSL)
struct VSInput { float3 Position : SV_POSITION; float4 Color : COLOR; }; struct PSInput { float4 Position : SV_POSITION; float4 Color : COLOR; }; PSInput VS(VSInput input) { PSInput output; output.Position = float4(input.Position, 1.0f); output.Color = input.Color; return output; }
Pixel Shader (HLSL)
float4 PS(PSInput input) : SV_TARGET { return input.Color; }
Create the Input Layout
Bind the new vertex structure to the input layout:
D3D11_INPUT_ELEMENT_DESC inputElements[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, sizeof(XMFLOAT3), D3D11_INPUT_PER_VERTEX_DATA, 0 } }; ID3D11InputLayout* inputLayout = nullptr; d3dDevice->CreateInputLayout(inputElements, ARRAYSIZE(inputElements), vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &inputLayout); d3dContext->IASetInputLayout(inputLayout);
3. Integrate Depth Buffers into the Render Loop
In your per-eye rendering code, bind the depth buffer alongside the color render target:
for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++) { // Get current color and depth buffers ID3D11Texture2D* colorTex = nullptr; ovr_GetTextureSwapChainBufferDX(Session, ColorSwapChain, eyeIndex, IID_PPV_ARGS(&colorTex)); ID3D11Texture2D* depthTex = nullptr; ovr_GetTextureSwapChainBufferDX(Session, DepthSwapChain, eyeIndex, IID_PPV_ARGS(&depthTex)); // Create render target view for color, depth stencil view for depth ID3D11RenderTargetView* rtv = nullptr; d3dDevice->CreateRenderTargetView(colorTex, nullptr, &rtv); ID3D11DepthStencilView* dsv = nullptr; D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; dsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; d3dDevice->CreateDepthStencilView(depthTex, &dsvDesc, &dsv); // Bind both to the output merger d3dContext->OMSetRenderTargets(1, &rtv, dsv); // Clear color and depth buffers float clearColor[] = { 0.1f, 0.1f, 0.1f, 1.0f }; d3dContext->ClearRenderTargetView(rtv, clearColor); d3dContext->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); // Your rendering code here (draw geometry with colored vertices) // Release resources to avoid memory leaks rtv->Release(); dsv->Release(); colorTex->Release(); depthTex->Release(); // Commit the color buffer to the swap chain ovr_CommitTextureSwapChain(Session, ColorSwapChain, eyeIndex); }
Key Things to Watch Out For
- Resolution Matching: Ensure your depth buffer dimensions exactly match the color buffer dimensions (use
ovr_GetFovTextureSizefor both). - Format Compatibility: The depth buffer format must be compatible with your color buffer format—
D24_UNORM_S8_UINTworks with most standard color formats likeR8G8B8A8_UNORM. - Resource Cleanup: Don’t forget to release all Direct3D resources after each eye render to avoid memory leaks.
This should get you up and running with depth testing and colored vertices without having to wade through the complexity of RoomTiny. Let me know if you hit any snags!
内容的提问来源于stack exchange,提问作者Mark

