Select DXF objects in OpenGL rendering orthographic projection

1 2    next >
overmaster
7/23/2007 2:20 PM

I work with OpenGL rendering and I want to know how I can build correct Matrix4D object for work with EntitySelector.GetEntitiesInRectangle(...) and EntitySelector.GetClosestEntities(...) methods when we have simply transformation orthographic projection (parallel projection).  
      Matrix4D projectionTransform = Transformation4D.GetOrthographicProjectionTransform(...);
      GL.MatrixMode(MatrixMode.Projection);
      GL.LoadMatrixd(ref projectionTransform);
I created normal zoom and drag in this orthographic projection but when I tried to do functionality selecting DXF objects by clicking mouse near them I could not build correct Matrix4D object for OpenGL rendering in orthographic projection.
   Please can you help me with this functionality. If this functionality possibly.

Wout
7/23/2007 3:08 PM

Hi,

The transformations taking place in OpenGL are the modeling/viewing, projection and viewport transformations (EDIT: alternatively the screen point can be normalized first to be in OpenGL clipping space). So you will have to take into account all these transformations. It sounds like you have omitted the viewport transformation, which is not explicitly present as a matrix in OpenGL, but that transformation is handled through the glViewport() call. The projection matrix transforms to a cube with corners (-1, -1, -1), (1, 1, 1). The viewport matrix transforms this to screen coordinates, so a simple translation and scaling transform.

Let me know if this is enough for you to get it to work!

Wout

overmaster
7/23/2007 3:45 PM

Hi,

Thanks for your quick answer but I can not undestand where I should use GL.Viewport(int x,
int y,
int width,
int height
) method.

I use next code for creating projection: It is a code from OpenGL View example in your solution but I modified it a little for implement my functionality (zoom and and drag).

private Matrix4D GetProjectionTransform()
{
      Vector3D boundsDelta = bounds.Delta;
      double boundsDeltaLength = boundsDelta.GetLength();
      double cameraDistance = 2.5d * boundsDeltaLength;     
      double frontClip = 0.4d * cameraDistance;
      double backClip = 1.6d * cameraDistance;

      // Scale such that front plane rectangle always fits the screen without distorting the image.
      double frontPlaneDx = boundsDeltaLength * scaleFactor;
      double frontPlaneDy = boundsDeltaLength * scaleFactor;
      double width = (double)ClientSize.Width;
      double height = (double)ClientSize.Height;

      // See if the screen width or height is the limiting factor.
      if (width / height > frontPlaneDx / frontPlaneDy)
      {
        frontPlaneDx *= (width / height) / (frontPlaneDx / frontPlaneDy);
      }
      else
      {
        frontPlaneDy *= (frontPlaneDx / frontPlaneDy) / (width / height);
      }

       // Use transformation below for orthographic projection (parallel projection).   
 
      Matrix4D projectionTransform =
          Transformation4D.GetOrthographicProjectionTransform(
            -0.5d * frontPlaneDx,
            0.5d * frontPlaneDx,
            -0.5d * frontPlaneDy,
            0.5d * frontPlaneDy,
            frontClip,
            backClip
          ) * Transformation4D.Translation(translation.X, -translation.Y, translation.Z);        
          
      if (glGraphics.RenderingContext != null) {
        glGraphics.RenderingContext.MakeCurrent();
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadMatrixd(ref projectionTransform);
      }
      return projectionTransform;

This methods create Matrix4D object and load it in GL and return this matrix and when I try to use this object in next piece of code:

protected override void OnMouseUp(MouseEventArgs e)
{
      WW.Math.Point2D endReferencePoint = new WW.Math.Point2D(e.X, e.Y);
      Matrix4D currentMatrix = GetProjectionTransform();
      closestEntities = EntitySelector.GetClosestEntities(
              model,
              GraphicsConfig.Default,
              currentMatrix,
              endReferencePoint,
              out distance
            );
}

I receive wrong result. What I doing wrong?

Wout
7/23/2007 4:04 PM

Hi,

As stated, there are 2 more transforms that form the full chain. You have picked just the projection transform from that chain. The missing pieces are:
- the model/view transform (which might be the Identity matrix, in which case you can disregard it).
- the viewport transform. This is handled implicitly by GlGraphics.Resize (in the example this is called from the Control's OnResize override). Typically the viewport is set to the client rectangle. So you have to create this matrix manually:
Matrix4D viewportTransform =
  Transformation4D.Scaling((double)ClientSize.Width / 2d, -(double)ClientSize.Height / 2d, 1d) *
  Transformation4D.Translation(1d, 1d, 0d)
(Note the y-axis reversal, because the screen's y-axis points down).

The total transform will be:
Matrix4D totalTransform = modelViewTransform * projectionTransform * viewportTransform.

You can check what the transform does by creating some points or line segments yourself, transforming then and draw using GDI if you like to experiment.

Wout

overmaster
10/23/2007 3:49 PM

Hello. I again retun to this topic because early I didn't to receive correct result for mouse selection in OpenGL mode. I try to use your advise but it's not helping to me. Now I think I need to create two methods one will convert OrthographicProjectionMatrix to normal 2DTransformMatrix which I can use in EntitySelector.GetClosestEntities(...) method and scale, move transformations and second opposite method which will convert 2DTransformMatrix to OrthographicProjectionMatrix for rendering in OpenGL.
Can you give me advice how I can convert OrthographicProjectionMatrix to normal 2DTransformMatrix and vice versa? Maybe you can give me full example of using OpenGL with scale, move and pick mouse selection functionality, exactly like as in your 'DxfExtendedViewExample VS2005' example but using OpenGL rendering instead of GDI rendering in it. I am very want to use exactly OpenGL rendering instead of GDI rendering in my application because rendering big dxf files in OpenGL greatly more quickly than in GDI
   Beforehand Thanks for your help.

overmaster
10/29/2007 11:13 AM

Can give me full example of using OpenGL with scale, move and pick mouse selection functionality, exactly like as in your 'DxfExtendedViewExample VS2005' example but using OpenGL rendering instead of GDI rendering in it. I am very want to use exactly OpenGL rendering instead of GDI rendering in my application because rendering big dxf files in OpenGL greatly more quickly than in GDI

overmaster
10/29/2007 11:16 AM

There are only rendering and rotation in your example for OpenGL 'DxfOpenGLViewExampleCS' I want get full example with scale, move and pick mouse selection functionality.

Wout
10/29/2007 11:18 AM

Hi,

I need to free a bit of time to work on that, I'll send you an example tomorrow.

Regards,

Wout

overmaster
10/29/2007 11:20 AM

Thanks, I'll be waiting for your response.

overmaster
10/31/2007 8:46 AM

Very big thanks for your example. I'm very impressed your solution. Thanks for your help.

1 2    next >