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
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:
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
Stupid copy paste error. The index of the u and v fields are all 0. Now it works...