Jump to content
  • Advertisement
Sign in to follow this  
lonewolff

Setting the texture of a quad

This topic is 988 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys,

I am wondering how I set a texture to be used by a shader to render on to a quad.

I think I must be pretty close, but the quad renders invisible.

There are a few steps involved.

Firstly, I am creating the texture programmatically;

	float texData[] =
	{
		1,0,0,1,
		0,1,0,1,
		0,0,1,1,
		1,1,0,1
	};

	D3D11_TEXTURE2D_DESC boxTexDesc;
	ZeroMemory(&boxTexDesc, sizeof(D3D11_TEXTURE2D_DESC));
	boxTexDesc.ArraySize = 1;
	boxTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	boxTexDesc.CPUAccessFlags = 0;
	boxTexDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	boxTexDesc.Height = 2;
	boxTexDesc.MipLevels = 1;
	boxTexDesc.MiscFlags = 0;
	boxTexDesc.SampleDesc.Count = 1;
	boxTexDesc.SampleDesc.Quality = 0;
	boxTexDesc.Usage = D3D11_USAGE_DEFAULT;
	boxTexDesc.Width = 2;

	
	ID3D11Texture2D *pTexture = NULL;

	ID3D11ShaderResourceView* srv;

	D3D11_SUBRESOURCE_DATA boxTexInitData;
	ZeroMemory(&boxTexInitData, sizeof(D3D11_SUBRESOURCE_DATA));
	boxTexInitData.pSysMem = texData;
	boxTexInitData.SysMemPitch = 2 * 8;
	boxTexInitData.SysMemSlicePitch = 2 * 2 * 8;

	result = d3dDevice->CreateTexture2D(&boxTexDesc, &boxTexInitData, &pTexture);
	if (FAILED(result))
		return 22221;

	result = d3dDevice->CreateShaderResourceView(pTexture, NULL, &srv);
	if (FAILED(result))
		return 22223;

