Advertisement

DX11 Vertex Calculation Confusion

Started by May 18, 2016 09:43 PM
1 comment, last by GAFO 8 years, 7 months ago

Hello Community,

I am trying to build up a simple renderer for dx11. Since I am at the very start and do not want use the toolkit and its drawing functions I searched in the web and came across this:


void DrawLine(float x1, float y1, float x2, float y2, Color color)
{
	if (this->dxManager->pContext == NULL)
		return;

	int a = color.A & 0xff;
	int r = color.R & 0xff;
	int g = color.G & 0xff;
	int b = color.B & 0xff;

	UINT viewportNumber = 1;

	D3D11_VIEWPORT vp;

	float blendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
	this->dxManager->pContext->OMSetBlendState(this->transparency, blendFactor, 0xffffffff);
	this->dxManager->pContext->RSGetViewports(&viewportNumber, &vp);

	float xx0 = 2.0f * (x1 - 0.5f) / vp.Width - 1.0f;
	float yy0 = 1.0f - 2.0f * (y1 - 0.5f) / vp.Height;
	float xx1 = 2.0f * (x2 - 0.5f) / vp.Width - 1.0f;
	float yy1 = 1.0f - 2.0f * (y2 - 0.5f) / vp.Height;

	COLOR_VERTEX* v = NULL;
	D3D11_MAPPED_SUBRESOURCE mapData;

	if (FAILED(this->dxManager->pContext->Map(this->mVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mapData)))
		return;

	v = (COLOR_VERTEX*)mapData.pData;

	v[0].Position.x = xx0;
	v[0].Position.y = yy0;
	v[0].Position.z = 0;
	v[0].Color = D3DXCOLOR(
		((float)r / 255.0f),
		((float)g / 255.0f),
		((float)b / 255.0f),
		((float)a / 255.0f));

	v[1].Position.x = xx1;
	v[1].Position.y = yy1;
	v[1].Position.z = 0;
	v[1].Color = D3DXCOLOR(
		((float)r / 255.0f),
		((float)g / 255.0f),
		((float)b / 255.0f),
		((float)a / 255.0f));

	this->dxManager->pContext->Unmap(this->mVertexBuffer, NULL);

	UINT Stride = sizeof(COLOR_VERTEX);
	UINT Offset = 0;

	this->dxManager->pContext->IASetVertexBuffers(0, 1, &this->mVertexBuffer, &Stride, &Offset);
	this->dxManager->pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP);
	this->dxManager->pContext->IASetInputLayout(this->mInputLayout);

	this->dxManager->pContext->VSSetShader(this->mVS, 0, 0);
	this->dxManager->pContext->PSSetShader(this->mPS, 0, 0);
	this->dxManager->pContext->GSSetShader(NULL, 0, 0);
	this->dxManager->pContext->Draw(2, 0);
}

It works very well , looks messy and will be cleaned up by me as soon I understand the calculations, since C/P makes no sense for me, but I still learn from existing code.

In this case its for Drawing a simple line. And it uses the "D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP" as common to me from dx9.

The only thing I do not understand is how/why the calculation from common position to the two vertext position works.


float xx0 = 2.0f * (x1 - 0.5f) / vp.Width - 1.0f;
float yy0 = 1.0f - 2.0f * (y1 - 0.5f) / vp.Height;
float xx1 = 2.0f * (x2 - 0.5f) / vp.Width - 1.0f;
float yy1 = 1.0f - 2.0f * (y2 - 0.5f) / vp.Height;

Because I would just have made the vertexes without seeing this code like:


//...
v[0].Position.x = x1;
v[0].Position.y = y1;
//...
v[1].Position.x = x2;
v[1].Position.y = y2;
//...

Like given from the function parameters.

I see that the viewport, means the size of the painting area gets calculated in somehow,

but what does the muliplication by 2.0f inside of the x coords or "1.0f - ..." in the y coords mean ? Or why is 0.5f substracted from

