Nothing is drawn

Started by
6 comments, last by haansn08 10 years, 8 months ago

Hello,

I'm still trying to get something on my screen except a blue rectangle,

(I guess it is the 5th time I make this project :( )

But nothing is drawn. I can't explain why - I have very little experience with Direct3D.

I'm not even sure my shaders get called.

Here's my render function:


	float color[] = {0.0f,0.25f,0.5f,1.0f};
	_devcon->ClearRenderTargetView(_target, color);
	//Do rendering stuff here

	//Set the primitive Topology
	_devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	//Set index & vertex buffers
	_devcon->IASetIndexBuffer(_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
	UINT stride = sizeof(Vertex), offset = 0;
	_devcon->IASetVertexBuffers(0, 1, &_vertexBuffer, &stride, &offset);

	//Activate the shaders
	_devcon->IASetInputLayout(_inputLayout);
	_devcon->VSSetShader(_vertexShader, 0, 0);
	_devcon->PSSetShader(_pixelShader, 0, 0);

	//Set the constant buffers
	ID3D11Buffer *matrixBuf;
	D3D11_BUFFER_DESC cbd;
	cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cbd.ByteWidth = sizeof(MatrixBuffer);
	cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	cbd.MiscFlags = 0;
	cbd.Usage = D3D11_USAGE_DYNAMIC;
	cbd.StructureByteStride = 0;

	MatrixBuffer m;
	m.world = XMMatrixIdentity();
	m.view = XMMatrixLookAtLH(XMLoadFloat3(new XMFLOAT3(0.0f,0.0f,-5.0f)),
		XMLoadFloat3(new XMFLOAT3(0.0f,0.0f,0.0f)),
		XMLoadFloat3(new XMFLOAT3(0.0f,1.0f,0.0f)));
	m.projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, 1.777f, 0.01f, 10000.0f);

	D3D11_SUBRESOURCE_DATA matrixData;
	matrixData.pSysMem = &m;
	matrixData.SysMemPitch = 0;
	matrixData.SysMemSlicePitch = 0;

	HRESULT hRes = _dev->CreateBuffer(&cbd, &matrixData, &matrixBuf);
	if (FAILED(hRes))
		return false;

	_devcon->VSSetConstantBuffers(0, 1, &matrixBuf);
	_devcon->DrawIndexed(18, 0, 0);

	_swapchain->Present(0,0);
	return true;

Btw. The structure MatrixBuffer is something like:


struct MatrixBuffer
{
	XMMATRIX world;
	XMMATRIX view;
	XMMATRIX projection;
};

And here's my vertex shader:


cbuffer cbPerObject
{
	float4x4 world;
	float4x4 view;
	float4x4 projection;
};
struct VertexIn
{
	float3 pos : POSITION;
	float4 col : COLOR;
};
struct VertexOut
{
	float4 pos : SV_POSITION;
	float4 col : COLOR;
};
VertexOut main (VertexIn input)
{
	VertexOut vout;
	vout.pos = float4 (input.pos, 1.0f);
	vout.pos = mul(vout.pos, world);
	vout.pos = mul(vout.pos, view);
	vout.pos = mul(vout.pos, projection);

	vout.col = input.col;

	return vout;
}

The shaders compile (hopefully) properly. (The result from D3DXCompileFromFile is S_OK!)

Advertisement

Vertex shader looks alright, but just to be sure define cbuffer like this:


cbuffer cbPerObject : register(b0)

I cannot remember multiplication order, it might be that you need to multiply matrix*vector instead of vector*matrix, or transpose your matrices before putting them into constant buffer.

Can we see your pixel shader? However considering how you pass color from vertex shader there's probably no issues.

I cannot see where you set your render targets, are you using any depth buffer?

I would be nice to see input layout definition, data for your vertex and index buffers.

Ultimately to find problems on your own you can use:

  1. Debugger, it should throw messages if some parameters are invalid
  2. PIX or Visual Studio 2012 graphical debugger, it'll allow to see how your vertices are transformed and which pixel are drawn or discarded.

This site is what you need

http://www.rastertek.com/tutindex.html

:)

Transposing the matrices didn't help (But you were right - I forgot to do so smile.png)

My pixel shader is just passing the color:


struct VertexOut
{
	float4 pos : SV_POSITION;
	float4 col : COLOR;
};
float4 main(VertexOut input) : SV_TARGET
{
	return input.col;
}

This is how I create the input layout.


