Introduction to
OpenGL Programming
What is OpenGL
   OpenGL is a software API to graphics hardware.
       designed as a streamlined, hardware-independent
        interface to be implemented on many different hardware
        platforms
       Intuitive, procedural interface with c binding
       No windowing commands !
       No high-level commands for describing models of three-
        dimensional objects
       The OpenGL Utility Library (GLU) provides many of the
        modeling features, such as quadric surfaces and NURBS
        curves and surfaces
SGI and GL
 Silicon Graphics (SGI) revolutionized the
  graphics workstation by implementing the
  pipeline in hardware (1982)
 To access the system, application
  programmers used a library called GL
 With GL, it was relatively simple to program
  three dimensional interactive applications
OpenGL
The success of GL lead to OpenGL (1992), a
  platform-independent API that was
    Easy to use
    Close enough to the hardware to get excellent
     performance
    Focus on rendering
    Omitted windowing and input to avoid window
     system dependencies
OpenGL Evolution
 Controlled        by an Architectural Review Board
 (ARB)
    Members include SGI, Microsoft, Nvidia, HP,
     3DLabs, IBM,…….
    Relatively stable (present version 2.0)
        Evolution reflects new hardware capabilities
            3D texture mapping and texture objects
            Vertex and fragment programs
    Allows for platform specific features through
     extensions
OpenGL Libraries
   OpenGL core library
     OpenGL32 on Windows

     GL on most unix/linux systems (libGL.a)

   OpenGL Utility Library (GLU)
     Provides functionality in OpenGL core but avoids
       having to rewrite code
   Links with window system
     GLX for X window systems, WGL for Windows

     Cross-platform GUI libraries: GLUT, SDL, FLTK, QT,
       …
Windowing with OpenGL
 OpenGL  is independent of any specific
  window system
 OpenGL can be used with different window
  systems
    X windows (GLX)
    MFC
    …
 GLUTprovide a portable API for creating
 window and interacting with I/O devices
GLUT
   OpenGL Utility Toolkit (GLUT)
     Provides functionality common to all window systems
           Open a window
           Get input from mouse and keyboard
           Menus
           Event-driven
       Code is portable but GLUT lacks the functionality of a
        good toolkit for a specific platform
           No slide bars, buttons, …
Software Organization

                   application program

     OpenGL Motif
    widget or similar     GLUT
               GLX, AGL
                or WGL             GLU

   X, Win32, Mac O/S                     OpenGL

               software and/or hardware
OpenGL Architecture
        Immediate Mode                           geometry
                                                  pipeline
                              Per Vertex
        Polynomial           Operations &
         Evaluator             Primitive
                              Assembly



      Display                                      Per Fragment   Frame
CPU     List
                                 Rasterization
                                                    Operations    Buffer



                                 Texture
                                 Memory
                  Pixel
                Operations
OpenGL as a state machine
   GL State Variables- can be set and queried by OpenGL. Remains
    unchanged until the next change.
       Projection and viewing matrix
       Color and material properties
       Lights and shading
       Line and polygon drawing modes
       …
   OpenGL functions are of two types
       Primitive generating
           Can cause output if primitive is visible
           How vertices are processed and appearance of primitive are controlled by the
            state
       State changing
           Transformation functions
           Attribute functions
OpenGL Syntax
   Functions have prefix gl and initial capital letters for each word
       glClearColor(), glEnable(), glPushMatrix()            …
   glu for GLU functions
       gluLookAt(), gluPerspective()       …
   Constants begin with GL_, use all capital letters
       GL_COLOR_BUFFER_BIT, GL_PROJECTION, GL_MODELVIEW …
   Extra letters in some commands indicate the number and type of
    variables
       glColor3f(), glVertex3f()       …
   OpenGL data types
       GLfloat, GLdouble, GLint, GLenum,         …
   Underlying storage mode is the same
   Easy to create overloaded functions in C++ but issue is efficiency
OpenGL function format
                        function name
                                          dimensions

                glVertex3f(x,y,z)


                              x,y,z are floats