x and y each time ? Are these corrections and scalings like I learned with the vertexes in openGL ?

I hope someone can tell me :)

,greetings

( ps: if somebody knows , is there a way to add a line width ? )

Is it in Normalized Device Coordinates? I've never heard of that in the DirectX world, but they love that in the OpenGL world.

Does the shader do a World*View*Projection calculation at the beginning? And do you set those from your program? If not, you're probably working in screen space/normalized device coordinates. In OGL those coordinates are a percentage. The center of the screen is the origin. The screen goes from -1 to 1 or -100% to 100% in both the width and height.

That's what those calculations remind me of. Honestly, I'm not sure what it's doing, but that's the first thing that comes to mind.

When I was doing DX I skipped straight to 3D and never messed with anything 2D. So, right from the very beginning I was using a WVP matrix. But I recently went through an OGL tutorial that did everything in normalized device coordinates which introduced me to the concept.

Advertisement

Well I am confused too and I didnt need to do something like this in e.g. dx9 ... Well I made some debug stepts for trying to understand.

If I do it like: (Rects are for position reference on screenshots)


float xx0 = 2.0f * (_from.x - 0.5f) / vp.Width - 1.0f;
float yy0 = 1.0f - 2.0f * (_from.y - 0.5f) / vp.Height;
float xx1 = 2.0f * (_to.x - 0.5f) / vp.Width - 1.0f;
float yy1 = 1.0f - 2.0f * (_to.y - 0.5f) / vp.Height;

http://prntscr.com/b6ef70

(correct drawn)

..


float xx0 = _from.x/vp.Width;
float yy0 = _from.y/vp.Height;
float xx1 = _to.x / vp.Width;
float yy1 = _to.y/vp.Height;

http://prntscr.com/b6ee31

(not correct)

..


float xx0 = 2.0f * _from.x/vp.Width;
float yy0 = 2.0f * _from.y / vp.Height;
float xx1 = 2.0f * _to.x / vp.Width;
float yy1 = 2.0f * _to.y / vp.Height;

http://prntscr.com/b6egkq

(not correct, and diagonal line tottaly missing)

...


float xx0 = 2.0f * _from.x/vp.Width;
float yy0 = 1.0f - 2.0f * _from.y / vp.Height;
float xx1 = 2.0f * _to.x / vp.Width;
float yy1 = 1.0f - 2.0f * _to.y / vp.Height;

http://prntscr.com/b6ehw6

( getting better, diagonal line back but too much on the right)

...


float xx0 = 2.0f * _from.x / vp.Width - 1.0f;
float yy0 = 1.0f - 2.0f * _from.y / vp.Height;
float xx1 = 2.0f * _to.x / vp.Width - 1.0f;
float yy1 = 1.0f - 2.0f * _to.y / vp.Height;

http://prntscr.com/b6ej2r

(well thats it pretty much)

So for x its like:

((2*x)/w) - 1

and for y like:

1 - ((2*y)/h)

At the end there will be a value between 0 and 1 .. the thing is , that this from coords and dimension to those values is normaly like x/w and y/h ...

but well I dont know what the developers think or why they cant use normal values which dont need to be devided trough the screen sizal hmm probably

a resolution thing. For a line its pretty easy, but then it goes further, since a square needs to be drawn with "D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP"

and at the moment Im trying to create more functions based on what I see here hm.

Still not knowing how I would set the width of a Line in dx11 .. I realy wonder why dx gets more and more complicated in the fundamentals by increasing version numbers,

means from 9 to 11/12 O.o cant they just keep it clean and straight forward .. like

1) load view

2)set vertexes without normalize etc because it gets scaled by view automaticly

3)draw

... thats how I would develop a drawing engine xD

edit: well it works, so i try to make circles, triangles etc now, all i need :P

edit2:

OW8qDbL.png

works all, but how In hell I set the thickness for "D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP" ?? O.o

This topic is closed to new replies.

Advertisement