opengl draw 3d quad strip
I presume that you have some knowledge of OpenGL. Otherwise, read "Introduction to OpenGL with second Graphics".
Example 1: 3D Shapes (OGL01Shape3D.cpp)
This example is taken from Nehe OpenGL Tutorial Lesson # v (@ http://nehe.gamedev.internet/), which displays a 3D colour-cube and a pyramid. The cube is made of of 6 quads, each having unlike colors. The hallow pyramid is made up of 4 triangle, with different colors on each of the vertices.
one two 3 4 5 6 7 eight 9 10 11 12 13 14 15 xvi 17 xviii 19 twenty 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 xl 41 42 43 44 45 46 47 48 49 l 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 | #include <windows.h> #include <GL/glut.h> char championship[] = "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(one.5f, 0.0f, -7.0f); glBegin(GL_QUADS); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, ane.0f, -1.0f); glVertex3f(-i.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, ane.0f, 1.0f); glColor3f(1.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -one.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(-ane.0f, -i.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -ane.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( ane.0f, 1.0f, one.0f); glVertex3f(-one.0f, 1.0f, i.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f( 1.0f, -one.0f, 1.0f); glColor3f(1.0f, i.0f, 0.0f); glVertex3f( 1.0f, -ane.0f, -i.0f); glVertex3f(-one.0f, -1.0f, -one.0f); glVertex3f(-1.0f, ane.0f, -one.0f); glVertex3f( one.0f, 1.0f, -i.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, ane.0f); glVertex3f(-1.0f, 1.0f, -ane.0f); glVertex3f(-1.0f, -1.0f, -i.0f); glVertex3f(-one.0f, -1.0f, ane.0f); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glVertex3f(i.0f, i.0f, one.0f); glVertex3f(1.0f, -1.0f, 1.0f); glVertex3f(1.0f, -ane.0f, -1.0f); glEnd(); glLoadIdentity(); glTranslatef(-1.5f, 0.0f, -half-dozen.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glColor3f(0.0f, i.0f, 0.0f); glVertex3f(-1.0f, -i.0f, ane.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(one.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(ane.0f, -1.0f, one.0f); glColor3f(0.0f, i.0f, 0.0f); glVertex3f(one.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(ane.0f, -1.0f, -one.0f); glColor3f(0.0f, 0.0f, 1.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,0.0f,1.0f); glVertex3f(-1.0f,-1.0f,-i.0f); glColor3f(0.0f,one.0f,0.0f); glVertex3f(-1.0f,-i.0f, 1.0f); glEnd(); glutSwapBuffers(); } void reshape(GLsizei width, GLsizei pinnacle) { if (superlative == 0) height = 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 main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(640, 480); glutInitWindowPosition(50, l); glutCreateWindow(title); glutDisplayFunc(display); glutReshapeFunc(reshape); initGL(); glutMainLoop(); return 0; } |
Overabundance Setup - main()
The program contains a initGL(), brandish() and reshape() functions.
The main() program:
- glutInit(&argc, argv);
Initializes the Glut. - glutInitWindowSize(640, 480);
glutInitWindowPosition(50, 50);
glutCreateWindow(title);
Creates a window with a title, initial width and height positioned at initial acme-left corner. - glutDisplayFunc(display);
Registersdisplay()as the re-pigment event handler. That is, the graphics sub-organization calls backbrandish()when the window outset appears and whenever there is a re-paint asking. - glutReshapeFunc(reshape);
Registersreshape()as the re-sized upshot 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 useglutSwapBuffers()to indicate to the GPU to bandy the forepart-buffer and dorsum-buffer during the next VSync (Vertical Synchronization). - initGL();
Invokes theinitGL()once to perform all one-fourth dimension initialization tasks. - glutMainLoop();
Finally, enters the upshot-processing loop.
One-time Initialization Operations - initGL()
The initGL() function performs the onetime initialization tasks. It is invoked from master() one time (and only one time).
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(ane.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Set the clearing (background) color to black (R=0, M=0, B=0) and opaque (A=1), and the immigration (background) depth to the farthest (Z=1). In display(), we invoke glClear() to articulate the colour 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 demand to enable depth-test to remove the hidden surface, and gear up the office used for the depth test.
glShadeModel(GL_SMOOTH);
We enable smooth shading in colour transition. The alternative is GL_FLAT. Try information technology out and encounter the difference.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
In graphics rendering, there is frequently a merchandise-off betwixt processing speed and visual quality. We tin apply glHint() to make up one's mind on the merchandise-off. In this instance, we ask for the all-time perspective correction, which may involve more processing. The default is GL_DONT_CARE.
Defining the Colour-cube and Pyramid
OpenGL's object is made upward of primitives (such as triangle, quad, polygon, betoken and line). A primitive is defined via one or more vertices. The color-cube is made up of six quads. Each quad is made upwards of iv vertices, defined in counter-clockwise (CCW) order, such equally the normal vector is pointing out, indicating the front face. All the iv vertices have the same color. The color-cube is divers in its local infinite (chosen model infinite) with origin at the center of the cube with sides of two units.
Similarly, the pyramid is made upwards of 4 triangles (without the base). Each triangle is made upward of 3 vertices, defined in CCW guild. 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 center of the pyramid.
Model Transform
The objects are defined in their local spaces (model spaces). We need to transform them to the common earth space, known equally model transform.
To perform model transform, we need to operate on the so-chosen model-view matrix (OpenGL has a few transformation matrices), by setting the current matrix fashion to model-view matrix:
glMatrixMode(GL_MODELVIEW);
We 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, -half-dozen.0f);
View Transform
The default camera position is:
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, one.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 Upwardly=(0,1,0) corresponds to y-centrality.
OpenGL graphics rendering pipeline performs and so-called view transform to bring the world space to camera's view infinite. In the case of the default camera position, no transform is needed.
Viewport Transform
void reshape(GLsizei width, GLsizei acme) {
glViewport(0, 0, width, elevation);
The graphics sub-system calls dorsum reshape() when the window first appears and whenever the window is resized, given the new window's width and height, in pixels. We set our application viewport to cover the entire window, top-left corner at (0, 0) of width and height, with default minZ of 0 and maxZ of i. We also employ the same aspect ratio of the viewport for the projection view frustum to prevent distortion. In the viewport, a pixel has (x, y) value every bit well as z-value for depth processing.
Project Transform
GLfloat aspect = (GLfloat)width / (GLfloat)summit;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
A camera has express field of view. The project models the view captured by the camera. There are two types of project: perspective projection and orthographic projection. In perspective project, object further to the photographic camera appears smaller compared with object of the aforementioned size nearer to the camera. In orthographic projection, the objects appear the same regardless of the z-value. Orthographic projection is a special case of perspective project where the camera is placed very far abroad. Nosotros shall discuss the orthographic projection in the later case.
To set the project, nosotros need to operate on the projection matrix. (Recall that we operated on the model-view matrix in model transform.)
We prepare the matrix manner to projection matrix and reset the matrix. We utilise the gluPerspective() to enable perspective projection, and set the fovy (view bending from the lesser-aeroplane to the meridian-plane), attribute ratio (width/height), zNear and zFar of the View Frustum (truncated pyramid). In this case, we set the fovy to 45°. We apply the same attribute ratio as the viewport to avert distortion. Nosotros set the zNear to 0.1 and zFar to 100 (z=-100). Accept that note the color-cube (1.five, 0, -7) and the pyramid (-1.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 near plane (z=0). The subsequent viewport transform transforms the clipping-volume to the viewport in screen space. The viewport is set earlier via the glViewport() role.
Instance two: 3D Shape with Animation (OGL02Animation.cpp)
Let'due south modify the previous example to carry out animation (rotating the cube and pyramid).
1 2 3 4 5 6 7 eight 9 x xi 12 thirteen 14 15 xvi 17 18 xix 20 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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 xc 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, i.0f); glClearDepth(ane.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, i.0f, 1.0f); glBegin(GL_QUADS); glColor3f(0.0f, one.0f, 0.0f); glVertex3f( 1.0f, ane.0f, -1.0f); glVertex3f(-one.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( one.0f, 1.0f, 1.0f); glColor3f(1.0f, 0.5f, 0.0f); glVertex3f( one.0f, -one.0f, 1.0f); glVertex3f(-1.0f, -1.0f, one.0f); glVertex3f(-i.0f, -1.0f, -1.0f); glVertex3f( i.0f, -1.0f, -1.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( one.0f, 1.0f, 1.0f); glVertex3f(-ane.0f, ane.0f, 1.0f); glVertex3f(-1.0f, -1.0f, one.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glColor3f(1.0f, one.0f, 0.0f); glVertex3f( 1.0f, -ane.0f, -ane.0f); glVertex3f(-1.0f, -i.0f, -1.0f); glVertex3f(-1.0f, one.0f, -1.0f); glVertex3f( one.0f, 1.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, ane.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-ane.0f, -ane.0f, 1.0f); glColor3f(one.0f, 0.0f, 1.0f); glVertex3f(one.0f, i.0f, -one.0f); glVertex3f(1.0f, one.0f, 1.0f); glVertex3f(1.0f, -1.0f, one.0f); glVertex3f(1.0f, -1.0f, -i.0f); glEnd(); glLoadIdentity(); glTranslatef(-1.5f, 0.0f, -6.0f); glRotatef(anglePyramid, i.0f, ane.0f, 0.0f); glBegin(GL_TRIANGLES); glColor3f(ane.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glColor3f(0.0f, ane.0f, 0.0f); glVertex3f(-one.0f, -i.0f, one.0f); glColor3f(0.0f, 0.0f, ane.0f); glVertex3f(one.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, -1.0f, i.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -ane.0f); glColor3f(ane.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(one.0f, -1.0f, -one.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-ane.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,-one.0f,-1.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-one.0f,-1.0f, ane.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) pinnacle = 1; GLfloat aspect = (GLfloat)width / (GLfloat)peak; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, attribute, 0.1f, 100.0f); } int master(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(640, 480); glutInitWindowPosition(50, fifty); glutCreateWindow(title); glutDisplayFunc(brandish); 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;
Nosotros define two global variables to go along track of the current rotational angles of the cube and pyramid. Nosotros also define the refresh menstruum as 15 msec (66 frames per 2nd).
void timer(int value) {
glutPostRedisplay();
glutTimerFunc(refreshMills, timer, 0); //
}
To perform blitheness, we define a role called timer(), which posts a re-paint request to activate display() when the timer expired, and then run the timer again. In master(), we perform the first timer() 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 Project (OGL03Orthographic.cpp)
As mentioned, OpenGL back up two type of projections: perspective and orthographic. In orthographic project, an object appears to be the aforementioned size regardless of the depth. Orthographic is a special instance of perspective projection, where the camera is placed very far away.
To use orthographic projection, change the reshape() function to invoke glOrtho().
void reshape(GLsizei width, GLsizei superlative) { if (tiptop == 0) height = 1; GLfloat aspect = (GLfloat)width / (GLfloat)acme; glViewport(0, 0, width, summit); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width >= height) { glOrtho(-3.0 * aspect, 3.0 * attribute, -3.0, iii.0, 0.ane, 100); } else { glOrtho(-3.0, 3.0, -3.0 / attribute, 3.0 / aspect, 0.ane, 100); } } In this example, nosotros set the cross-section of view-volume according to the attribute ratio of the viewport, and depth from 0.1 to 100, corresponding to z=-0.1 to z=-100. Accept note that the cube and pyramid are contained within the view-book.
Case 4: Vertex Assortment
In the earlier instance, 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 performance. Furthermore, each vertex is specified and processed three times.
Link to OpenGL/Computer Graphics References and Resources
Source: https://www3.ntu.edu.sg/home/ehchua/programming/opengl/CG_Examples.html
Post a Comment for "opengl draw 3d quad strip"