0
\$\begingroup\$

I have to render two objects, more exactly, same object twice, just to clarify, all my constant buffers are dynamics, created like whit this flags:

D3D11_USAGE_DYNAMIC, 
sizeof(ProjectionsBufferType), 
D3D11_BIND_CONSTANT_BUFFER, 
D3D11_CPU_ACCESS_WRITE,

void init()
{
            HRESULT hr = createHardwareDevice(device_.GetAddressOf(), context_.GetAddressOf());
            throwIfFail(hr, "Could not initialize DX11.1 device");

            if (device_ == nullptr)
                throw "DX11.1 device null";

            if (context_ == nullptr)
                throw "DX11.1 context null";

            // Obtain DXGI factory from device (since we used nullptr for pAdapter above)
            ComPtr<IDXGIFactory1> dxgiFactory = nullptr;
            {
                ComPtr<IDXGIDevice> dxgiDevice = nullptr;
                hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(dxgiDevice.GetAddressOf()));
                throwIfFail(hr, "Could not initialize DX11.1 device");

                ComPtr < IDXGIAdapter> adapter = nullptr;
                hr = dxgiDevice->GetAdapter(adapter.GetAddressOf());
                if (SUCCEEDED(hr)) {
                    hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(dxgiFactory.GetAddressOf()));
                }
            }
            throwIfFail(hr, "Could not initialize DX11.1 device");

            // Upgrade to DX11.1
            ComPtr<IDXGIFactory2> dxgiFactory2 = nullptr;
            hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(dxgiFactory2.GetAddressOf()));
            throwIfFail(hr, "Could not initialize IDXGIFactory2 for DX11.1 device");

            // Create swap chain
            DXGI_SWAP_CHAIN_DESC1 sd;
            ZeroMemory(&sd, sizeof(sd));
            sd.Width = width;
            sd.Height = height;
            sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
            sd.SampleDesc.Count = 1;
            sd.SampleDesc.Quality = 0;
            sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
            sd.BufferCount = 1;
            //sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;

            //sd.SwapEffect = 
            hr = dxgiFactory2->CreateSwapChainForHwnd(device_.Get(), hWnd, &sd, nullptr, nullptr, swapChain_.GetAddressOf());
            throwIfFail(hr, "Could not initialize swap chain or upgrade for DX11.1 device");

            // Note this tutorial doesn't handle full-screen swapchains so we block the
            // ALT+ENTER shortcut
            dxgiFactory2->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);


            // Create a render target view
            ComPtr<ID3D11Texture2D> backBuffer = nullptr;
            hr = swapChain_->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)(backBuffer.GetAddressOf()));
            throwIfFail(hr, "Could not initialize swap surface for DX11.1 device");

            // Create the target view
            hr = device_->CreateRenderTargetView(backBuffer.Get(), nullptr, targetView_.GetAddressOf());
            throwIfFail(hr, "Could not initialize back buffer surface for DX11.1 device");

            // Create depth stencil texture
            D3D11_TEXTURE2D_DESC descDepth;
            ZeroMemory(&descDepth, sizeof(descDepth));
            descDepth.Width = width;
            descDepth.Height = height;
            descDepth.MipLevels = 1;
            descDepth.ArraySize = 1;
            descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
            descDepth.SampleDesc.Count = 1;
            descDepth.SampleDesc.Quality = 0;
            descDepth.Usage = D3D11_USAGE_DEFAULT;
            descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
            descDepth.CPUAccessFlags = 0;
            descDepth.MiscFlags = 0;
            hr = device_->CreateTexture2D(&descDepth, nullptr, depthStencil_.GetAddressOf());
            throwIfFail(hr, "Failed DX11.1 init. Cannot create stencil");

            // Create the depth stencil view
            D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
            ZeroMemory(&descDSV, sizeof(descDSV));
            descDSV.Format = descDepth.Format;
            descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
            descDSV.Texture2D.MipSlice = 0;
            hr = device_->CreateDepthStencilView(depthStencil_.Get(), &descDSV, _zBuffer.GetAddressOf());
            throwIfFail(hr, "Failed DX11.1 init. Cannot create stencil");

            context_->OMSetRenderTargets(1, targetView_.GetAddressOf(), _zBuffer.Get());

            // Setup the viewport
            D3D11_VIEWPORT vp;
            vp.Width = (FLOAT)width;
            vp.Height = (FLOAT)height;
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            context_->RSSetViewports(1, &vp);
}

Here it will render the object twice..

void render()
{
        context_->ClearRenderTargetView(targetView_.Get(), _backgroundColor);
        context_->ClearDepthStencilView(_zBuffer.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);

//SETUP SAMPLERS textures, buffers..
        context_->IASetInputLayout(layout);
        context_->VSSetShader(vs.Get(), NULL, 0);
        context_->PSSetShader(ps.Get(), NULL, 0);

        //............setup samplers and textures..

        UINT offset = 0;
        auto sizeOfVertex = model->getSizeofVertexBuffer();
        context_->IASetVertexBuffers(0, 1, model->getVertexBuffer().GetAddressOf(), &sizeOfVertex, &offset);

        context_->VSSetConstantBuffers(PROJECTIONS_BUFFER, 1, projBuff.GetAddressOf());


        context_->PSSetConstantBuffers(PROJECTIONS_BUFFER, 1, projBuff.GetAddressOf());
        context_->Draw(faceCount * 3, 0);

        //SECOND OBJECT..
        context_->IASetInputLayout(layout);
        context_->VSSetShader(vs.Get(), NULL, 0);
        context_->PSSetShader(ps.Get(), NULL, 0);

        //............setup samplers and textures..

        UINT offset = 0;
        auto sizeOfVertex = model->getSizeofVertexBuffer();
        context_->IASetVertexBuffers(0, 1, model->getVertexBuffer().GetAddressOf(), &sizeOfVertex, &offset);
        //..........Transform projection buffer to traslate second object..

        context_->VSSetConstantBuffers(PROJECTIONS_BUFFER, 1, projBuff.GetAddressOf());


        context_->PSSetConstantBuffers(PROJECTIONS_BUFFER, 1, projBuff.GetAddressOf());
        context_->Draw(faceCount * 3, 0);

        HRESULT hr = swapChain_->Present(0, 0);

}

