Android Opengl Draw Circle 2d

OpenGL Tutorial

An Introduction on OpenGL with 2D Graphics

Setting Up OpenGL

To set up OpenGL, depending on your programming platform, read:

  • How to write OpenGL programs in C/C++.
  • How to write OpenGL programs in Java: JOGL or LWJGL.
  • How to write OpenGL|ES programs in Android.

Example ane: Setting Upwards OpenGL and Glut (GL01Hello.cpp)

Brand certain that you tin run the "GL01Hello.cpp" described in "How to write OpenGL programs in C/C++", reproduced below:

1 2 3 4 5 vi seven viii 9 10 xi 12 xiii 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
                    #include <windows.h>   #include <GL/glut.h>      void brandish() {    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);     glClear(GL_COLOR_BUFFER_BIT);                   glBegin(GL_QUADS);                     glColor3f(i.0f, 0.0f, 0.0f);        glVertex2f(-0.5f, -0.5f);           glVertex2f( 0.5f, -0.5f);       glVertex2f( 0.5f,  0.5f);       glVertex2f(-0.5f,  0.5f);    glEnd();      glFlush();   }    int principal(int argc, char** argv) {    glutInit(&argc, argv);                     glutCreateWindow("OpenGL Setup Test");     glutInitWindowSize(320, 320);       glutInitWindowPosition(fifty, 50);     glutDisplayFunc(brandish);     glutMainLoop();               return 0; }
#include <windows.h>

The header "windows.h" is needed for the Windows platform only.

#include <GL/overabundance.h>

We also included the GLUT header, which is guaranteed to include "glu.h" (for GL Utility) and "gl.h" (for Core OpenGL).

The rest of the program will be explained in due grade.

Introduction

OpenGL (Open Graphics Library) is a cross-platform, hardware-accelerated, linguistic communication-independent, industrial standard API for producing 3D (including 2D) graphics. Modern computers have dedicated GPU (Graphics Processing Unit) with its own memory to speed upwards graphics rendering. OpenGL is the software interface to graphics hardware. In other words, OpenGL graphic rendering commands issued by your applications could be directed to the graphic hardware and accelerated.

We employ 3 sets of libraries in our OpenGL programs:

  1. Cadre OpenGL (GL): consists of hundreds of commands, which begin with a prefix "gl" (eastward.g., glColor, glVertex, glTranslate, glRotate). The Core OpenGL models an object via a set of geometric primitives such as point, line and polygon.
  2. OpenGL Utility Library (GLU): built on-top of the core OpenGL to provide important utilities (such as setting photographic camera view and projection) and more edifice models (such equally qradric surfaces and polygon tessellation). GLU commands starting time with a prefix "glu" (e.g., gluLookAt, gluPerspective).
  3. OpenGL Utilities Toolkit (Glut): OpenGL is designed to be contained of the windowing system or operating system. Overabundance is needed to interact with the Operating System (such equally creating a window, handling key and mouse inputs); it too provides more building models (such as sphere and torus). GLUT commands start with a prefix of "glut" (e.g., glutCreatewindow, glutMouseFunc). Overabundance is platform contained, which is built on superlative of platform-specific OpenGL extension such as GLX for X Window System, WGL for Microsoft Window, and AGL, CGL or Cocoa for Mac Os.
    Quoting from the opengl.org: "GLUT is designed for constructing minor to medium sized OpenGL programs. While Glut is well-suited to learning OpenGL and developing simple OpenGL applications, GLUT is non a total-featured toolkit so large applications requiring sophisticated user interfaces are better off using native window system toolkits. GLUT is unproblematic, easy, and small."
    Alternative of Overabundance includes SDL, ....
  4. OpenGL Extension Wrangler Library (GLEW): "GLEW is a cross-platform open-source C/C++ extension loading library. GLEW provides efficient run-fourth dimension mechanisms for determining which OpenGL extensions are supported on the target platform." Source and pre-build binary available at http://glew.sourceforge.cyberspace/. A standalone utility chosen "glewinfo.exe" (under the "bin" directory) can exist used to produce the list of OpenGL functions supported by your graphics organization.
  5. Others.

Vertex, Primitive and Color

Example 2: Vertex, Primitive and Color (GL02Primitive.cpp)

Try edifice and runnng this OpenGL C/C++ plan:

ane 2 3 four 5 6 7 eight 9 x 11 12 thirteen 14 15 sixteen 17 xviii 19 20 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 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 fourscore
                    #include <windows.h>   #include <GL/glut.h>      void initGL() {        glClearColor(0.0f, 0.0f, 0.0f, i.0f);  }    void display() {    glClear(GL_COLOR_BUFFER_BIT);             glBegin(GL_QUADS);                     glColor3f(1.0f, 0.0f, 0.0f);        glVertex2f(-0.8f, 0.1f);            glVertex2f(-0.2f, 0.1f);            glVertex2f(-0.2f, 0.7f);       glVertex2f(-0.8f, 0.7f);         glColor3f(0.0f, i.0f, 0.0f);        glVertex2f(-0.7f, -0.6f);       glVertex2f(-0.1f, -0.6f);       glVertex2f(-0.1f,  0.0f);       glVertex2f(-0.7f,  0.0f);         glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f(-0.9f, -0.7f);       glColor3f(i.0f, 1.0f, one.0f);        glVertex2f(-0.5f, -0.7f);       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f(-0.5f, -0.3f);       glColor3f(one.0f, 1.0f, one.0f);        glVertex2f(-0.9f, -0.3f);    glEnd();      glBegin(GL_TRIANGLES);                 glColor3f(0.0f, 0.0f, one.0f);        glVertex2f(0.1f, -0.6f);       glVertex2f(0.7f, -0.6f);       glVertex2f(0.4f, -0.1f);         glColor3f(1.0f, 0.0f, 0.0f);        glVertex2f(0.3f, -0.4f);       glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f(0.9f, -0.4f);       glColor3f(0.0f, 0.0f, one.0f);        glVertex2f(0.6f, -0.9f);    glEnd();      glBegin(GL_POLYGON);                   glColor3f(i.0f, 1.0f, 0.0f);        glVertex2f(0.4f, 0.2f);       glVertex2f(0.6f, 0.2f);       glVertex2f(0.7f, 0.4f);       glVertex2f(0.6f, 0.6f);       glVertex2f(0.4f, 0.6f);       glVertex2f(0.3f, 0.4f);    glEnd();      glFlush();   }    int primary(int argc, char** argv) {    glutInit(&argc, argv);              glutCreateWindow("Vertex, Primitive & Color");      glutInitWindowSize(320, 320);       glutInitWindowPosition(50, l);     glutDisplayFunc(display);           initGL();                           glutMainLoop();                     return 0; }

The expected output and the coordinates are as follows. Have notation that iv shapes accept pure color, and two shapes have color blending from their vertices.

I shall explain the program in the following sections.

OpenGL as a State Machine

OpenGL operates equally a state motorcar, and maintain a set of country variables (such as the foreground color, background colour, and many more). In a land car, once the value of a state variable is set, the value persists until a new value is given.

For case, we set the "clearing" (background) colour to blackness in one case in initGL(). We utilize this setting to clear the window in the brandish() repeatedly (brandish() is called back whenever there is a window re-paint request) - the immigration color is non inverse in the entire plan.

            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);      glClear(GL_COLOR_BUFFER_BIT);

Another instance: If we employ glColor function to set the current foreground color to "ruby-red", then "red" will be used for all the subsequent vertices, until we apply some other glColor function to change the foreground color.

In a state auto, everything shall remain until you explicitly change information technology!

Naming Convention for OpenGL Functions

An OpenGL functions:

  • begins with lowercase gl (for core OpenGL), glu (for OpenGL Utility) or overabundance (for OpenGL Utility Toolkit).
  • followed by the purpose of the function, in camel case (initial-capitalized), e.chiliad., glColor to specify the cartoon colour, glVertex to define the position of a vertex.
  • followed past specifications for the parameters, east.chiliad., glColor3f takes iii bladder parameters. glVectex2i takes ii int parameters.
    (This is needed as C Linguistic communication does not back up function overloading. Different versions of the role need to be written for dissimilar parameter lists.)

