opengl draw 3d coordinate system
I assume that you lot have some knowledge of OpenGL. Otherwise, read "Introduction to OpenGL with 2d Graphics".
Example 1: 3D Shapes (OGL01Shape3D.cpp)
This case is taken from Nehe OpenGL Tutorial Lesson # 5 (@ http://nehe.gamedev.net/), which displays a 3D color-cube and a pyramid. The cube is made of of vi quads, each having different colors. The hallow pyramid is made up of 4 triangle, with dissimilar colors on each of the vertices.
1 ii 3 4 v vi seven viii nine 10 xi 12 13 14 15 sixteen 17 18 19 twenty 21 22 23 24 25 26 27 28 29 thirty 31 32 33 34 35 36 37 38 39 forty 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 seventy 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | #include <windows.h> #include <GL/glut.h> char championship[] = "3D Shapes"; void initGL() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(i.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(1.5f, 0.0f, -7.0f); glBegin(GL_QUADS); glColor3f(0.0f, one.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -one.0f); glVertex3f(-one.0f, 1.0f, -one.0f); glVertex3f(-1.0f, i.0f, ane.0f); glVertex3f( i.0f, one.0f, 1.0f); glColor3f(one.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -one.0f); glVertex3f( i.0f, -1.0f, -one.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f(-i.0f, 1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f( i.0f, -1.0f, 1.0f); glColor3f(one.0f, i.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f(-one.0f, -i.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f( ane.0f, 1.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f(-ane.0f, -1.0f, -i.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glColor3f(ane.0f, 0.0f, ane.0f); glVertex3f(1.0f, 1.0f, -ane.0f); glVertex3f(1.0f, 1.0f, 1.0f); glVertex3f(ane.0f, -1.0f, one.0f); glVertex3f(i.0f, -1.0f, -1.0f); glEnd(); glLoadIdentity(); glTranslatef(-1.5f, 0.0f, -6.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 0.0f, ane.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(i.0f, -1.0f, one.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 0.0f, one.0f); glVertex3f(1.0f, -i.0f, i.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -i.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, one.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-ane.0f, -1.0f, -ane.0f); glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glColor3f(0.0f,0.0f,1.0f); glVertex3f(-1.0f,-ane.0f,-1.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-1.0f,-1.0f, ane.0f); glEnd(); glutSwapBuffers(); } void reshape(GLsizei width, GLsizei height) { if (height == 0) summit = 1; GLfloat aspect = (GLfloat)width / (GLfloat)height; glViewport(0, 0, width, summit); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, attribute, 0.1f, 100.0f); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(640, 480); glutInitWindowPosition(fifty, l); glutCreateWindow(title); glutDisplayFunc(display); glutReshapeFunc(reshape); initGL(); glutMainLoop(); return 0; } |
GLUT Setup - principal()
The program contains a initGL()
, display()
and reshape()
functions.
The main()
program:
- glutInit(&argc, argv);
Initializes the Glut. - glutInitWindowSize(640, 480);
glutInitWindowPosition(l, 50);
glutCreateWindow(title);
Creates a window with a title, initial width and top positioned at initial superlative-left corner. - glutDisplayFunc(display);
Registersdisplay()
every bit the re-paint event handler. That is, the graphics sub-organisation calls dorsumdisplay()
when the window first appears and whenever there is a re-pigment request. - glutReshapeFunc(reshape);
Registersreshape()
as the re-sized result handler. That is, the graphics sub-system calls backreshape()
when the window beginning appears and whenever the window is re-sized. - glutInitDisplayMode(GLUT_DOUBLE);
Enables double buffering. Indisplay()
, we useglutSwapBuffers()
to signal to the GPU to swap the front-buffer and back-buffer during the next VSync (Vertical Synchronization). - initGL();
Invokes theinitGL()
one time to perform all 1-time initialization tasks. - glutMainLoop();
Finally, enters the event-processing loop.
Ane-Fourth dimension Initialization Operations - initGL()
The initGL()
function performs the erstwhile initialization tasks. It is invoked from primary()
once (and only once).
glClearColor(0.0f, 0.0f, 0.0f, ane.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Set the immigration (background) color to blackness (R=0, Thousand=0, B=0) and opaque (A=1), and the immigration (groundwork) depth to the farthest (Z=1). In display()
, we invoke glClear()
to clear the color and depth buffer, with the clearing color and depth, earlier rendering the graphics. (Also the color buffer and depth buffer, OpenGL also maintains an aggregating buffer and a stencil buffer which shall be discussed later.)
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
Nosotros need to enable depth-test to remove the hidden surface, and set the part used for the depth test.
glShadeModel(GL_SMOOTH);
We enable shine shading in color transition. The alternative is GL_FLAT
. Endeavor it out and meet the difference.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
In graphics rendering, at that place is oft a merchandise-off between processing speed and visual quality. Nosotros can use glHint()
to decide on the trade-off. In this example, we ask for the best perspective correction, which may involve more processing. The default is GL_DONT_CARE
.
Defining the Color-cube and Pyramid
OpenGL'southward object is made up of primitives (such every bit triangle, quad, polygon, point and line). A primitive is divers via one or more vertices. The color-cube is made up of half dozen quads. Each quad is made up of 4 vertices, divers in counter-clockwise (CCW) club, such as the normal vector is pointing out, indicating the front confront. All the iv vertices accept the same color. The color-cube is defined in its local space (called model infinite) with origin at the center of the cube with sides of 2 units.
Similarly, the pyramid is made upward of 4 triangles (without the base of operations). Each triangle is made up of 3 vertices, divers in CCW society. The 5 vertices of the pyramid are assigned different colors. The color of the triangles are interpolated (and blend smoothly) from its 3 vertices. Once more, the pyramid is defined in its local infinite with origin at the center of the pyramid.
Model Transform
The objects are defined in their local spaces (model spaces). We need to transform them to the common globe space, known equally model transform.
To perform model transform, we need to operate on the so-called model-view matrix (OpenGL has a few transformation matrices), by setting the current matrix manner to model-view matrix:
glMatrixMode(GL_MODELVIEW);
We perform translations on cube and pyramid, respectively, to position them on the earth space:
glLoadIdentity();
glTranslatef(1.5f, 0.0f, -vii.0f);
glLoadIdentity();
glTranslatef(-1.5f, 0.0f, -6.0f);
View Transform
The default camera position is:
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0)
That is, EYE=(0,0,0)
at the origin, AT=(0,0,-100)
pointing at negative-z axis (into the screen), and UP=(0,i,0)
corresponds to y-axis.
OpenGL graphics rendering pipeline performs so-called view transform to bring the world infinite to photographic camera's view space. In the instance of the default camera position, no transform is needed.
Viewport Transform
void reshape(GLsizei width, GLsizei height) {
glViewport(0, 0, width, height);
The graphics sub-system calls back reshape()
when the window first appears and whenever the window is resized, given the new window's width
and height
, in pixels. Nosotros set our application viewport to embrace the unabridged window, top-left corner at (0, 0) of width
and superlative
, with default minZ
of 0 and maxZ
of 1. We likewise use the same attribute ratio of the viewport for the project view frustum to prevent distortion. In the viewport, a pixel has (ten, y) value too equally z-value for depth processing.
Projection Transform
GLfloat aspect = (GLfloat)width / (GLfloat)pinnacle;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, attribute, 0.1f, 100.0f);
A camera has express field of view. The projection models the view captured by the camera. There are two types of projection: perspective projection and orthographic projection. In perspective projection, object farther to the camera appears smaller compared with object of the same size nearer to the photographic camera. In orthographic projection, the objects announced the same regardless of the z-value. Orthographic projection is a special instance of perspective projection where the photographic camera is placed very far away. We shall discuss the orthographic projection in the afterward example.
To fix the projection, we need to operate on the projection matrix. (Think that we operated on the model-view matrix in model transform.)
We set the matrix way to projection matrix and reset the matrix. We utilise the gluPerspective()
to enable perspective projection, and gear up the fovy (view bending from the bottom-aeroplane to the top-airplane), attribute ratio (width/elevation), zNear and zFar of the View Frustum (truncated pyramid). In this instance, we set the fovy to 45°. We use the aforementioned aspect ratio as the viewport to avoid baloney. We fix the zNear to 0.1 and zFar to 100 (z=-100). Have that annotation the color-cube (ane.five, 0, -7) and the pyramid (-i.5, 0, -6) are contained within the View Frustum.
The project transform transforms the view frustum to a 2x2x1 cuboid clipping-volume centered on the nearly plane (z=0). The subsequent viewport transform transforms the clipping-book to the viewport in screen space. The viewport is prepare before via the glViewport()
function.
Example 2: 3D Shape with Blitheness (OGL02Animation.cpp)
Allow'southward modify the previous instance to carry out animation (rotating the cube and pyramid).
1 two 3 four five 6 7 eight 9 ten 11 12 13 14 15 16 17 18 19 xx 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 lx 61 62 63 64 65 66 67 68 69 lxx 71 72 73 74 75 76 77 78 79 lxxx 81 82 83 84 85 86 87 88 89 ninety 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | #include <windows.h> #include <GL/glut.h> char title[] = "3D Shapes with blitheness"; GLfloat anglePyramid = 0.0f; GLfloat angleCube = 0.0f; int refreshMills = 15; void initGL() { glClearColor(0.0f, 0.0f, 0.0f, one.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } void brandish() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(1.5f, 0.0f, -7.0f); glRotatef(angleCube, one.0f, i.0f, 1.0f); glBegin(GL_QUADS); glColor3f(0.0f, ane.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f(-i.0f, 1.0f, -i.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, one.0f, i.0f); glColor3f(1.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -1.0f, one.0f); glVertex3f(-i.0f, -1.0f, 1.0f); glVertex3f(-i.0f, -i.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glColor3f(i.0f, 0.0f, 0.0f); glVertex3f( one.0f, 1.0f, i.0f); glVertex3f(-1.0f, 1.0f, i.0f); glVertex3f(-1.0f, -1.0f, one.0f); glVertex3f( one.0f, -ane.0f, 1.0f); glColor3f(i.0f, 1.0f, 0.0f); glVertex3f( ane.0f, -1.0f, -1.0f); glVertex3f(-1.0f, -one.0f, -1.0f); glVertex3f(-ane.0f, ane.0f, -1.0f); glVertex3f( i.0f, i.0f, -ane.0f); glColor3f(0.0f, 0.0f, ane.0f); glVertex3f(-1.0f, one.0f, one.0f); glVertex3f(-one.0f, 1.0f, -i.0f); glVertex3f(-one.0f, -ane.0f, -1.0f); glVertex3f(-one.0f, -ane.0f, i.0f); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glVertex3f(one.0f, 1.0f, 1.0f); glVertex3f(one.0f, -ane.0f, 1.0f); glVertex3f(one.0f, -1.0f, -ane.0f); glEnd(); glLoadIdentity(); glTranslatef(-i.5f, 0.0f, -6.0f); glRotatef(anglePyramid, 1.0f, i.0f, 0.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-ane.0f, -i.0f, 1.0f); glColor3f(0.0f, 0.0f, i.0f); glVertex3f(one.0f, -i.0f, 1.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 0.0f, i.0f); glVertex3f(1.0f, -ane.0f, ane.0f); glColor3f(0.0f, ane.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); glColor3f(ane.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -one.0f); glColor3f(0.0f, 0.0f, i.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glColor3f(i.0f,0.0f,0.0f); glVertex3f( 0.0f, one.0f, 0.0f); glColor3f(0.0f,0.0f,i.0f); glVertex3f(-ane.0f,-one.0f,-one.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-ane.0f,-1.0f, 1.0f); glEnd(); glutSwapBuffers(); anglePyramid += 0.2f; angleCube -= 0.15f; } void timer(int value) { glutPostRedisplay(); glutTimerFunc(refreshMills, timer, 0); } void reshape(GLsizei width, GLsizei height) { if (height == 0) meridian = 1; GLfloat aspect = (GLfloat)width / (GLfloat)height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, aspect, 0.1f, 100.0f); } int chief(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(640, 480); glutInitWindowPosition(50, 50); glutCreateWindow(championship); glutDisplayFunc(display); glutReshapeFunc(reshape); initGL(); glutTimerFunc(0, timer, 0); glutMainLoop(); return 0; } |
The new codes are:
GLfloat anglePyramid = 0.0f;
GLfloat angleCube = 0.0f;
int refreshMills = 15;
We ascertain two global variables to continue track of the current rotational angles of the cube and pyramid. Nosotros too define the refresh menstruation as 15 msec (66 frames per 2nd).
void timer(int value) {
glutPostRedisplay();
glutTimerFunc(refreshMills, timer, 0); //
}
To perform animation, we define a part called timer()
, which posts a re-paint request to actuate display()
when the timer expired, and and then run the timer again. In main()
, nosotros perform the showtime timer()
phone call via glutTimerFunc(0, timer, 0)
.
glRotatef(angleCube, 1.0f, ane.0f, 1.0f);
......
glRotatef(anglePyramid, 1.0f, 1.0f, 0.0f);
......
anglePyramid += 0.2f;
angleCube -= 0.15f;
In display()
, we rotate the cube and pyramid based on their rotational angles, and update the angles later each refresh.
Case 3: Orthographic Projection (OGL03Orthographic.cpp)
Every bit mentioned, OpenGL back up two type of projections: perspective and orthographic. In orthographic projection, an object appears to be the aforementioned size regardless of the depth. Orthographic is a special example of perspective projection, where the camera is placed very far abroad.
To employ orthographic projection, alter the reshape()
function to invoke glOrtho()
.
void reshape(GLsizei width, GLsizei pinnacle) { if (meridian == 0) height = 1; GLfloat attribute = (GLfloat)width / (GLfloat)height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width >= meridian) { glOrtho(-3.0 * aspect, 3.0 * attribute, -3.0, iii.0, 0.1, 100); } else { glOrtho(-3.0, 3.0, -iii.0 / attribute, 3.0 / aspect, 0.ane, 100); } }
In this instance, we fix the cantankerous-section of view-volume co-ordinate to the aspect ratio of the viewport, and depth from 0.1 to 100, respective to z=-0.i to z=-100. Take note that the cube and pyramid are contained within the view-volume.
Example 4: Vertex Array
In the earlier example, drawing a cube requires at least 24 glVertex
functions and a pair of glBegin
and glEnd
. Part calls may involve high overhead and hinder the operation. Furthermore, each vertex is specified and candy three times.
Link to OpenGL/Computer Graphics References and Resources
Source: https://www3.ntu.edu.sg/home/ehchua/programming/opengl/CG_Examples.html
0 Response to "opengl draw 3d coordinate system"
Post a Comment