OpenGL problems in conduit

Hi @dale ,
I’m trying to draw with opengl but the view model projection matrix can’t be gotten from the old way.
I did find the model transform from de Display only.
Can I get the others somewhere on RC?
Any ideas?

Many Thanks.

Pau

Hi @Pau_Costa,

Can you provide me some code that is not working for you?

Thanks,

– Dale

Hi @dale,

On this code(working on V5) I’m using Tao to get the matrix, on V6 this matrix are always the identity. Why? I believe because on the current version of OpenGL will no longer work.

c# code:

var modelView = new float[16];
var projection = new float[16];
Gl.glGetFloatv(Gl.GL_MODELVIEW_MATRIX, modelView);
Gl.glGetFloatv(Gl.GL_PROJECTION_MATRIX, projection);

I compute the modelViewProjection and hand it to the shader.
With the MVP matrix the vertices are on a wrong position when the shader draws.

Shader:

#version 330

layout (location = 0) in vec3 aVertex;

precision mediump float;
uniform mat4 uMVP;

out vec3 vertex;

void main() {
  	vec4 pos = uMVP * vec4(aVertex, 1.0f);
  	vertex = aVertex;
  	gl_Position = pos;
}

So I’m asking for help finding this matrices.
Let me know if you need more info.
Thanks.

Pau

We pretty much exclusively use shaders for all OpenGL drawing in V6 and don’t set legacy matrix state. For your case, it looks like you want the single combined world to clip transform to feed your shader. You should be able to get this with the following code:

Transform world2clip = e.Viewport.GetTransform(CoordinateSystem.World, CoordinateSystem.Clip);
Transform modelTransform = e.Display.ModelTransform;
world2clip = world2clip * modelTransform;
float[] uMVP = new float[16];
int index = 0;
for (int j = 0; j < 4; j++)
  for (int i = 0; i < 4; i++)
    uMVP[index++] = (float)world2clip[i,j];
// flip z axis
uMVP[2] = -uMVP[2];
uMVP[6] = -uMVP[6];
uMVP[10] = -uMVP[10];
uMVP[14] = -uMVP[14];

That should work in both V5 and V6. I can add helper functions for this in the future, but they will only be available in V6.

1 Like

Hi @stevebaer,
I’m using the code you provided, it appears to work, the geometry is drawn where it must be.
The problem is moving the camera. Here a video:

The object is a CustomMeshObject added on the document, with the OnDraw overrided to use OpenGL to draw wires.
Drawing bounding box corners with red here:

Any ideas where/what should I look for?
Thank you.

Pau

Hi Pau,

If you are dynamically drawing geometry, make sure to override the Rhino.Display.DisplayConduit.CalculateBoundingBox virtual function and include the bounding box of the objects you are dynamically drawing, so as to increase the bounding box of scene. In doing this, dynamically drawn objects will not be clipped.

For example:

protected override void CalculateBoundingBox(Rhino.Display.CalculateBoundingBoxEventArgs e)
{
  if (null != Mesh)
  {
    e.IncludeBoundingBox(Mesh.GetBoundingBox(false));
  }
}

– Dale

The display uses the bounding box of your object’s geometry to help determine the view frustum.

You don’t need direct OpenGL calls to draw this and I would recommend using the supplied display pipeline draw functions instead. This way things like vector printing will work with your object.

Hi,

@dale I did try using a custom Rhino.Display.DisplayConduit overriding CalculateBoundingBox but still doing the same.
@stevebaer Using the display pipeline draw functions I can’t achieve what I need, it drawing too much lines reduce the performance(on V5 and V6) so I’m trying to draw it with OpenGL as was on my plugin V5 .

Looks like the problem is when moving the camera draws before CalculateBoundingBox or something like this.
Moving the camera the object is clipped, after stopping and releasing the mouse button it is correctly draw.
If you think about something else I can do to solve this, let me know.

Thank You.

-Pau

Does the geometry in your custom object have the correct bounding box?

Hi @stevebaer,

May be I didn’t explain myself, on this img we can see the red corners of the bounding box drawn using:
DisplayPipeline.DrawBoxCorners Method (BoundingBox, Color), the rest of the object is drawn by OpenGL

I think the boundingBox its correct.

Pau

Hi,
I’m still trying but nothing works.

  • Computing the matrix myself = same error
  • Checked matrix from wrong displays and correct ones and both have the same matrix ( checked where the camera and view options were the same)
  • Using Rhino.Display.DisplayConduit have a low performance with big objects

Any thing I can do?

Thank You

Pau

Hi @stevebaer and @dale