The convention tin can be expressed as follows:

          returnType          glFunction[234][sifd]          (type value, ...);            returnType          glFunction[234][sifd]v          (type          *value);        

The function may take ii, 3, or 4 parameters, in type of s (GLshort), i (GLint), f (GLfloat) or d (GLdouble). The '5' (for vector) denotes that the parameters are kept in an array of two, 3, or iv elements, and pass into the function equally an array arrow.

OpenGL defines its own data types:

  • Signed Integers: GLbyte (8-bit), GLshort (sixteen-bit), GLint (32-fleck).
  • Unsigned Integers: GLubyte (viii-fleck), GLushort (16-bit), GLuint (32-scrap).
  • Floating-indicate numbers: GLfloat (32-bit), GLdouble (64-fleck), GLclampf and GLclampd (betwixt 0.0 and 1.0).
  • GLboolean (unsigned char with 0 for fake and non-0 for true).
  • GLsizei (32-bit non-negative integers).
  • GLenum (32-bit enumerated integers).

The OpenGL types are divers via typedef in "gl.h" as follows:

typedef unsigned int    GLenum; typedef unsigned char   GLboolean; typedef unsigned int    GLbitfield; typedef void            GLvoid; typedef signed char     GLbyte;          typedef short           GLshort;         typedef int             GLint;           typedef unsigned char   GLubyte;         typedef unsigned short  GLushort;        typedef unsigned int    GLuint;          typedef int             GLsizei;         typedef float           GLfloat;         typedef float           GLclampf;        typedef double          GLdouble;        typedef double          GLclampd;        

OpenGL's constants begins with "GL_", "GLU_" or "GLUT_", in capital separated with underscores, e.g., GL_COLOR_BUFFER_BIT.

For examples,

glVertex3f(1.1f, 2.2f, 3.3f);         glVertex2i(4, 5);                     glColor4f(0.0f, 0.0f, 0.0f, 1.0f);      GLdouble aVertex[] = {ane.1, two.two, 3.3}; glVertex3fv(aVertex);        

Former Initialization initGL()

The initGL() is meant for carrying out one-time OpenGL initialization tasks, such as setting the clearing colour. initGL() is invoked once (and simply once) in chief().

Callback Handler display()

The function brandish() is known equally a callback event handler. An consequence handler provides the response to a detail consequence (such as key-printing, mouse-click, window-paint). The function display() is meant to be the handler for window-paint event. The OpenGL graphics system calls back display() in response to a window-paint request to re-paint the window (due east.thousand., window first appears, window is restored after minimized, and window is resized). Callback means that the function is invoked past the organization, instead of called by the your program.

The Display() runs when the window first appears and once per subsequent re-paint asking. Observe that we included OpenGL graphics rendering lawmaking within the display() office, so as to re-draw the unabridged window when the window first appears and upon each re-pigment asking.

Setting up Glut - main()

Overabundance provides high-level utilities to simplify OpenGL programming, especially in interacting with the Operating System (such as creating a window, handling key and mouse inputs). The following GLUT functions were used in the above plan:

  • glutInit: initializes GLUT, must be called before other GL/Overabundance functions. It takes the same arguments as the main().
    void              glutInit(int *argc, char **argv)
  • glutCreateWindow: creates a window with the given title.
    int              glutCreateWindow(char *title)
  • glutInitWindowSize: specifies the initial window width and peak, in pixels.
    void              glutInitWindowSize(int              width, int              height)
  • glutInitWindowPosition: positions the top-left corner of the initial window at (x, y). The coordinates (x, y), in term of pixels, is measured in window coordinates, i.eastward., origin (0, 0) is at the top-left corner of the screen; x-axis pointing right and y-axis pointing down.
    void              glutInitWindowPosition(int              10, int              y)
  • glutDisplayFunc: registers the callback role (or issue handler) for handling window-pigment result. The OpenGL graphic organisation calls back this handler when it receives a window re-paint request. In the example, nosotros register the office display() as the handler.
    void              glutDisplayFunc(void (*func)(void))
  • glutMainLoop: enters the infinite event-processing loop, i.e, put the OpenGL graphics arrangement to expect for events (such every bit re-paint), and trigger corresponding event handlers (such as display()).
    void              glutMainLoop()

In the main() function of the example:

glutInit(&argc, argv); glutCreateWindow("Vertex, Primitive & Color"); glutInitWindowSize(320, 320); glutInitWindowPosition(50, 50);

We initialize the GLUT and create a window with a championship, an initial size and position.

glutDisplayFunc(brandish);

We register display() role equally the callback handler for window-paint result. That is, brandish() runs when the window showtime appears and whenever at that place is a request to re-paint the window.

initGL();

We call the initGL() to perform all the one-fourth dimension initialization operations. In this example, we set up the clearing (groundwork) color in one case, and apply information technology repeatably in the brandish() function.

glutMainLoop();

We so put the plan into the event-handling loop, awaiting for events (such as window-paint request) to trigger off the respective outcome handlers (such as brandish()).

Colour

We use glColor function to set the foreground color, and glClearColor function to set the background (or clearing) color.

void          glColor3f(GLfloat          red, GLfloat          green, GLfloat          blue) void          glColor3fv(GLfloat *colorRGB) void          glColor4f(GLfloat          blood-red, GLfloat          green, GLfloat          bluish, GLfloat          blastoff) void          glColor4fv(GLfloat          *colorRGBA)   void          glClearColor(GLclampf          red, GLclampf          green, GLclampf          bluish, GLclampf          alpha)        

Notes:

  • Colour is typically specified in float in the range 0.0f and 1.0f.
  • Colour can be specified using RGB (Ruby-Green-Blue) or RGBA (Red-Green-Blue-Blastoff) components. The 'A' (or alpha) specifies the transparency (or opacity) index, with value of i denotes opaque (non-transparent and cannot see-thru) and value of 0 denotes total transparent. We shall discuss alpha afterwards.

In the higher up case, we set the background color via glClearColor in initGL(), with R=0, G=0, B=0 (black) and A=1 (opaque and cannot run into through).

            glClearColor(0.0f, 0.0f, 0.0f, ane.0f);        

In brandish(), we fix the vertex color via glColor3f for subsequent vertices. For example, R=one, Grand=0, B=0 (red).

            glColor3f(1.0f, 0.0f, 0.0f);        

Geometric Primitives

In OpenGL, an object is made up of geometric primitives such as triangle, quad, line segment and signal. A primitive is fabricated up of one or more vertices. OpenGL supports the following primitives:

A geometric primitive is defined by specifying its vertices via glVertex function, enclosed inside a pair glBegin and glEnd.

void          glBegin(GLenum          shape)    void          glVertex[234][sifd]          (type          x,          blazon          y,          type          z, ...)    void          glVertex[234][sifd]five          (type          *coords) void          glEnd()

glBegin specifies the type of geometric object, such as GL_POINTS, GL_LINES, GL_QUADS, GL_TRIANGLES, and GL_POLYGON. For types that terminate with 'S', you tin can define multiple objects of the same blazon in each glBegin/glEnd pair. For case, for GL_TRIANGLES, each set of iii glVertex's defines a triangle.

The vertices are normally specified in float precision. Information technology is because integer is not suitable for trigonometric operations (needed to conduct out transformations such every bit rotation). Precision of bladder is sufficient for carrying out intermediate operations, and render the objects finally into pixels on screen (with resolution of says 800x600, integral precision). double precision is often not necessary.

In the in a higher place case:

glBegin(GL_QUADS);     glEnd();

we define 3 color quads (GL_QUADS) with 12x glVertex() functions.

glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(-0.8f, 0.1f); glVertex2f(-0.2f, 0.1f); glVertex2f(-0.2f, 0.7f); glVertex2f(-0.8f, 0.7f);

