Tuesday, March 17, 2015

Sample OpenGL Program



1:  #include<stdio.h>  
2:  #include<GL/glut.h>  
3:  void myInit()  
4:  {  
5:     glClearColor(1.0, 1.0, 1.0, 1.0);  
6:     glColor3f(1.0, 0.0, 0.0);  
7:     glMatrixMode(GL_PROJECTION);  
8:     glLoadIdentity();  
9:     gluOrtho2D(0.0, 10.0, 0.0, 10.0);  
10:    glMatrixMode(GL_MODELVIEW);  
11:  }  
12:  void display()  
13:  {  
14:     glClear(GL_COLOR_BUFFER_BIT);  
15:     glBegin(GL_LINES);  
16:      glVertex2f(1.0, 1.0);  
17:      glVertex2f(9.0, 9.0);  
18:     glEnd();  
19:     glFlush();  
20:  }  
21:  int main(int argc, char **argv)  
22:  {  
23:    glutInit(&argc, argv);  
24:    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);  
25:    glutInitWindowSize(400, 300);  
26:    glutInitWindowPosition(100, 100);  
27:    glutCreateWindow("My First Example");  
28:    glutDisplayFunc(display);  
29:    myInit();  
30:    glutMainLoop();  
31:    return 0;  
32:  }  

This program draws line between two points (1,1) and (9,9) 

Output:


Line 2 includes header file glut.h present in GL folder. Inclusion of glut.h is mandatory as it contains function declarations that are necessary for compilation. Functions available under glut.h can internally call glu.h and gl.h headers. gl.h is a core header file which provides core functionality features for OpenGL. Functions available in glu.h file internally call functions from gl.h header. Functions starting with glut keyword belong to glut.h header file; similar statements can be made for functions belonging to glu.h and gl.h header files. All function names of OpenGL use Camel Casing convention except for the first keyword.

Let's analyze the code from main() function:

Line 23 specifies glutInit() function[this function belongs to glut.h header, as it starts with keyword glut]. This function specifies the interaction between the window system and OpenGL.

Line 24 specifies the usage of RGB coloring mode and usage of SINGLE buffered display. We can also specify DOUBLE, that specifies double buffered display.

Line 25 specifies width and height of the window as 400 and 300 pixels respectively.

Line 26 positions the window in (100, 100) measured from IV-quadrant.

Line 27 gives the name for the window.

Line 28 registers a display callback function myDisplay(), that is invoked automatically whenever there is a need for window refresh.

Line 30 enters the GLUT event processing loop. This routine is called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.

Now let's focus our attention on myInit() function:

Line 5 specifies the background color for the window. First three arguments specify the normalized intensity values for RED, GREEN and BLUE colors. Fourth argument specifies ALPHA value, that sets the transparency for the window. To use the fourth argument, BLENDING has to be enabled. In this example, solid window with white color is rendered.

Line 6 specifies the color of the primitives in RGB values. In this example, primitives are drawn with red color. Note that color is an attribute of the primitive and is part of OpenGL state. This means that once the attribute is set, it will be active throughout program execution.

Line 7 changes the matrix from MODELVIEW to PROJECTION. OpenGL supports two types of matrices of order 4X4 (also called as homogeneous coordinate system matrices). MODELVIEW matrix specifies transformation of primitives as well as positioning and orienting the camera. PROJECTION matrix specifies the type of projection (parallel or perspective).

Line 8 loads 4X4 identity matrix to PROJECTION matrix.

Line 9 specifies that the program is using orthographic projection (a type of parallel projection) and also specifies the area of 2D view rectangle. First and third argument values specify (left, bottom) point and second and fourth argument values specify (right, top) point of the view rectangle. Note that this function internally calls glOrtho() function, which specifies 3D vew volume with (near, far) values as ZERO.

VIEW VOLUME specification using glOrtho()

Line 10 switches back the matrix from PROJECTION to MODELVIEW. Note that it is important to use MODELVIEW matrix for modeling objects, as these specifications are part of MODELVIEW transformations.

Let's briefly discuss myDisplay() function:

Line 14 clears the buffer flag. This function can clear all types of buffer flags supported by OpenGL. In this example, color buffer flag is cleared (reset).

Line 15 draws lines between pair of vertices such that no lines share a common point. Specification of vertices have to be done between glBegin() and glEnd() functions. OpenGL has many options to be passed to glBegin() function:

  • GL_POINTS - each vertex specification is displayed at a size of at-least one pixel (we can change the size of the pixel using glPointSize() function)
  • GL_LINE_STRIP - connects successive vertices to form successive line segments. But this option does not join last vertex with first
  • GL_LINE_LOOP - same as GL_LINE_LOOP but connects last vertex with first and hence forms a line loop
  • GL_POLYGON - the edges are the same as they would be if we used GL_LINE_LOOP; however the interior of the polygon is filled according to the color state (this can to be specified using glColor3f() function)
  • GL_TRIANGLES - successive groups of three vertices are interpreted as triangles
  • GL_QUADS - successive groups of four vertices are interpreted as quadrilaterals
  • GL_TRIANGLE_STRIP - each additional vertex is combined with the previous two vertices to define a new triangle
  • GL_QUAD_STRIP - to new vertices with the previous two vertices are combined to define a new quadrilateral
  • GL_TRIANGLE_FAN - fixes the first vertex and next successive pairs of vertices determine the triangles

glBegin() options

Lines 16-17 specifies two 2D points with the coordinates (1, 1) and (9, 9) [these values are specified in Object Coordinate System].

Line 19 empties all supported buffers of OpenGL (like network buffer, graphics accelerator, etc), causing all issued commands to be executed as quickly as they are accepted by the actual rendering engine. Though this execution may not be completed in any particular time period, it does complete in finite time.


No comments:

Post a Comment