Rogad's picture

Loading OBJ files and displaying meshes in Viewport help

Hi everyone :)

Just discovered OpenTK today after going around a lot of places. I got the tutorial starter program working fine with the triangle.

I'm just thinking now about more complex things.

Short story - I am building an animated talking head using OBJ files and morph targets. I have got this all working in C# with WPF. All well and good, but the performance whilst okay, could do with a speed injection so I can add more features to my talking head.

Anyway, so now I am looking at OpenTK, which I understand will use the graphics card. I'm still learning 3D but understand some of the basics.

I understand what makes up a mesh and I have been using Helix 3D Toolkit with WPF. But like I said my code is not that fast.

So it's back to Windows Forms as the OpenTK toolkit doesn't really seem to need the WPF 3D functions despite me liking them make my life easy. ;)

But I need a new OpenTK method of importing an OBJ file. I found an OBJ mesh loader here : http://www.opentk.com/files/ObjMeshLoader.cs

Given all this, once I have loaded the OBJ into a mesh, how do I go about displaying it in the Viewport ?

Could someone possibly give me some sample code ? If so that would be great !

Thanks for reading :)


Comments

Comment viewing options

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

I found this page, which is where the OBJ importer code comes from originally : http://www.opentk.com/node/642

I grabbed the two cs files and they are now in my project. I had to update some of it as the 'math' had been moved to OpenTK namespace. But the code essentially remains the same. The project builds without errors except I just get a black window.:

Here's my Program.cs :

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using GL = OpenTK.Graphics.OpenGL.GL;
 
 
namespace Example
{
    class MyApplication
    {
        [STAThread]
        public static void Main()
        {
            ObjMesh foo = new ObjMesh("C:/Users/Roger/Desktop/tyler/neutral.obj");
 
            using (var game = new GameWindow())
            {
                game.Load += (sender, e) =>
                {
                    // setup settings, load textures, sounds
                    game.VSync = VSyncMode.On;
                };
 
                game.Resize += (sender, e) =>
                {
                    GL.Viewport(0, 0, game.Width, game.Height);
                };
 
                game.UpdateFrame += (sender, e) =>
                {
                    // add game logic, input handling
                    if (game.Keyboard[Key.Escape])
                    {
                        game.Exit();
                    }
                };
 
                game.RenderFrame += (sender, e) =>
                {
                    // render graphics
                    GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit | OpenTK.Graphics.OpenGL.ClearBufferMask.DepthBufferBit);
 
                    GL.MatrixMode(OpenTK.Graphics.OpenGL.MatrixMode.Projection);
                    GL.LoadIdentity();
                    GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0);
 
                    GL.Begin(PrimitiveType.Quads);
                    foo.Render();
                    GL.End();
 
                    game.SwapBuffers();
                };
 
                // Run the game at 60 updates per second
                game.Run(60.0);
            }
        }
    }
}

The model is on the desktop, it's made with quads. It's a human figure model. But yeah, I am probably making a noob mistake or the OBJ importer is not working.

I thought maybe someone could have a glance at my code above. Am I right in thinking that the game.RenderFrame is called continuously ? I guessed that is a loop so put the render call in there.

I imagine I need to be setting up a camera or something somehow ? I have no idea what the Ortho line does yet maybe that is where I am going wrong :/

Cheers :)

the Fiddler's picture

This is correct, UpdateFrame and RenderFrame are called in a loop until you call Exit().

If you want to use WinForms or WPF, then you should add a reference to OpenTK.GLControl and drag-drop a GLControl on your Form/WindowsFormsHost. The GameWindow is meant to be used standalone.

GL.Ortho is an OpenGL 1.x call that sets up an orthographic projection. If the model is not visible it might be that it falls outside of your camera frustum (e.g. behind the camera of outside the left/right/top/bottom/far planes.) Try something like:

GL.Ortho(-1, 1, -1, 1, -1024, 1024);

Chapter 3 of the Red Book covers this topic in more detail. The OpenGL wiki is another useful resource mostly focused on modern, shader-based OpenGL.

Rogad's picture

Hi,

Thanks for the reply and the explanations. Currently I am just playing with the standalone window, trying to get this importer to work. I found the tutorial for the GLControl. I'll take a look at those links too.

I tried

GL.Ortho(-1, 1, -1, 1, -1024, 1024);

But I still get a black screen.

With the window are the camera controls linked to the mouse or is that something you have to build ?

I thought maybe I could go hunting for the model if it's even there.

Cheers.

the Fiddler's picture

Not out of the box. OpenTK allows you to program the GPU using low-level OpenGL commands - it's not a high level toolkit like WPF.

That said, building a camera is not very difficult. Google for "OpenTK camera".

I would suggest testing the camera on a simple example like VBOStatic.cs before you test the obj reader, just in case there is a bug in the reader.

Rogad's picture

I just thought, should I be adding a light to the game window or is there a light already set up ?

the Fiddler's picture

Lighting is disabled by default. When lighting is disabled, vertices are colored using GL.Color4() (IIRC, default is white).

Rogad's picture

OK then I should be seeing something if there's anything there. I think I will do some of the tutorials and come back to this. Thanks for your help.

febriano's picture
  private void SetupViewport()
        {
            float aspectRatio = (float)glControl1.Width / (float)glControl1.Height;
 
            GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
 
            Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView((float)(System.Math.PI / 4f), aspectRatio, 0.01f, 2000f);
            GL.MultMatrix(ref perspective);
 
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
        }

try this in your setup viewport .
amd move your cam position

Matrix4 LookAt = Matrix4.LookAt( new  Vector3(000,0,10), Vector3.Zero, Vector3.UnitY);
 
            GL.MatrixMode(MatrixMode.Modelview);

the new vecot3 x,y,z positions so you can change your view maybe the model is not in the came region