We fix the color to ruby-red (R=1, Yard=0, B=0). All subsequent vertices will take the color of cerise. Take note that in OpenGL, colour (and many backdrop) is practical to vertices rather than archaic shapes. The color of the a primitive shape is interpolated from its vertices.

We similarly define a 2d quad in greenish.

For the third quad (as follows), the vertices have unlike color. The color of the quad surface is interpolated from its vertices, resulting in a shades of white to night gray, as shown in the output.

glColor3f(0.2f, 0.2f, 0.2f);   glVertex2f(-0.9f, -0.7f); glColor3f(1.0f, one.0f, one.0f);   glVertex2f(-0.5f, -0.7f); glColor3f(0.2f, 0.2f, 0.2f);   glVertex2f(-0.5f, -0.3f); glColor3f(1.0f, one.0f, ane.0f);   glVertex2f(-0.9f, -0.3f);

2nd Coordinate Organization and the Default View

The post-obit diagram shows the OpenGL 2D Coordinate Organisation, which corresponds to the everyday 2d Cartesian coordinates with origin located at the bottom-left corner.

The default OpenGL 2D clipping-area (i.e., what is captured by the camera) is an orthographic view with 10 and y in the range of -1.0 and 1.0, i.e., a 2x2 square with centered at the origin. This clipping-area is mapped to the viewport on the screen. Viewport is measured in pixels.

Written report the in a higher place example to convince yourself that the second shapes created are positioned correctly on the screen.

Clipping-Expanse & Viewport

Try dragging the corner of the window to make it bigger or smaller. Observe that all the shapes are distorted.

We can handle the re-sizing of window via a callback handler reshape(), which can be programmed to adjust the OpenGL clipping-expanse according to the window's aspect ratio.

Clipping Surface area: Clipping area refers to the area that tin exist seen (i.east., captured past the camera), measured in OpenGL coordinates.

The function gluOrtho2D can exist used to set the clipping area of second orthographic view. Objects outside the clipping surface area will be clipped away and cannot be seen.

void          gluOrtho2D(GLdouble          left, GLdouble          right, GLdouble          bottom, GLdouble          top)        

To ready the clipping area, we need to result a series of commands as follows: we showtime select the so-called projection matrix for operation, and reset the project matrix to identity. We and then choose the 2nd orthographic view with the desired clipping area, via gluOrtho2D().

            glMatrixMode(GL_PROJECTION);       glLoadIdentity();                  gluOrtho2D(-1.0, 1.0, -i.0, one.0);        

Viewport: Viewport refers to the display area on the window (screen), which is measured in pixels in screen coordinates (excluding the title bar).

The clipping area is mapped to the viewport. We can use glViewport function to configure the viewport.

void          glViewport(GLint          xTopLeft, GLint          yTopLeft, GLsizei          width, GLsizei          height)

Suppose the the clipping area'south (left, right, lesser, top) is (-1.0, 1.0, -1.0, 1.0) (in OpenGL coordinates) and the viewport's (xTopLeft, xTopRight, width, superlative) is (0, 0, 640, 480) (in screen coordinates in pixels), then the bottom-left corner (-1.0, -1.0) maps to (0, 0) in the viewport, the tiptop-right corner (one.0, 1.0) maps to (639, 479). It is obvious that if the aspect ratios for the clipping surface area and the viewport are not the same, the shapes volition be distorted.

Take note that in the earlier instance, the windows' size of 320x320 has a foursquare shape, with a aspect ratio consistent with the default 2x2 squarish clipping-area.

Case 3: Clipping-area and Viewport (GL03Viewport.cpp)

1 2 iii 4 5 six vii 8 9 10 xi 12 13 14 xv 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 twoscore 41 42 43 44 45 46 47 48 49 fifty 51 52 53 54 55 56 57 58 59 lx 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 ninety 91 92 93 94 95 96 97 98 99 100 101 102
                    #include <windows.h>   #include <GL/glut.h>      void initGL() {        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  }   void display() {    glClear(GL_COLOR_BUFFER_BIT);             glBegin(GL_QUADS);                     glColor3f(1.0f, 0.0f, 0.0f);        glVertex2f(-0.8f, 0.1f);            glVertex2f(-0.2f, 0.1f);            glVertex2f(-0.2f, 0.7f);       glVertex2f(-0.8f, 0.7f);         glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f(-0.7f, -0.6f);       glVertex2f(-0.1f, -0.6f);       glVertex2f(-0.1f,  0.0f);       glVertex2f(-0.7f,  0.0f);         glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f(-0.9f, -0.7f);       glColor3f(1.0f, i.0f, 1.0f);        glVertex2f(-0.5f, -0.7f);       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f(-0.5f, -0.3f);       glColor3f(ane.0f, ane.0f, 1.0f);        glVertex2f(-0.9f, -0.3f);    glEnd();      glBegin(GL_TRIANGLES);                 glColor3f(0.0f, 0.0f, 1.0f);        glVertex2f(0.1f, -0.6f);       glVertex2f(0.7f, -0.6f);       glVertex2f(0.4f, -0.1f);         glColor3f(1.0f, 0.0f, 0.0f);        glVertex2f(0.3f, -0.4f);       glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f(0.9f, -0.4f);       glColor3f(0.0f, 0.0f, 1.0f);        glVertex2f(0.6f, -0.9f);    glEnd();      glBegin(GL_POLYGON);                   glColor3f(1.0f, 1.0f, 0.0f);        glVertex2f(0.4f, 0.2f);       glVertex2f(0.6f, 0.2f);       glVertex2f(0.7f, 0.4f);       glVertex2f(0.6f, 0.6f);       glVertex2f(0.4f, 0.6f);       glVertex2f(0.3f, 0.4f);    glEnd();      glFlush();   }                                      void reshape(GLsizei width, GLsizei elevation) {          if (height == 0) height = 1;                    GLfloat aspect = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, pinnacle);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();                 if (width >= tiptop) {             gluOrtho2D(-1.0 * aspect, 1.0 * attribute, -one.0, 1.0);    } else {             gluOrtho2D(-ane.0, 1.0, -1.0 / aspect, 1.0 / aspect);    } }                   int primary(int argc, char** argv) {    glutInit(&argc, argv);              glutInitWindowSize(640, 480);       glutInitWindowPosition(l, 50);     glutCreateWindow("Viewport Transform");      glutDisplayFunc(display);                         glutReshapeFunc(reshape);                      initGL();                           glutMainLoop();                     render 0; }

A reshape() function, which is called back when the window starting time appears and whenever the window is re-sized, can exist used to ensure consequent aspect ratio between clipping-area and viewport, as shown in the higher up example. The graphics sub-system passes the window'southward width and height, in pixels, into the reshape().

GLfloat aspect = (GLfloat)width / (GLfloat)height;

We compute the attribute ratio of the new re-sized window, given its new width and superlative provided by the graphics sub-system to the callback role reshape().

glViewport(0, 0, width, top);

We set the viewport to cover the entire new re-sized window, in pixels.
Try setting the viewport to embrace only a quarter (lower-correct qradrant) of the window via glViewport(0, 0, width/2, height/2).

glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width >= height) {    gluOrtho2D(-1.0 * aspect, one.0 * attribute, -1.0, 1.0); } else {    gluOrtho2D(-1.0, i.0, -1.0 / aspect, i.0 / aspect); }        

We set the aspect ratio of the clipping surface area to friction match the viewport. To set up the clipping area, we first choose the operate on the projection matrix via glMatrixMode(GL_PROJECTION). OpenGL has two matrices, a projection matrix (which deals with camera projection such equally setting the clipping surface area) and a model-view matrix (for transforming the objects from their local spaces to the common world space). We reset the project matrix via glLoadIdentity().

Finally, we invoke gluOrtho2D() to gear up the clipping area with an aspect ratio matching the viewport. The shorter side has the range from -1 to +i, every bit illustrated below:

