Jump to content
  • Advertisement
Sign in to follow this  
GAFO

DX11 Vertex Calculation Confusion

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

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 ? )

 

 

Share this post


Link to post
Share on other sites
Advertisement

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.

Share this post


Link to post
Share on other sites

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

 

Edited by GAFO

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!