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 @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 @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.
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.
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):
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.
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.
Hi,
Using DisplayPipeline.GetOpenGLWorldToClip works as expected. Thanks
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
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?