We demand to register the reshape() callback handler with GLUT via glutReshapeFunc() in the primary() as follows:

int primary(int argc, char** argv) {    glutInitWindowSize(640, 480);    ......    glutReshapeFunc(reshape); }

In the higher up chief() function, we specify the initial window size to 640x480, which is non-squarish. Attempt re-sizing the window and detect the changes.

Note that the reshape() runs at least once when the window starting time appears. It is then chosen back whenever the window is re-shaped. On the other paw, the initGL() runs one time (and only one time); and the display() runs in response to window re-paint request (e.g., after the window is re-sized).

Translation & Rotation

In the above sample, we positioned each of the shapes by defining their vertices with respective to the aforementioned origin (called globe space). It took me quite a while to effigy out the absolute coordinates of these vertices.

Instead, we could position each of the shapes by defining their vertices with respective to their own center (called model space or local space). We can then utilise translation and/or rotation to position the shapes at the desired locations in the world infinite, as shown in the following revised display() function.

Example 4: Translation and Rotation (GL04ModelTransform.cpp)

1 2 three 4 5 half-dozen vii viii 9 10 11 12 13 fourteen 15 sixteen 17 xviii 19 20 21 22 23 24 25 26 27 28 29 xxx 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 70 71 72 73 74 75 76 77 78 79 fourscore 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
                    #include <windows.h>   #include <GL/glut.h>      void initGL() {        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  }    void brandish() {    glClear(GL_COLOR_BUFFER_BIT);                                          glMatrixMode(GL_MODELVIEW);          glLoadIdentity();                      glTranslatef(-0.5f, 0.4f, 0.0f);     glBegin(GL_QUADS);                      glColor3f(one.0f, 0.0f, 0.0f);         glVertex2f(-0.3f, -0.3f);            glVertex2f( 0.3f, -0.3f);            glVertex2f( 0.3f,  0.3f);       glVertex2f(-0.3f,  0.3f);    glEnd();      glTranslatef(0.1f, -0.7f, 0.0f);     glBegin(GL_QUADS);                      glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f(-0.3f, -0.3f);       glVertex2f( 0.3f, -0.3f);       glVertex2f( 0.3f,  0.3f);       glVertex2f(-0.3f,  0.3f);    glEnd();      glTranslatef(-0.3f, -0.2f, 0.0f);     glBegin(GL_QUADS);                       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f(-0.2f, -0.2f);       glColor3f(1.0f, 1.0f, 1.0f);        glVertex2f( 0.2f, -0.2f);       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f( 0.2f,  0.2f);       glColor3f(1.0f, 1.0f, 1.0f);        glVertex2f(-0.2f,  0.2f);    glEnd();      glTranslatef(i.1f, 0.2f, 0.0f);     glBegin(GL_TRIANGLES);                 glColor3f(0.0f, 0.0f, one.0f);        glVertex2f(-0.3f, -0.2f);       glVertex2f( 0.3f, -0.2f);       glVertex2f( 0.0f,  0.3f);    glEnd();      glTranslatef(0.2f, -0.3f, 0.0f);         glRotatef(180.0f, 0.0f, 0.0f, 1.0f);        glBegin(GL_TRIANGLES);                      glColor3f(1.0f, 0.0f, 0.0f);        glVertex2f(-0.3f, -0.2f);       glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f( 0.3f, -0.2f);       glColor3f(0.0f, 0.0f, ane.0f);        glVertex2f( 0.0f,  0.3f);    glEnd();      glRotatef(-180.0f, 0.0f, 0.0f, one.0f);     glTranslatef(-0.1f, one.0f, 0.0f);          glBegin(GL_POLYGON);                         glColor3f(1.0f, 1.0f, 0.0f);        glVertex2f(-0.1f, -0.2f);       glVertex2f( 0.1f, -0.2f);       glVertex2f( 0.2f,  0.0f);       glVertex2f( 0.1f,  0.2f);       glVertex2f(-0.1f,  0.2f);       glVertex2f(-0.2f,  0.0f);    glEnd();                                    glFlush();    }    void reshape(GLsizei width, GLsizei height) {          if (peak == 0) tiptop = i;                    GLfloat aspect = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, height);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();    if (width >= height) {             gluOrtho2D(-1.0 * attribute, 1.0 * attribute, -1.0, 1.0);    } else {             gluOrtho2D(-1.0, 1.0, -i.0 / attribute, ane.0 / aspect);    } }    int primary(int argc, char** argv) {    glutInit(&argc, argv);              glutInitWindowSize(640, 480);       glutInitWindowPosition(50, 50);     glutCreateWindow("Model Transform");      glutDisplayFunc(display);           glutReshapeFunc(reshape);           initGL();                           glutMainLoop();                     return 0; }
glMatrixMode(GL_MODELVIEW);  glLoadIdentity();        

Translation and rotation are parts of so-called model transform, which transform from the objects from the local infinite (or model space) to the mutual globe space. To carry out model transform, we gear up the matrix mode to mode-view matrix (GL_MODELVIEW) and reset the matrix. (Retrieve that in the previous example, we set the matrix mode to project matrix (GL_PROJECTION) to set the clipping area.)

OpenGL is operating as a land machine. That is, once a state is set, the value of the land persists until it is changed. In other words, once the coordinates are translated or rotated, all the subsequent operations will be based on this coordinates.

Translation is done via glTranslate role:

void          gltranslatef          (GLfloat          x, GLfloat          y, GLfloat          z)        

Take note that glTranslatef function must be placed outside the glBegin/glEnd, where every bit glColor can be placed inside glBegin/glEnd.

Rotation is done via glRotatef office:

void          glRotatef          (GLfloat          angle, GLfloat          x, GLfloat          y, GLfloat          z)        

Have note that the rotational bending is measured in degrees (instead of radians) in OpenGL.

In the above case, nosotros translate within the x-y plane (z=0) and rotate about the z-axis (which is normal to the x-y plane).

Blitheness

Idle Function

To perform animation (e.g., rotating the shapes), you could register an idle() callback handler with Glut, via glutIdleFunc command. The graphic organization will telephone call back the idle() role when there is no other event to be processed.

void glutIdleFunc(void (*func)(void))

In the idle() role, you could issue glutPostRedisplay command to post a window re-paint asking, which in turn will activate display() function.

void idle() {    glutPostRedisplay();    }

Take note that the above is equivalent to registering display() as the idle function.

            glutIdleFunc(display);

Double Buffering

Double buffering uses 2 display buffers to smoothen animation. The side by side screen is prepared in a back buffer, while the current screen is held in a front end buffer. Once the preparation is done, you can use glutSwapBuffer command to bandy the front and dorsum buffers.

To use double buffering, yous need to brand two changes:

  1. In the main(), include this line before creating the window:
    glutInitDisplayMode(GLUT_DOUBLE);            
  2. In the brandish() function, replace glFlush() with glutSwapBuffers(), which swap the front and back buffers.

Double buffering should exist used in blitheness. For static display, single buffering is sufficient. (Many graphics hardware ever double buffered, then it is difficult to run into the differences.)

Example v: Animation using Idle Office (GL05IdleFunc.cpp)

The post-obit program rotates all the shapes created in our previous example using idle office with double buffering.