belongs to GL library


         glVertex3fv(p)

                              p is a pointer to an array
OpenGL #defines
 Most
     constants are defined in the include files
 gl.h, glu.h and glut.h
    Note #include <GL/glut.h> should
     automatically include the others
    Examples
    glBegin(GL_POLYGON)
    glClear(GL_COLOR_BUFFER_BIT)
 include
       files also define OpenGL data types:
 GLfloat, GLdouble,….
GLUT
 Developed  by Mark Kilgard
 Hides the complexities of differing window
  system APIs
     Default user interface for class projects
 Glut   routines have prefix glut
     glutCreateWindow() …
 Has  very limited GUI interface
 Glui is the C++ extension of glut
Glut Routines
   Initialization: glutInit() processes (and removes) command-line
    arguments that may be of interest to glut and the window system and
    does general initialization of Glut and OpenGL
       Must be called before any other glut routines
   Display Mode: The next procedure, glutInitDisplayMode(),
    performs initializations informing OpenGL how to set up the frame
    buffer.
       Display Mode         Meaning
       GLUT_RGB             Use RGB colors
       GLUT_RGBA            Use RGB plus alpha (for transparency)
       GLUT_INDEX           Use indexed colors (not recommended)

       GLUT_DOUBLE          Use double buffering (recommended)
       GLUT_SINGLE          Use single buffering (not recommended)

       GLUT_DEPTH           Use depth-buffer (for hidden surface removal.)
Glut Routines
 Window    Setup
    glutInitWindowSize(int width, int height)
    glutInitWindowPosition(int x, int y)
    glutCreateWindow(char* title)
A Simple Program
Generate a square on a solid background
simple.c
 #include <GL/glut.h>
 void mydisplay(){
      glClear(GL_COLOR_BUFFER_BIT);
         glBegin(GL_POLYGON);
                 glVertex2f(-0.5, -0.5);
                 glVertex2f(-0.5, 0.5);
                 glVertex2f(0.5, 0.5);
                 glVertex2f(0.5, -0.5);
         glEnd();
         glFlush();
 }
 int main(int argc, char** argv){
        glutInit(&argc, argv);
        glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
        glutInitWindowSize(500,500);
        glutInitWindowPosition(0,0);
        glutCreateWindow("simple");
        glutDisplayFunc(mydisplay);
        init();
        glutMainLoop();
 }
Closer Look at the main()
 #include <GL/glut.h>                    includes gl.h
 int main(int argc, char** argv)
 {
   glutInit(&argc,argv);
   glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
   glutInitWindowSize(500,500);
   glutInitWindowPosition(0,0);
   glutCreateWindow("simple");
   glutDisplayFunc(mydisplay);   define window     properties

     init();                         display callback
                        set OpenGL state
     glutMainLoop();
 }
                            enter event loop
init.c
                                black clear color
void init()                                opaque window
{
  glClearColor (0.0, 0.0, 0.0, 1.0);

    glColor3f(1.0, 1.0, 1.0);         fill/draw with white

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
}

                                viewing volume
Event Handling
   Virtually all interactive graphics programs are even
    driven
   GLUT uses callbacks to handle events
       Windows system invokes a particular procedure when an
        event of particular type occurs.
       MOST IMPORTANT: display event
         Signaled when window first displays and whenever portions
          of the window reveals from blocking window
         glutDisplayFunc(void (*func)(void)) registers
          the display callback function
   Running the program: glutMainLoop()
       Main event loop. Never exit()
More Callbacks
   glutReshapeFunc(void (*func)(int w, int h)) indicates
    what action should be taken when the window is resized.
   glutKeyboardFunc(void (*func)(unsigned char key, int
    x, int y)) and glutMouseFunc(void (*func)(int button,
    int state, int x, int y)) allow you to link a keyboard key or a
    mouse button with a routine that's invoked when the key or mouse
    button is pressed or released.
   glutMotionFunc(void (*func)(int x, int y)) registers a
    routine to call back when the mouse is moved while a mouse button is
    also pressed.

   glutIdleFunc(void (*func)(void)) registers a function that's to
    be executed if no other events are pending - for example, when the
    event loop would otherwise be idle
