Jump to content
  • Advertisement
Sign in to follow this  
Federico Barlotti

Clarification about shaders and Directx11

This topic is 798 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

I've seen written all over the place, since DX10 the FFP is no longer supported and you need to set up shaders, otherwise there is no way to draw things. In basically every tutorials, in fact, you have to set up the input layout, fill in the "IA", etc.

But... I tried to not do any of that, and just create a vertex buffer, fill it with 3 (custom declared) "VERTEX" objects, and draw it. No shaders are being loaded, compiled, created nor set as active anywhere in the code, yet it renders a perfect moving triangle on screen.

 

Am I missing something very obvious here?

Share this post


Link to post
Share on other sites
Advertisement

Yeah that should not work. Without a vertex shader, there's no way that D3D knows where those vertices should be placed on the screen. 

What's your code look like?

Share this post


Link to post
Share on other sites

I set up the wievport, swapchain, DX11 device, etc., then create a vertex buffer and set it as active

D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));

bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(VERTEX) * 3;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
hr = dev->CreateBuffer(&bd, NULL, &pVBuffer);

UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);

Then, in the main frame function, create and update an array of three vertices... 

devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));

static float r = 0.5;
static float h = 0;

h += 0.001;

if (h >= 2 * D3DX_PI)
{
    h = 0;
}

vertices[0] = { r*cos(-(D3DX_PI / 6) + h), r*sin(-(D3DX_PI / 6) + h), 0.0, D3DXCOLOR(1.0, 0.0, 0.0, 1.0) };
vertices[1] = { r*cos((D3DX_PI / 2) + h), r*sin((D3DX_PI / 2) + h), 0.0, D3DXCOLOR(0.0, 1.0, 0.0, 1.0) };
vertices[2] = { r*cos(7 * (D3DX_PI / 6) + h), r*sin(7 * (D3DX_PI / 6) + h), 0.0, D3DXCOLOR(0.0, 0.0, 1.0, 1.0) };

And fill the buffer, which is already active

fillBuffer<VERTEX[]>(dev, devcon, &pVBuffer, vertices, sizeof(VERTEX)*3);

...

template <typename T> HRESULT fillBuffer(ID3D11Device *dev, ID3D11DeviceContext *devcon, ID3D11Buffer **ppOut, T pIn, UINT vSize)
{
	HRESULT hr;

	D3D11_MAPPED_SUBRESOURCE ms;
	hr = devcon->Map(*ppOut, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
	if (FAILED(hr))
		return hr;
	memcpy(ms.pData, pIn, vSize);
	devcon->Unmap(*ppOut, NULL);

	return S_OK;
}

Then I draw the triangle and present the frame

devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devcon->Draw(3, 0);

return swapchain->Present(0, 0);

And voilà.

 

Admittedly, if I try to use the shader I was working on, the output image is exactly the same, but I tried cleaning every part of the code where the shader is used or set up and it still works. I even renamed the .hlsl file and recompiled everything to be sure. Could it be a caching/partial compilation issue?

Edited by Banderi

Share this post


Link to post
Share on other sites
Excluding the possibility that you did set a shader earlier and didn't unset it, or some 3rd party dll did (such as Direct2D), 3D APIs are like web browsers: when you do something the docs specifically tell you not to do but it still works on your machine, it doesn't mean it will work on other machines.

Share this post


Link to post
Share on other sites

Hmm, is it a general statement or did I do something very bad in my code?

I am including the FBX SDK .dll since I would have tried and tackled it in a later time, though I'm not doing anything with it. Could that be the problem?

Share this post


Link to post
Share on other sites

Just call ID3D11DeviceContext::VSGetShader or ID3D11DeviceContext::PSGetShader to see what shader is bound.

Share this post


Link to post
Share on other sites

They both return a null pointer, and for some reason now the GPU sometimes crashes when I attempt to start the program or resume it after pausing the debug... I'm not gonna attempt to run it without a shader anymore though, since the GPU apparently can't recover if it crashes a second time (thus requiring me to reboot). Maybe my GPU is just weird, I dunno.

 

Now, onto new and painful issues, since I just can't get the matrix buffer to be accepted by the shader...

Edited by Banderi

Share this post


Link to post
Share on other sites

Yes, the documentation for all of the *SetShader calls states:

 

 

Passing in NULL disables the shader for this pipeline stage.

 

However, the Shader Stages page also states:

 

 

The vertex shader stage must always be active for the pipeline to execute.

 

So by running with a NULL vertex shader, one of two things is happening: either your vertex shader isn't actually NULL, or your driver has a bug that is allowing the graphics pipeline to execute without a VS.

 

Either way you're relying on undocumented, undefined or erroneous behaviour.  Instead you should familiarise yourself with the way things are supposed to work according to the documentation, and rely on that instead.

Share this post


Link to post
Share on other sites

There is no SetShader call active anywhere in the code, so it's most probably the second one.

 

And I know that isn't the way it's supposed to be done, I was just wondering why it just so happened to work magically like that.

Share this post


Link to post
Share on other sites

Try specifying D3D11_CREATE_DEVICE_DEBUG when you create the device and see if it splits out any warnings/errors for you.

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!