Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: GL Project doesn't work properly.

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    GL Project doesn't work properly.

    Hello there,
    with this problem I asked lots of people with no success so far.
    My hope is that the people at the official opengl forums are able to help me out. So here's my question/problem:

    I'm using code which tries to work like Glu.Project() since OpenTK doesn't support Glu.

    Code :
            Vector4 pos = new Vector4(s.Position.X, 0.0f, s.Position.Y, 1.0f);
            Matrix4 mov = new Matrix4();
            Matrix4 prj = new Matrix4();
            Matrix4 mpj = new Matrix4();
            float[] vp = new float[4];
     
            GL.GetFloat(GetPName.ModelviewMatrix, out mov);
            GL.GetFloat(GetPName.ProjectionMatrix, out prj);
            GL.GetFloat(GetPName.Viewport, vp);
     
            Matrix4.Mult(ref prj, ref mov, out mpj);
            Vector4.Transform(ref pos, ref mpj, out pos);
     
            // Final mathematics as described in OpenGL 2.1 Glu specs
            s.set2DPos(new Vector2f( (vp[0] + (vp[2] * (pos.X + 1) / 2.0f)),
                                    (vp[1] + (vp[3] * (pos.Y + 1) / 2.0f)) ));
     
            // Final mathematics as described in OpenGL 3 Vector specs
            s.set2DPos(new Vector2f( (view[2] / 2 * pos.X + view[0]),
                                    (view[3] / 2 * pos.X + view[1]) ));
     
            // Neither of them work, but in relation OpenGL 3 vector specs work better.

    s is a class which primary exists as a model in 3D space at s.Position.
    But the values I'm getting from this are astronomically far beyond the window boundaries.

    The ModelView matrix from a breakpoint:

    Code :
    {(1, 0, 0, 0)
    (0, 0.7071068, 0.7071068, 0)
    (0, -0.7071068, 0.7071068, 0)
    (0, -141.4214, -141.4214, 1)}

    The Projection matrix from a breakpoint:

    Code :
    {(1.931371, 0, 0, 0)
    (0, 2.414213, 0, 0)
    (0, 0, -1.0002, -1)
    (0, 0, -2.0002, 0)}
    Am I doing something wrong or did I get something wrong? Am I missing something?
    ( see previous suggestions at http://stackoverflow.com/questions/4...-work-properly )

  2. #2
    Member Regular Contributor
    Join Date
    Apr 2010
    Posts
    491

    Re: GL Project doesn't work properly.

    Your model view matrix looks as if it is printed transposed, have you checked that you consistently store your matrices in column major order (you could store them row major, but then need to transpose before passing on to OpenGL).

    Code :
    Vector4 pos = new Vector4(s.Position.X, 0.0f, s.Position.Y, 1.0f);

    why do you ignore s.Position.Z and put Y into the third coordinate?

  3. #3
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    Re: GL Project doesn't work properly.

    Since I'm only using the matrix4 class from OpenTK, which is designed for OpenGL, I suppose it to use the correct format for OpenGL.

    I'm working on project in which 3d objects only can be placed at a zero height.

  4. #4
    Member Regular Contributor
    Join Date
    Apr 2010
    Posts
    491

    Re: GL Project doesn't work properly.

    Ok. I just noticed that you are missing the perspective divide step though. After

    Code :
    Vector4.Transform(ref pos, ref mpj, out pos);

    you need to divide pos.XYZ by pos.W - the viewport transformation takes normalized device coordinates as input, after applying the modelview and projection matrices you only have clip coordinates.

  5. #5
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    Re: GL Project doesn't work properly.

    Thank you!
    I implemented your that division to the Glu formula like this:
    Code :
    s.set2DPos(new Vector2f( (view[0] + (view[2] * (pos.X/pos.W + 1) / 2.0f)),
                             (view[1] + (view[3] * (pos.Y/pos.W + 1) / 2.0f)) ));
    The resulting X coordinate is very close now (its just off a little too far but you can actually see it moving with the object when turning Y to something visible but Y ist still very far off target.

  6. #6
    Advanced Member Frequent Contributor
    Join Date
    Oct 2009
    Posts
    595

    Re: GL Project doesn't work properly.

    Cobra, what you are trying to do is trivial. Pick us some book on linear algebra, you won't regret it. You can download plenty on the Internet.

  7. #7
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    Re: GL Project doesn't work properly.

    Don't think I didn't do anything to solve this problem myself, don't think I'd rather use other people than soluting problems myself.

    I've read dozens of documents, forum topics, articles, and whatnot.
    I tried various methods that work for most people in several scenarios.

    All those methods are supposed to work, but in my case they don't, that's why I'm asking for the help of experts, hoping not to get bumped off as some lazy guy trying to have an easy time.
    This problem is seriously eating me up.

    So thanks to you, ugluk, for not helping in any aspect. (no offense intended, just stating the facts)

  8. #8
    Advanced Member Frequent Contributor
    Join Date
    Oct 2009
    Posts
    595

    Re: GL Project doesn't work properly.

    Ok, I show you some code, I used a long time ago, but, seriously, this is easy.

    The idea was to detect clicking on a 2D gui element. Please don't be offended by my statement. Reading an LA book is different than reading [censored] people write in the forums. Here it goes:

    Code :
      Vector<GLfloat, 4> tmp_origin;
      std::copy(origin.begin(), origin.end(), tmp_origin.begin());
     
      Vector<GLfloat, 4> position(tmp_origin + Vector<GLfloat, 4>(x, 0, z, 0));
      position(1) = 0;
      position(3) = 1;
     
      Vector<GLfloat, 4> proj_position(projection_matrix * modelview_matrix *
        position);
      proj_position /= proj_position(3);
     
      aabb.a(0) = std::floor(.5 * width * (proj_position(0) + 1) + .5);
      aabb.a(1) = std::floor(height - 1 -
        .5 * (proj_position(1) + 1) * height + .5);
     
      aabb.b = Vector<GLfloat, 2>(GLfloat(texture.get_width()),
        GLfloat(texture.get_height()));

    I hope this helps you somehow. The idea was to detect a click inside a texture, displayed as a 2D GUI element Be sure to round better than I have. If you need more code, I have plenty. You probably forgot to take the origin into account or something. There are easy ways to test your projection formula for errors.

    Code :
      Vector<GLfloat, 4> tmpa;
      std::copy(get_player_frog().fr_ptr->get_position().begin(),
        get_player_frog().fr_ptr->get_position().end(), tmpa.begin());
      tmpa(3) = 1;
     
      Vector<GLfloat, 4> tmpb(projection_matrix * modelview_matrix * tmpa);
      tmpb /= tmpb(3);
     
      frog_screen(0) = std::floor(.5 * (tmpb(0) + 1) * width + .5);
      frog_screen(1) = std::floor(height - 1 - .5 * (tmpb(1) + 1) * height + .5);

    I don't like C#. Why don't you try your hand at C++? You won't need any C# magic and maths is a lot faster.

    BTW: The above code works on untransposed matrices, your's look transposed.

  9. #9
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    Re: GL Project doesn't work properly.

    Thanks, I tried with transposing the matrices, what got me to the current state:
    Code :
    Vector4 pos = new Vector4(s.Position.X, 0.0f, s.Position.Y, 1.0f);
    Vector3 pos3 = new Vector3(s.Position.X, 0.0f, s.Position.Y);
    Matrix4 model = new Matrix4();
    Matrix4 proj = new Matrix4();
    Matrix4 mpj = new Matrix4();
    float[] view = new float[4];
     
    GL.GetFloat(GetPName.ModelviewMatrix, out model);
     
    [quote][/QUOTE]
    GL.GetFloat(GetPName.ProjectionMatrix, out proj);
    GL.GetFloat(GetPName.Viewport, view);
     
    Matrix4.Transpose(ref model, out model);
    Matrix4.Transpose(ref proj, out proj);
    Matrix4.Mult(ref proj, ref model, out mpj);
    Vector4.Transform(ref pos, ref mpj, out pos);
    pos.Div(pos.W);
     
    s.set2DPos(new Vector2f((view[0] + (view[2] * (pos.X + 1) / 2.0f)),
                            (view[1] + (view[3] * (pos.Y) / 2.0f)) ));

    Which get's me a lot closer to the behaviour I intended. You can actually see the the point, but it only moves some pixels when the original object is moving across the screen.
    Additionaly, if i move the camera around both axis seem inverted and false scaled.

    Quote Originally Posted by ugluk
    but, seriously, this is easy.
    To you this might be the easiest of all tasks but to me this one is actually pretty challanging, so I highly appreciate any constructive help which gets me understanding and solving my problem I got here.

    Quote Originally Posted by ugluk
    I don't like C#. Why don't you try your hand at C++?
    I do like C# and I dont see any sense in digging into a new language and then rewriting all my code to eventually get this issue of the project resolved.

  10. #10
    Advanced Member Frequent Contributor
    Join Date
    Oct 2009
    Posts
    595

    Re: GL Project doesn't work properly.

    Hmm, why don't you add 1 to pos.Y in the s.set2DPos call? Well, even if you do that you'll probably get a wrong Y coordinate. Use my view transform from the code, I've posted and it will work.

    Read up the glViewport() specs.

    http://www.opengl.org/sdk/docs/man/

    GL was not meant to be used from C only, but C# is a sore in my eye, yet with modern GL programming almost everything runs on the GPU, so you'll be forced to write C-like code even though you don't like it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •