Advertisement

Cylinder done in the geometry shader in Directx 11.

Started by December 30, 2015 04:53 PM
1 comment, last by terryeverlast 9 years, 2 months ago

I have a exercise in my book that says draw a circle with a LineStrip then make a cylinder with the geometry shader with no caps.

Here is what I want in the image.

rr7cbp.png

So far I have worked on making the like the image above but no luck

Here is what I got.

210n96o.png

Here is my code.

My geometry shader code is


[maxvertexcount(2)]
void GS(line VertexOut gin[2],
inout LineStream<GeoOut> stream)
{
float3 up = float3(0.0f, 1.0f, 0.0f);
float3 look = gEyePosW - gin[0].CenterW;
look.y = 0.0f; // y-axis aligned, so project to xz-plane
look = normalize(look);
float3 right = cross(up, look);
float halfWidth  = 0.5f*gin[0].SizeW.x;
float halfHeight = 0.5f*gin[0].SizeW.y;
float4 v[3];
v[0] = float4(gin[0].CenterW + halfHeight*up*10, 1.0f);
v[1] = float4(gin[0].CenterW - halfHeight*up*10, 1.0f);

GeoOut gout;
[unroll]
for(int i = 0; i < 2; ++i)
{
  gout.PosH	 = mul(v[i], gViewProj);
  gout.PosW	 = v[i].xyz;
  gout.NormalW  = look;
  gout.Tex      = gTexC[i];
  stream.Append(gout);
}
}

My vertex code is


void TreeBillboardApp::BuildCylinder()
{
	Vertex::Cyl v[vertexcount];

UINT count = 20;
for(UINT i = 0; i < count; ++i)
{
  v[i].Pos    = XMFLOAT3(5 * cosf(i),1.0f,  5 * sinf(i));
 
}
     
	D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof(Vertex::Cyl) * count;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = v;
    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &CylinderVB));
}

How can I make mine like the first image? Need some ideas.

The reference output looks like a triangle list, not a line list.

You can output a triangle stream from the GS even though your input geometry would be lines.

In this case, I would output two triangles per line segment so as to represent one quad face of the cylinder.

When you get this working, you're halfway done with a shadow volume extrusion method :)

Niko Suni

Advertisement

Ok,got the cylinder now.

2r2amw4.png


Vertex::TreePointSprite v[TreeCount];

const UINT numSlices = 32;

	const UINT numCircleVerts = 33;
	const UINT vertexCount = 2*numCircleVerts;

	float dTheta = 2.0f*XM_PI/numSlices;

	Vertex::Basic32 vertices[vertexCount];

	for(UINT i = 0; i < numCircleVerts; ++i)
	{
		float x = 5*cosf(i*dTheta);
		float z = 5*sinf(i*dTheta);

		v[i].Pos    = XMFLOAT3(x, 0.0f, z);
		
	
	}
     
	D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof(Vertex::TreePointSprite) * 34;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = v;
    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mTreeSpritesVB));

The geo shader code


[maxvertexcount(7)]
void GS(line VertexOut gin[2],
inout LineStream<GeoOut> stream)
{

float4 v[2];
float4 b[1];
v[0] = float4(gin[0].CenterW.xyz, 1.0f);

v[1] = float4(gin[1].CenterW.xyz, 1.0f);

const float StripWidth = 0.5f;
	float2 dir = normalize(v[1].xy - v[0].xy);
	float4 off = float4(-dir.y, dir.x, 0, 0);

GeoOut gout;

  gout.PosH	 = mul(v[0]-off*5, gViewProj);

  stream.Append(gout);

   gout.PosH	 = mul(v[0]+off*5, gViewProj);

  stream.Append(gout);

    gout.PosH	 = mul(v[1]-off*5, gViewProj);

  stream.Append(gout);

  stream.RestartStrip();
  

  gout.PosH	 = mul(v[0]-off*5, gViewProj);

  stream.Append(gout);

    gout.PosH	 = mul(v[1]-off*5, gViewProj);

  stream.Append(gout);

   stream.RestartStrip();
   gout.PosH	 = mul(v[0]+off*5, gViewProj);

  stream.Append(gout);

   gout.PosH	 = mul(v[1]+off*5, gViewProj);

  stream.Append(gout);
  

}

This topic is closed to new replies.

Advertisement