We are doing more research about this issue and we think there’s problems with the Frustum Near and Far planes. To test this we only draw the edges of the mesh with OpenGL, the geometry and the bounding box of the object it’s being drawn with Rhino pipeline.We saw 2 different problems (both related):

  1. Moving the view (with the right mouse). At some point the edges seems cut by the frustum. Then I do a window selection to force the redraw. Then the edges are being displayed right again and the Far and Near planes distance are different from the previous draw (why if the view didnt move?) Video attached - if you want to see all the values at the command line are being displayed, maximize the video-:
    https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/0/7/07ae66a91a13f8ba389cf9688e84676764310aa4.mp4
  2. Moving the mouse wheel (only “one step”). Here the draw is being executed twice with the same view and shows incorrect results on the first drawing, on the second draw shows the edges right. See again ZNear and ZFar values are different - seems the first draw uses the ZFar and ZNear from the previous draw-, that makes no sense. Attached video - again values at the command line, maximize the video to see all-: https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/4/b/4b3ba898a65258554d347c2b7d27823d35e8cdf7.mp4

We tried to compute the ModelViewMatrix by ourselves or using the method explained by @stevebaer, both are wrong with the same values. This is how we compute the values:

Plane near, far;
e.Viewport.GetFrustumNearPlane(out near);
e.Viewport.GetFrustumFarPlane(out far);
double halfDiagonal, halfVertical, halfHorizontal;
e.Viewport.GetCameraAngle(out halfDiagonal, out halfVertical, out halfHorizontal);
var fovy = halfVertical * 2;
var zNear = Convert.ToSingle(e.Viewport.CameraLocation.DistanceTo(near.Origin));
var zFar = Convert.ToSingle(e.Viewport.CameraLocation.DistanceTo(far.Origin));
Rhino.RhinoApp.WriteLine($“FrustumInfo: FOVY={fovy} Aspect={e.Viewport.FrustumAspect} ZNear={zNear} ZFar={zFar}”);

Hope this helps you guys to solve the issues, it’s important to us to get this solved.

Regards,

I just added the following functions to RhinoCommon to retrieve the same 16 float transformations that Rhino uses for drawing geometry with it’s shaders.

  • DisplayPipeline.GetOpenGLWorldToCamera
  • DisplayPipeline.GetOpenGLWorldToClip
  • DisplayPipeline.GetOpenGLCameraToClip

You will want to use the GetOpenGLWorldToClip function for the shader example that you provided above. These functions should be available in tomorrow’s WIP.

Can you elaborate on this? We put a lot of effort into improving display performance but there is always the chance that we are missing something.

1 Like

Hi,

Using DisplayPipeline.GetOpenGLWorldToClip works as expected. Thanks :grinning:

About the Display performance:
My idea was to draw the edges of the mesh:

Using Display.DrawMeshWires had a lower performance than Display.DrawLines(Line[],Color). I don’t know why, because the lines have duplicated vertex to load, still going faster. Is the DrawMeshWires doing some extra steps?

Thank you

Pau

I see what is happening. There is some display caching logic that needs to be added to RhinoCommon for mesh and brep drawing routines which should make them eventually much faster than calling DrawLines

Please try using DrawMeshWires in the WIP available next week. I just adjusted the code to use cached display information if it is available.

Thank you so much Steve,

We will try with DrawMeshWires and give you some feedback :slight_smile:

Regards,

Hi everybody, I read this very interesting old post and I would like to know if the GLSL open gl shader language is still available in Rhino v7.
I’m starting to write a Rhino plugIn in C++ and I need to draw some objects in RhinoConduit with OpenGL.
My Idea is to draw something in SC_POSTDRAWOBJECTS RhinoConduit event with glDrawArrays functions and apply to it the MVP matrix.
Is the correct way to do it or is completely wrong?
thank you for any answer

Why not use the functions available in our display pipeline and engine classes to draw things? Is there something missing in these functions that you need?

We still use OpenGL on Windows and gl functions can be called while in a conduit virtual function.

Hi Steve, thank you for your answer. Oh yes for simple things I’m using the display pipeline but now I’m working with ModuleWorks (a CAM library) inside my Rhino plugin and they use Open GL to draw.
In practice in my SC_POSTDRAWOBJECTS Conduit events I must load the modelView and Projection matrices and load it in my shader with glUniformMatrix4fv before to call the draw function of ModuleWorks.
If I understand I can take these matrices from functions:

CRhinoDisplayEngine::WorldToCamera 
CRhinoDisplayEngine::CameraToClip

Is it correct?