drawing image over 3d world opengl
I presume that you accept some cognition 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 # five (@ http://nehe.gamedev.internet/), which displays a 3D color-cube and a pyramid. The cube is made of of vi quads, each having unlike colors. The hallow pyramid is made up of four triangle, with different colors on each of the vertices.
one 2 3 4 five 6 7 8 9 10 11 12 13 14 15 sixteen 17 eighteen xix 20 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 fifty 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 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 | #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, ane.0f, 0.0f); glVertex3f( one.0f, i.0f, -i.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( i.0f, 1.0f, i.0f); glColor3f(ane.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f(-i.0f, -1.0f, 1.0f); glVertex3f(-one.0f, -1.0f, -one.0f); glVertex3f( ane.0f, -1.0f, -one.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( one.0f, 1.0f, 1.0f); glVertex3f(-one.0f, 1.0f, 1.0f); glVertex3f(-1.0f, -one.0f, i.0f); glVertex3f( ane.0f, -one.0f, 1.0f); glColor3f(i.0f, 1.0f, 0.0f); glVertex3f( i.0f, -1.0f, -1.0f); glVertex3f(-one.0f, -ane.0f, -i.0f); glVertex3f(-1.0f, i.0f, -one.0f); glVertex3f( 1.0f, i.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, ane.0f, 1.0f); glVertex3f(-1.0f, one.0f, -one.0f); glVertex3f(-i.0f, -1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -i.0f); glVertex3f(ane.0f, i.0f, 1.0f); glVertex3f(1.0f, -1.0f, ane.0f); glVertex3f(1.0f, -1.0f, -1.0f); glEnd(); glLoadIdentity(); glTranslatef(-one.5f, 0.0f, -6.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 0.0f, i.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(ane.0f, -i.0f, 1.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, 1.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(ane.0f, -1.0f, -ane.0f); glColor3f(i.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); glColor3f(0.0f, 0.0f, one.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,1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glColor3f(0.0f,i.0f,0.0f); glVertex3f(-1.0f,-1.0f, 1.0f); glEnd(); glutSwapBuffers(); } void reshape(GLsizei width, GLsizei tiptop) { if (elevation == 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(l, 50); glutCreateWindow(title); glutDisplayFunc(display); glutReshapeFunc(reshape); initGL(); glutMainLoop(); render 0; } |
GLUT Setup - main()
The program contains a initGL()
, display()
and reshape()
functions.
The chief()
program:
- glutInit(&argc, argv);
Initializes the Overabundance. - glutInitWindowSize(640, 480);
glutInitWindowPosition(50, 50);
glutCreateWindow(title);
Creates a window with a title, initial width and meridian positioned at initial top-left corner. - glutDisplayFunc(display);
Registersdisplay()
as the re-paint issue handler. That is, the graphics sub-system calls backbrandish()
when the window commencement appears and whenever in that location is a re-paint request. - glutReshapeFunc(reshape);
Registersreshape()
as the re-sized upshot handler. That is, the graphics sub-system calls backreshape()
when the window kickoff appears and whenever the window is re-sized. - glutInitDisplayMode(GLUT_DOUBLE);
Enables double buffering. Indisplay()
, we utiliseglutSwapBuffers()
to indicate to the GPU to swap the front end-buffer and back-buffer during the next VSync (Vertical Synchronization). - initGL();
Invokes theinitGL()
once to perform all one-time initialization tasks. - glutMainLoop();
Finally, enters the upshot-processing loop.
One-Time Initialization Operations - initGL()
The initGL()
role performs the one-time initialization tasks. It is invoked from master()
once (and but one time).
glClearColor(0.0f, 0.0f, 0.0f, i.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Set the clearing (background) color to blackness (R=0, G=0, B=0) and opaque (A=1), and the clearing (background) depth to the farthest (Z=1). In brandish()
, nosotros invoke glClear()
to clear the color and depth buffer, with the clearing colour and depth, before rendering the graphics. (Besides the colour buffer and depth buffer, OpenGL besides maintains an accumulation buffer and a stencil buffer which shall be discussed subsequently.)
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
We need to enable depth-test to remove the hidden surface, and ready the function used for the depth examination.
glShadeModel(GL_SMOOTH);
We enable smooth shading in colour transition. The alternative is GL_FLAT
. Effort it out and encounter the divergence.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
In graphics rendering, at that place is often a trade-off between processing speed and visual quality. Nosotros can utilize glHint()
to decide on the trade-off. In this case, we inquire for the all-time perspective correction, which may involve more processing. The default is GL_DONT_CARE
.
Defining the Color-cube and Pyramid
OpenGL's object is made upwards of primitives (such equally triangle, quad, polygon, point and line). A primitive is defined via one or more than vertices. The colour-cube is fabricated up of six quads. Each quad is made upward of 4 vertices, divers in counter-clockwise (CCW) club, such as the normal vector is pointing out, indicating the front face. All the 4 vertices take the same color. The color-cube is defined in its local infinite (called model space) with origin at the center of the cube with sides of 2 units.
Similarly, the pyramid is made upwards of four triangles (without the base). Each triangle is fabricated upwardly of three vertices, defined in CCW order. The 5 vertices of the pyramid are assigned different colors. The color of the triangles are interpolated (and blend smoothly) from its 3 vertices. Over 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 infinite, known as model transform.
To perform model transform, we need to operate on the and so-chosen model-view matrix (OpenGL has a few transformation matrices), past 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, -6.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,ane,0)
corresponds to y-axis.
OpenGL graphics rendering pipeline performs and then-called view transform to bring the world space to camera's view space. In the instance of the default camera position, no transform is needed.
Viewport Transform
void reshape(GLsizei width, GLsizei acme) {
glViewport(0, 0, width, pinnacle);
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. We set our application viewport to cover the entire window, top-left corner at (0, 0) of width
and top
, with default minZ
of 0 and maxZ
of ane. We besides utilise the same aspect ratio of the viewport for the project view frustum to forestall baloney. In the viewport, a pixel has (x, y) value as well as z-value for depth processing.
Project Transform
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
A photographic camera has limited 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 camera appears smaller compared with object of the same size nearer to the camera. In orthographic projection, the objects appear the same regardless of the z-value. Orthographic projection is a special instance of perspective projection where the camera is placed very far away. We shall discuss the orthographic projection in the later example.
To fix the project, we demand to operate on the project matrix. (Call up that we operated on the model-view matrix in model transform.)
We set up the matrix mode to projection matrix and reset the matrix. We utilize the gluPerspective()
to enable perspective projection, and set the fovy (view angle from the bottom-airplane to the top-plane), aspect ratio (width/superlative), zNear and zFar of the View Frustum (truncated pyramid). In this example, we set the fovy to 45°. We use the same aspect ratio every bit the viewport to avoid distortion. We set the zNear to 0.i and zFar to 100 (z=-100). Take that note the color-cube (1.5, 0, -7) and the pyramid (-1.v, 0, -half-dozen) are contained inside the View Frustum.
The projection transform transforms the view frustum to a 2x2x1 cuboid clipping-volume centered on the most airplane (z=0). The subsequent viewport transform transforms the clipping-volume to the viewport in screen space. The viewport is ready earlier via the glViewport()
function.
Example 2: 3D Shape with Animation (OGL02Animation.cpp)
Let'southward modify the previous case to carry out blitheness (rotating the cube and pyramid).
1 ii 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 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 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, i.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, -vii.0f); glRotatef(angleCube, ane.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glVertex3f(-ane.0f, 1.0f, -1.0f); glVertex3f(-1.0f, ane.0f, 1.0f); glVertex3f( 1.0f, i.0f, i.0f); glColor3f(1.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -i.0f, one.0f); glVertex3f(-one.0f, -1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f( one.0f, -one.0f, -ane.0f); glColor3f(one.0f, 0.0f, 0.0f); glVertex3f( one.0f, 1.0f, i.0f); glVertex3f(-1.0f, 1.0f, one.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f( i.0f, -ane.0f, 1.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f( 1.0f, -ane.0f, -1.0f); glVertex3f(-1.0f, -ane.0f, -1.0f); glVertex3f(-ane.0f, i.0f, -one.0f); glVertex3f( 1.0f, i.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, one.0f, one.0f); glVertex3f(-i.0f, 1.0f, -i.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, ane.0f); glColor3f(one.0f, 0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glVertex3f(one.0f, 1.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glEnd(); glLoadIdentity(); glTranslatef(-1.5f, 0.0f, -6.0f); glRotatef(anglePyramid, one.0f, 1.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, -1.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, ane.0f); glVertex3f(i.0f, -i.0f, 1.0f); glColor3f(0.0f, i.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, one.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(i.0f, -1.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-i.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,-i.0f,-1.0f); glColor3f(0.0f,i.0f,0.0f); glVertex3f(-1.0f,-i.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 meridian) { if (elevation == 0) meridian = one; GLfloat aspect = (GLfloat)width / (GLfloat)height; glViewport(0, 0, width, top); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, aspect, 0.1f, 100.0f); } int primary(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(640, 480); glutInitWindowPosition(fifty, 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 define two global variables to keep track of the current rotational angles of the cube and pyramid. Nosotros too define the refresh period as xv msec (66 frames per 2nd).
void timer(int value) {
glutPostRedisplay();
glutTimerFunc(refreshMills, timer, 0); //
}
To perform animation, we define a role chosen timer()
, which posts a re-pigment asking to activate display()
when the timer expired, and so run the timer over again. In main()
, we perform the first timer()
call via glutTimerFunc(0, timer, 0)
.
glRotatef(angleCube, i.0f, i.0f, ane.0f);
......
glRotatef(anglePyramid, i.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 project, 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 away.
To utilize 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)height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width >= top) { glOrtho(-3.0 * attribute, 3.0 * aspect, -3.0, 3.0, 0.1, 100); } else { glOrtho(-3.0, 3.0, -iii.0 / attribute, 3.0 / aspect, 0.1, 100); } }
In this example, we fix the cantankerous-department 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-volume.
Instance four: Vertex Array
In the earlier example, cartoon a cube requires at least 24 glVertex
functions and a pair of glBegin
and glEnd
. Office calls may involve high overhead and hinder the performance. Furthermore, each vertex is specified and candy three times.
Link to OpenGL/Calculator Graphics References and Resources
Source: https://www3.ntu.edu.sg/home/ehchua/programming/opengl/CG_Examples.html
0 Response to "drawing image over 3d world opengl"
Post a Comment