Then geometry is being created like this;

	// Create input layout
	D3D11_INPUT_ELEMENT_DESC vertexLayout[] =
	{
		{ "POSITION", 0 ,DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	// Number of elements is important
	unsigned int totalLayoutElements = 3;//ARRAYSIZE(vertexLayout);
	result = d3dDevice->CreateInputLayout(vertexLayout, totalLayoutElements, d3dVsBuffer->GetBufferPointer(), d3dVsBuffer->GetBufferSize(), &d3dInputLayout);
	if (FAILED(result))
		return 9000;

	// Make some geometry
	int nVerts = 6;
	Float9* vertex_data = new Float9[nVerts];
	vertex_data[0] = { -0.5f, -0.5f, 0.0f,		1.0f, 0.0f, 0.0f, 1.0f		,0.0f ,0.0f};
	vertex_data[1] = { -0.5f, 0.5f, 0.0f, 		0.0f, 1.0f, 0.0f, 1.0f		,0.0f ,1.0f };
	vertex_data[2] = { 0.5f, -0.5f, 0.0f,		0.0f, 0.0f, 1.0f, 1.0f		,1.0f ,0.0f };
	vertex_data[3] = { 0.5f, -0.5f, 0.0f,		0.0f, 0.0f, 1.0f, 1.0f		,1.0f ,0.0f };
	vertex_data[4] = { -0.5f, 0.5f, 0.0f,		0.0f, 1.0f, 0.0f, 1.0f		,0.0f ,1.0f };
	vertex_data[5] = { 0.5f, 0.5f, 0.0f,		1.0f, 0.0f, 0.0f, 1.0f		,1.0f ,1.0f };

	D3D11_BUFFER_DESC vertexDesc;
	ZeroMemory(&vertexDesc, sizeof(vertexDesc));
	vertexDesc.Usage = D3D11_USAGE_DEFAULT;
	vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vertexDesc.ByteWidth = sizeof(Float9) * nVerts;

	D3D11_SUBRESOURCE_DATA resourceData;
	ZeroMemory(&resourceData, sizeof(resourceData));
	resourceData.pSysMem = vertex_data;
	
	result = d3dDevice->CreateBuffer(&vertexDesc, &resourceData, &d3dVertexBuffer);
	if (FAILED(result))
		return 11000;

And then I am setting the texture to be used by the shader

d3dContext->CSSetShaderResources(0, 0, &srv);

Finally, the shader looks like this

SamplerState samLinear : register(s0);
Texture2D squareMap : register(t0);

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
    float2 tex0 : TEXCOORD0;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR, float2 tex0 : TEXCOORD0)
{
    VOut output;

    output.position = position;
    output.color = color;
    output.tex0 = tex0;

    return output;
}

//float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
float4 PShader(VOut pin) : SV_TARGET
{
// * Following commented section works ok *
//    float4 test;
//    test.x = 1.0f;
//    test.y = 1.0f;
//    test.z = 1.0f;
//    test.w = 1.0f;
//    return test;

// * So does this *
//    return pin.color;

    // This makes the quad invisible though
    float4 texColor = squareMap.Sample(samLinear, pin.tex0);
    return texColor;
}

Any advice would be greatly appreciated, as I almost have the hang of DirectX 11 now (I think) smile.png

Share this post


Link to post
Share on other sites
Advertisement

Close.

 

Try:

d3dContext->PSSetShaderResources(0, 1, &srv);

You chose "CS" which refers to Compute Shaders not Pixel Shaders. The second argument is how many textures you want to set, which in your case is 1, not 0.

Share this post


Link to post
Share on other sites

You're going to have other issues too with the "initial data" you've passed in.

 

The array you've provided is 32-bit floating point data per channel (128-bit per pixel), yet the texture you've created is 8 bits per channel (32 bits per pixel). Try changing your 'texData' array to "unsigned char" and use values between 0 and 255.

 

You've also set the 'SysMemPitch' of the data to 16 bytes, which isn't correct in either case. This refers to the number of bytes per row in your input data, which should either be 2 (width) * 16 in the case of 128-bit floating point textures, or 2 * 4 in the case of 32-bit per pixel formats.

Share this post


Link to post
Share on other sites

Close.
 
Try:




d3dContext->PSSetShaderResources(0, 1, &srv);
You chose "CS" which refers to Compute Shaders not Pixel Shaders. The second argument is how many textures you want to set, which in your case is 1, not 0.


Thanks heaps. Just changed it to a 1 and it is still invisible, unfortunately. [Edit] Hang on a sec I see the 'P' instead of the 'C' now. You are spot on. Just rendering colours a bit off as per what ajmiles has pointed out.

Checking out ajmiles suggestion also smile.png Edited by DarkRonin

Share this post


Link to post
Share on other sites

 


Thanks heaps. Just changed it to a 1 and it is still invisible, unfortunately.

Checking out ajmiles suggestion also smile.png

 

Yup, listen to that ajmiles guy also, he knows his stuff! :)

Share this post


Link to post
Share on other sites
Made the following changes and it is working perfectly!
 
	unsigned char texData[] =
	{
		255.0f,0,0,255.0f,
		0,255.0f,0,255.0f,
		0,0,255.0f,255.0f,
		255.0f,255.0f,0,255.0f
	};

// and

	D3D11_SUBRESOURCE_DATA boxTexInitData;
	ZeroMemory(&boxTexInitData, sizeof(D3D11_SUBRESOURCE_DATA));
	boxTexInitData.pSysMem = texData;
	boxTexInitData.SysMemPitch = 2 * 4;
	boxTexInitData.SysMemSlicePitch = 2 * 2 * 4;

// and

	d3dContext->PSSetShaderResources(0, 1, &srv);
Thanks heaps guys, it is hugely appreciated smile.png


Yup, listen to that ajmiles guy also, he knows his stuff! smile.png


Certainly does smile.png Edited by DarkRonin

Share this post


Link to post
Share on other sites

Here a way to avoid to send the UV and store them using only position to compute them :

struct VS_INPUT
{
  float4 Position : POSITION;
};

struct VS_OUTPUT
{
  float4 Position : SV_POSITION;
  float2 TexCoord : TEXCOORD0;
};

VS_OUTPUT main( in VS_INPUT Input )
{
  VS_OUTPUT Output;
  Output.Position = Input.Position;
  Output.TexCoord = 0.5f * float2( Output.Position.x, -Output.Position.y ) + 0.5f;
  return Output;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!