XNA equivalent of glVertex2f()?

Started by
7 comments, last by MatsK 12 years, 2 months ago
I'm trying to port some OpenGL code to XNA - could someone please explain the XNA equivalent of glVertex2f()?
Also, what's the equivalent of glColor3f()?


void DrawBonesSkeleton(Bone_t& Bone){
glTranslatef(Bone.Translation.x, Bone.Translation.y, Bone.Translation.z);
float RotationMatrix[16];
FindQuaternionMatrix(RotationMatrix, &Bone.Rotation);
glMultMatrixf(RotationMatrix);

if(!strcmp(Bone.Name, "ROOT"))
glColor3f(1.0, 0.0, 0.0);
else if(!strcmp(Bone.Name, "HEAD"))
glColor3f(1.0, 1.0, 0.0);
else
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POINTS); glVertex2f(0, 0); glEnd();

for(unsigned i=0; i<Bone.ChildrenCount; i++){
glPushMatrix();
DrawBonesSkeleton(*Bone.Children);
glPopMatrix();
}
}
Advertisement
Those equivalent calls don't exist in xna (im 99% sure). For your case look into VertexPositionColor and DrawUserPrimitives. So its kinda like setting up vertex buffer in OpenGL except you don't use a vertex buffer unless you need/want one.
There is no equivalent. What XNA (and D3D) uses is roughly equivalent to OpenGL's vertex arrays and VBOs. You may find it easier to port the OpenGL code to use these before doing the port to XNA as you'll have a closer mapping between the concepts.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Yeah there's really not much of an equivalent to OGL immediate mode. As the previous poster said, DrawUserPrimitives is your closest bet, but at the minimum you need to specify your geometry in an array (probably do not want to keep recreating this as you're drawing your bones on the fly, instead create one and resize it when needed).

This is where something like "VertexPositionColor" comes in handy as that's a structure (and XNA has several such) that describes all the attributes (position, color, etc) at a single vertex. But basically behind the scenes, DrawUserPrimitives is still just a vertex buffer, one that is dynamic and circular (so the resource is enabled to be written to once a frame, nor is it re-created every frame if it runs out of space).
Right, so I used DrawUserPrimitives() to draw a Vertex at the location for each bone.
But it doesn't seem to work! All the vertices seem to be drawn in the same place.
I thought setting the World Matrix to a bone's global translation would control where the vertex would be rendered. But this seems to be wrong. Should I be setting the transformation matrix instead?
Ok, so here's my ported code:

public void DrawBones(GraphicsDevice Devc, BasicEffect Effect, Bone Bne)
{
Matrix Mat = new Matrix();

//The translation controls where stuff is rendered in 3D space.
Mat.Translation = Bne.GlobalTranslation;

Matrix RotationMatrix = new Matrix();
FindQuaternionMatrix(ref RotationMatrix, Bne.GlobalRotation);

//glMultMatrixf()
Mat = Mat * RotationMatrix;

VertexPositionColor Vertex;

if (Bne.BoneName.Equals("ROOT"))
{
Vertex = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1.0f), new Color(1.0f, 0.0f,
0.0f));
}
else if (Bne.BoneName.Equals("HEAD"))
{
Vertex = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1.0f), new Color(1.0f, 1.0f,
0.0f));
}
else
{
Vertex = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1.0f), new Color(0.0f, 1.0f,
0.0f));
}

Effect.World = Mat;

Devc.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.PointList, new VertexPositionColor[] { Vertex }, 0,
1);

for (int i = 0; i < Bne.Children.Count; i++)
DrawBones(Devc, Effect, Bne.Children);
}


As you might be able to tell, I thought the bone's translation matrix would control where stuff was rendered to, but that doesn't seem to be a correct assumption, because all the vertices seem to be drawn in the same place!
What am I doing wrong?
FindQuaternionMatrix:

private void FindQuaternionMatrix(ref Matrix Mat, Quaternion Quat)
{
float x2 = Quat.X * Quat.X;
float y2 = Quat.Y * Quat.Y;
float z2 = Quat.Z * Quat.Z;
float xy = Quat.X * Quat.Y;
float xz = Quat.X * Quat.Z;
float yz = Quat.Y * Quat.Z;
float wx = Quat.W * Quat.X;
float wy = Quat.W * Quat.Y;
float wz = Quat.W * Quat.Z;
Mat.M11 = 1.0f - 2.0f * (y2 + z2);
Mat.M12 = 2.0f * (xy - wz);
Mat.M13 = 2.0f * (xz + wy);
Mat.M14 = 0.0f;
Mat.M21 = 2.0f * (xy + wz);
Mat.M22 = 1.0f - 2.0f * (x2 + z2);
Mat.M23 = 2.0f * (yz - wx);
Mat.M24 = 0.0f;
Mat.M31 = 2.0f * (xz - wy);
Mat.M32 = 2.0f * (yz + wx);
Mat.M33 = 1.0f - 2.0f * (x2 + y2);
Mat.M34 = 0.0f;
Mat.M41 = 0.0f;
Mat.M42 = 0.0f;
Mat.M43 = 0.0f;
Mat.M44 = 1.0f;
}
You have the matrix multiplication the wrong way, it should be Scale * Rotation * Translation. Also, XNA does have built in mechanisms to convert quaternions to matrices and vice versa - Quaternion.CreateFromRotationMatrix and Matrix.CreateFromQuaternion.

And also a point worth mentioning, it's generally a good idea to batch your geometry (a single draw call per vertex to me just sounds like a bad idea!), e.g. process all the bones and compile a list of points that you use in a single draw call at the end. Although that would require you to pre-transform the vertex positions on the CPU side, and have the effect's world matrix set to the Identity.
Hm, so I did:


public void DrawBones(GraphicsDevice Devc, BasicEffect Effect, Bone Bne)
{
Matrix Mat = new Matrix();
//The translation controls where stuff is rendered in 3D space.
Mat.Translation = Bne.GlobalTranslation; Matrix RotationMatrix = Matrix.CreateFromQuaternion(Bne.GlobalRotation);
//glMultMatrixf()
Mat = Mat * RotationMatrix; VertexPositionColor Vertex;
if (Bne.BoneName.Equals("ROOT"))
{
Vertex = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1.0f), new Color(1.0f, 0.0f,
0.0f));
}
else if (Bne.BoneName.Equals("HEAD"))
{
Vertex = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1.0f), new Color(1.0f, 1.0f,
0.0f));
}
else
{
Vertex = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1.0f), new Color(0.0f, 1.0f,
0.0f));
} Effect.World = Mat;
Devc.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.PointList, new VertexPositionColor[] { Vertex }, 0,
1);
for (int i = 0; i < Bne.Children.Count; i++)
DrawBones(Devc, Effect, Bne.Children);
}


I still only get one bone drawn though (or all the bones are drawn in the same place)! :(
Why?

This topic is closed to new replies.

Advertisement