User:Hg200: Difference between revisions

Jump to navigation Jump to search
1,740 bytes added ,  4 January 2021
m
no edit summary
mNo edit summary
mNo edit summary
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Investigations on update_camera() =
= OpenGL coordinate systems =
 
In the second part of <math display="inline">\rightarrow</math> "axes::properties::update_camera ()" the view transformation "x_gl_mat1" and projection matrix "x_gl_mat2" are put together. The following article illustrates some of the properties of "x_gl_mat1" and "x_gl_mat2".
 
== OpenGL coordinate systems ==


In the Octave plotting backend, we find various OpenGL transformations. Some of the classic OpenGL transformation steps, as well as coordinate systems, are shown in the following picture:  
In the Octave plotting backend, we find various OpenGL transformations. Some of the classic OpenGL transformation steps, as well as coordinate systems, are shown in the following picture:  
Line 9: Line 5:
[[File:Octave_coordinate_systems.png|center|350px]]
[[File:Octave_coordinate_systems.png|center|350px]]


== The Octave coordinate system ==
= The Octave coordinate system =


In Octave a plot scene is defined by a "view point", a "camera target" and an "up vector".
In Octave a plot scene is defined by a "view point", a "camera target" and an "up vector".


[[File:Octave_view_point_setup_to_scale.png|center|750px]]
[[File:Octave_view_point_setup_to_scale.png|center|750px]]
= update_camera() =
In the second part of <math display="inline">\rightarrow</math> "axes::properties::update_camera ()" the view transformation "x_gl_mat1" and projection matrix "x_gl_mat2" are put together. The following chapter illustrates some of the properties of "x_gl_mat1" and "x_gl_mat2".


== The role of "x_gl_mat1" ==
== The role of "x_gl_mat1" ==
=== x_view ===


The following section of code composes the matrix "x_view", which is a subset of "x_gl_mat1". The matrix "x_gl_mat1" consists of multiple translations, scales and one rotation operation.
The following section of code composes the matrix "x_view", which is a major subset of "x_gl_mat1". The matrix "x_gl_mat1" consists of multiple translations, scales and one rotation operation. The individual operation steps are shown in a picture below.


{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
Line 56: Line 57:
</syntaxhighlight>}}
</syntaxhighlight>}}


To visualize the matrix properties, the "x_gl_mat1" matrix is multiplied by the object coordinates. The plot box is now aligned with the Z-axis and the view point is at the origin <math display="inline">[0,0,0]</math>. The matrix transforms world coordinates into camera coordinates. The purple planes show the near and far clipping planes.
=== x_gl_mat1 ===


[[File:Octave_x_gl_mat1_setup.png|center|250px]]
To visualize the matrix properties, the "x_gl_mat1" matrix is multiplied by the object coordinates. After the transformation, the plot box is aligned with the Z-axis and the view point is at the origin <math display="inline">[0,0,0]</math>. The matrix transforms world coordinates into camera coordinates. The purple planes show the near and far clipping planes.
 
[[File:Octave_x_gl_mat1_setup.png|center|300px]]


The individual translation, scaling and rotation operations of "x_gl_mat1", are shown in the following figure:
The individual translation, scaling and rotation operations of "x_gl_mat1", are shown in the following figure:
Line 66: Line 69:
== The role of "x_gl_mat2" ==
== The role of "x_gl_mat2" ==


The matrix "x_gl_mat2" is composed of the sub matrices "x_viewport" and "x_projection". The purpose of these matrices is to fit the 2D image of the above transformation result into a "bounding box". The bounding box is defined as follows:
=== Bounding box ===
 
The matrix "x_gl_mat2" is composed of the sub matrices "x_viewport" and "x_projection". The purpose of these matrices is to fit the associated 2D image of the above transformation result into a "bounding box". The bounding box is defined as follows:


  bb(0), bb(1): Position of the "viewport"
* bb(0), bb(1): Position of the "viewport"
  bb(2), bb(3): Width and height of the "viewport"
* bb(2), bb(3): Width and height of the "viewport"


Hint: If you debug in "update_camera ()", you can print "bb":   
Hint: If you debug in "update_camera ()", you can print "bb":   


   (gdb) print *bb.rep.data@bb.rep.len
   (gdb) print *bb.rep.data@bb.rep.len
  (gdb) $1 = {72.79, 31.50, 434, 342.29}