D3D11_INPUT_ELEMENT_DESC layout[] = 
	{
		{"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},
	};
	HR(_dev->CreateInputLayout(layout, 2, vs->GetBufferPointer(), vs->GetBufferSize(), &_inputLayout));

And this guy should create the geometry of a pyramid:


HRESULT PyramidApp::InitGeometry()
{
	//Create the vertices
	Vertex pyramid_vertices[] = {
		{XMFLOAT3(+0.0f, +2.0f, +0.0f), XMFLOAT4(1.0f, 0.5f, 0.25f, 1.0f)}, //Spitze		0
		{XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(0.25f, 0.5f, 0.5f, 1.0f)}, //Links vorne	1
		{XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(0.5f, 1.0f, 0.5f, 1.0f)}, //Links hinten	2
		{XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(0.5f, 0.5f, 0.25f, 1.0f)}, //rechts vorne	3
		{XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.5f, 1.0f)}, //rechts hinten	4
	};
	//Create a vertex buffer
	D3D11_BUFFER_DESC vbd;
	ZeroMemory(&vbd, sizeof(vbd));
	vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vbd.ByteWidth = sizeof(pyramid_vertices);
	vbd.Usage = D3D11_USAGE_IMMUTABLE;

	D3D11_SUBRESOURCE_DATA vdata;
	vdata.pSysMem = pyramid_vertices;
	HR(_dev->CreateBuffer(&vbd, &vdata, &_vertexBuffer));
	//Create the index Buffer
	UINT pyramid_indices[] = {
		0, 3, 1,
		0, 4, 3,
		0, 2, 4,
		0, 1, 2,
		1, 3, 2,
		2, 3, 4
	};
	D3D11_BUFFER_DESC ibd;
	ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	ibd.ByteWidth = sizeof(pyramid_indices);
	ibd.CPUAccessFlags = 0;
	ibd.MiscFlags = 0;
	ibd.StructureByteStride = 0;
	ibd.Usage = D3D11_USAGE_IMMUTABLE;

	D3D11_SUBRESOURCE_DATA idata;
	idata.pSysMem = pyramid_indices;
	HR(_dev->CreateBuffer(&ibd, &idata, &_indexBuffer));
	return S_OK;
}

The entire source code is in the attachment ;)

(Sorry for the incorrect use of design patterns - I'm only 14 and the GoF book is difficult to understand for a non-english...)

This site is what you need

http://www.rastertek.com/tutindex.html

Yeah - I know this site and many commands I've learned from there, but I don't like how little code is explained...

Now I'm following the book "Introduction to 3D Game Programming with DirectX 11" (Frank Luna) as good as I can (e.g. I can't use the Effect Library for some reason...)

I couldn't find call to ID3D11DeviceContext::ClearDepthStencilView, pixels probably get discarded all the time after first frame. Add following line next to ClearRenderTargetView().


_devcon->ClearDepthStencilView(_depthStencil, D3D11_CLEAR_DEPTH, 1, 0);

There are also other bugs.

Following code makes me think your other language is C# or Java.


	m.view = XMMatrixLookAtLH(XMLoadFloat3(new XMFLOAT3(0.0f,0.0f,-5.0f)),
		XMLoadFloat3(new XMFLOAT3(0.0f,0.0f,0.0f)),
		XMLoadFloat3(new XMFLOAT3(0.0f,1.0f,0.0f)));

If you call new() every frame without deleting those vectors you'll eventually run out of memory, also it's better to use stack in this case. Something around this is better:


m.view = XMMatrixLookAtLH(XMFLOAT3(0.0f,0.0f,-5.0f), XMFLOAT3(0.0f,0.0f,0.0f)), XMFLOAT3(0.0f,1.0f,0.0f));

Similar problem few lines below.


HRESULT hRes = _dev->CreateBuffer(&cbd, &matrixData, &matrixBuf);

You create new buffer every frame and don't delete it. It'll trash your GPU memory. Use Map() method to edit values in the buffer: http://msdn.microsoft.com/en-us/library/windows/desktop/ff476457%28v=vs.85%29.aspx

I think there is something wrong with these lines


vbd.ByteWidth = sizeof(pyramid_vertices);

ibd.ByteWidth = sizeof(pyramid_indices);

Following code makes me think your other language is C# or Java.

C# smile.png

I did this because XMMatrixLookAtLH expects a XMVector as an argument put I can't construct these so easily!

Solved it this way:


XMFLOAT3 pos (0.0f,0.0f,-5.0f);
XMFLOAT3 at(0.0f,0.0f,0.0f);
XMFLOAT3 up (0.0f,1.0f,0.0f);
m.view = XMMatrixLookAtLH(XMLoadFloat3(&pos),XMLoadFloat3(&at),XMLoadFloat3(&up));

But I found the problem:

I was missing the call (Sorry, Zaoshi Kaba, I didn't read the line where you said I needed to set my render target - should've read your post more exactly,)


_devcon->OMSetRenderTargets(1, &_target, _depthStencil);

(Clearing the Z-Buffer and transposing the matrices was also a problem - thanks everybody!)

This topic is closed to new replies.

Advertisement