- Home /
 
Using Graphics.DrawMeshNow() in the Repaint event of an OnGUI function of an EditorWindow with custom projection matrix
I am attempting to draw meshes inside an EditorWindow. Sounds easy: there's a Graphics.DrawMeshNow() function that draws a mesh, and indeed in my editor's OnGUI repaint event it draws the mesh wonderfully in orthographic projection. But the near/far planes are too close together!
So I've been looking at changing the projection matrix. Here's the code:
             Matrix4x4 model = Matrix4x4.TRS(
                 new Vector3(midCol.xMin + width/2,y + width/2,-50), 
                 Quaternion.AngleAxis(180,new Vector3(0,0,1)) * Quaternion.AngleAxis(45,new Vector3(1,0,0)) * Quaternion.AngleAxis(Time.realtimeSinceStartup*60,new Vector3(0.0f,1.0f,0.0f)), 
                 Vector3.one * 10 * mag);
     
             Matrix4x4 proj = Matrix4x4.identity;
             float f = 1000;
             float n = 0.01f;
             float sw = Screen.width;
             float sh = Screen.height;
             proj[0,0] = 2.0f / (sw);
             proj[1,1] = 2.0f / (-sh);
             proj[2,2] = -2.0f / (f - n);
 
             proj[3,0] = -1;
             proj[3,1] = 1;
             proj[3,2] = -( (f + n) / (f - n) );
 
             proj[3,3] = 1;
 
             if (sceneryMaterial.SetPass(0))
             {
                 //GL.PushMatrix(); // does nothing since modifying GL matrix does nothing
 
                 for (int i = 0; i < 4; i++)
                     for (int j = 0; j < 4; j++)
                         proj[i,j] = Random.Range(-1000,1000);
 
                 Matrix4x4 gm = GUI.matrix;
                 //GL.LoadProjectionMatrix(proj); // does nothing!
         
                 GUI.matrix = proj; // DOES NOTHING SOMEBODY KILL ME
 
                 Matrix4x4[] camProj = new Matrix4x4[Camera.allCamerasCount];
                 for (int i = 0; i < Camera.allCamerasCount; i++) {
                     camProj[i] = Camera.allCameras[i].projectionMatrix; // Camera equivalent of GL.push/pop matrix
                 }     
 
                 //Camera.main.pixelRect = new Rect(100,100,100,100); // this messes with subsequent views unless reset
                 //Camera.main.projectionMatrix = proj; // GL.push/pop matrix have no effect on this; also, DOES NOTHING
                 
                 for (int i = 0; i < Camera.allCamerasCount; i++) {
                     Camera.allCameras[i].projectionMatrix = proj; // Camera equivalent of GL.push/pop matrix
                 }     
 
                 Matrix4x4 mx = model; // used to try multiplying my own ortho projection matrix in here, with disastrous results
 
                 Graphics.DrawMeshNow(selectedGraphic.visualMesh, mx);
 
                 for (int i = 0; i < Camera.allCamerasCount; i++) {
                     Camera.allCameras[i].projectionMatrix = camProj[i]; // Camera equivalent of GL.push/pop matrix
                 }     
                 GUI.matrix = gm; // restore the gui matrix FOR ALL THE GOOD IT DID ME
                 //GL.PopMatrix(); // does nothing
             }
 
               NONE of these projection matrix modifications affects DrawMeshNow() in any way.
Let me be clear: I've messed with the GL matrix, every possible camera matrix AND the GUI matrix, and none of them change how DrawMeshNow() draws a mesh in an OnGUI repaint event.
I need answers! Does anyone know where I can put a projection matrix?
Thanks in advance!
Answer by Alex_May · Sep 30, 2015 at 03:14 PM
In the time-honoured tradition of answering my own questions, I have solved this issue, my particular issue that I had with the near/far planes. It is a hack, but it works. I squish down the z axis in the model matrix, so that the verts come out at zero on the z axis. Back-face culling means the model displays correctly. Obviously this could be changed to preserve some z information but I was so excited that I had to come post here first.
Here is the code:
    Matrix4x4 model = Matrix4x4.TRS(some_model_position_on_screen, some_rotation, Vector3.one * 10 * mag);
    model = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, new Vector3(1,1,0)) * model;
 
               The last line is the important one - after setting up the model matrix, I simply multiply in a matrix that zeroes the z axis.
The original problem I had was caused by having to scale up the model to roughly 80 times its normal size to be displayed correctly on-screen - something I could have avoided having to do if I had control of the projection matrix, either by setting the near/far planes where I wanted, or by changing it so my units made more sense on-screen.
Thanks for reading or whatever.
Your answer
 
             Follow this Question
Related Questions
How to get an array inside a simple class at Editor window and change arraysize? 0 Answers
Will this script that does drawmeshinstancedprocedural actually work? 0 Answers
Is it possible to override Unity camera rendering? 1 Answer
Graphics.DrawMeshNow on top of gui elements 1 Answer
Event.button activating constantly? 0 Answers