flopoloco's picture

Assimp

Hello, I am messing with Assimp.NET
https://code.google.com/p/assimp-net/wiki/GettingStarted

I want to create a simplified version of the example for studying purposes in immediate mode (next step is to go vertex array objects, but now I want to understand things better).
https://code.google.com/p/assimp-net/source/browse/trunk/AssimpNet.Sampl...

This loop works.

//			GL.Begin(BeginMode.Polygon);
//			for (int v = 0; v < mesh.Vertices.Length; v++) {
//				var norm = mesh.Normals[v];
//				var vert = mesh.Vertices[v];
//				var tex = mesh.GetTextureCoords(0)[v];
//				GL.TexCoord2(tex.X, tex.Y);
//				GL.Normal3(norm.X, norm.Y, norm.Z);
//				GL.Vertex3(vert.X, vert.Y, vert.Z);
//			}
//			GL.End();

How can do the same with triangles instead?

			GL.Begin(BeginMode.Triangles);
			for (int i = 0; i < mesh.Faces.Length; i++) {
				var face = mesh.Faces[i];
				for (int j = 0; j < 3; j++) {
					var index = face.Indices[j];
					var vert = mesh.Vertices[index];
					//?????????????????????????
					//Wrong Wrong Wrong Wrong
//				var tex = mesh.GetTextureCoords(0)[v];
//				GL.TexCoord2(tex.X, tex.Y);
//				GL.Normal3(norm.X, norm.Y, norm.Z);
					GL.Vertex3(vert.X, vert.Y, vert.Z);
				}
			}
			GL.End();

I don't know what exactly am I missing, I've reading tutorials and trying things but can't figure it out.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
winterhell's picture

Your code seems to be correct.
What problem are you getting? Are there triangles that intertwine that are not present in the original model?
To debug this you can
a) switch to BeginMode.Points to see if the vertices are in the correct place(or if they are even called from the face array)
b) try with a triangle, then with a quad and finally with cube and more detailed model
When you have a model with only 4 vertices you can easily check the arrays if they are correct.Just hit a breakpoint and check the contents of the Mesh.Faces and Mesh.Vertices, or alternatively trace through the iterations of the loop.

Are your face indices starting from 0? In 3ds max the first vertex has an index 1.

flopoloco's picture

Hello winterhell, thanks for the response... I looked at your suggestions and they helped, the model is drawn nice with points, then that you said with the indices was that some faces had 3 indices other had 4, I had to make a distinction between these two to fix the problem.

using System;
using System.Drawing;
using Debug = System.Diagnostics.Debug;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using Assimp;
 
namespace AssimpTest
{
	class MainClass
	{
		public static void Main(string[] args)
		{
 
			#region Assimp
			var import = new AssimpImporter();
			var filename = "../../../bin/Data/duck.dae";
			var model = import.ImportFile(filename);
			//Debug.WriteLine(model.Meshes);
			var mesh = model.Meshes[0];
			#endregion
 
			#region Drawing
			Func<Assimp.Vector3D, OpenTK.Vector3> toVec3 = (v) => {
				return new Vector3(v.X, v.Y, v.Z);
			};		
			#endregion
 
			#region OpenTK
			var window = new GameWindow(800, 600);
			window.Load += (object sender, EventArgs e) => {
				GL.Enable(EnableCap.DepthTest);
				GL.Enable(EnableCap.Normalize);
				GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
//				GL.FrontFace(FrontFaceDirection.Cw);
			};
 
 
			window.Resize += (object sender, EventArgs e) => {
				GL.Viewport(0, 0, window.Width, window.Height);
				float ratio = window.Width / (float)window.Height;
				Matrix4 persp = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, ratio, 1, 5000);
				GL.MatrixMode(MatrixMode.Projection);
				GL.LoadMatrix(ref persp);
			};
			window.RenderFrame += (object sender, FrameEventArgs e) => {
				GL.ClearColor(Color.CornflowerBlue);
				GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
				GL.MatrixMode(MatrixMode.Modelview);
				Matrix4 lookat = Matrix4.LookAt(0, 0, 500, 0, 0, 0, 0, 1, 0);
				GL.LoadMatrix(ref lookat);
 
				// Points (works fine)
//				GL.Begin(BeginMode.Points);
//				foreach (var i in mesh.Vertices)
//					GL.Vertex3(toVec3(i));
//				GL.End();
 
				// Does not work
//				GL.Begin(BeginMode.Triangles);
//				var indexCount = new int[] { 0, 1, 2, 2, 3, 0 };
//				for (int i = 0; i < mesh.GetIntIndices().Length; i += 4) {
//					foreach (var j in indexCount) {
//						GL.Vertex3(toVec3(mesh.Vertices[i + j]));
//					}
//				}
//				GL.End();
 
				// Does not work
//				GL.Begin(BeginMode.Triangles);
//				foreach (var i in mesh.Faces) {
//					foreach (var j in i.Indices) {
//						GL.Vertex3(toVec3(mesh.Vertices[j]));
//					}
//				}
//				GL.End();
 
				// This works great but need to figure out a better way
//				GL.Begin(BeginMode.Triangles);
//				foreach (var i in mesh.Faces) {
//					if (i.IndexCount == 3) {
//						var f1 = mesh.Vertices[i.Indices[0]];
//						var f2 = mesh.Vertices[i.Indices[1]];
//						var f3 = mesh.Vertices[i.Indices[2]];
//						GL.Vertex3(toVec3(f1));
//						GL.Vertex3(toVec3(f2));
//						GL.Vertex3(toVec3(f3));
//					}
//					
//					if (i.IndexCount == 4) {
//						var f1 = mesh.Vertices[i.Indices[0]];
//						var f2 = mesh.Vertices[i.Indices[1]];
//						var f3 = mesh.Vertices[i.Indices[2]];
//						var f4 = mesh.Vertices[i.Indices[3]];
//						GL.Vertex3(toVec3(f1));
//						GL.Vertex3(toVec3(f2));
//						GL.Vertex3(toVec3(f3));
//						GL.Vertex3(toVec3(f3));
//						GL.Vertex3(toVec3(f4));
//						GL.Vertex3(toVec3(f1));
//					}
//				}
//				GL.End();
 
 
 
 
 
				window.SwapBuffers();
			};
 
			window.Run();
			#endregion
		}
	}
}

But what bothers me now is that my version is very boring and sucks :), I can't reverse engineer the drawing code on the example which is very straight and simple, I can't figure out what is going wrong. Any help much appreciated.

winterhell's picture

Since the file format can store 3 and 4-sided polygons, its very likely it also does arbitrary number. In 3D modelling its easy to stumble across such. For example the cylinder cap can be one.
If that is the case, you'll want to take it into consideration. For immediate mode it might be fine(or not, depending on how big the model is) if you generalize your code to just do GL.Begin(BeginMode.Polygon)/GL.End() for each face.

You'd be better off if your models are triangulated. There might be an option to do that in the file exporter or modelling program, or you can investigate triangulation of n-sided polygons. Best case scenario they are convex and then you can do a simple loop which spawns polygons with the points (0,1,2), (0,2,3),(0,3,4)...(0,n-1,n);

When you switch to VBOs for performance reasons you'll want as lower number of arrays as you can, and with the triangulated mesh you can do that.

flopoloco's picture

I was out a few days due to illness and now back in action.
In any case someone bumps this thread later I will mention what I did to make it work.

No more no less I imported the mesh (Collada .dae) in Blender and I exported again making sure that faces were triangulated. Then with a vertex buffer object and an element buffer object problems solved.

I had to do it from the first minute... :)