gl.LoadMatrixf and gl.LookAt

Apr 5, 2014 at 3:58 AM
Hi
When i am trying to use gl.LoadMatrixf to set camera position i can get black screen only. It is only possible to have a view if i use gl.LookAt. how i can use LoadMatrixf ? i want to move the camera as a first person
Coordinator
Apr 6, 2014 at 12:10 AM
Hi I'm not sure what you're trying to do - you can use glLookAt (or gl.Perspective and so on) to build a projection matrix, or you can use glLoadMatrix to specify your own matrix - either works fine. For example, in the cel shading example I use transformations from another library (glmnet) and pass them in (I use glLoadIdentity and glMultMatrix but it's essentially the same as glLoadMatrix). If you let me know what's not working I might be able to help.
Apr 6, 2014 at 2:10 AM
I am trying to design an environment like Games those that the user can move eye position using keyboard and rotate the camera around using mouse. In order to do that i designed (u-n-v ) axis to be moved with camera and i have a matrix contains new (u-n-v) in every second as well as the eye position. The problem is that i can run the same calculation using c++ and openCv but here in c# it seems not possible.
    private void openGLControl_OpenGLDraw(object sender, OpenGLEventArgs args)
    {
        DrawScene();
        CreatObjects();

    }

    private void DrawScene()
    {
        gl = openGLControl.OpenGL;
        gl.MatrixMode(OpenGL.GL_PROJECTION);  // Setup the projection from 3D to 2D
        gl.LoadIdentity();
        gl.Viewport(0, 0, (int)this.Width, (int)this.Height);
        gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);
        SetupCamera();
        gl.MatrixMode(OpenGL.GL_MODELVIEW);
    }

   void SetupCamera()
    {
        gl = openGLControl.OpenGL;
        float[] matrix = new float[16];  // This is a 4x4 transformation matrix stored in
        // column major order.

        /* Create the camera transform */
        matrix[0] = MyCamera.u.x; matrix[4] = MyCamera.u.y; matrix[8] = MyCamera.u.z;
        matrix[1] = MyCamera.v.x; matrix[5] = MyCamera.v.y; matrix[9] = MyCamera.v.z;
        matrix[2] = MyCamera.n.x; matrix[6] = MyCamera.n.y; matrix[10] = MyCamera.n.z;
        matrix[3] = 0.0f;         matrix[7] = 0.0f;         matrix[11] = 0.0f;

        matrix[12] = -MyCamera.eyePosition.DotProduct(MyCamera.u);
        matrix[13] = -MyCamera.eyePosition.DotProduct(MyCamera.v);
        matrix[14] = -MyCamera.eyePosition.DotProduct(MyCamera.n);
        matrix[15] = 1.0f;

        /* postmultiply the camera matrix times the current transform */
        gl.LoadMatrixf(matrix);
    } 

   private void CreatObjects()
    {
        gl = openGLControl.OpenGL;
        gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);  //  Clear the color and depth buffer.
        gl.LoadIdentity();   //  Load the identity matrix.

        CreateRec(gl, 200, 60, 90, new Point3D(0, -9, -50), Mytexturepath, Mytexturepath);

        gl.Viewport(0, 0, (int)this.Width, (int)this.Height);
        gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);

        gl.End();
        gl.Flush();

    }





Coordinator
Apr 6, 2014 at 10:24 PM
I suggest start with the trivial case - do not use the setup camera call at all and verify you can see the model at the centre of the screen. Then bring in the camera transformation, but starting with the translation first which is trivial.

I can however see a bug already - you call:

glMatrixMode(GL_PROJECTION)l
glLoadIdenity();

So your projection matrix is the identity - so far so good:

glViewport()
glPerspective()

Starting to look odd here - you only need to call glViewport when the width/height changes, not every frame. You also don't need to call it with the projection matrix active, so this is essentially adding noise to your code. Call glViewport only when the viewport size changes and once on initialisation. Now you call glPerspective - again, no problems here.

SetupCamera

OK, now you create a 4x4 matrix and load it. So you've completely trashed what was there before - the first glLoadIdentity and the glPerspective calls have absolutely no purpose if you do this.

You then start drawing, but then after drawing again call viewport (not needed) and glPerspective - which again has no effect - you're multiplying the modelview matrix by this point (almost certainly not what you want to do) but not drawing anything after.

My suggestions:
  1. Handle the Resize event of the OpenGL control - in that event handler set the projection matrix, load the identity, create a perspective transformation then use glMultMatrix to modify the perspective transformation, not overwriting it, then go back to the modelview.
  2. Do all drawing in the draw function, but nothing else - don't switch to the projection matrix.
So keep the projection matrix manipulation separate - do it when needed. Also, try using glmnet for matrix mathematics if you need it - it has functionality similar to glm.