windowsdirectxdirectx-11hlsldirect3d11

Direct3D 11 and 2D : wrong display of a texture


I am still trying to improve my test program about Direct3D 11 in 2D, without any additional library (see direct3d 11 and 2D: pass coordinates of a vertex as int and not float).

I now want to display a memory buffer (BGRA colorspace, B being the lower byte) in a rectangle.

The result should be

enter image description here

Note that the pixel at the 4 corners is pink.

When I create the texture and use a shader to draw it in a rectangle of the window, I get:

enter image description here

that is 3 bands (blue, red and pink). I've searched a lot, modify some parameters, without luck.

the code to create the memory buffer and the texture:



unsigned int *data_new(int w, int h)
{
    unsigned int *d;
    unsigned int *iter;
    int i;
    int j;

    DBG_FCT;

    d = malloc(w * h * sizeof(unsigned int));
    if (!d)
        return NULL;

    iter = d;
    for (j = 0; j < h; j++)
    {
        if (j < h/2)
        {
            /* red, otherwise green */
            for (i = 0; i < w; i++, iter++)
                *iter = (i < w/2) ? 0xffff0000 : 0xff00ff00;
        }
        else
        {
            /* blue, otherwise yellow */
            for (i = 0; i < w; i++, iter++)
                *iter = (i < w/2) ? 0xff0000ff : 0xffffff00;
        }
    }

    /* pink on corners, coords (i,j) --> i*h+j */
    d[0] = 0xffff00ff;
    d[w -1] = 0xffff00ff;
    d[w * (h - 1)] = 0xffff00ff;
    d[w * h - 1] = 0xffff7f00;

    return d;
}

/*** texture ***/

