Can anyone share how to render 3d primitives or 3d line in an efficient way.
eg. render a massive amount of boudingbox or simple shape
This is how I render all my stars in 3D.
public override void Draw(GraphicsDevice dev)
{
if (WorldState.GetWorldState().SunDirection.Y > 0.02)
{
world = Matrix.CreateScale(1, -1, 1);
Matrix trans = Matrix.CreateRotationY(-MathHelper.ToRadians((float)WorldState.GetWorldState().LST)) * Matrix.CreateFromYawPitchRoll((float)WorldState.GetWorldState().CameraLongitude, (float)WorldState.GetWorldState().CameraLatitude, 0);
effect.World = world;
effect.View = Matrix.Identity;
effect.Projection = WorldState.GetWorldState().Projection;
Matrix mw = WorldState.GetWorldState().View * world;
Vector2 Origin = new Vector2(texture.Width / 2, texture.Height / 2);
batch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, null, DepthStencilState.None, RasterizerState.CullNone, effect);
for (int i = 0; i < Verts.Count; i++)
{
Vector3 worldspace = Vector3.Transform(Verts[i], trans);
Vector3 viewSpaceTextPosition = Vector3.Transform(worldspace, mw);
batch.Draw(texture, new Vector2(viewSpaceTextPosition.X, viewSpaceTextPosition.Y), null, Colours[i], 0.0f, Origin, 1.0f, SpriteEffects.None, viewSpaceTextPosition.Z);
}
batch.End();
}
}
It’s very efficient
You can get a SpriteBatch extension that draws primitives with a quick google search
.
.
Can anyone share how to render 3d primitives or 3d line
.
.
public class Grid3dOrientation
{
public Grid3d gridForward;
public Grid3d gridRight;
public Grid3d gridUp;
public bool autoNoCull = true;
/// <summary>
/// Uses a better version, width height applys to each side of the center.
/// Draws 3 3d grids, linewith should be very small like .001.
/// </summary>
public Grid3dOrientation(int rows, int columns, float width, float height, float lineWidth)
{
gridForward = new Grid3d(rows, columns, width, height, lineWidth, true, 0);
gridRight = new Grid3d(rows, columns, width, height, lineWidth, true, 1);
gridUp = new Grid3d(rows, columns, width, height, lineWidth, true, 2);
}
/// <summary>
/// Draws 3 3d grids, linewith should be very small like .001
/// </summary>
public Grid3dOrientation(int x, int y, float lineWidth)
{
gridForward = new Grid3d(x, y, lineWidth, true, 0);
gridRight = new Grid3d(x, y, lineWidth, true, 1);
gridUp = new Grid3d(x, y, lineWidth, true, 2);
}
/// <summary>
/// Draws 3 3d grids, linewith should be very small like .001
/// </summary>
public Grid3dOrientation(int x, int y, float scale, float lineWidth)
{
gridForward = new Grid3d(x, y, scale, lineWidth, true, 0);
gridRight = new Grid3d(x, y, scale, lineWidth, true, 1);
gridUp = new Grid3d(x, y, scale, lineWidth, true, 2);
}
/// <summary>
/// Draws this world grid with basic effect.
/// </summary>
public void DrawWithBasicEffect(GraphicsDevice gd, BasicEffect effect, Matrix world, float scale, Texture2D forwardTexture, Texture2D upTexture, Texture2D rightTexture)
{
// Draw a 3d full orientation grid
if (autoNoCull)
gd.RasterizerState = RasterizerState.CullNone;
effect.World = Matrix.CreateScale(scale) * world;
bool isLighting = effect.LightingEnabled;
effect.LightingEnabled = false;
effect.Texture = upTexture;
gridForward.Draw(gd, effect);
effect.Texture = forwardTexture;
gridRight.Draw(gd, effect);
effect.Texture = rightTexture;
gridUp.Draw(gd, effect);
if (isLighting)
effect.LightingEnabled = true;
}
/// <summary>
/// The method expects that the shader can accept a parameter named TextureA.
/// </summary>
public void Draw(GraphicsDevice gd, Effect effect, Matrix world, float scale, Texture2D forwardTexture, Texture2D upTexture, Texture2D rightTexture)
{
// Draw a 3d full orientation grid
if (autoNoCull)
gd.RasterizerState = RasterizerState.CullNone;
effect.Parameters["World"].SetValue(Matrix.CreateScale(scale) * world);
effect.Parameters["TextureA"].SetValue(upTexture);
gridForward.Draw(gd, effect);
effect.Parameters["TextureA"].SetValue(forwardTexture);
gridRight.Draw(gd, effect);
effect.Parameters["TextureA"].SetValue(rightTexture);
gridUp.Draw(gd, effect);
}
public void Draw(GraphicsDevice gd, Effect effect)
{
if (autoNoCull)
gd.RasterizerState = RasterizerState.CullNone;
gridForward.Draw(gd, effect);
gridRight.Draw(gd, effect);
gridUp.Draw(gd, effect);
}
public void Draw(GraphicsDevice gd, Effect effect, float scale)
{
if (autoNoCull)
gd.RasterizerState = RasterizerState.CullNone;
effect.Parameters["World"].SetValue(Matrix.CreateScale(scale) * Matrix.Identity);
gridForward.Draw(gd, effect);
gridRight.Draw(gd, effect);
gridUp.Draw(gd, effect);
}
public void Draw(GraphicsDevice gd, Effect effect, int part0to2)
{
if (autoNoCull)
gd.RasterizerState = RasterizerState.CullNone;
if (part0to2 == 0)
{
gridForward.Draw(gd, effect);
}
else
{
if (part0to2 == 1)
gridRight.Draw(gd, effect);
else
gridUp.Draw(gd, effect);
}
}
}
public class Grid3d
{
int xrows;
int ycol;
public VertexPositionTexture[] vertices;
public int[] indices;
/// <summary>
/// Use this one its newer and makes more sense.
/// </summary>
public Grid3d(int rows, int columns, float width, float height, float lineSize, bool centered, int flipOption)
{
CreateGrid3d(rows, columns, width, height, lineSize, centered, flipOption);
}
public Grid3d(int rows, int columns, float lineSize, bool centered, int flipOption)
{
CreateGrid3d(rows, columns, 1f, lineSize, centered, flipOption);
}
public Grid3d(int rows, int columns, float scale, float lineSize, bool centered, int flipOption)
{
CreateGrid3d(rows, columns, scale, lineSize, centered, flipOption);
}
/// <summary>
/// Creates a grid for 3d modelspace.
/// The Width Height is doubled into negative and positive.
/// linesize should be a very small value less then 1;
/// flip options range from 0 to 2
/// </summary>
public void CreateGrid3d(int rows, int columns, float scale, float lineSize, bool centered, int flipOption)
{
rows *= 2;
columns *= 2;
Vector3 centerOffset = Vector3.Zero;
if (centered)
centerOffset = new Vector3(-.5f, -.5f, 0f);
xrows = rows;
ycol = columns;
int len = xrows * 4 + ycol * 4;
float xratio = 1f / xrows;
float yratio = 1f / ycol;
vertices = new VertexPositionTexture[len];
indices = new int[(xrows * 6 + ycol * 6) * 2];
int vIndex = 0;
int iIndex = 0;
for (int x = 0; x < xrows; x++)
{
int svIndex = vIndex;
Vector3 xpos = new Vector3(xratio * x, 0f, 0f);
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, 0f, 0f) + xpos + centerOffset) * scale, new Vector2(0f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, 1f, 0f) + xpos + centerOffset) * scale, new Vector2(0f, 1f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(lineSize, 0f, 0f) + xpos + centerOffset) * scale, new Vector2(1f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(lineSize, 1f, 0f) + xpos + centerOffset) * scale, new Vector2(1f, 1f)); vIndex++;
indices[iIndex + 0] = svIndex + 0; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 2;// triangle 1
indices[iIndex + 3] = svIndex + 2; indices[iIndex + 4] = svIndex + 1; indices[iIndex + 5] = svIndex + 3;// triangle 2
indices[iIndex + 0] = svIndex + 2; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 0;// triangle 3 backface
indices[iIndex + 3] = svIndex + 3; indices[iIndex + 4] = svIndex + 2; indices[iIndex + 5] = svIndex + 1;// triangle 4 backface
iIndex += 6 * 2;
}
for (int y = 0; y < ycol; y++)
{
int svIndex = vIndex;
Vector3 ypos = new Vector3(0f, yratio * y, 0f);
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, 0f, 0f) + ypos + centerOffset) * scale, new Vector2(0f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, lineSize, 0f) + ypos + centerOffset) * scale, new Vector2(0f, 1f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(1f, 0f, 0f) + ypos + centerOffset) * scale, new Vector2(1f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(1f, lineSize, 0f) + ypos + centerOffset) * scale, new Vector2(1f, 1f)); vIndex++;
indices[iIndex + 0] = svIndex + 0; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 2;// triangle 1
indices[iIndex + 3] = svIndex + 2; indices[iIndex + 4] = svIndex + 1; indices[iIndex + 5] = svIndex + 3;// triangle 2
indices[iIndex + 0] = svIndex + 2; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 0;// triangle 3 backface
indices[iIndex + 3] = svIndex + 3; indices[iIndex + 4] = svIndex + 2; indices[iIndex + 5] = svIndex + 1;// triangle 4 backface
iIndex += 6 * 2;
}
Flip(flipOption);
}
/// <summary>
/// Slightly improved version simpler to use makes mores sense.
/// </summary>
public void CreateGrid3d(int rows, int columns, float mwidth, float mheight, float lineSize, bool centered, int flipOption)
{
rows *= 2;
columns *= 2;
mwidth *= 2;
mheight *= 2;
Vector3 centerOffset = Vector3.Zero;
if (centered)
centerOffset = new Vector3(-mwidth * .5f, -mheight * .5f, 0f);
xrows = rows;
ycol = columns;
int len = xrows * 4 + ycol * 4;
float xratio = 1f / xrows;
float yratio = 1f / ycol;
float xLineRate = mwidth / xrows;
float yLineRate = mheight / ycol;
vertices = new VertexPositionTexture[len];
indices = new int[(xrows * 6 + ycol * 6) * 2];
int vIndex = 0;
int iIndex = 0;
for (int x = 0; x < xrows; x++)
{
int svIndex = vIndex;
Vector3 xpos = new Vector3(xLineRate * x, 0f, 0f);
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, 0f, 0f) + xpos + centerOffset), new Vector2(0f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, mheight, 0f) + xpos + centerOffset), new Vector2(0f, 1f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(lineSize, 0f, 0f) + xpos + centerOffset), new Vector2(1f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(lineSize, mheight, 0f) + xpos + centerOffset), new Vector2(1f, 1f)); vIndex++;
indices[iIndex + 0] = svIndex + 0; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 2;// triangle 1
indices[iIndex + 3] = svIndex + 2; indices[iIndex + 4] = svIndex + 1; indices[iIndex + 5] = svIndex + 3;// triangle 2
indices[iIndex + 0] = svIndex + 2; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 0;// triangle 3 backface
indices[iIndex + 3] = svIndex + 3; indices[iIndex + 4] = svIndex + 2; indices[iIndex + 5] = svIndex + 1;// triangle 4 backface
iIndex += 6 * 2;
}
for (int y = 0; y < ycol; y++)
{
int svIndex = vIndex;
Vector3 ypos = new Vector3(0f, yLineRate * y, 0f);
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, 0f, 0f) + ypos + centerOffset), new Vector2(0f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(0f, lineSize, 0f) + ypos + centerOffset), new Vector2(0f, 1f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(mwidth, 0f, 0f) + ypos + centerOffset), new Vector2(1f, 0f)); vIndex++;
vertices[vIndex] = new VertexPositionTexture((new Vector3(mwidth, lineSize, 0f) + ypos + centerOffset), new Vector2(1f, 1f)); vIndex++;
indices[iIndex + 0] = svIndex + 0; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 2;// triangle 1
indices[iIndex + 3] = svIndex + 2; indices[iIndex + 4] = svIndex + 1; indices[iIndex + 5] = svIndex + 3;// triangle 2
indices[iIndex + 0] = svIndex + 2; indices[iIndex + 1] = svIndex + 1; indices[iIndex + 2] = svIndex + 0;// triangle 3 backface
indices[iIndex + 3] = svIndex + 3; indices[iIndex + 4] = svIndex + 2; indices[iIndex + 5] = svIndex + 1;// triangle 4 backface
iIndex += 6 * 2;
}
Flip(flipOption);
}
void Flip(int flipOption)
{
if (flipOption == 1)
{
int index = 0;
for (int x = 0; x < xrows; x++)
{
for (int i = 0; i < 4; i++)
{
var p = vertices[index].Position;
vertices[index].Position = new Vector3(0f, p.X, p.Y);
index++;
}
}
for (int y = 0; y < ycol; y++)
{
for (int i = 0; i < 4; i++)
{
var p = vertices[index].Position;
vertices[index].Position = new Vector3(0f, p.X, p.Y);
index++;
}
}
}
if (flipOption == 2)
{
int index = 0;
for (int x = 0; x < xrows; x++)
{
for (int i = 0; i < 4; i++)
{
var p = vertices[index].Position;
vertices[index].Position = new Vector3(p.Y, 0f, p.X);
index++;
}
}
for (int y = 0; y < ycol; y++)
{
for (int i = 0; i < 4; i++)
{
var p = vertices[index].Position;
vertices[index].Position = new Vector3(p.Y, 0f, p.X);
index++;
}
}
}
}
public void Draw(GraphicsDevice gd, Effect effect)
{
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
gd.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, (indices.Length / 3), VertexPositionTexture.VertexDeclaration);
}
}
}
You would use a basic effect for this it draws a bunch of lines as grids.
.
.
render a massive amount
.
.
Instancing for massive amounts of the same type of thing.
Other wise if it has to be cpu side make a pooled buffer.
At the bottom is some example instancing code.