Compilation on Windows
  See  class web site on how to set up a project
   with OpenGL
  Visual C++
      Get glut.h, glut32.lib and glut32.dll from web
      Create a console application
      Add opengl32.lib, glut32.lib, glut32.lib to project
       settings (under link tab)
Simple Animation
 Animation
    Redraw + swap buffers
    What looks like if using single buffer
    Example program
 More   on the glut documentation
    Chapter 2 of textbook
    OpenGL redbook
    Links in the class resources page
OpenGL Drawing
   We have learned how to create a window
   Steps in the display function
       Clear the window
       Set drawing attributes
       Send drawing commands
       Swap the buffers
   OpenGL coordinate system has different origin from
    the window system
       Uses lower left corner instead of upper left corner as origin
Clear the Window
 glClear(GL_COLOR_BUFFER_BIT)
    clears the frame buffer by overwriting it with the
     background color.
    Background color is a state set by
     glClearColor(GLfloat r, GLfloat g,
     GLfloat b, GLfloat a) in the init().
Drawing Attributes: Color
   glColor3f(GLfloat r, GLfloat g, GLfloat b)            sets the
    drawing color
       glColor3d(), glColor3ui() can also be used
       Remember OpenGL is a state machine
       Once set, the attribute applies to all subsequent defined
        objects until it is set to some other value
       glColor3fv() takes a flat array as input
   There are more drawing attributes than color
       Point size: glPointSize()
       Line width: glLinewidth()
       Dash or dotted line: glLineStipple()
       Polygon pattern: glPolygonStipple()
       …
Drawing Commands
   Simple Objects glRectf()
   Complex Objects
       Use construct
        glBegin(mode) and
        glEnd() and a list of
        vertices in between
           glBegin(mode)
              glVertex(v0);
               glVertex(v1);
               ...
            glEnd();
   Some other commands can
    also be used between
    glBegin() and glEnd(), e.g.
    glColor3f().
   Example
Projection and Viewport
Orthographic projection
   Orthographic View
       glOrtho(left,
        right, bottom,
        top, front, back)
           Specifies the
            coordinates of 3D
            region to be projected
                                      z=0
            into the image space.
           Any drawing outside the
            region will be
            automatically clipped
            away.
Viewports
 Do not have use the entire window for the
  image: glViewport(x,y,w,h)
 Values in pixels (screen coordinates)
Window to Viewport mapping


Aspect Ratio: Height/Width
If the aspect ratio of the window
Is different from that of the
viewport, the picture will be
distorted.
Sierpinski Gasket (2D)
   Start with a triangle




   Connect bisectors of sides and remove central
    triangle




   Repeat
Example
 Five   subdivisions
Gasket Program
#include <GL/glut.h>
/* initial triangle */
GLfloat v[3][2]={{-1.0, -0.58},
           {1.0, -0.58}, {0.0, 1.15}};
int n; /* number of recursive steps */
void triangle( GLfloat *a, GLfloat *b, GLfloat *c)
/* display one triangle */
{
      glVertex2fv(a);
      glVertex2fv(b);
      glVertex2fv(c);
}
Triangle Subdivision
void divide_triangle(GLfloat *a, GLfloat *b, GLfloat *c, int
    m)
{
/* triangle subdivision using vertex numbers */
     point2 v0, v1, v2;
     int j;
     if(m>0)
       {
         for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2;
         for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2;
         for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2;
         divide_triangle(a, v0, v1, m-1);
         divide_triangle(c, v1, v2, m-1);
         divide_triangle(b, v2, v0, m-1);
     }
     else(triangle(a,b,c));
  /* draw triangle at end of recursion */
}
Gasket Display Functions
void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
    divide_triangle(v[0], v[1], v[2], n);
    glEnd();
    glFlush();
}