1 2 3 4 5 six 7 eight 9 ten 11 12 13 fourteen 15 16 17 18 nineteen twenty 21 22 23 24 25 26 27 28 29 xxx 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
                    #include <windows.h>   #include <GL/glut.h>                       GLfloat angle = 0.0f;                                     void initGL() {        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  }                                      void idle() {    glutPostRedisplay();    }                   void display() {    glClear(GL_COLOR_BUFFER_BIT);                                         glMatrixMode(GL_MODELVIEW);         glLoadIdentity();                                                                       glPushMatrix();                         glTranslatef(-0.5f, 0.4f, 0.0f);        glRotatef(angle, 0.0f, 0.0f, ane.0f);                                    glBegin(GL_QUADS);                         glColor3f(1.0f, 0.0f, 0.0f);            glVertex2f(-0.3f, -0.3f);       glVertex2f( 0.3f, -0.3f);       glVertex2f( 0.3f,  0.3f);       glVertex2f(-0.3f,  0.3f);    glEnd();                  glPopMatrix();                            glPushMatrix();                         glTranslatef(-0.4f, -0.3f, 0.0f);       glRotatef(bending, 0.0f, 0.0f, i.0f);                                    glBegin(GL_QUADS);       glColor3f(0.0f, i.0f, 0.0f);        glVertex2f(-0.3f, -0.3f);       glVertex2f( 0.3f, -0.3f);       glVertex2f( 0.3f,  0.3f);       glVertex2f(-0.3f,  0.3f);    glEnd();                  glPopMatrix();                            glPushMatrix();                         glTranslatef(-0.7f, -0.5f, 0.0f);       glRotatef(bending, 0.0f, 0.0f, i.0f);                                    glBegin(GL_QUADS);       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f(-0.2f, -0.2f);       glColor3f(one.0f, 1.0f, 1.0f);        glVertex2f( 0.2f, -0.2f);       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f( 0.2f,  0.2f);       glColor3f(ane.0f, 1.0f, i.0f);        glVertex2f(-0.2f,  0.2f);    glEnd();                  glPopMatrix();                            glPushMatrix();                         glTranslatef(0.4f, -0.3f, 0.0f);        glRotatef(angle, 0.0f, 0.0f, 1.0f);                                    glBegin(GL_TRIANGLES);       glColor3f(0.0f, 0.0f, one.0f);        glVertex2f(-0.3f, -0.2f);       glVertex2f( 0.3f, -0.2f);       glVertex2f( 0.0f,  0.3f);    glEnd();                  glPopMatrix();                            glPushMatrix();                         glTranslatef(0.6f, -0.6f, 0.0f);        glRotatef(180.0f + angle, 0.0f, 0.0f, 1.0f);                                    glBegin(GL_TRIANGLES);       glColor3f(ane.0f, 0.0f, 0.0f);        glVertex2f(-0.3f, -0.2f);       glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f( 0.3f, -0.2f);       glColor3f(0.0f, 0.0f, 1.0f);        glVertex2f( 0.0f,  0.3f);    glEnd();                  glPopMatrix();                            glPushMatrix();                         glTranslatef(0.5f, 0.4f, 0.0f);         glRotatef(bending, 0.0f, 0.0f, 1.0f);                                    glBegin(GL_POLYGON);       glColor3f(1.0f, 1.0f, 0.0f);        glVertex2f(-0.1f, -0.2f);       glVertex2f( 0.1f, -0.2f);       glVertex2f( 0.2f,  0.0f);       glVertex2f( 0.1f,  0.2f);       glVertex2f(-0.1f,  0.2f);       glVertex2f(-0.2f,  0.0f);    glEnd();                  glPopMatrix();                            glutSwapBuffers();             angle += 0.2f;                  }    void reshape(GLsizei width, GLsizei acme) {          if (height == 0) pinnacle = ane;                    GLfloat aspect = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, height);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();    if (width >= meridian) {             gluOrtho2D(-one.0 * attribute, i.0 * attribute, -one.0, 1.0);    } else {             gluOrtho2D(-1.0, 1.0, -1.0 / attribute, i.0 / aspect);    } }    int main(int argc, char** argv) {    glutInit(&argc, argv);                            glutInitDisplayMode(GLUT_DOUBLE);                                    glutInitWindowSize(640, 480);       glutInitWindowPosition(50, l);     glutCreateWindow("Animation via Idle Function");      glutDisplayFunc(display);           glutReshapeFunc(reshape);                         glutIdleFunc(idle);                                    initGL();                           glutMainLoop();                     return 0; }

In the in a higher place example, instead of accumulating all the translations and undoing the rotations, we use glPushMatrix to save the current state, perform transformations, and restore the saved land via glPopMatrix. (In the above instance, nosotros can likewise utilize glLoadIdentity to reset the matrix before the side by side transformations.)

GLfloat angle = 0.0f;        

We define a global variable called bending to keep track of the rotational bending of all the shapes. We will afterwards utilize glRotatef to rotate all the shapes to this angle.

angle += 0.2f;

At the end of each refresh (in brandish()), nosotros update the rotational angle of all the shapes.

glutSwapBuffers();                    glutInitDisplayMode(GLUT_DOUBLE);        

Instead of glFlush() which flushes the framebuffer for brandish immediately, we enable double buffering and employ glutSwapBuffer() to swap the front- and dorsum-buffer during the VSync for smoother display.

void idle() {    glutPostRedisplay();    }   glutIdleFunc(idle);        

We define an idle() function, which posts a re-paint request and invoke display(), if there is no issue outstanding. We annals this idle() function in main() via glutIdleFunc().

Double Buffering & Refresh Rate

When double buffering is enabled, glutSwapBuffers synchronizes with the screen refresh interval (VSync). That is, the buffers will be swapped at the same time when the monitor is putting up a new frame. As the result, idle() office, at best, refreshes the animation at the same rate every bit the refresh rate of the monitor (60Hz for LCD/LED monitor). It may operates at half the monitor refresh rate (if the computations takes more than than 1 refresh interval), 1-third, one-fourth, and so on, because information technology need to wait for the VSync.

Timer Function

With idle(), we have no control to the refresh interval. We could register a Timer() function with GLUT via glutTimerFunc. The Timer() function will be called back at the specified fixed interval.

void glutTimerFunc(unsigned int          millis, void (*func)(int          value),          value)        

Instance 6: Animation via Timer Function (GL06TimerFunc.cpp)

The post-obit modifications rotate all the shapes created in the earlier example counter-clockwise by 2 caste per thirty milliseconds.