Object *texture_new(D3d *d3d,
                    int x, int y,
                    int w, int h,
                    unsigned int *img)
{
    Vertex vertices[4];
    unsigned int indices[6];
    D3D11_BUFFER_DESC desc_buffer;
    D3D11_TEXTURE2D_DESC desc_tex;
    D3D11_SUBRESOURCE_DATA data_sr;
    Object *o;
    HRESULT res;

    DBG_FCT;

    o = (Object *)calloc(1, sizeof(Object));
    if (!o)
        return NULL;

    /** vertex and index buffers **/

    /* vertex upper left */
    vertices[0].x = x;
    vertices[0].y = y;
    vertices[0].r = 0;
    vertices[0].g = 0;
    vertices[0].b = 0;
    vertices[0].a = 0;
    vertices[0].u = 0.0f;
    vertices[0].v = 0.0f;
    /* vertex upper right*/
    vertices[1].x = x + w;
    vertices[1].y = y;
    vertices[1].r = 0;
    vertices[1].g = 0;
    vertices[1].b = 0;
    vertices[1].a = 0;
    vertices[0].u = 1.0f;
    vertices[0].v = 0.0f;
    /* vertex bottom right*/
    vertices[2].x = x + w;
    vertices[2].y = y + h;
    vertices[2].r = 0;
    vertices[2].g = 0;
    vertices[2].b = 0;
    vertices[2].a = 0;
    vertices[0].u = 1.0f;
    vertices[0].v = 1.0f;
    /* vertex bottom left*/
    vertices[3].x = x;
    vertices[3].y = y + h;
    vertices[3].r = 0;
    vertices[3].g = 0;
    vertices[3].b = 0;
    vertices[3].a = 0;
    vertices[0].u = 0.0f;
    vertices[0].v = 1.0f;

    /* triangle upper left */
    indices[0] = 0;
    indices[1] = 1;
    indices[2] = 3;
    /* triangle bottom right */
    indices[3] = 1;
    indices[4] = 2;
    indices[5] = 3;

    o->stride = sizeof(Vertex);
    o->offset = 0U;
    o->index_count = 6U;

    desc_buffer.ByteWidth = sizeof(vertices);
    desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
    desc_buffer.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    desc_buffer.MiscFlags = 0U;
    desc_buffer.StructureByteStride = 0U;

    data_sr.pSysMem = vertices;
    data_sr.SysMemPitch = 0U;
    data_sr.SysMemSlicePitch = 0U;

    res =ID3D11Device_CreateBuffer(d3d->d3d_device,
                                   &desc_buffer,
                                   &data_sr,
                                   &o->vertex_buffer);
    if (FAILED(res))
    {
        free(o);
        return NULL;
    }

    DBG_NAME(ID3D11Device, o->vertex_buffer, "Vertex buffer");

    desc_buffer.ByteWidth = sizeof(indices);
    desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
    desc_buffer.BindFlags = D3D11_BIND_INDEX_BUFFER;
    desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    desc_buffer.MiscFlags = 0U;
    desc_buffer.StructureByteStride = 0U;

    data_sr.pSysMem = indices;
    data_sr.SysMemPitch = 0U;
    data_sr.SysMemSlicePitch = 0U;

    res =ID3D11Device_CreateBuffer(d3d->d3d_device,
                                   &desc_buffer,
                                   &data_sr,
                                   &o->index_buffer);
    if (FAILED(res))
    {
        ID3D11Buffer_Release(o->vertex_buffer);
        free(o);
        return NULL;
    }

    DBG_NAME(ID3D11Device, o->index_buffer, "Index buffer");

    /** texture 2D **/

    desc_tex.Width = w;
    desc_tex.Height = h;
    desc_tex.MipLevels = 1;
    desc_tex.ArraySize = 1;
    desc_tex.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    desc_tex.SampleDesc.Count = 1U;
    desc_tex.SampleDesc.Quality = 0U;
    desc_tex.Usage = D3D11_USAGE_DYNAMIC;
    desc_tex.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    desc_tex.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    desc_tex.MiscFlags = 0U;

    data_sr.pSysMem = img;
    data_sr.SysMemPitch = 4U * (unsigned int)w;
    data_sr.SysMemSlicePitch = 0U; /* for 3D resources only */

    res = ID3D11Device_CreateTexture2D(d3d->d3d_device,
                                       &desc_tex,
                                       &data_sr,
                                       &o->texture);
    if (FAILED(res))
    {
        ID3D11Buffer_Release(o->index_buffer);
        ID3D11Buffer_Release(o->vertex_buffer);
        free(o);
        return NULL;
    }

    DBG_NAME(ID3D11Device, o->texture, "Texture object");

    res = ID3D11Device_CreateShaderResourceView(d3d->d3d_device,
                                                (ID3D11Resource *)o->texture,
                                                NULL,
                                                &o->texture_view);
    if (FAILED(res))
    {
        ID3D11Texture2D_Release(o->texture);
        ID3D11Buffer_Release(o->index_buffer);
        ID3D11Buffer_Release(o->vertex_buffer);
        free(o);
        return NULL;
    }

    DBG_NAME(ID3D11Device, o->texture_view, "Texture view object");

    o->type = OBJECT_TYPE_TEXTURE;

    return o;
}

and the shader:

cbuffer cv_viewport : register(b0)
{
    row_major int2x3 rotation_matrix;
    float2 ivps;
}

struct vs_input
{
    uint2 position : POSITION;
    float4 color : COLOR;
    float2 uv : UV;
};

struct ps_input
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
    float2 uv : UV;
};

ps_input main_vs(vs_input input )
{
    ps_input output;
    float2 o = float2(mul(rotation_matrix, int3(input.position, 1))) * ivps;
    o *= 2.0f;
    o -= 1.0f;
    o.y *= -1.0f;
    output.position = float4(o, 0.0f, 1.0f);
    output.color = input.color;
    output.uv = input.uv;
    return output;
}

Texture2D texture_ : register(t0);
SamplerState sampler_ : register(s0);

float4 main_ps(ps_input input) : SV_TARGET
{
    //return input.color;
    return texture_.Sample(sampler_, input.uv);
}

the complete source code is in this git repository (d3d_7.c and shader_7.hlsl only for the texture code).

I use dynamic texture because the texture can be changed during the final program execution.

Does someone see where the issue is ?

thank you


Solution

  • Stupid copy paste error. The index of the u and v fields are all 0. Now it works...