•   By having the glBegin and glEnd in the display callback rather
    than in the function triangle and using GL_TRIANGLES rather
    than GL_POLYGON in glBegin, we call glBegin and glEnd
    only once for the entire gasket rather than once for each triangle
Example: 3D Gasket
    after 5 iterations
Tetrahedron Code
void tetrahedron( int m)
{
    glColor3f(1.0,0.0,0.0);
    divide_triangle(v[0], v[1],   v[2], m);
    glColor3f(0.0,1.0,0.0);
    divide_triangle(v[3], v[2],   v[1], m);
    glColor3f(0.0,0.0,1.0);
    divide_triangle(v[0], v[3],   v[1], m);
    glColor3f(0.0,0.0,0.0);
    divide_triangle(v[0], v[2],   v[3], m);
}

Open gl

  • 1.
  • 2.
    What is OpenGL  OpenGL is a software API to graphics hardware.  designed as a streamlined, hardware-independent interface to be implemented on many different hardware platforms  Intuitive, procedural interface with c binding  No windowing commands !  No high-level commands for describing models of three- dimensional objects  The OpenGL Utility Library (GLU) provides many of the modeling features, such as quadric surfaces and NURBS curves and surfaces
  • 3.
    SGI and GL Silicon Graphics (SGI) revolutionized the graphics workstation by implementing the pipeline in hardware (1982)  To access the system, application programmers used a library called GL  With GL, it was relatively simple to program three dimensional interactive applications
  • 4.
    OpenGL The success ofGL lead to OpenGL (1992), a platform-independent API that was  Easy to use  Close enough to the hardware to get excellent performance  Focus on rendering  Omitted windowing and input to avoid window system dependencies
  • 5.
    OpenGL Evolution  Controlled by an Architectural Review Board (ARB)  Members include SGI, Microsoft, Nvidia, HP, 3DLabs, IBM,…….  Relatively stable (present version 2.0)  Evolution reflects new hardware capabilities  3D texture mapping and texture objects  Vertex and fragment programs  Allows for platform specific features through extensions
  • 6.
    OpenGL Libraries  OpenGL core library  OpenGL32 on Windows  GL on most unix/linux systems (libGL.a)  OpenGL Utility Library (GLU)  Provides functionality in OpenGL core but avoids having to rewrite code  Links with window system  GLX for X window systems, WGL for Windows  Cross-platform GUI libraries: GLUT, SDL, FLTK, QT, …
  • 7.
    Windowing with OpenGL OpenGL is independent of any specific window system  OpenGL can be used with different window systems  X windows (GLX)  MFC  …  GLUTprovide a portable API for creating window and interacting with I/O devices
  • 8.
    GLUT  OpenGL Utility Toolkit (GLUT)  Provides functionality common to all window systems  Open a window  Get input from mouse and keyboard  Menus  Event-driven  Code is portable but GLUT lacks the functionality of a good toolkit for a specific platform  No slide bars, buttons, …
  • 9.
    Software Organization application program OpenGL Motif widget or similar GLUT GLX, AGL or WGL GLU X, Win32, Mac O/S OpenGL software and/or hardware
  • 10.
    OpenGL Architecture Immediate Mode geometry pipeline Per Vertex Polynomial Operations & Evaluator Primitive Assembly Display Per Fragment Frame CPU List Rasterization Operations Buffer Texture Memory Pixel Operations
  • 11.
    OpenGL as astate machine  GL State Variables- can be set and queried by OpenGL. Remains unchanged until the next change.  Projection and viewing matrix  Color and material properties  Lights and shading  Line and polygon drawing modes  …  OpenGL functions are of two types  Primitive generating  Can cause output if primitive is visible  How vertices are processed and appearance of primitive are controlled by the state  State changing  Transformation functions  Attribute functions
  • 12.
    OpenGL Syntax  Functions have prefix gl and initial capital letters for each word  glClearColor(), glEnable(), glPushMatrix() …  glu for GLU functions  gluLookAt(), gluPerspective() …  Constants begin with GL_, use all capital letters  GL_COLOR_BUFFER_BIT, GL_PROJECTION, GL_MODELVIEW …  Extra letters in some commands indicate the number and type of variables  glColor3f(), glVertex3f() …  OpenGL data types  GLfloat, GLdouble, GLint, GLenum, …  Underlying storage mode is the same  Easy to create overloaded functions in C++ but issue is efficiency
  • 13.
    OpenGL function format function name dimensions glVertex3f(x,y,z) x,y,z are floats belongs to GL library glVertex3fv(p) p is a pointer to an array
  • 14.
    OpenGL #defines  Most constants are defined in the include files gl.h, glu.h and glut.h  Note #include <GL/glut.h> should automatically include the others  Examples  glBegin(GL_POLYGON)  glClear(GL_COLOR_BUFFER_BIT)  include files also define OpenGL data types: GLfloat, GLdouble,….
  • 15.
    GLUT  Developed by Mark Kilgard  Hides the complexities of differing window system APIs  Default user interface for class projects  Glut routines have prefix glut  glutCreateWindow() …  Has very limited GUI interface  Glui is the C++ extension of glut
  • 16.
    Glut Routines  Initialization: glutInit() processes (and removes) command-line arguments that may be of interest to glut and the window system and does general initialization of Glut and OpenGL  Must be called before any other glut routines  Display Mode: The next procedure, glutInitDisplayMode(), performs initializations informing OpenGL how to set up the frame buffer.  Display Mode Meaning  GLUT_RGB Use RGB colors  GLUT_RGBA Use RGB plus alpha (for transparency)  GLUT_INDEX Use indexed colors (not recommended)  GLUT_DOUBLE Use double buffering (recommended)  GLUT_SINGLE Use single buffering (not recommended)  GLUT_DEPTH Use depth-buffer (for hidden surface removal.)
  • 17.
    Glut Routines  Window Setup  glutInitWindowSize(int width, int height)  glutInitWindowPosition(int x, int y)  glutCreateWindow(char* title)
  • 18.
    A Simple Program Generatea square on a solid background
  • 19.
    simple.c #include <GL/glut.h> void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, 0.5); glVertex2f(0.5, -0.5); glEnd(); glFlush(); } int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("simple"); glutDisplayFunc(mydisplay); init(); glutMainLoop(); }
  • 20.
    Closer Look atthe main() #include <GL/glut.h> includes gl.h int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("simple"); glutDisplayFunc(mydisplay); define window properties init(); display callback set OpenGL state glutMainLoop(); } enter event loop
  • 21.
    init.c black clear color void init() opaque window { glClearColor (0.0, 0.0, 0.0, 1.0); glColor3f(1.0, 1.0, 1.0); fill/draw with white glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); } viewing volume
  • 22.
    Event Handling  Virtually all interactive graphics programs are even driven  GLUT uses callbacks to handle events  Windows system invokes a particular procedure when an event of particular type occurs.  MOST IMPORTANT: display event  Signaled when window first displays and whenever portions of the window reveals from blocking window  glutDisplayFunc(void (*func)(void)) registers the display callback function  Running the program: glutMainLoop()  Main event loop. Never exit()
  • 23.
    More Callbacks  glutReshapeFunc(void (*func)(int w, int h)) indicates what action should be taken when the window is resized.  glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) and glutMouseFunc(void (*func)(int button, int state, int x, int y)) allow you to link a keyboard key or a mouse button with a routine that's invoked when the key or mouse button is pressed or released.  glutMotionFunc(void (*func)(int x, int y)) registers a routine to call back when the mouse is moved while a mouse button is also pressed.  glutIdleFunc(void (*func)(void)) registers a function that's to be executed if no other events are pending - for example, when the event loop would otherwise be idle
  • 24.
    Compilation on Windows  See class web site on how to set up a project with OpenGL  Visual C++  Get glut.h, glut32.lib and glut32.dll from web  Create a console application  Add opengl32.lib, glut32.lib, glut32.lib to project settings (under link tab)
  • 25.
    Simple Animation  Animation  Redraw + swap buffers  What looks like if using single buffer  Example program  More on the glut documentation  Chapter 2 of textbook  OpenGL redbook  Links in the class resources page
  • 26.
    OpenGL Drawing  We have learned how to create a window  Steps in the display function  Clear the window  Set drawing attributes  Send drawing commands  Swap the buffers  OpenGL coordinate system has different origin from the window system  Uses lower left corner instead of upper left corner as origin
  • 27.
    Clear the Window glClear(GL_COLOR_BUFFER_BIT)  clears the frame buffer by overwriting it with the background color.  Background color is a state set by glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) in the init().
  • 28.
    Drawing Attributes: Color  glColor3f(GLfloat r, GLfloat g, GLfloat b) sets the drawing color  glColor3d(), glColor3ui() can also be used  Remember OpenGL is a state machine  Once set, the attribute applies to all subsequent defined objects until it is set to some other value  glColor3fv() takes a flat array as input  There are more drawing attributes than color  Point size: glPointSize()  Line width: glLinewidth()  Dash or dotted line: glLineStipple()  Polygon pattern: glPolygonStipple()  …
  • 29.
    Drawing Commands  Simple Objects glRectf()  Complex Objects  Use construct glBegin(mode) and glEnd() and a list of vertices in between  glBegin(mode) glVertex(v0); glVertex(v1); ... glEnd();  Some other commands can also be used between glBegin() and glEnd(), e.g. glColor3f().  Example
  • 30.
  • 31.
    Orthographic projection  Orthographic View  glOrtho(left, right, bottom, top, front, back)  Specifies the coordinates of 3D region to be projected z=0 into the image space.  Any drawing outside the region will be automatically clipped away.
  • 32.
    Viewports  Do nothave use the entire window for the image: glViewport(x,y,w,h)  Values in pixels (screen coordinates)
  • 33.
    Window to Viewportmapping Aspect Ratio: Height/Width If the aspect ratio of the window Is different from that of the viewport, the picture will be distorted.
  • 34.
    Sierpinski Gasket (2D)  Start with a triangle  Connect bisectors of sides and remove central triangle  Repeat
  • 35.
    Example  Five subdivisions
  • 36.
    Gasket Program #include <GL/glut.h> /*initial triangle */ GLfloat v[3][2]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}}; int n; /* number of recursive steps */ void triangle( GLfloat *a, GLfloat *b, GLfloat *c) /* display one triangle */ { glVertex2fv(a); glVertex2fv(b); glVertex2fv(c); }
  • 37.
    Triangle Subdivision void divide_triangle(GLfloat*a, GLfloat *b, GLfloat *c, int m) { /* triangle subdivision using vertex numbers */ point2 v0, v1, v2; int j; if(m>0) { for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2; for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2; for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2; divide_triangle(a, v0, v1, m-1); divide_triangle(c, v1, v2, m-1); divide_triangle(b, v2, v0, m-1); } else(triangle(a,b,c)); /* draw triangle at end of recursion */ }
  • 38.
    Gasket Display Functions voiddisplay() { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); divide_triangle(v[0], v[1], v[2], n); glEnd(); glFlush(); } • By having the glBegin and glEnd in the display callback rather than in the function triangle and using GL_TRIANGLES rather than GL_POLYGON in glBegin, we call glBegin and glEnd only once for the entire gasket rather than once for each triangle
  • 39.
    Example: 3D Gasket after 5 iterations
  • 40.
    Tetrahedron Code void tetrahedron(int m) { glColor3f(1.0,0.0,0.0); divide_triangle(v[0], v[1], v[2], m); glColor3f(0.0,1.0,0.0); divide_triangle(v[3], v[2], v[1], m); glColor3f(0.0,0.0,1.0); divide_triangle(v[0], v[3], v[1], m); glColor3f(0.0,0.0,0.0); divide_triangle(v[0], v[2], v[3], m); }