1 ii 3 4 five half dozen seven viii 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 xl 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 70 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
                    #include <windows.h>   #include <GL/overabundance.h>      GLfloat angle = 0.0f;   int refreshMills = 30;     void initGL() {        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  }                                      void Timer(int value) {    glutPostRedisplay();          glutTimerFunc(refreshMills, Timer, 0);  }                   void brandish() {    glClear(GL_COLOR_BUFFER_BIT);       glMatrixMode(GL_MODELVIEW);         glLoadIdentity();                     glPushMatrix();                         glTranslatef(-0.5f, 0.4f, 0.0f);        glRotatef(angle, 0.0f, 0.0f, ane.0f);     glBegin(GL_QUADS);                         glColor3f(i.0f, 0.0f, 0.0f);            glVertex2f(-0.3f, -0.3f);       glVertex2f( 0.3f, -0.3f);       glVertex2f( 0.3f,  0.3f);       glVertex2f(-0.3f,  0.3f);    glEnd();    glPopMatrix();                            glPushMatrix();                         glTranslatef(-0.4f, -0.3f, 0.0f);       glRotatef(angle, 0.0f, 0.0f, 1.0f);     glBegin(GL_QUADS);       glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f(-0.3f, -0.3f);       glVertex2f( 0.3f, -0.3f);       glVertex2f( 0.3f,  0.3f);       glVertex2f(-0.3f,  0.3f);    glEnd();    glPopMatrix();                            glPushMatrix();                         glTranslatef(-0.7f, -0.5f, 0.0f);       glRotatef(angle, 0.0f, 0.0f, i.0f);     glBegin(GL_QUADS);       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f(-0.2f, -0.2f);       glColor3f(one.0f, 1.0f, 1.0f);        glVertex2f( 0.2f, -0.2f);       glColor3f(0.2f, 0.2f, 0.2f);        glVertex2f( 0.2f,  0.2f);       glColor3f(ane.0f, 1.0f, 1.0f);        glVertex2f(-0.2f,  0.2f);    glEnd();    glPopMatrix();                            glPushMatrix();                         glTranslatef(0.4f, -0.3f, 0.0f);        glRotatef(angle, 0.0f, 0.0f, 1.0f);     glBegin(GL_TRIANGLES);       glColor3f(0.0f, 0.0f, 1.0f);        glVertex2f(-0.3f, -0.2f);       glVertex2f( 0.3f, -0.2f);       glVertex2f( 0.0f,  0.3f);    glEnd();    glPopMatrix();                            glPushMatrix();                         glTranslatef(0.6f, -0.6f, 0.0f);        glRotatef(180.0f + angle, 0.0f, 0.0f, 1.0f);     glBegin(GL_TRIANGLES);       glColor3f(1.0f, 0.0f, 0.0f);        glVertex2f(-0.3f, -0.2f);       glColor3f(0.0f, 1.0f, 0.0f);        glVertex2f( 0.3f, -0.2f);       glColor3f(0.0f, 0.0f, 1.0f);        glVertex2f( 0.0f,  0.3f);    glEnd();    glPopMatrix();                            glPushMatrix();                         glTranslatef(0.5f, 0.4f, 0.0f);         glRotatef(angle, 0.0f, 0.0f, 1.0f);     glBegin(GL_POLYGON);       glColor3f(one.0f, one.0f, 0.0f);        glVertex2f(-0.1f, -0.2f);       glVertex2f( 0.1f, -0.2f);       glVertex2f( 0.2f,  0.0f);       glVertex2f( 0.1f,  0.2f);       glVertex2f(-0.1f,  0.2f);       glVertex2f(-0.2f,  0.0f);    glEnd();    glPopMatrix();                            glutSwapBuffers();             angle += ii.0f; }    void reshape(GLsizei width, GLsizei meridian) {          if (meridian == 0) elevation = i;                    GLfloat aspect = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, height);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();    if (width >= height) {             gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -i.0, ane.0);    } else {             gluOrtho2D(-1.0, 1.0, -1.0 / attribute, 1.0 / attribute);    } }    int main(int argc, char** argv) {    glutInit(&argc, argv);              glutInitDisplayMode(GLUT_DOUBLE);      glutInitWindowSize(640, 480);       glutInitWindowPosition(l, 50);     glutCreateWindow("Animation via Idle Function");      glutDisplayFunc(brandish);           glutReshapeFunc(reshape);                         glutTimerFunc(0, Timer, 0);                      initGL();                           glutMainLoop();                     return 0; }
void Timer(int value) {    glutPostRedisplay();                       glutTimerFunc(refreshMills, Timer, 0);  }

We replace the idle() part past a timer() function, which mail service a re-pigment request to invoke brandish(), afterward the timer expired.

glutTimerFunc(0, Timer, 0);        

In primary(), we register the timer() function, and actuate the timer() immediately (with initial timer = 0).

More GLUT functions

  • glutInitDisplayMode: requests a display with the specified mode, such as color mode (GLUT_RGB, GLUT_RGBA, GLUT_INDEX), single/double buffering (GLUT_SINGLE, GLUT_DOUBLE), enable depth (GLUT_DEPTH), joined with a bit OR '|'.
    void glutInitDisplayMode(unsigned int              displayMode)

    For case,

    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);            

Case 7: A Bouncing Ball (GL07BouncingBall.cpp)

This case shows a ball bouncing within the window. Accept note that circle is non a primitive geometric shape in OpenGL. This example uses TRIANGLE_FAN to compose a circle.

1 2 3 4 5 6 seven 8 9 10 11 12 thirteen 14 15 16 17 18 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 70 71 72 73 74 75 76 77 78 79 eighty 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
                    #include <windows.h>   #include <GL/overabundance.h>   #include <Math.h>      #ascertain PI three.14159265f    char title[] = "Bouncing Ball (2D)";   int windowWidth  = 640;      int windowHeight = 480;      int windowPosX   = fifty;       int windowPosY   = 50;         GLfloat ballRadius = 0.5f;    GLfloat ballX = 0.0f;          GLfloat ballY = 0.0f; GLfloat ballXMax, ballXMin, ballYMax, ballYMin;  GLfloat xSpeed = 0.02f;       GLfloat ySpeed = 0.007f; int refreshMillis = 30;          GLdouble clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop;    void initGL() {    glClearColor(0.0, 0.0, 0.0, i.0);  }    void brandish() {    glClear(GL_COLOR_BUFFER_BIT);      glMatrixMode(GL_MODELVIEW);        glLoadIdentity();                    glTranslatef(ballX, ballY, 0.0f);          glBegin(GL_TRIANGLE_FAN);       glColor3f(0.0f, 0.0f, one.0f);         glVertex2f(0.0f, 0.0f);              int numSegments = 100;       GLfloat angle;       for (int i = 0; i <= numSegments; i++) {           angle = i * ii.0f * PI / numSegments;            glVertex2f(cos(angle) * ballRadius, sin(bending) * ballRadius);       }    glEnd();      glutSwapBuffers();            ballX += xSpeed;    ballY += ySpeed;        if (ballX > ballXMax) {       ballX = ballXMax;       xSpeed = -xSpeed;    } else if (ballX < ballXMin) {       ballX = ballXMin;       xSpeed = -xSpeed;    }    if (ballY > ballYMax) {       ballY = ballYMax;       ySpeed = -ySpeed;    } else if (ballY < ballYMin) {       ballY = ballYMin;       ySpeed = -ySpeed;    } }    void reshape(GLsizei width, GLsizei acme) {        if (meridian == 0) tiptop = one;                    GLfloat aspect = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, top);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();                 if (width >= elevation) {       clipAreaXLeft   = -one.0 * attribute;       clipAreaXRight  = one.0 * aspect;       clipAreaYBottom = -1.0;       clipAreaYTop    = 1.0;    } else {       clipAreaXLeft   = -i.0;       clipAreaXRight  = 1.0;       clipAreaYBottom = -i.0 / aspect;       clipAreaYTop    = 1.0 / aspect;    }    gluOrtho2D(clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop);    ballXMin = clipAreaXLeft + ballRadius;    ballXMax = clipAreaXRight - ballRadius;    ballYMin = clipAreaYBottom + ballRadius;    ballYMax = clipAreaYTop - ballRadius; }    void Timer(int value) {    glutPostRedisplay();        glutTimerFunc(refreshMillis, Timer, 0);  }    int main(int argc, char** argv) {    glutInit(&argc, argv);                glutInitDisplayMode(GLUT_DOUBLE);     glutInitWindowSize(windowWidth, windowHeight);      glutInitWindowPosition(windowPosX, windowPosY);     glutCreateWindow(championship);          glutDisplayFunc(display);         glutReshapeFunc(reshape);         glutTimerFunc(0, Timer, 0);       initGL();                         glutMainLoop();                   return 0; }

[TODO] Explanation

Handling Keyboard Inputs with GLUT

