3d cube line drawing with value
I assume that you accept some knowledge of OpenGL. Otherwise, read "Introduction to OpenGL with 2D Graphics".
Instance 1: 3D Shapes (OGL01Shape3D.cpp)
This example is taken from Nehe OpenGL Tutorial Lesson # 5 (@ http://nehe.gamedev.net/), which displays a 3D color-cube and a pyramid. The cube is fabricated of of six quads, each having different colors. The hallow pyramid is made up of four triangle, with different colors on each of the vertices.
1 ii 3 4 five half-dozen 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 thirty 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 60 61 62 63 64 65 66 67 68 69 lxx 71 72 73 74 75 76 77 78 79 80 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 | #include <windows.h> #include <GL/overabundance.h> char title[] = "3D Shapes"; void initGL() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.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, 1.0f, 0.0f); glVertex3f( ane.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -one.0f); glVertex3f(-ane.0f, i.0f, i.0f); glVertex3f( i.0f, i.0f, one.0f); glColor3f(i.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -i.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(-ane.0f, -1.0f, -ane.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( ane.0f, i.0f, one.0f); glVertex3f(-ane.0f, ane.0f, 1.0f); glVertex3f(-one.0f, -1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, i.0f); glColor3f(ane.0f, 1.0f, 0.0f); glVertex3f( i.0f, -i.0f, -one.0f); glVertex3f(-1.0f, -1.0f, -i.0f); glVertex3f(-1.0f, 1.0f, -ane.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-i.0f, ane.0f, -1.0f); glVertex3f(-i.0f, -1.0f, -1.0f); glVertex3f(-ane.0f, -1.0f, 1.0f); glColor3f(ane.0f, 0.0f, i.0f); glVertex3f(1.0f, i.0f, -one.0f); glVertex3f(ane.0f, 1.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); glVertex3f(ane.0f, -1.0f, -1.0f); glEnd(); glLoadIdentity(); glTranslatef(-i.5f, 0.0f, -6.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(-i.0f, -one.0f, 1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(one.0f, -1.0f, 1.0f); glColor3f(i.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(one.0f, -one.0f, 1.0f); glColor3f(0.0f, 1.0f, 0.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, 1.0f, 0.0f); glVertex3f(i.0f, -1.0f, -1.0f); glColor3f(0.0f, 0.0f, one.0f); glVertex3f(-1.0f, -1.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,-1.0f,-1.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-one.0f,-1.0f, i.0f); glEnd(); glutSwapBuffers(); } void reshape(GLsizei width, GLsizei height) { if (summit == 0) acme = 1; GLfloat aspect = (GLfloat)width / (GLfloat)acme; glViewport(0, 0, width, peak); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, aspect, 0.1f, 100.0f); } int master(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(640, 480); glutInitWindowPosition(fifty, 50); glutCreateWindow(title); glutDisplayFunc(display); glutReshapeFunc(reshape); initGL(); glutMainLoop(); return 0; } |
GLUT Setup - primary()
The programme contains a initGL()
, display()
and reshape()
functions.
The master()
programme:
- glutInit(&argc, argv);
Initializes the Overabundance. - glutInitWindowSize(640, 480);
glutInitWindowPosition(50, 50);
glutCreateWindow(championship);
Creates a window with a title, initial width and height positioned at initial top-left corner. - glutDisplayFunc(display);
Registersdisplay()
as the re-paint event handler. That is, the graphics sub-system calls backdisplay()
when the window first appears and whenever at that place is a re-paint request. - glutReshapeFunc(reshape);
Registersreshape()
as the re-sized event handler. That is, the graphics sub-system calls backreshape()
when the window first appears and whenever the window is re-sized. - glutInitDisplayMode(GLUT_DOUBLE);
Enables double buffering. Indisplay()
, we utiliseglutSwapBuffers()
to betoken to the GPU to swap the forepart-buffer and dorsum-buffer during the next VSync (Vertical Synchronization). - initGL();
Invokes theinitGL()
one time to perform all one-fourth dimension initialization tasks. - glutMainLoop();
Finally, enters the event-processing loop.
One-Time Initialization Operations - initGL()
The initGL()
function performs the one-fourth dimension initialization tasks. Information technology is invoked from primary()
one time (and just one time).
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(one.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Set up the clearing (background) color to black (R=0, G=0, B=0) and opaque (A=i), and the clearing (groundwork) depth to the uttermost (Z=1). In brandish()
, we invoke glClear()
to clear the color and depth buffer, with the clearing colour and depth, earlier rendering the graphics. (Besides the color buffer and depth buffer, OpenGL also maintains an accumulation buffer and a stencil buffer which shall be discussed later.)
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
We need to enable depth-test to remove the subconscious surface, and set the role used for the depth test.
glShadeModel(GL_SMOOTH);
We enable shine shading in colour transition. The culling is GL_FLAT
. Try information technology out and see the difference.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
In graphics rendering, there is frequently a trade-off between processing speed and visual quality. We can employ glHint()
to make up one's mind on the trade-off. In this case, nosotros ask for the best perspective correction, which may involve more processing. The default is GL_DONT_CARE
.
Defining the Colour-cube and Pyramid
OpenGL'southward object is made up of primitives (such equally triangle, quad, polygon, bespeak and line). A primitive is defined via one or more vertices. The color-cube is fabricated up of 6 quads. Each quad is made upwardly of 4 vertices, defined in counter-clockwise (CCW) lodge, such as the normal vector is pointing out, indicating the front face. All the four vertices take the same colour. The color-cube is defined in its local space (called model space) with origin at the middle of the cube with sides of 2 units.
Similarly, the pyramid is fabricated up of four triangles (without the base). Each triangle is made up of three vertices, defined in CCW gild. The five vertices of the pyramid are assigned different colors. The color of the triangles are interpolated (and blend smoothly) from its 3 vertices. Again, the pyramid is defined in its local space with origin at the middle of the pyramid.
Model Transform
The objects are divers in their local spaces (model spaces). We need to transform them to the common world space, known as 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 mode to model-view matrix:
glMatrixMode(GL_MODELVIEW);
Nosotros perform translations on cube and pyramid, respectively, to position them on the world space:
glLoadIdentity();
glTranslatef(1.5f, 0.0f, -7.0f);
glLoadIdentity();
glTranslatef(-1.5f, 0.0f, -vi.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,one,0)
corresponds to y-centrality.
OpenGL graphics rendering pipeline performs so-called view transform to bring the globe space to camera's view space. In the case of the default camera position, no transform is needed.
Viewport Transform
void reshape(GLsizei width, GLsizei peak) {
glViewport(0, 0, width, height);
The graphics sub-system calls dorsum reshape()
when the window starting time appears and whenever the window is resized, given the new window's width
and tiptop
, in pixels. We set our application viewport to cover the entire window, pinnacle-left corner at (0, 0) of width
and meridian
, with default minZ
of 0 and maxZ
of 1. We also use the same aspect ratio of the viewport for the projection view frustum to prevent distortion. In the viewport, a pixel has (x, y) value likewise every bit z-value for depth processing.
Projection Transform
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
A camera has limited field of view. The projection models the view captured past the photographic camera. There are two types of projection: perspective projection and orthographic projection. In perspective projection, object further to the camera appears smaller compared with object of the aforementioned size nearer to the camera. In orthographic projection, the objects appear the aforementioned regardless of the z-value. Orthographic project is a special case of perspective projection where the camera is placed very far abroad. We shall hash out the orthographic projection in the later case.
To prepare the project, we need to operate on the projection matrix. (Recollect that we operated on the model-view matrix in model transform.)
Nosotros fix the matrix fashion to projection matrix and reset the matrix. Nosotros employ the gluPerspective()
to enable perspective projection, and set up the fovy (view angle from the lesser-plane to the top-plane), aspect ratio (width/elevation), zNear and zFar of the View Frustum (truncated pyramid). In this example, we prepare the fovy to 45°. We utilize the aforementioned aspect ratio as the viewport to avoid distortion. We set the zNear to 0.1 and zFar to 100 (z=-100). Take that note the colour-cube (1.five, 0, -7) and the pyramid (-1.5, 0, -6) are independent within the View Frustum.
The projection transform transforms the view frustum to a 2x2x1 cuboid clipping-volume centered on the near plane (z=0). The subsequent viewport transform transforms the clipping-volume to the viewport in screen infinite. The viewport is prepare before via the glViewport()
office.
Example 2: 3D Shape with Animation (OGL02Animation.cpp)
Allow's modify the previous example to carry out animation (rotating the cube and pyramid).
1 2 three 4 5 6 7 8 nine 10 xi 12 13 xiv 15 16 17 xviii 19 20 21 22 23 24 25 26 27 28 29 30 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 70 71 72 73 74 75 76 77 78 79 fourscore 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 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 animation"; GLfloat anglePyramid = 0.0f; GLfloat angleCube = 0.0f; int refreshMills = 15; void initGL() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.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); glRotatef(angleCube, 1.0f, 1.0f, ane.0f); glBegin(GL_QUADS); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f( one.0f, 1.0f, -one.0f); glVertex3f(-ane.0f, i.0f, -1.0f); glVertex3f(-one.0f, ane.0f, 1.0f); glVertex3f( ane.0f, 1.0f, 1.0f); glColor3f(1.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -1.0f, one.0f); glVertex3f(-i.0f, -ane.0f, one.0f); glVertex3f(-1.0f, -i.0f, -i.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glColor3f(one.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, i.0f); glVertex3f(-one.0f, -1.0f, 1.0f); glVertex3f( i.0f, -1.0f, ane.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -one.0f); glVertex3f(-ane.0f, -1.0f, -1.0f); glVertex3f(-one.0f, 1.0f, -one.0f); glVertex3f( one.0f, one.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-one.0f, 1.0f, -1.0f); glVertex3f(-one.0f, -1.0f, -1.0f); glVertex3f(-ane.0f, -1.0f, i.0f); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glVertex3f(one.0f, 1.0f, ane.0f); glVertex3f(i.0f, -one.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glEnd(); glLoadIdentity(); glTranslatef(-one.5f, 0.0f, -6.0f); glRotatef(anglePyramid, ane.0f, one.0f, 0.0f); glBegin(GL_TRIANGLES); glColor3f(i.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glColor3f(0.0f, one.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(1.0f, -ane.0f, 1.0f); glColor3f(one.0f, 0.0f, 0.0f); glVertex3f(0.0f, ane.0f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(ane.0f, -ane.0f, -i.0f); glColor3f(one.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, -ane.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, -one.0f, -ane.0f); glColor3f(one.0f,0.0f,0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glColor3f(0.0f,0.0f,1.0f); glVertex3f(-one.0f,-1.0f,-1.0f); glColor3f(0.0f,i.0f,0.0f); glVertex3f(-1.0f,-ane.0f, i.0f); glEnd(); glutSwapBuffers(); anglePyramid += 0.2f; angleCube -= 0.15f; } void timer(int value) { glutPostRedisplay(); glutTimerFunc(refreshMills, timer, 0); } void reshape(GLsizei width, GLsizei tiptop) { if (pinnacle == 0) height = 1; GLfloat aspect = (GLfloat)width / (GLfloat)elevation; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, aspect, 0.1f, 100.0f); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(640, 480); glutInitWindowPosition(l, 50); glutCreateWindow(title); 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 define two global variables to keep rails of the current rotational angles of the cube and pyramid. Nosotros too define the refresh menses equally 15 msec (66 frames per second).
void timer(int value) {
glutPostRedisplay();
glutTimerFunc(refreshMills, timer, 0); //
}
To perform animation, we ascertain a office called timer()
, which posts a re-paint request to activate display()
when the timer expired, and so run the timer again. In chief()
, we perform the start timer()
telephone call via glutTimerFunc(0, timer, 0)
.
glRotatef(angleCube, 1.0f, 1.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 after each refresh.
Example 3: Orthographic Projection (OGL03Orthographic.cpp)
As mentioned, OpenGL support two type of projections: perspective and orthographic. In orthographic projection, an object appears to be the same size regardless of the depth. Orthographic is a special case of perspective projection, where the photographic camera is placed very far away.
To use orthographic projection, change the reshape()
function to invoke glOrtho()
.
void reshape(GLsizei width, GLsizei height) { if (height == 0) superlative = 1; GLfloat aspect = (GLfloat)width / (GLfloat)elevation; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width >= peak) { glOrtho(-3.0 * attribute, 3.0 * attribute, -three.0, 3.0, 0.one, 100); } else { glOrtho(-three.0, 3.0, -three.0 / aspect, three.0 / aspect, 0.1, 100); } }
In this example, we set the cross-section of view-volume according to the aspect ratio of the viewport, and depth from 0.1 to 100, corresponding to z=-0.1 to z=-100. Take note that the cube and pyramid are independent within the view-book.
Example iv: Vertex Array
In the earlier case, cartoon a cube requires at to the lowest degree 24 glVertex
functions and a pair of glBegin
and glEnd
. Part calls may involve loftier overhead and hinder the operation. Furthermore, each vertex is specified and processed three times.
Link to OpenGL/Computer Graphics References and Resources
mcguirewinfievanded.blogspot.com
Source: https://www3.ntu.edu.sg/home/ehchua/programming/opengl/CG_Examples.html
0 Response to "3d cube line drawing with value"
Enregistrer un commentaire