User:Hg200: Difference between revisions

Jump to navigation Jump to search
2,362 bytes added ,  4 January 2021
m
no edit summary
No edit summary
mNo edit summary
 
(9 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 images illustrate some of the properties of "x_gl_mat1" and "x_gl_mat2".
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:


== The Octave coordinate system ==
[[File:Octave_coordinate_systems.png|center|350px]]
 
= 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".
Line 9: Line 11:
[[File:Octave_view_point_setup_to_scale.png|center|750px]]
[[File:Octave_view_point_setup_to_scale.png|center|750px]]


== OpenGL coordinate systems ==
= update_camera() =


[[File:Octave_coordinate_systems.png|center|750px]]
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 54: 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 ===
 
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|250px]]
[[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 64: 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"


In the following simplified code section, the field of view (FOV) is determined such that the image is fitted into the bounding box of the window:
Hint: If you debug in "update_camera ()", you can print "bb": 
 
  (gdb) print *bb.rep.data@bb.rep.len
  (gdb) $1 = {72.79, 31.50, 434, 342.29}
 
Compare the result with the output on the Octave prompt:
 
  hax = axes ();
  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
 
=== 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 94: Line 118:
     v_angle = get_cameraviewangle ();
     v_angle = get_cameraviewangle ();


  // x_projection: identity "diag([1, 1, 1, 1])"
  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
   // is necessary because "v_angle" can be set manually.
   // is necessary because "v_angle" can be set manually.
Line 101: 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 115: Line 143:
     pix = (bb(2) < bb(3) ? bb(2) : bb(3));
     pix = (bb(2) < bb(3) ? bb(2) : bb(3));


  // x_viewport: identity "diag([1, 1, 1, 1])"
  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.
   translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
   translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
Line 123: Line 153:
</syntaxhighlight>}}
</syntaxhighlight>}}


Note: The projection and viewport 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