Compare the result with the output in the Octave prompt:
Compare the result with the output on the Octave prompt:


   hax = axes ();
   hax = axes ();
   get (hax, "position");
   get (hax, "position")
  ans = 73.80 47.20 434.00 342.30
  get (gcf, 'position')
  ans = 22 300 560 420
 
Where 420 - 342.30 - 31.5 + 1 = 47.20


In the following simplified code section the matrix "x_projection" is assembled. It is used to scale the image of the above transformation into the bounding box of the window. For this purpose, the field of view (FOV) must be calculated:
=== x_projection ===
 
In the following simplified code section the matrix "x_projection" is composed. It is used to normalize the image of the above transformation. For this purpose, the field of view (FOV) must be calculated:


{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
Line 105: Line 118:
     v_angle = get_cameraviewangle ();
     v_angle = get_cameraviewangle ();


   // x_projection = diag([1, 1, 1, 1])
   // x_projection: identity "diag([1, 1, 1, 1])"
   Matrix x_projection = xform_matrix ();
   Matrix x_projection = xform_matrix ();
   // Calculate backwards from the angle to the ratio. This step
   // Calculate backwards from the angle to the ratio. This step
Line 114: Line 127:
</syntaxhighlight>}}
</syntaxhighlight>}}


"x_viewport" is a 2D transformation used to place the "normalized" plot box in the center of the bounding box:
=== x_viewport ===
 
"x_viewport" is a transformation used to place the previously "normalized" plot box in the center and to fit it tightly into the bounding box:


{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
Line 128: Line 143:
     pix = (bb(2) < bb(3) ? bb(2) : bb(3));
     pix = (bb(2) < bb(3) ? bb(2) : bb(3));


   // x_viewport = diag([1, 1, 1, 1])
   // x_viewport: identity "diag([1, 1, 1, 1])"
   Matrix x_viewport = xform_matrix ();
   Matrix x_viewport = xform_matrix ();
   // Move to the center of the bounding box inside the figure.
   // Move to the center of the bounding box inside the figure.
Line 138: Line 153:
</syntaxhighlight>}}
</syntaxhighlight>}}


Note: The matrix just scales x, y so that the image fits tightly into the bounding box. The z-coordinate is not modified.
Note: The matrix "x_gl_mat2" scales x, y. However the z-coordinate is not modified!
 
= setup_opengl_transformation () =
 
== OpenGL backend ==
 
In the OpenGL backend, the view matrix, an orthographic matrix, and the viewport transform are used to transform the octave plot into the screen window.
 
{{Code|Section of opengl_renderer::setup_opengl_transformation ()"|<syntaxhighlight lang="C" style="font-size:13px">
 
  Matrix x_zlim = props.get_transform_zlim ();
 
  xZ1 = x_zlim(0)-(x_zlim(1)-x_zlim(0))/2;
  xZ2 = x_zlim(1)+(x_zlim(1)-x_zlim(0))/2;
 
  // Load x_gl_mat1 and x_gl_mat2
  Matrix x_mat1 = props.get_opengl_matrix_1 ();
  Matrix x_mat2 = props.get_opengl_matrix_2 ();
 
  m_glfcns.glMatrixMode (GL_MODELVIEW);
  m_glfcns.glLoadIdentity ();
  m_glfcns.glScaled (1, 1, -1);
  // Matrix x_gl_mat1
  m_glfcns.glMultMatrixd (x_mat1.data ());
  m_glfcns.glMatrixMode (GL_PROJECTION);
  m_glfcns.glLoadIdentity ();
 
  Matrix vp = get_viewport_scaled ();
  // Install orthographic projection matrix with viewport
  // setting "0, vp(2), vp(3), 0" and near / far values "xZ1, xZ2"
  m_glfcns.glOrtho (0, vp(2), vp(3), 0, xZ1, xZ2);
  // Matrix x_gl_mat2
  m_glfcns.glMultMatrixd (x_mat2.data ());
  m_glfcns.glMatrixMode (GL_MODELVIEW);
 
  m_glfcns.glClear (GL_DEPTH_BUFFER_BIT);
 
</syntaxhighlight>}}
 
Hint: If you debug in "setup_opengl_transformation ()", you can print the viewport "vp": 
 
  (gdb) print *vp.rep.data@vp.rep.len
  (gdb) $1 = {0, 0, 560, 420}
 
This is consistent with the window size.
20

edits

Navigation menu