private void openGLControl_OpenGLDraw(object sender, SharpGL.RenderEventArgs args)
        {
            OpenGL gl = openGLControl.OpenGL;

            // Clear the color and depth buffer.
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            foreach (DrawHelper drawHelper in listDrawPolygonHelper)
            {
                drawHelper.draw();
            }
            foreach (DrawHelper drawHelper in listDrawEllipseHelper)
            {
                drawHelper.draw();
            }
            foreach (DrawHelper drawHelper in listDrawColor)
            {
                drawHelper.draw();
            }

            List <Point> controlPoints = selectedPoints;

            if (controlPoints.Count > 0)
            {
                DrawHelper controlPointsDraw = new DrawHelper(gl, OpenGL.GL_POINTS, controlPoints, colorDialog1.Color, 1.0f, 5.0f);
                controlPointsDraw.draw();
            }

            if (started) // neu mouse dang down va di chuyen, ve duong live tuy vao draw cai gi
            {
                if (drawingRadio.Checked)
                {
                    int drawingMode           = getDrawingOption();
                    DrawChosenOption liveDraw = new DrawChosenOption(drawingMode, pStart, pEnd, gl);

                    uint       openglMode     = (drawingMode == DrawChosenOption.DRAW_LINE) ? OpenGL.GL_LINES : OpenGL.GL_LINE_LOOP;
                    DrawHelper liveDrawHelper = new DrawHelper(gl, openglMode, liveDraw.getDrawingPoints(), colorDialog1.Color, (float)numericUpDown1.Value);
                    liveDrawHelper.draw();
                }
                else if (drawRandomRadio.Checked)
                {
                    List <Point> points = drawRandomPolygon.getControlPoints();
                    points.Add(new Point(pEnd.X, pEnd.Y));
                    DrawHelper liveDrawHelper = new DrawHelper(gl, OpenGL.GL_LINE_LOOP, points, colorDialog1.Color, (float)numericUpDown1.Value);
                    liveDrawHelper.draw();
                }
            }

            if (ended) // da mouse up, tinh thoi gian ve hinh
            {
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                textBox1.Text = elapsedMs.ToString() + " ms";
                ended         = false;
            }
        }
        private void openGLControl_MouseUp(object sender, MouseEventArgs e)
        {
            OpenGL gl = openGLControl.OpenGL;

            // update toa do end
            pEnd = new Point(e.Location.X, gl.RenderContextProvider.Height - e.Location.Y);
            if (drawingRadio.Checked)
            {
                // Them action ve hinh vao snapshot
                int drawingMode = getDrawingOption();
                // calculate draw / control points
                DrawChosenOption newDrawChosen = new DrawChosenOption(drawingMode, pStart, pEnd, gl);
                uint             openglMode    = (drawingMode == DrawChosenOption.DRAW_LINE) ? OpenGL.GL_LINES : OpenGL.GL_LINE_LOOP;
                List <Point>     points        = newDrawChosen.getDrawingPoints();

                if ((drawingMode == DrawChosenOption.DRAW_CIRCLE || drawingMode == DrawChosenOption.DRAW_ELIPSE) && points.Count > 2)
                {
                    listDrawEllipseHelper.Add(new DrawHelper(gl, openglMode, points, colorDialog1.Color, (float)numericUpDown1.Value));
                    listEllipses.Add(new Ellipse(newDrawChosen.getControlPoints(), drawingMode));
                }
                else
                {
                    listDrawPolygonHelper.Add(new DrawHelper(gl, openglMode, points, colorDialog1.Color, (float)numericUpDown1.Value));
                    listPolygons.Add(new Polygon(newDrawChosen.getControlPoints(), drawingMode));
                }

                // update status (da xong ve~ di chuyen tren man hinh)
                started = false;
                ended   = true;
                // Bat dau stop watch dem thoi gian thuc thi ve hinh
                watch = System.Diagnostics.Stopwatch.StartNew();
                // Reset 2 diem
                resetPoints();
            }
            else if (selectRadio.Checked) // select and (dragging / scale / rotate / nothing)
            {
                if (pStart == pEnd)       //only select
                {
                    if (selectedType == SELECTED_POLYGON)
                    {
                        selectedPoints = new List <Point>(listPolygons[selectedIndex].getControlPoints());
                    }
                    else if (selectedType == SELECTED_ELLIPSE)
                    {
                        selectedPoints = new List <Point>(listEllipses[selectedIndex].getControlPoints());
                    }
                }
                else // select and (dragging / scale / rotate)
                {
                    List <Point> controlPoints = new List <Point>(), drawingPoints = new List <Point>();
                    // select and drag
                    if (selectedType == SELECTED_POLYGON)  //select a polygon
                    {
                        AffineTransform af           = new AffineTransform(listPolygons[selectedIndex].getControlPoints(), listPolygons[selectedIndex].type);
                        bool            didTransform = false;
                        //bedin transform
                        if (selectedControlPointIndex == -1) // neu select polygon nhung khong select control point => translate
                        {
                            if (af.translate(pStart, pEnd))
                            {
                                controlPoints = af.getControlPoints();
                                didTransform  = true;
                            }
                        }
                        else // else rotate va scale => pStart la 1 diem control point
                        {
                            //do both rotate and scale (get updated control points after rotate)
                            // if one of them failed => do nothing =)))
                            if (af.rotate(pStart, pEnd) && af.scale(af.getControlPoints()[selectedControlPointIndex], pEnd))
                            {
                                controlPoints = af.getControlPoints();
                                didTransform  = true;
                            }
                        }
                        // end transform

                        if (didTransform)
                        {
                            //geting drawing points
                            if (listPolygons[selectedIndex].type == DrawChosenOption.DRAW_RANDOM)
                            {
                                DrawRandomPolygon newDRP = new DrawRandomPolygon(gl, controlPoints);
                                drawingPoints = new List <Point>(newDRP.getDrawingPoints());
                            }
                            else
                            {
                                DrawChosenOption newDCO = new DrawChosenOption(listPolygons[selectedIndex].type, controlPoints, gl);
                                drawingPoints = new List <Point>(newDCO.getDrawingPoints());
                            }

                            // update lists
                            listPolygons[selectedIndex].setPoints(controlPoints);
                            selectedPoints = controlPoints;
                            listDrawPolygonHelper[selectedIndex].setPoints(drawingPoints);
                        }
                        else
                        {
                            selectedPoints = listPolygons[selectedIndex].getControlPoints();
                        }
                    }

                    if (selectedType == SELECTED_ELLIPSE) //select a ellipse
                    {
                        AffineTransform af = new AffineTransform(listEllipses[selectedIndex].getControlPoints(), listEllipses[selectedIndex].type);

                        bool didTransform = false;
                        //bedin transform
                        if (selectedControlPointIndex == -1) // neu select ellipse nhung khong select control point => translate
                        {
                            if (af.translate(pStart, pEnd))
                            {
                                controlPoints = af.getControlPoints();
                                didTransform  = true;
                            }
                        }
                        else //else rotate and scale, pStart la 1 diem control point
                        {
                            if (af.rotate(pStart, pEnd) && af.scale(af.getControlPoints()[selectedControlPointIndex], pEnd))
                            {
                                controlPoints = af.getControlPoints();
                                didTransform  = true;
                            }
                        }
                        //end transform

                        if (didTransform)
                        {
                            DrawChosenOption newDCO = new DrawChosenOption(listEllipses[selectedIndex].type, controlPoints, gl);
                            drawingPoints = new List <Point>(newDCO.getDrawingPoints());

                            listEllipses[selectedIndex].setPoints(controlPoints);
                            listDrawEllipseHelper[selectedIndex].setPoints(drawingPoints);
                            selectedPoints = controlPoints;
                        }
                        else
                        {
                            selectedPoints = listEllipses[selectedIndex].getControlPoints();
                        }
                    }

                    //SELECTED NONE thi k lam gi
                }
            }
        }