{"id":11,"date":"2021-10-05T07:22:05","date_gmt":"2021-10-05T07:22:05","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/?p=11"},"modified":"2021-10-05T07:22:06","modified_gmt":"2021-10-05T07:22:06","slug":"understanding-various-coordinate-systems-in-opengl","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/2021\/10\/05\/understanding-various-coordinate-systems-in-opengl\/","title":{"rendered":"Understanding Various Coordinate Systems in OpenGL"},"content":{"rendered":"\n<p><strong>Introduction<\/strong><\/p>\n\n\n\n<p>My first impression when the term \u201ccoordinate systems\u201d came up in my graphic class was that it is easy; everyone knows what a coordinate system is. However, when I started to work on my first project with OpenGL, I started to be overwhelmed by too many coordinate systems. There are at least 5 different important coordinate systems that learners should notice: Object space (or local space, or model space), world space, view space (or eye space, or camera space), clip space, and screen space. If we do not understand this concept well, we might have trouble later as we try to build our first 3D object.\u00a0<\/p>\n\n\n\n<p><strong>The Right hand coordinate system in OpenGL<\/strong><\/p>\n\n\n\n<p>The coordinate system used in OpenGL is right hand coordinate. Different from the 3D coordinate that we learned from math, the y axis is up and the positive z axis points towards the viewer. Figure 1 is helpful for me to understand the roles and relationships of those different spaces in the general graphic pipeline [1].\u00a0<\/p>\n\n\n\n<p><em>Local space (or model space) <\/em>is the coordinate of the object relative to its local origin (0,0,0). For example, initially, a sphere is at the origin, its position can be later moved to a different location using transformation using model matrix. By this process, the object is put into a <em>world space <\/em>whose coordinates help locate the locations of all objects in the virtual world that is defined by our programming.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"525\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/1-1024x525.png\" alt=\"\" class=\"wp-image-12\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/1-1024x525.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/1-300x154.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/1-768x394.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/1.png 1368w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Figure1: Different spaces in the graphic pipeline.<br>Source: Adapt from [1] https:\/\/learnopengl.com\/Getting-started\/Coordinate-Systems<\/figcaption><\/figure>\n\n\n\n<p><strong>Matrix transformation from model space to world space<\/strong><\/p>\n\n\n\n<p>The process of transforming from model space to world space can be performed by many types of transformation: translation, scaling, and rotation. Let V(x,y,z) is a vertex of the object. Mathematically, to transform object coordinate to world coordinate, we multiply matrices as shown below. Mathematical concepts help learners understand what actually happens when a 3D object transforms. However, in practice, no matrix multiplication is explicitly done by users.\u00a0 We just simply call built-in functions such as glTranslatef(), glRotatef(), or glScalef() etc.; but we need to know proper parameters to pass in the functions so that objects can end up in the desired location in world space by understanding matrix transformation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"584\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/3-1-1024x584.png\" alt=\"\" class=\"wp-image-19\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/3-1-1024x584.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/3-1-300x171.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/3-1-768x438.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/3-1.png 1392w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Another important key in this transformation is the order of transformation; this is taken into consideration when compound transformation is done. Compound transformation is a series of transformations; they need to be written in the reversed order before the object is dawn. Basically, compound transportation is matrix transformation; translation and rotation are not commutative. As illustrated in figure 2, rotation after translation create different result from translation after rotation [3].<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"872\" height=\"510\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/4.png\" alt=\"\" class=\"wp-image-20\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/4.png 872w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/4-300x175.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/4-768x449.png 768w\" sizes=\"auto, (max-width: 872px) 100vw, 872px\" \/><figcaption>Figure 2: The order of transformation affects the presentation of objects. <br>Source: Adapted from https:\/\/www.cs.cmu.edu\/afs\/cs\/academic\/class\/15462-s09\/www\/lec\/03\/lec03a.pdf<\/figcaption><\/figure>\n\n\n\n<p><strong>Example of transformation done in OpenGL<\/strong><\/p>\n\n\n\n<p>As shown in the figure 3 [4], originally, the object coordinate is at (0,0,0). We want the object to be scaled, rotated and then translated into world space. The order of our built-in functions for transformation are arranged in a reversed order: glTranslatef() is called before glRotatef() , and then glScalef() before object is drawn by calling gluCylinder().<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"872\" height=\"604\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/5.png\" alt=\"\" class=\"wp-image-21\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/5.png 872w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/5-300x208.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/5-768x532.png 768w\" sizes=\"auto, (max-width: 872px) 100vw, 872px\" \/><figcaption>Figure 3: An example of transformation in OpenGL. <br>Source:http:\/\/www.csc.villanova.edu\/~mdamian\/Past\/graphicsfa10\/notes\/HierarchyHand.pdf<\/figcaption><\/figure>\n\n\n\n<p><em>View space<\/em> is the scene that is viewed by the eye (or camera). In order to set the view space, we need to somehow set the view matrix and perform matrix transformation. In OpenGL, users can simply call the function gluLookAt( ex, ey, ez, lx, ly, lz, ux, uy, uz ). In this function (ex, ey, ez) is the eye position, (lx,ly, lz) is the look-at position, and (ux,uy, uz) is the up vector. This function will automatically do the calculation for users. Some learners might wonder what is the up vector? The up vector is used to calculate the right vector. The picture below (Figure 4) will help users understand more about the eye position, direction, right vector, and up vector.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"196\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/6.png\" alt=\"\" class=\"wp-image-22\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/6.png 756w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/6-300x78.png 300w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><figcaption>Figure 4: How the camera coordinate is set in OpenGL. <br>Source: Adapted from [1]<\/figcaption><\/figure>\n\n\n\n<p>Mathematically, this is also a matrix multiplication as shown in Figure 5. R, U, D are the right vector, the up vector, and the direction vector respectively. P is the eye&#8217;s position.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"292\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/7-1024x292.png\" alt=\"\" class=\"wp-image-23\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/7-1024x292.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/7-300x86.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/7-768x219.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/7.png 1178w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Figure 5: Matrix multiplication related to the function gluLookAt(). <br>Source: Adapted from [1]<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><em>Clip space<\/em> is formed by projecting view space using projection matrix. OpenGL requires x, y, z coordinates of vertices ranging from -1.0 to 1.0 in order to show up on the screen. Otherwise, any vertices that are outside of the clipping space will be clipped. There are two types of projection: orthographic and perspective projection. Figure 6 shows the different visual effect from those projections. The perspective projection imitates how the image is observed by eyes in real life.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1382\" height=\"604\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/8-1024x448.png\" alt=\"\" class=\"wp-image-24\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/8-1024x448.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/8-300x131.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/8-768x336.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/10\/8.png 1382w\" sizes=\"auto, (max-width: 1382px) 100vw, 1382px\" \/><figcaption>Figure 6: Differences between orthographic and perspective projection. <br>Source: Adapted from [1]<\/figcaption><\/figure>\n\n\n\n<p>In OpenGL, to do the perspective projection, we use the function <strong>gluPerspective<\/strong>( fovy, aspect, zn, zf ). Fovy is the vertical angle in degrees; aspect is the width-height ratio; zn is the near clipping plane and zf is the far clipping plane. To do the orthographic projection, we use the function void <strong>glOrtho<\/strong> (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)<\/p>\n\n\n\n<p><strong>Conclusion<\/strong>: <\/p>\n\n\n\n<p>A solid understanding of how coordinate systems work in the graphic pipeline is important as learners might apply that concept when building their first 3D object. Matrix transformation is the basic mechanism for moving object space into world space. It is helpful to relate built-in functions in OpenGL with their works in different spaces related to the graphic pipeline.\u00a0<\/p>\n\n\n\n<p><strong>Reference<\/strong><\/p>\n\n\n\n<p>[1] Learning OpenGL -Your #1 Resource for OpenGL. <em>Coordinate System<\/em>.[Online]. Available: https:\/\/learnopengl.com\/Getting-started\/Coordinate-Systems. Accessed on Oct 1st, 2021. <\/p>\n\n\n\n<p>[2] OpenGL Programming Guide. Appendix F Homogeneous Coordinates and Transformation Matrices. [Online]. Available: https:\/\/www.glprogramming.com\/red\/appendixf.html. Accessed on Oct 1st, 2021.<\/p>\n\n\n\n<p>[3] Zeyang Li. <em>Transformations in OpenGL<\/em>. Carnegie Mellon University. [Online]. Available: https:\/\/www.cs.cmu.edu\/afs\/cs\/academic\/class\/15462-s09\/www\/lec\/03\/lec03a.pdf. Accessed on Oct 2nd, 2021. <\/p>\n\n\n\n<p>[4] Villanova University. <em>3D OpenGL Basic Models Hierarchical Modeling<\/em>. [Online]. Available: http:\/\/www.csc.villanova.edu\/~mdamian\/Past\/graphicsfa10\/notes\/HierarchyHand.pdf. Accessed on Oct 2nd, 2021<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction My first impression when the term \u201ccoordinate systems\u201d came up in my graphic class was that it is easy; everyone knows what a coordinate system is. However, when I started to work on my first project with OpenGL, I started to be overwhelmed by too many coordinate systems. There are at least 5 different&hellip; <a class=\"more-link\" href=\"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/2021\/10\/05\/understanding-various-coordinate-systems-in-opengl\/\">Continue reading <span class=\"screen-reader-text\">Understanding Various Coordinate Systems in OpenGL<\/span><\/a><\/p>\n","protected":false},"author":11550,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-11","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts\/11","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/users\/11550"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/comments?post=11"}],"version-history":[{"count":5,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts\/11\/revisions"}],"predecessor-version":[{"id":25,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts\/11\/revisions\/25"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/media?parent=11"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/categories?post=11"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/tags?post=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}