The problem is next: When I render 1 object, it will render fine, when I render second, render fine, but when I render both, the first rendered simply dissapears showing only the second one. When I debug using visual studio, the Render screen flashes constantly from first to second, never stops, however the Visual studio graphics debugger shows the calls: ClearRenderTargetView(.....) ClearDepthStencilView(......) Draw(21760,0) Draw(21760,0) Present(0,0)

When I click on first Draw call, show me the first rendered object, when I click second Draw call, shows me BOTH objects, but when I click Present, the first object simply disappears and only shows me the second one..

When I test the pixel shader in position where the first element should be, it gives me the color should be in this position, however, not showing both objects in rendered screen..image showing graphics debugger Pixel color in position where should be first image..

UPDATE: now checking on the Graphic debugger I have this(pixel rejected) and don't know why:Pixel rejected on graphics debugger

UPDATE2: Pixel shader stage did not run on 2 draws, only run on the first..Stage did not run SOLVED:

D3D11_DEPTH_STENCIL_DESC dsDesc;

        // Depth test parameters
        dsDesc.DepthEnable = true;
        dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
        dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; //FIX TO EXECUTE ALL PIXEL SHADERS!!!

        // Stencil test parameters
        dsDesc.StencilEnable = true;
        dsDesc.StencilReadMask = 0xFF;
        dsDesc.StencilWriteMask = 0xFF;

        // Stencil operations if pixel is front-facing
        dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
        dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
        dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
        dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

        // Stencil operations if pixel is back-facing
        dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
        dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
        dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
        dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

        // Create depth stencil state
        ID3D11DepthStencilState* pDSState;
        device_->CreateDepthStencilState(&dsDesc, &pDSState);
        context_->OMSetDepthStencilState(pDSState, 0);

UPDATE3: All pixel shaders are executing right now, but the output merger did not show me both objects, still "PIXEL WAS EXCLUDED BECAUSE IT FAILED A DEPTH TEST"..

\$\endgroup\$
  • \$\begingroup\$ Looks like its flipping between backbuffers, with the first item being discarded as its a frame behind. Don't know why. I would suggest, render to off screen buffer, and copyresource that frame into your backbuffer. If it still is happening, at least you know its nothing to do with your back buffer. \$\endgroup\$ – ErnieDingo May 25 at 22:21
  • \$\begingroup\$ could you please let me know how to do that? code example? thks \$\endgroup\$ – KronuZ May 25 at 23:26
  • \$\begingroup\$ Basically, create another Texture2D with render target view attached (will be additional code, but straight forward). Texture should be the same dimensions as your backbuffer. Once you've done that, set your rendertarget to that instead. once you have executed your render draw calls, excute a CopyResource (if its not a MSAA texture), or a ResolveSubresource call (going off the top of my head).. The source of the copy should be your texture, and the target being the backbuffer. Once the copy is completed, execute present as per normal. \$\endgroup\$ – ErnieDingo May 26 at 0:45
  • \$\begingroup\$ Are you rendering only in response to WM_PAINT messages? \$\endgroup\$ – Maximus Minimus May 26 at 6:42
  • \$\begingroup\$ Same as nearly all tutorials and examples:LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { PAINTSTRUCT ps; HDC hdc; switch( message ) { case WM_PAINT: hdc = BeginPaint( hWnd, &ps ); EndPaint( hWnd, &ps ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0; } \$\endgroup\$ – KronuZ May 26 at 15:08
0
\$\begingroup\$

Finally I solve the problem, was the DYNAMIC BUFFER, on the map function do not use D3D11_MAP_WRITE_NO_OVERWRITE unless you are an expert, buffer update was the problem, instead use: D3D11_MAP_WRITE_DISCARD. I have tested anything, since write 3, 4, 5 objects to change Rasterizer, to add D3D11_DEPTH_STENCIL_DESC, D3D11_BLEND_DESC1 and none of those work, always render only 1 Object, and always the last one... When I changed from D3D11_MAP_WRITE_NO_OVERWRITE to D3D11_MAP_WRITE_DISCARD in call:

Map(buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);

Problem solved

Microsoft: (https://docs.microsoft.com/en-us/windows/win32/direct3d11/how-to--use-dynamic-resources) D3D11_MAP_WRITE_NO_OVERWRITE indicates that the app will not overwrite data already in use in the dynamic buffer. The Map call will return a pointer to the old data, which will allow the app to add new data in unused regions of the vertex or index buffer. The app must not modify vertices or indices that are used in a draw operation as they might still be in use by the GPU.

We recommend that the app then use D3D11_MAP_WRITE_DISCARD after the dynamic buffer is full to receive a new region of memory, which discards the old vertex or index data after the GPU is finished.

StackOverflow explanation: https://stackoverflow.com/questions/23368880/differences-of-directx11-d3d11-map

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.