We can register callback functions to handle keyboard inputs for normal and special keys, respectively.

  • glutKeyboardFunc: registers callback handler for keyboard event.
    void              glutKeyboardFunc              (void (*func)(unsigned char              key, int              x, int              y)            
  • glutSpecialFunc: registers callback handler for special key (such every bit arrow keys and office keys).
    void              glutSpecialFunc              (void (*func)(int              specialKey, int              x, int              y)            

Example 8: Switching between Total-Screen and Windowed-mode (GL08FullScreen.cpp)

For the billowy ball program, the following special-key handler toggles between full-screen and windowed modes using F1 fundamental.

i ii 3 4 5 half dozen vii 8 nine 10 eleven 12 thirteen fourteen 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 l 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 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>   #include <Math.h>      #ascertain PI 3.14159265f    char championship[] = "Full-Screen & Windowed Manner";   int windowWidth  = 640;      int windowHeight = 480;      int windowPosX   = fifty;       int windowPosY   = l;         GLfloat ballRadius = 0.5f;    GLfloat ballX = 0.0f;          GLfloat ballY = 0.0f; GLfloat ballXMax, ballXMin, ballYMax, ballYMin;  GLfloat xSpeed = 0.02f;       GLfloat ySpeed = 0.007f; int refreshMillis = 30;          GLdouble clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop;                  bool fullScreenMode = true;                                     void initGL() {    glClearColor(0.0, 0.0, 0.0, 1.0);  }    void display() {    glClear(GL_COLOR_BUFFER_BIT);      glMatrixMode(GL_MODELVIEW);        glLoadIdentity();                    glTranslatef(ballX, ballY, 0.0f);          glBegin(GL_TRIANGLE_FAN);       glColor3f(0.0f, 0.0f, 1.0f);         glVertex2f(0.0f, 0.0f);              int numSegments = 100;       GLfloat angle;       for (int i = 0; i <= numSegments; i++) {           angle = i * 2.0f * PI / numSegments;            glVertex2f(cos(angle) * ballRadius, sin(angle) * ballRadius);       }    glEnd();      glutSwapBuffers();            ballX += xSpeed;    ballY += ySpeed;        if (ballX > ballXMax) {       ballX = ballXMax;       xSpeed = -xSpeed;    } else if (ballX < ballXMin) {       ballX = ballXMin;       xSpeed = -xSpeed;    }    if (ballY > ballYMax) {       ballY = ballYMax;       ySpeed = -ySpeed;    } else if (ballY < ballYMin) {       ballY = ballYMin;       ySpeed = -ySpeed;    } }    void reshape(GLsizei width, GLsizei height) {        if (summit == 0) height = i;                    GLfloat attribute = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, summit);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();                 if (width >= height) {       clipAreaXLeft   = -1.0 * aspect;       clipAreaXRight  = 1.0 * aspect;       clipAreaYBottom = -one.0;       clipAreaYTop    = 1.0;    } else {       clipAreaXLeft   = -one.0;       clipAreaXRight  = 1.0;       clipAreaYBottom = -i.0 / attribute;       clipAreaYTop    = 1.0 / attribute;    }    gluOrtho2D(clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop);    ballXMin = clipAreaXLeft + ballRadius;    ballXMax = clipAreaXRight - ballRadius;    ballYMin = clipAreaYBottom + ballRadius;    ballYMax = clipAreaYTop - ballRadius; }    void Timer(int value) {    glutPostRedisplay();        glutTimerFunc(refreshMillis, Timer, 0);  }                                      void specialKeys(int central, int ten, int y) {    switch (key) {       case GLUT_KEY_F1:              fullScreenMode = !fullScreenMode;                   if (fullScreenMode) {                                  windowPosX   = glutGet(GLUT_WINDOW_X);              windowPosY   = glutGet(GLUT_WINDOW_Y);             windowWidth  = glutGet(GLUT_WINDOW_WIDTH);             windowHeight = glutGet(GLUT_WINDOW_HEIGHT);             glutFullScreen();                                } else {                                                      glutReshapeWindow(windowWidth, windowHeight);              glutPositionWindow(windowPosX, windowPosX);             }          break;    } }                                     int chief(int argc, char** argv) {    glutInit(&argc, argv);                glutInitDisplayMode(GLUT_DOUBLE);     glutInitWindowSize(windowWidth, windowHeight);      glutInitWindowPosition(windowPosX, windowPosY);     glutCreateWindow(title);          glutDisplayFunc(display);         glutReshapeFunc(reshape);         glutTimerFunc(0, Timer, 0);                                         glutSpecialFunc(specialKeys);     glutFullScreen();                                                 initGL();                         glutMainLoop();                   render 0; }

[TODO] Explanation

[TODO] Using glVertex to draw a Circle is inefficient (due to the compute-intensive sin() and cos() functions). Attempt using GLU'south quadric.

Example nine: Key-Controlled (GL09KeyControl.cpp)

For the bouncing ball program, the following key and special-cardinal handlers provide exits with ESC (27), increment/subtract y speed with up-/downwardly-arrow central, increase/subtract x speed with left-/right-arrow central, increment/decrease ball's radius with PageUp/PageDown fundamental.

1 2 3 4 5 six seven 8 9 10 11 12 13 14 xv 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 fifty 51 52 53 54 55 56 57 58 59 threescore 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 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
                    #include <windows.h>   #include <GL/glut.h>   #include <Math.h>      #define PI 3.14159265f    char championship[] = "Total-Screen & Windowed Fashion";   int windowWidth  = 640;      int windowHeight = 480;      int windowPosX   = l;       int windowPosY   = 50;         GLfloat ballRadius = 0.5f;    GLfloat ballX = 0.0f;         GLfloat ballY = 0.0f; GLfloat ballXMax, ballXMin, ballYMax, ballYMin;  GLfloat xSpeed = 0.02f;       GLfloat ySpeed = 0.007f; int refreshMillis = thirty;          GLdouble clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop;   bool fullScreenMode = true;     void initGL() {    glClearColor(0.0, 0.0, 0.0, 1.0);  }    void display() {    glClear(GL_COLOR_BUFFER_BIT);      glMatrixMode(GL_MODELVIEW);        glLoadIdentity();                    glTranslatef(ballX, ballY, 0.0f);          glBegin(GL_TRIANGLE_FAN);       glColor3f(0.0f, 0.0f, 1.0f);         glVertex2f(0.0f, 0.0f);              int numSegments = 100;       GLfloat angle;       for (int i = 0; i <= numSegments; i++) {           angle = i * 2.0f * PI / numSegments;            glVertex2f(cos(bending) * ballRadius, sin(angle) * ballRadius);       }    glEnd();      glutSwapBuffers();            ballX += xSpeed;    ballY += ySpeed;        if (ballX > ballXMax) {       ballX = ballXMax;       xSpeed = -xSpeed;    } else if (ballX < ballXMin) {       ballX = ballXMin;       xSpeed = -xSpeed;    }    if (ballY > ballYMax) {       ballY = ballYMax;       ySpeed = -ySpeed;    } else if (ballY < ballYMin) {       ballY = ballYMin;       ySpeed = -ySpeed;    } }    void reshape(GLsizei width, GLsizei height) {        if (height == 0) elevation = 1;                    GLfloat aspect = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, height);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();                 if (width >= meridian) {       clipAreaXLeft   = -1.0 * aspect;       clipAreaXRight  = 1.0 * aspect;       clipAreaYBottom = -1.0;       clipAreaYTop    = i.0;    } else {       clipAreaXLeft   = -1.0;       clipAreaXRight  = i.0;       clipAreaYBottom = -1.0 / aspect;       clipAreaYTop    = 1.0 / aspect;    }    gluOrtho2D(clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop);    ballXMin = clipAreaXLeft + ballRadius;    ballXMax = clipAreaXRight - ballRadius;    ballYMin = clipAreaYBottom + ballRadius;    ballYMax = clipAreaYTop - ballRadius; }    void Timer(int value) {    glutPostRedisplay();        glutTimerFunc(refreshMillis, Timer, 0);  }                                      void keyboard(unsigned char cardinal, int 10, int y) {    switch (cardinal) {       case 27:               exit(0);          interruption;    } }    void specialKeys(int key, int x, int y) {    switch (cardinal) {       case GLUT_KEY_F1:              fullScreenMode = !fullScreenMode;                   if (fullScreenMode) {                                  windowPosX   = glutGet(GLUT_WINDOW_X);              windowPosY   = glutGet(GLUT_WINDOW_Y);             windowWidth  = glutGet(GLUT_WINDOW_WIDTH);             windowHeight = glutGet(GLUT_WINDOW_HEIGHT);             glutFullScreen();                                } else {                                                      glutReshapeWindow(windowWidth, windowHeight);              glutPositionWindow(windowPosX, windowPosX);             }          intermission;       case GLUT_KEY_RIGHT:              xSpeed *= 1.05f; break;       case GLUT_KEY_LEFT:               xSpeed *= 0.95f; pause;       case GLUT_KEY_UP:                 ySpeed *= i.05f; break;       case GLUT_KEY_DOWN:               ySpeed *= 0.95f; interruption;       instance GLUT_KEY_PAGE_UP:            ballRadius *= 1.05f;          ballXMin = clipAreaXLeft + ballRadius;          ballXMax = clipAreaXRight - ballRadius;          ballYMin = clipAreaYBottom + ballRadius;          ballYMax = clipAreaYTop - ballRadius;          break;       case GLUT_KEY_PAGE_DOWN:           ballRadius *= 0.95f;          ballXMin = clipAreaXLeft + ballRadius;          ballXMax = clipAreaXRight - ballRadius;          ballYMin = clipAreaYBottom + ballRadius;          ballYMax = clipAreaYTop - ballRadius;          break;    } }                                     int main(int argc, char** argv) {    glutInit(&argc, argv);                glutInitDisplayMode(GLUT_DOUBLE);     glutInitWindowSize(windowWidth, windowHeight);      glutInitWindowPosition(windowPosX, windowPosY);     glutCreateWindow(title);          glutDisplayFunc(display);         glutReshapeFunc(reshape);         glutTimerFunc(0, Timer, 0);       glutSpecialFunc(specialKeys);     glutKeyboardFunc(keyboard);                  
glutFullScreen(); initGL(); glutMainLoop(); render 0; }

[TODO] Explanation

Handling Mouse Inputs with Overabundance

Similarly, we can annals callback office to handle mouse-click and mouse-motion.

  • glutMouseFunc: registers callback handler for mouse click.
    void glutMouseFunc(void (*func)(int              button, int              state, int              x, int              y)            
  • glutMotionFunc: registers callback handler for mouse motility (when the mouse is clicked and moved).
    void glutMotionFunc(void (*func)(int              10, int              y)            

Case 10: Mouse-Controlled (GL10MouseControl.cpp)

For the bouncing ball program, the post-obit mouse handler pause the motion with left-mouse click, and resume with right-mouse click.

1 2 iii iv 5 6 vii 8 9 10 11 12 thirteen 14 xv sixteen 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 l 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 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 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
                    #include <windows.h>   #include <GL/glut.h>   #include <Math.h>      #define PI iii.14159265f    char title[] = "Full-Screen & Windowed Mode";   int windowWidth  = 640;      int windowHeight = 480;      int windowPosX   = 50;       int windowPosY   = 50;         GLfloat ballRadius = 0.5f;    GLfloat ballX = 0.0f;         GLfloat ballY = 0.0f; GLfloat ballXMax, ballXMin, ballYMax, ballYMin;  GLfloat xSpeed = 0.02f;       GLfloat ySpeed = 0.007f; int refreshMillis = 30;          GLdouble clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop;   bool fullScreenMode = true;                   bool paused = faux;          GLfloat xSpeedSaved, ySpeedSaved;                                     void initGL() {    glClearColor(0.0, 0.0, 0.0, i.0);  }    void display() {    glClear(GL_COLOR_BUFFER_BIT);      glMatrixMode(GL_MODELVIEW);        glLoadIdentity();                    glTranslatef(ballX, ballY, 0.0f);          glBegin(GL_TRIANGLE_FAN);       glColor3f(0.0f, 0.0f, 1.0f);         glVertex2f(0.0f, 0.0f);              int numSegments = 100;       GLfloat bending;       for (int i = 0; i <= numSegments; i++) {           bending = i * 2.0f * PI / numSegments;            glVertex2f(cos(angle) * ballRadius, sin(angle) * ballRadius);       }    glEnd();      glutSwapBuffers();            ballX += xSpeed;    ballY += ySpeed;        if (ballX > ballXMax) {       ballX = ballXMax;       xSpeed = -xSpeed;    } else if (ballX < ballXMin) {       ballX = ballXMin;       xSpeed = -xSpeed;    }    if (ballY > ballYMax) {       ballY = ballYMax;       ySpeed = -ySpeed;    } else if (ballY < ballYMin) {       ballY = ballYMin;       ySpeed = -ySpeed;    } }    void reshape(GLsizei width, GLsizei superlative) {        if (elevation == 0) meridian = one;                    GLfloat aspect = (GLfloat)width / (GLfloat)height;          glViewport(0, 0, width, height);          glMatrixMode(GL_PROJECTION);      glLoadIdentity();                 if (width >= summit) {       clipAreaXLeft   = -1.0 * aspect;       clipAreaXRight  = ane.0 * attribute;       clipAreaYBottom = -1.0;       clipAreaYTop    = ane.0;    } else {       clipAreaXLeft   = -1.0;       clipAreaXRight  = ane.0;       clipAreaYBottom = -one.0 / attribute;       clipAreaYTop    = 1.0 / attribute;    }    gluOrtho2D(clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop);    ballXMin = clipAreaXLeft + ballRadius;    ballXMax = clipAreaXRight - ballRadius;    ballYMin = clipAreaYBottom + ballRadius;    ballYMax = clipAreaYTop - ballRadius; }    void Timer(int value) {    glutPostRedisplay();        glutTimerFunc(refreshMillis, Timer, 0);  }    void keyboard(unsigned char key, int x, int y) {    switch (central) {       instance 27:               exit(0);          pause;    } }    void specialKeys(int key, int 10, int y) {    switch (key) {       case GLUT_KEY_F1:              fullScreenMode = !fullScreenMode;                   if (fullScreenMode) {                                  windowPosX   = glutGet(GLUT_WINDOW_X);              windowPosY   = glutGet(GLUT_WINDOW_Y);             windowWidth  = glutGet(GLUT_WINDOW_WIDTH);             windowHeight = glutGet(GLUT_WINDOW_HEIGHT);             glutFullScreen();                                } else {                                                      glutReshapeWindow(windowWidth, windowHeight);              glutPositionWindow(windowPosX, windowPosX);             }          break;       case GLUT_KEY_RIGHT:              xSpeed *= one.05f; pause;       case GLUT_KEY_LEFT:               xSpeed *= 0.95f; break;       example GLUT_KEY_UP:                 ySpeed *= one.05f; break;       instance GLUT_KEY_DOWN:               ySpeed *= 0.95f; break;       example GLUT_KEY_PAGE_UP:            ballRadius *= ane.05f;          ballXMin = clipAreaXLeft + ballRadius;          ballXMax = clipAreaXRight - ballRadius;          ballYMin = clipAreaYBottom + ballRadius;          ballYMax = clipAreaYTop - ballRadius;          break;       case GLUT_KEY_PAGE_DOWN:           ballRadius *= 0.95f;          ballXMin = clipAreaXLeft + ballRadius;          ballXMax = clipAreaXRight - ballRadius;          ballYMin = clipAreaYBottom + ballRadius;          ballYMax = clipAreaYTop - ballRadius;          break;    } }                                      void mouse(int button, int land, int ten, int y) {    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {        paused = !paused;                if (paused) {          xSpeedSaved = xSpeed;            ySpeedSaved = ySpeed;          xSpeed = 0;                      ySpeed = 0;       } else {          xSpeed = xSpeedSaved;            ySpeed = ySpeedSaved;       }    } }                   int main(int argc, char** argv) {    glutInit(&argc, argv);                glutInitDisplayMode(GLUT_DOUBLE);     glutInitWindowSize(windowWidth, windowHeight);      glutInitWindowPosition(windowPosX, windowPosY);     glutCreateWindow(title);          glutDisplayFunc(display);         glutReshapeFunc(reshape);         glutTimerFunc(0, Timer, 0);       glutSpecialFunc(specialKeys);     glutKeyboardFunc(keyboard);       glutFullScreen();                               glutMouseFunc(mouse);                                    initGL();                         glutMainLoop();                   render 0; }

[TODO] Explanation

Example 11: A Unproblematic Paint programme

[TODO] Apply mouse-motion and GL_LINE_STRIP.

Link to OpenGL/Computer Graphics References and Resources

bowenappitsed.blogspot.com

Source: https://www3.ntu.edu.sg/home/ehchua/programming/opengl/cg_introduction.html

0 Response to "Android Opengl Draw Circle 2d"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel