0

I'm making my graphics engine. I want to have the ability to write it on C++, but create UI for an editor on C#. So with some defines, I disable rendering to a window and trying to do the off-screen rendering to pass then data to c# but I have a problem, I'm understanding why it's happening (it's how DirectX create textures and stores them) but have no clue how to fix it. So here are the results.

Imaged rendered to the window: image rendered to the window

Image rendered to bmp (flipped): image rendered to bmp(flipped)

On the first image, all looks good, and on the second as you can see I have flipped Y, and maybe X (not sure) coordinates. And for maybe useful information, I represent normals as color.

Here is my code

Vertex Buffer

cbuffer Transformation : register(b0) {
    matrix transformation;
};

cbuffer ViewProjection : register(b1) {
    matrix  projection;
    matrix  view;
};

struct VS_OUT {
    float2 texcoord : TextureCoordinate;
    float3 normal : Normal;
    float4 position : SV_Position;
};

VS_OUT main(float3 position : Position, float3 normal : Normal, float2 texcoord : TextureCoordinate) {
    matrix tView = transpose(view);
    matrix tProjection = transpose(projection);
    matrix tTransformation = transpose(transformation);

    matrix MVP = mul(tTransformation, mul(tView, tProjection));
    VS_OUT result;
    result.position = mul(float4(position, 1.0f), MVP);
    result.texcoord = texcoord;
    result.normal = normal;
    
    return result;
}

Pixel buffer

float4 main(float2 texcoord : TextureCoordinate, float3 normal : Normal) : SV_Target
{
    float3 color = (normal + 1) * 0.5f;
    return float4(color.rgb, 1.0f);
}

DirectX code for offscreen rendering initialization

D3D_FEATURE_LEVEL FeatureLevels[] = {
            D3D_FEATURE_LEVEL_11_1,
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0,
            D3D_FEATURE_LEVEL_9_3,
            D3D_FEATURE_LEVEL_9_2,
            D3D_FEATURE_LEVEL_9_1
        };

        UINT deviceFlags = 0;

#if defined(DEBUG) || defined(_DEBUG)
        deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif      

        DirectX11Call(D3D11CreateDevice(
            nullptr,
            D3D_DRIVER_TYPE_HARDWARE,
            nullptr,
            deviceFlags,
            FeatureLevels,
            ARRAYSIZE(FeatureLevels),
            D3D11_SDK_VERSION,
            &m_Device,
            &m_FeatureLevel,
            &m_DeviceContext
        ))

        D3D11_TEXTURE2D_DESC renderingDescription = {};
        renderingDescription.Width = width;
        renderingDescription.Height = height;
        renderingDescription.ArraySize = 1;
        renderingDescription.SampleDesc.Count = 1;
        renderingDescription.Usage = D3D11_USAGE_DEFAULT;
        renderingDescription.BindFlags = D3D11_BIND_RENDER_TARGET;
        renderingDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        m_Device->CreateTexture2D(&renderingDescription, nullptr, &m_Target);

        renderingDescription.BindFlags = 0;
        renderingDescription.Usage = D3D11_USAGE_STAGING;
        renderingDescription.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
        m_Device->CreateTexture2D(&renderingDescription, nullptr, &m_Output);

        DirectX11Call(m_Device->CreateRenderTargetView(m_Target.Get(), nullptr, &m_RenderTargetView))

        D3D11_DEPTH_STENCIL_DESC depthStencilStateDescription = {};
        depthStencilStateDescription.DepthEnable = TRUE;
        depthStencilStateDescription.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
        depthStencilStateDescription.DepthFunc = D3D11_COMPARISON_LESS;

        Microsoft::WRL::ComPtr<ID3D11DepthStencilState> depthStencilState;
        DirectX11Call(m_Device->CreateDepthStencilState(&depthStencilStateDescription, &depthStencilState))
        m_DeviceContext->OMSetDepthStencilState(depthStencilState.Get(), 0);

        D3D11_TEXTURE2D_DESC depthStencilDescription = {};
        depthStencilDescription.Width = width;
        depthStencilDescription.Height = height;
        depthStencilDescription.MipLevels = 1;
        depthStencilDescription.ArraySize = 1;
        depthStencilDescription.Format = DXGI_FORMAT_D32_FLOAT;
        depthStencilDescription.SampleDesc.Count = 1;
        depthStencilDescription.SampleDesc.Quality = 0;
        depthStencilDescription.Usage = D3D11_USAGE_DEFAULT;
        depthStencilDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;
        depthStencilDescription.CPUAccessFlags = 0;
        depthStencilDescription.MiscFlags = 0;

        DirectX11Call(m_Device->CreateTexture2D(&depthStencilDescription, nullptr, &m_DepthStencilBuffer))

        D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDescription = {};
        depthStencilViewDescription.Format = DXGI_FORMAT_D32_FLOAT;
        depthStencilViewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
        depthStencilViewDescription.Texture2D.MipSlice = 0;

        DirectX11Call(m_Device->CreateDepthStencilView(m_DepthStencilBuffer.Get(), &depthStencilViewDescription, &m_DepthStencilView))

        m_DeviceContext->OMSetRenderTargets(1, m_RenderTargetView.GetAddressOf(), m_DepthStencilView.Get());

        m_DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        D3D11_VIEWPORT viewPort;
        viewPort.TopLeftX = 0.0f;
        viewPort.TopLeftY = 0.0f;
        viewPort.Width = static_cast<float>(width);
        viewPort.Height = static_cast<float>(height);
        viewPort.MinDepth = 0.0f;
        viewPort.MaxDepth = 1.0f;
        m_DeviceContext->RSSetViewports(1, &viewPort);

        D3D11_RASTERIZER_DESC rasterizerDescription = {};
        rasterizerDescription.FillMode = D3D11_FILL_SOLID;
        rasterizerDescription.CullMode = D3D11_CULL_FRONT;

        Microsoft::WRL::ComPtr<ID3D11RasterizerState> rasterizerState;
        DirectX11Call(m_Device->CreateRasterizerState(&rasterizerDescription, &rasterizerState))
        m_DeviceContext->RSSetState(rasterizerState.Get());

Code for drawing to texture

    m_DeviceContext->Flush();

    m_DeviceContext->CopyResource(m_Output.Get(), m_Target.Get());

    static const UINT resource_id = D3D11CalcSubresource(0, 0, 0);
    m_DeviceContext->Map(m_Output.Get(), resource_id, D3D11_MAP_READ, 0, &m_OutputResource);

The difference between rendering to a window is that I'm also creating swapchain. So my question is how can I fix it (flipping on CPU bad solution and it may cause problems with shaders like in this example where I have different color for sphere)

maij
  • 4,094
  • 2
  • 12
  • 28
obivan
  • 1
  • 1
  • Do you need to render the image on bmp the same as on the window? Similar problem: [Direct3D11: Flipping ID3D11Texture2D](https://stackoverflow.com/questions/46824276/direct3d11-flipping-id3d11texture2d) – Strive Sun Mar 11 '21 at 07:52
  • Kind of, I go with a more simple solution, I`m making a C# ui and thought it`s a good idea to transfer data as pixel but now I`m just getting a handle of the window that C# creates and rendering to it – obivan Mar 11 '21 at 13:30
  • You can add your new ideas to the question at any time. If you have a solution, you can also post an answer. – Strive Sun Mar 12 '21 at 05:46

0 Answers0