diff --git a/samples/qt/VoxelDemo/inc/VoxelClient_VisDrawer.h b/samples/qt/VoxelDemo/inc/VoxelClient_VisDrawer.h
index a2f0e6e2cb..d79dbd0985 100644
--- a/samples/qt/VoxelDemo/inc/VoxelClient_VisDrawer.h
+++ b/samples/qt/VoxelDemo/inc/VoxelClient_VisDrawer.h
@@ -19,7 +19,31 @@
 #include "Voxel_VisData.h"
 #include <Graphic3d_BndBox4f.hxx>
 
-#include <OpenGl_GraphicDriver.hxx>
+#include <Voxel_Prs.hxx>
+
+//! Voxel presentation using UserDraw.
+class VoxelClient_PrsGl : public Voxel_Prs
+{
+
+public:
+
+  //! Empty constructor.
+  VoxelClient_PrsGl() {}
+
+protected:
+
+  //! Override compute to create UserDraw element.
+  Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                                        const Handle(Prs3d_Presentation)&           thePrs,
+                                        const Standard_Integer                      theMode) Standard_OVERRIDE;
+
+public:
+
+  DEFINE_STANDARD_RTTI(VoxelClient_PrsGl, Voxel_Prs)
+
+};
+
+DEFINE_STANDARD_HANDLE(VoxelClient_PrsGl, Voxel_Prs)
 
 class VoxelClient_VisDrawer
 {
@@ -29,8 +53,6 @@ public:
 
 public:
 
-  Standard_EXPORT static void Init (Handle(OpenGl_GraphicDriver)& theDriver);
-
 	Standard_EXPORT VoxelClient_VisDrawer(Voxel_VisData* theData);
 	Standard_EXPORT virtual ~VoxelClient_VisDrawer();
 
diff --git a/samples/qt/VoxelDemo/src/Application.cpp b/samples/qt/VoxelDemo/src/Application.cpp
index f6148f8116..c7d5896a7e 100644
--- a/samples/qt/VoxelDemo/src/Application.cpp
+++ b/samples/qt/VoxelDemo/src/Application.cpp
@@ -322,8 +322,6 @@ Application::Application()
     myDisplayedZMin = -DBL_MAX;
     myDisplayedZMax =  DBL_MAX;
 
-	VoxelClient_VisDrawer::Init(myViewer->getGraphicDriver());
-
     resize( 450, 600 );
 
     myViewer->getIC()->SetAutoActivateSelection (Standard_False);
@@ -1858,7 +1856,7 @@ void Application::initPrs()
 {
 	if (myVoxels.IsNull())
     {
-		myVoxels = new Voxel_Prs;
+		myVoxels = new VoxelClient_PrsGl();
         myVoxels->SetDisplayMode(Voxel_VDM_POINTS);
         myVoxels->SetColor(Quantity_NOC_WHITE);
         myVoxels->SetPointSize(1.0);
diff --git a/samples/qt/VoxelDemo/src/Viewer.cpp b/samples/qt/VoxelDemo/src/Viewer.cpp
index f71805b23f..5c639b6f40 100644
--- a/samples/qt/VoxelDemo/src/Viewer.cpp
+++ b/samples/qt/VoxelDemo/src/Viewer.cpp
@@ -202,9 +202,9 @@ void Viewer::setDegenerateMode(const bool on)
     AIS_ListIteratorOfListOfInteractive itri(displayed);
     for (; itri.More(); itri.Next())
     {
-        if (itri.Value()->DynamicType() == STANDARD_TYPE(Voxel_Prs))
+        Handle(Voxel_Prs) prs = Handle(Voxel_Prs)::DownCast(itri.Value());
+        if (!prs.IsNull())
         {
-            Handle(Voxel_Prs) prs = Handle(Voxel_Prs)::DownCast(itri.Value());
             prs->SetDegenerateMode(on);
             myView->Redraw();
             break;
diff --git a/samples/qt/VoxelDemo/src/VoxelClient_VisDrawer.cxx b/samples/qt/VoxelDemo/src/VoxelClient_VisDrawer.cxx
index ee315c2710..f23e525e0d 100644
--- a/samples/qt/VoxelDemo/src/VoxelClient_VisDrawer.cxx
+++ b/samples/qt/VoxelDemo/src/VoxelClient_VisDrawer.cxx
@@ -33,7 +33,7 @@
 #include <gce_MakePln.hxx>
 #include <Quantity_Color.hxx>
 #include <Aspect_TypeOfLine.hxx>
-#include <Graphic3d_CUserDraw.hxx>
+#include <Prs3d_Root.hxx>
 
 #include <InterfaceGraphic_telem.hxx>
 #include <OpenGl_Element.hxx>
@@ -117,37 +117,25 @@ void VoxelClient_VisDrawer::VisElement::Render
 //purpose  : visdrawer element create callback, adds an element to graphic
 //           driver's structure
 //=======================================================================
-
-static OpenGl_Element* VisDrawerCallBack (const Graphic3d_CUserDraw* theUserDraw)
+void VoxelClient_PrsGl::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                                 const Handle(Prs3d_Presentation)&           thePrs,
+                                 const Standard_Integer                      theMode)
 {
-  if (theUserDraw == 0)
-    return 0;
+  if (myVisData == NULL)
+  {
+    return;
+  }
+  Voxel_Prs::Compute (thePrsMgr, thePrs, theMode);
 
-  // Retrieve the user structure
-  Voxel_VisData* aUserData = (Voxel_VisData*) (theUserDraw->Data);
+  Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast (Prs3d_Root::CurrentGroup (thePrs));
+  VoxelClient_VisDrawer::VisElement* anElem = new VoxelClient_VisDrawer::VisElement ((Voxel_VisData* )myVisData);
+  aGroup->AddElement (anElem);
 
-  if (aUserData == 0)
-    return 0;
-
-  VoxelClient_VisDrawer::VisElement *aElem = 
-    new VoxelClient_VisDrawer::VisElement (aUserData);
-
-  if (theUserDraw->Bounds != 0)
-    aElem->EvaluateBounds (*(theUserDraw->Bounds));
-
-  return aElem;
-}
-
-/**************************************************************************/
-void VoxelClient_VisDrawer::Init (Handle(OpenGl_GraphicDriver)& theDriver)
-{
-    static Standard_Boolean isInitializeded(Standard_False);
-
-    if (!isInitializeded)
-    {
-        isInitializeded = Standard_True;
-        theDriver->UserDrawCallback() = VisDrawerCallBack;
-    }
+  Graphic3d_BndBox4f aMinMax;
+  anElem->EvaluateBounds (aMinMax);
+  aGroup->SetMinMaxValues (aMinMax.CornerMin().x(), aMinMax.CornerMin().y(), aMinMax.CornerMin().z(),
+                           aMinMax.CornerMax().x(), aMinMax.CornerMax().y(), aMinMax.CornerMax().z());
+  thePrsMgr->StructureManager()->Update (thePrsMgr->StructureManager()->UpdateMode());
 }
 
 /**************************************************************************/
diff --git a/src/Aspect/Aspect_GraphicCallbackProc.hxx b/src/Aspect/Aspect_GraphicCallbackProc.hxx
deleted file mode 100644
index f6bb079fae..0000000000
--- a/src/Aspect/Aspect_GraphicCallbackProc.hxx
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _Aspect_GraphicCallbackProc_HeaderFile
-#define _Aspect_GraphicCallbackProc_HeaderFile
-
-// To manage client post display
-
-#include <Aspect_Display.hxx>
-#include <Aspect_Drawable.hxx>
-#include <Aspect_RenderingContext.hxx>
-#include <Standard_Handle.hxx>
-#include <Standard_Transient.hxx>
-
-// The flags below provide additional information to define the moment when
-// callback was invoked in redraw procedure. These flags are bitwise OR'ed
-// with the "reason" value of callback:
-// 1) OCC_PRE_REDRAW  - callback was invoked before redrawing underlayer
-//                      ( at the beginning of redraw procedure );
-// 2) OCC_PRE_OVERLAY - callback was invoked before redrawing overlayer;
-// Otherwise, if no flags added to the "reason" value, the callback was
-// invoked at the end of redraw ( after the overlayer is redrawn )
-#define OCC_PRE_REDRAW  0x4000
-#define OCC_PRE_OVERLAY 0x8000
-
-// mask for all additional callbacks that invoked in process of redrawing
-#define OCC_REDRAW_ADDITIONAL_CALLBACKS ( OCC_PRE_REDRAW | OCC_PRE_OVERLAY )
-
-typedef struct
-{
-  int reason;
-  int wsID;
-  int viewID;
-  bool IsCoreProfile;
-  Handle(Standard_Transient) glContext;
-} Aspect_GraphicCallbackStruct;
-
-// Prototype for callback function to perform custom drawing within the same window and GL context.
-typedef int (*Aspect_GraphicCallbackProc) (Aspect_Drawable               theWindowID,
-                                           void*                         theUserData,
-                                           Aspect_GraphicCallbackStruct* theCallData);
-
-#endif /* _Aspect_GraphicCallbackProc_HeaderFile */
diff --git a/src/Aspect/FILES b/src/Aspect/FILES
index 3c32b5c075..fd0ad1f64b 100755
--- a/src/Aspect/FILES
+++ b/src/Aspect/FILES
@@ -26,7 +26,6 @@ Aspect_GenId.hxx
 Aspect_GradientBackground.cxx
 Aspect_GradientBackground.hxx
 Aspect_GradientFillMethod.hxx
-Aspect_GraphicCallbackProc.hxx
 Aspect_GraphicDeviceDefinitionError.hxx
 Aspect_Grid.cxx
 Aspect_Grid.hxx
diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES
index 6cfa10ed2b..f373a1a9f4 100755
--- a/src/Graphic3d/FILES
+++ b/src/Graphic3d/FILES
@@ -55,7 +55,6 @@ Graphic3d_CStructure.cxx
 Graphic3d_CStructure.hxx
 Graphic3d_CStructurePtr.hxx
 Graphic3d_CTexture.hxx
-Graphic3d_CUserDraw.hxx
 Graphic3d_CView.cxx
 Graphic3d_CView.hxx
 Graphic3d_CycleError.hxx
diff --git a/src/Graphic3d/Graphic3d_CUserDraw.hxx b/src/Graphic3d/Graphic3d_CUserDraw.hxx
deleted file mode 100644
index 3151b7017d..0000000000
--- a/src/Graphic3d/Graphic3d_CUserDraw.hxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-/*============================================================================*/
-/*==== Titre: Graphic3d_CUserDraw.hxx					      */
-/*==== Role : The header file of primitive type "CUserDraw" from Graphic3d    */
-/*====									      */
-/*==== Implementation:  This is a primitive type implemented with typedef     */
-/*============================================================================*/
-
-#ifndef _Graphic3d_CUserDraw_HeaderFile
-#define _Graphic3d_CUserDraw_HeaderFile
-
-#include <InterfaceGraphic_Graphic3d.hxx>
-typedef CALL_DEF_USERDRAW Graphic3d_CUserDraw;
-
-#endif /*Graphic3d_CUserDraw_HeaderFile*/
diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx
index ec55376985..4fb824b8db 100644
--- a/src/Graphic3d/Graphic3d_CView.hxx
+++ b/src/Graphic3d/Graphic3d_CView.hxx
@@ -14,7 +14,6 @@
 #ifndef _Graphic3d_CView_HeaderFile
 #define _Graphic3d_CView_HeaderFile
 
-#include <Aspect_GraphicCallbackProc.hxx>
 #include <Aspect_Handle.hxx>
 #include <Aspect_PrintAlgo.hxx>
 #include <Aspect_RenderingContext.hxx>
@@ -252,16 +251,10 @@ public:
   virtual Standard_Boolean SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) = 0;
 
   //! Creates and maps rendering window to the view.
-  //! @param theView [in] the view to associate with the window.
   //! @param theWindow [in] the window.
   //! @param theContext [in] the rendering context. If NULL the context will be created internally.
-  //! @param theDisplayCB [in] the display callback function. If is not a NULL value, then the callback will be
-  //! invoked at the end of the OCC graphic traversal and just before the swap of buffers.
-  //! @param theClientData [in] the client data for the callback.
   virtual void SetWindow (const Handle(Aspect_Window)& theWindow,
-                          const Aspect_RenderingContext theContext = NULL,
-                          const Aspect_GraphicCallbackProc& theDisplayCB = NULL,
-                          const Standard_Address theClientData = NULL) = 0;
+                          const Aspect_RenderingContext theContext = NULL) = 0;
 
   //! Returns the window associated to the view.
   virtual Handle(Aspect_Window) Window() const = 0;
diff --git a/src/Graphic3d/Graphic3d_Group.cxx b/src/Graphic3d/Graphic3d_Group.cxx
index 4000c7c717..42ad428d7e 100644
--- a/src/Graphic3d/Graphic3d_Group.cxx
+++ b/src/Graphic3d/Graphic3d_Group.cxx
@@ -1074,30 +1074,6 @@ void Graphic3d_Group::Marker (const Graphic3d_Vertex& thePoint,
   AddPrimitiveArray (aPoints, theToEvalMinMax);
 }
 
-// =======================================================================
-// function : UserDraw
-// purpose  :
-// =======================================================================
-void Graphic3d_Group::UserDraw (const Standard_Address /*theObject*/,
-                                const Standard_Boolean /*theToEvalMinMax*/,
-                                const Standard_Boolean theContainsFacet)
-{
-  if (IsDeleted())
-  {
-    return;
-  }
-
-  // Without this modification, the group assumes the primitive contains
-  // no polygons and does not require the Z-buffer for display.
-  if (!MyContainsFacet && theContainsFacet)
-  {
-    myStructure->GroupsWithFacet (1);
-    MyContainsFacet = Standard_True;
-  }
-
-  Update();
-}
-
 // =======================================================================
 // function : Text
 // purpose  :
diff --git a/src/Graphic3d/Graphic3d_Group.hxx b/src/Graphic3d/Graphic3d_Group.hxx
index 3c780cfa6b..a73e918d09 100644
--- a/src/Graphic3d/Graphic3d_Group.hxx
+++ b/src/Graphic3d/Graphic3d_Group.hxx
@@ -248,9 +248,6 @@ public:
   //! Creates a primitive array with single marker using AddPrimitiveArray().
   Standard_EXPORT void Marker (const Graphic3d_Vertex& thePoint, const Standard_Boolean theToEvalMinMax = Standard_True);
 
-  //! Creates a UserDraw primitive using obsolete API.
-  Standard_EXPORT virtual void UserDraw (const Standard_Address theObject, const Standard_Boolean theToEvalMinMax = Standard_True, const Standard_Boolean theContainsFacet = Standard_False);
-
   //! sets the stencil test to theIsEnabled state;
   Standard_EXPORT virtual void SetStencilTestOptions (const Standard_Boolean theIsEnabled) = 0;
 
diff --git a/src/InterfaceGraphic/InterfaceGraphic_Graphic3d.hxx b/src/InterfaceGraphic/InterfaceGraphic_Graphic3d.hxx
index 9f78faa0cd..175d789bef 100644
--- a/src/InterfaceGraphic/InterfaceGraphic_Graphic3d.hxx
+++ b/src/InterfaceGraphic/InterfaceGraphic_Graphic3d.hxx
@@ -84,13 +84,4 @@ typedef struct
   CALL_DEF_POINT   Point;
 } CALL_DEF_TRANSFORM_PERSISTENCE;
 
-/* USERDRAW DATA */
-
-typedef struct {
-
-  void*               Data;
-  Graphic3d_BndBox4f* Bounds;
-
-} CALL_DEF_USERDRAW;
-
 #endif /* InterfaceGraphic_Graphic3dHeader */
diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx
index 2e9c9594c0..393eca0466 100644
--- a/src/OpenGl/OpenGl_GraphicDriver.cxx
+++ b/src/OpenGl/OpenGl_GraphicDriver.cxx
@@ -66,8 +66,7 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio
 #endif
   myCaps           (new OpenGl_Caps()),
   myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
-  myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
-  myUserDrawCallback (NULL)
+  myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator())
 {
 #if !defined(_WIN32) && !defined(__ANDROID__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
   if (myDisplayConnection.IsNull())
@@ -388,15 +387,6 @@ Standard_Integer OpenGl_GraphicDriver::InquirePlaneLimit()
   return aCtx.IsNull() ? 0 : Max (aCtx->MaxClipPlanes() - 2, 0);
 }
 
-// =======================================================================
-// function : UserDrawCallback
-// purpose  :
-// =======================================================================
-OpenGl_GraphicDriver::OpenGl_UserDrawCallback_t& OpenGl_GraphicDriver::UserDrawCallback()
-{
-  return myUserDrawCallback;
-}
-
 // =======================================================================
 // function : DefaultTextHeight
 // purpose  :
diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx
index c78b8438c1..b297ce36aa 100644
--- a/src/OpenGl/OpenGl_GraphicDriver.hxx
+++ b/src/OpenGl/OpenGl_GraphicDriver.hxx
@@ -33,7 +33,6 @@
 #include <Graphic3d_TextPath.hxx>
 #include <Graphic3d_HorizontalTextAlignment.hxx>
 #include <Graphic3d_VerticalTextAlignment.hxx>
-#include <Graphic3d_CUserDraw.hxx>
 #include <Graphic3d_GraduatedTrihedron.hxx>
 #include <Graphic3d_TypeOfComposition.hxx>
 #include <Graphic3d_ExportFormat.hxx>
@@ -194,12 +193,6 @@ public:
   Standard_EXPORT Standard_Boolean MemoryInfo (Standard_Size&           theFreeBytes,
                                                TCollection_AsciiString& theInfo) const;
 
-  //! UserDraw function prototype
-  typedef OpenGl_Element* (*OpenGl_UserDrawCallback_t )(const CALL_DEF_USERDRAW* );
-
-  //! Method to setup UserDraw callback
-  Standard_EXPORT OpenGl_UserDrawCallback_t& UserDrawCallback();
-
 public:
 
   //! Method to retrieve valid GL context.
@@ -228,7 +221,6 @@ protected:
   Handle(OpenGl_Caps)                                             myCaps;
   NCollection_Map<Handle(OpenGl_View)>                            myMapOfView;
   NCollection_DataMap<Standard_Integer, OpenGl_Structure*>        myMapOfStructure;
-  OpenGl_UserDrawCallback_t                                       myUserDrawCallback;
 
 public:
 
diff --git a/src/OpenGl/OpenGl_Group.cxx b/src/OpenGl/OpenGl_Group.cxx
index 33868355bb..917d2836dc 100644
--- a/src/OpenGl/OpenGl_Group.cxx
+++ b/src/OpenGl/OpenGl_Group.cxx
@@ -25,7 +25,6 @@
 #include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_ArrayOfPrimitives.hxx>
-#include <Graphic3d_CUserDraw.hxx>
 #include <Graphic3d_GroupDefinitionError.hxx>
 
 
@@ -271,36 +270,6 @@ void OpenGl_Group::Text (const Standard_CString                  theTextUtf,
 
 }
 
-// =======================================================================
-// function : UserDraw
-// purpose  :
-// =======================================================================
-void OpenGl_Group::UserDraw (const Standard_Address theObject,
-                             const Standard_Boolean theToEvalMinMax,
-                             const Standard_Boolean theContainsFacet)
-{
-  if (IsDeleted())
-  {
-    return;
-  }
-
-  OpenGl_Structure* aStruct = GlStruct();
-  if (aStruct->GlDriver()->UserDrawCallback() == NULL)
-  {
-    return;
-  }
-
-  Graphic3d_CUserDraw aUserDraw;
-  aUserDraw.Data   = theObject;
-  aUserDraw.Bounds = theToEvalMinMax ? &myBounds : NULL;
-  OpenGl_Element* aUserDrawElem = aStruct->GlDriver()->UserDrawCallback()(&aUserDraw);
-  if (aUserDrawElem != NULL)
-  {
-    AddElement (aUserDrawElem);
-  }
-  Graphic3d_Group::UserDraw (theObject, theToEvalMinMax, theContainsFacet);
-}
-
 // =======================================================================
 // function : SetFlippingOptions
 // purpose  :
diff --git a/src/OpenGl/OpenGl_Group.hxx b/src/OpenGl/OpenGl_Group.hxx
index 72bdc249a4..7c481e9f1d 100644
--- a/src/OpenGl/OpenGl_Group.hxx
+++ b/src/OpenGl/OpenGl_Group.hxx
@@ -87,11 +87,6 @@ public:
                                      const Graphic3d_VerticalTextAlignment   theVTA,
                                      const Standard_Boolean                  theToEvalMinMax) Standard_OVERRIDE;
 
-  //! Add UserDraw element using obsolete API
-  Standard_EXPORT virtual void UserDraw (const Standard_Address theObject,
-                                         const Standard_Boolean theToEvalMinMax,
-                                         const Standard_Boolean theContainsFacet);
-
   //! Add flipping element
   Standard_EXPORT virtual void SetFlippingOptions (const Standard_Boolean theIsEnabled,
                                                    const gp_Ax2&          theRefPlane);
diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx
index b2f76c59a1..4b3ae3b382 100644
--- a/src/OpenGl/OpenGl_View.cxx
+++ b/src/OpenGl/OpenGl_View.cxx
@@ -15,7 +15,6 @@
 
 #include <OpenGl_View.hxx>
 
-#include <Aspect_GraphicCallbackProc.hxx>
 #include <Aspect_RenderingContext.hxx>
 #include <Aspect_Window.hxx>
 #include <Graphic3d_AspectFillArea3d.hxx>
@@ -107,9 +106,6 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myMainSceneFbos[1]      = new OpenGl_FrameBuffer();
   myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
   myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
-
-  myDisplayCallback.Func = NULL;
-  myDisplayCallback.Data = NULL;
 }
 
 // =======================================================================
@@ -234,18 +230,13 @@ Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolea
 // purpose  :
 // =======================================================================
 void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow,
-                             const Aspect_RenderingContext theContext,
-                             const Aspect_GraphicCallbackProc& theDisplayCB,
-                             const Standard_Address theClientData)
+                             const Aspect_RenderingContext theContext)
 {
   myWindow = myDriver->CreateRenderWindow (theWindow, theContext);
   Standard_ASSERT_RAISE (!myWindow.IsNull(),
                          "OpenGl_View::SetWindow, "
                          "Failed to create OpenGl window.");
 
-  myDisplayCallback.Func = theDisplayCB;
-  myDisplayCallback.Data = theClientData;
-
   myWorkspace = new OpenGl_Workspace (this, myWindow);
   myWorldViewProjState.Reset();
   myToUpdateEnvironmentMap = Standard_True;
diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx
index 60f56eb41d..864a512504 100644
--- a/src/OpenGl/OpenGl_View.hxx
+++ b/src/OpenGl/OpenGl_View.hxx
@@ -123,16 +123,10 @@ public:
   Standard_EXPORT Standard_Boolean SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) Standard_OVERRIDE;
 
   //! Creates and maps rendering window to the view.
-  //! @param theView [in] the view to associate with the window.
   //! @param theWindow [in] the window.
   //! @param theContext [in] the rendering context. If NULL the context will be created internally.
-  //! @param theDisplayCB [in] the display callback function. If is not a NULL value, then the callback will be
-  //! invoked at the end of the OCC graphic traversal and just before the swap of buffers.
-  //! @param theClientData [in] the client data for the callback.
-  Standard_EXPORT virtual void SetWindow (const Handle(Aspect_Window)& theWindow,
-                                          const Aspect_RenderingContext theContext,
-                                          const Aspect_GraphicCallbackProc& theDisplayCB,
-                                          const Standard_Address theClientData) Standard_OVERRIDE;
+  Standard_EXPORT virtual void SetWindow (const Handle(Aspect_Window)&  theWindow,
+                                          const Aspect_RenderingContext theContext) Standard_OVERRIDE;
 
   //! Returns window associated with the view.
   virtual Handle(Aspect_Window) Window() const Standard_OVERRIDE { return myWindow->PlatformWindow(); }
@@ -442,8 +436,6 @@ public:
 
   void SetBackgroundGradientType (const Aspect_GradientFillMethod AType);
 
-  void DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace);
-
   //! Returns list of OpenGL Z-layers.
   const OpenGl_LayerList& LayerList() const { return myZLayers; }
 
@@ -471,10 +463,11 @@ protected: //! @name Internal methods for managing GL resources
   //! Initializes OpenGl resource for environment texture.
   void initTextureEnv (const Handle(OpenGl_Context)& theContext);
 
-protected: //! @name Internal redrawing sub-routines
+protected: //! @name low-level redrawing sub-routines
 
   //! Redraws view for the given monographic camera projection, or left/right eye.
-  void redraw (const Graphic3d_Camera::Projection theProjection, OpenGl_FrameBuffer* theReadDrawFbo);
+  Standard_EXPORT virtual void redraw (const Graphic3d_Camera::Projection theProjection,
+                                       OpenGl_FrameBuffer*                theReadDrawFbo);
 
   //! Redraws view for the given monographic camera projection, or left/right eye.
   //!
@@ -488,30 +481,18 @@ protected: //! @name Internal redrawing sub-routines
   //!
   //! @return false if immediate structures has been rendered directly into FrontBuffer
   //! and Buffer Swap should not be called.
-  bool redrawImmediate (const Graphic3d_Camera::Projection theProjection,
-                        OpenGl_FrameBuffer* theReadFbo,
-                        OpenGl_FrameBuffer* theDrawFbo,
-                        const Standard_Boolean theIsPartialUpdate = Standard_False);
-
-  //! Copy content of Back buffer to the Front buffer.
-  void copyBackToFront();
-
-  //! Initialize blit quad.
-  OpenGl_VertexBuffer* initBlitQuad (const Standard_Boolean theToFlip);
+  Standard_EXPORT virtual bool redrawImmediate (const Graphic3d_Camera::Projection theProjection,
+                                                OpenGl_FrameBuffer* theReadFbo,
+                                                OpenGl_FrameBuffer* theDrawFbo,
+                                                const Standard_Boolean theIsPartialUpdate = Standard_False);
 
   //! Blit image from/to specified buffers.
-  bool blitBuffers (OpenGl_FrameBuffer*    theReadFbo,
-                    OpenGl_FrameBuffer*    theDrawFbo,
-                    const Standard_Boolean theToFlip = Standard_False);
+  Standard_EXPORT bool blitBuffers (OpenGl_FrameBuffer*    theReadFbo,
+                                    OpenGl_FrameBuffer*    theDrawFbo,
+                                    const Standard_Boolean theToFlip = Standard_False);
 
   //! Setup default FBO.
-  void bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo = NULL);
-
-  //! Blend together views pair into stereo image.
-  void drawStereoPair();
-
-  //! Invokes display callback.
-  void displayCallback (const Standard_Integer theReason);
+  Standard_EXPORT void bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo = NULL);
 
 protected: //! @name Rendering of GL graphics (with prepared drawing buffer).
 
@@ -519,21 +500,24 @@ protected: //! @name Rendering of GL graphics (with prepared drawing buffer).
   //! @param theProjection [in] the projection that should be used for rendering.
   //! @param theReadDrawFbo [in] the framebuffer for rendering graphics.
   //! @param theToDrawImmediate [in] the flag indicates whether the rendering performs in immediate mode.
-  void render (Graphic3d_Camera::Projection theProjection,
-               OpenGl_FrameBuffer*          theReadDrawFbo,
-               const Standard_Boolean       theToDrawImmediate);
+  Standard_EXPORT virtual void render (Graphic3d_Camera::Projection theProjection,
+                                       OpenGl_FrameBuffer*          theReadDrawFbo,
+                                       const Standard_Boolean       theToDrawImmediate);
 
   //! Renders the graphical scene.
   //! @param theReadDrawFbo [in] the framebuffer for rendering graphics.
   //! @param theToDrawImmediate [in] the flag indicates whether the rendering performs in immediate mode.
-  void renderScene (OpenGl_FrameBuffer*    theReadDrawFbo,
-                    const Standard_Boolean theToDrawImmediate);
+  Standard_EXPORT virtual void renderScene (OpenGl_FrameBuffer*    theReadDrawFbo,
+                                            const Standard_Boolean theToDrawImmediate);
+
+  //! Draw background (gradient / image)
+  Standard_EXPORT virtual void drawBackground (const Handle(OpenGl_Workspace)& theWorkspace);
 
   //! Render set of structures presented in the view.
   //! @param theReadDrawFbo [in] the framebuffer for rendering graphics.
   //! @param theToDrawImmediate [in] the flag indicates whether the rendering performs in immediate mode.
-  void renderStructs (OpenGl_FrameBuffer*    theReadDrawFbo,
-                      const Standard_Boolean theToDrawImmediate);
+  Standard_EXPORT virtual void renderStructs (OpenGl_FrameBuffer*    theReadDrawFbo,
+                                              const Standard_Boolean theToDrawImmediate);
 
   //! Renders trihedron.
   void renderTrihedron (const Handle(OpenGl_Workspace) &theWorkspace);
@@ -555,6 +539,17 @@ private:
   Standard_EXPORT virtual void changePriority (const Handle(Graphic3d_CStructure)& theCStructure,
                                                const Standard_Integer theNewPriority) Standard_OVERRIDE;
 
+private:
+
+  //! Copy content of Back buffer to the Front buffer.
+  void copyBackToFront();
+
+  //! Initialize blit quad.
+  OpenGl_VertexBuffer* initBlitQuad (const Standard_Boolean theToFlip);
+
+  //! Blend together views pair into stereo image.
+  void drawStereoPair();
+
 protected:
 
   OpenGl_GraphicDriver*    myDriver;
@@ -603,12 +598,6 @@ protected:
 
   Handle(OpenGl_Texture) myTextureEnv;
 
-  struct
-  {
-    Aspect_GraphicCallbackProc Func;
-    Standard_Address           Data;
-  } myDisplayCallback;
-
 protected: //! @name Rendering properties
 
   //! Two framebuffers (left and right views) store cached main presentation
diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx
index b1c38324d7..85af74fedb 100644
--- a/src/OpenGl/OpenGl_View_Redraw.cxx
+++ b/src/OpenGl/OpenGl_View_Redraw.cxx
@@ -149,10 +149,10 @@ static void bindLight (const OpenGl_Light&             theLight,
 #endif
 
 //=======================================================================
-//function : DrawBackground
+//function : drawBackground
 //purpose  :
 //=======================================================================
-void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
+void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
 {
   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
 
@@ -804,7 +804,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   // Render background
   if (!theToDrawImmediate)
   {
-    DrawBackground (myWorkspace);
+    drawBackground (myWorkspace);
   }
 
 #if !defined(GL_ES_VERSION_2_0)
@@ -924,7 +924,6 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   // Resetting GL parameters according to the default aspects
   // in order to synchronize GL state with the graphic driver state
   // before drawing auxiliary stuff (trihedrons, overlayer)
-  // and invoking optional callbacks
   myWorkspace->ResetAppliedAspect();
 
   aContext->ChangeClipping().RemoveAll();
@@ -958,12 +957,6 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
     }
   }
 
-  // ==============================================================
-  //      Step 5: Invoke callback after redraw
-  // ==============================================================
-
-  displayCallback (0);
-
   // ==============================================================
   //      Step 6: Keep shader manager informed about last View
   // ==============================================================
@@ -1525,6 +1518,7 @@ bool OpenGl_View::blitBuffers (OpenGl_FrameBuffer*    theReadFbo,
       aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
       theReadFbo->DepthStencilTexture()->Unbind (aCtx, GL_TEXTURE0 + 1);
       theReadFbo->ColorTexture()       ->Unbind (aCtx, GL_TEXTURE0 + 0);
+      aCtx->BindProgram (NULL);
     }
     else
     {
@@ -1759,23 +1753,3 @@ void OpenGl_View::copyBackToFront()
 #endif
   myIsImmediateDrawn = Standard_False;
 }
-
-// =======================================================================
-// function : displayCallback
-// purpose  :
-// =======================================================================
-void OpenGl_View::displayCallback (const Standard_Integer theReason)
-{
-  if (myDisplayCallback.Func == NULL)
-  {
-    return;
-  }
-
-  Aspect_GraphicCallbackStruct aCallData;
-  aCallData.reason    = theReason;
-  aCallData.glContext = myWorkspace->GetGlContext();
-  aCallData.wsID      = -1;
-  aCallData.viewID    = myId;
-  aCallData.IsCoreProfile = (myWorkspace->GetGlContext()->core11 == NULL);
-  myDisplayCallback.Func (myWindow->PlatformWindow()->NativeHandle(), myDisplayCallback.Data, &aCallData);
-}
diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx
index dbabd2dac6..fbf0cfc344 100644
--- a/src/V3d/V3d_View.cxx
+++ b/src/V3d/V3d_View.cxx
@@ -245,10 +245,8 @@ void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
 //function : SetWindow
 //purpose  :
 //=============================================================================
-void V3d_View::SetWindow (const Handle(Aspect_Window)&      theWindow,
-                          const Aspect_RenderingContext     theContext,
-                          const Aspect_GraphicCallbackProc& theDisplayCB,
-                          const Standard_Address            theClientData)
+void V3d_View::SetWindow (const Handle(Aspect_Window)&  theWindow,
+                          const Aspect_RenderingContext theContext)
 {
   if (myView->IsRemoved())
   {
@@ -257,7 +255,7 @@ void V3d_View::SetWindow (const Handle(Aspect_Window)&      theWindow,
 
   // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
   MyWindow = theWindow;
-  myView->SetWindow (theWindow, theContext, theDisplayCB, theClientData);
+  myView->SetWindow (theWindow, theContext);
   MyViewer->SetViewOn (this);
   SetRatio();
   Redraw();
diff --git a/src/V3d/V3d_View.hxx b/src/V3d/V3d_View.hxx
index 53f71e58f0..290dd1f76d 100644
--- a/src/V3d/V3d_View.hxx
+++ b/src/V3d/V3d_View.hxx
@@ -21,7 +21,6 @@
 #include <Aspect_FillMethod.hxx>
 #include <Aspect_GradientBackground.hxx>
 #include <Aspect_GradientFillMethod.hxx>
-#include <Aspect_GraphicCallbackProc.hxx>
 #include <Aspect_Handle.hxx>
 #include <Aspect_PrintAlgo.hxx>
 #include <Aspect_RenderingContext.hxx>
@@ -135,18 +134,10 @@ public:
   //! If <aContext> is not NULL the graphic context is used
   //! to draw something in this view.
   //! Otherwise an internal graphic context is created.
-  //! If <aDisplayCB> is not NULL then a user display CB is
-  //! call at the end of the OCC graphic traversal and just
-  //! before the swap of buffers. The <aClientData> is pass
-  //! to this call back.
-  //! Warning! raises MultiplyDefined from Standard
-  //! if the view is already activated in a window.
   //! Warning: The view is centered and resized to preserve
   //! the height/width ratio of the window.
   Standard_EXPORT void SetWindow (const Handle(Aspect_Window)& theWindow,
-                                  const Aspect_RenderingContext theContext = NULL,
-                                  const Aspect_GraphicCallbackProc& theDisplayCB = NULL,
-                                  const Standard_Address theClientData = NULL);
+                                  const Aspect_RenderingContext theContext = NULL);
 
   Standard_EXPORT void SetMagnify (const Handle(Aspect_Window)& theWindow,
                                    const Handle(V3d_View)& thePreviousView,
diff --git a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx
index 5269f20c83..ab41e0a1cc 100644
--- a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx
+++ b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx
@@ -81,17 +81,9 @@ public:
     Handle(VUserDrawObj) myIObj;
 
   public:
-    Element (const Handle(VUserDrawObj)& theIObj,
-             Graphic3d_BndBox4f* theBounds)
-    : myIObj( theIObj )
-    {
-      if (!myIObj.IsNull())
-        myIObj->GetBounds(theBounds);
-    }
+    Element (const Handle(VUserDrawObj)& theIObj) : myIObj (theIObj) {}
 
-    virtual ~Element ()
-    {
-    }
+    virtual ~Element() {}
 
     virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
     {
@@ -119,21 +111,28 @@ private:
 
     // Called by VUserDrawElement
     void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
-    void GetBounds(Graphic3d_BndBox4f* theBounds);
 
+private:
     GLfloat myCoords[6];
-
     friend class Element;
 };
 
-void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
-                           const Handle(Prs3d_Presentation)& thePresentation,
+void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                           const Handle(Prs3d_Presentation)& thePrs,
                            const Standard_Integer /*theMode*/)
 {
-  thePresentation->Clear();
+  thePrs->Clear();
 
-  Handle(Graphic3d_Group) aGrp = Prs3d_Root::CurrentGroup(thePresentation);
-  aGrp->UserDraw(this, Standard_True, Standard_True);
+  Graphic3d_Vec4 aBndMin (myCoords[0], myCoords[1], myCoords[2], 1.0f);
+  Graphic3d_Vec4 aBndMax (myCoords[3], myCoords[4], myCoords[5], 1.0f);
+  Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast (thePrs->NewGroup());
+  aGroup->SetMinMaxValues (aBndMin.x(), aBndMin.y(), aBndMin.z(),
+                           aBndMax.x(), aBndMax.y(), aBndMax.z());
+  VUserDrawObj::Element* anElem = new VUserDrawObj::Element (this);
+  aGroup->AddElement(anElem);
+
+  // invalidate bounding box of the scene
+  thePrsMgr->StructureManager()->Update (thePrsMgr->StructureManager()->UpdateMode());
 }
 
 void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
@@ -150,26 +149,12 @@ void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelec
   theSelection->Add(aSensitive);
 }
 
-void VUserDrawObj::GetBounds(Graphic3d_BndBox4f* theBounds)
-{
-  if (theBounds)
-  {
-    Graphic3d_Vec4 aMinPt (myCoords[0], myCoords[1], myCoords[2], 1.0f);
-    Graphic3d_Vec4 aMaxPt (myCoords[3], myCoords[4], myCoords[5], 1.0f);
-    if (!theBounds->IsValid())
-    {
-      theBounds->Combine (Graphic3d_BndBox4f (aMinPt, aMaxPt));
-    }
-    else
-    {
-      theBounds->CornerMin() = aMinPt;
-      theBounds->CornerMax() = aMaxPt;
-    }
-  }
-}
-
 void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
 {
+  // this sample does not use GLSL programs - make sure it is disabled
+  Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
+  aCtx->BindProgram (NULL);
+
   // To test linking against OpenGl_Workspace and all aspect classes
   const OpenGl_AspectLine* aLA = theWorkspace->AspectLine(0);
   const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(0);
@@ -179,9 +164,6 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
   TEL_COLOUR aColor = theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ?
     *(theWorkspace->HighlightColor) : aLA->Color();
 
-  // To test OpenGl_Window
-  //Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
-
   // Finally draw something to make sure UserDraw really works
   glPushAttrib(GL_ENABLE_BIT);
   glDisable(GL_LIGHTING);
@@ -197,17 +179,6 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
 
 } // end of anonymous namespace
 
-OpenGl_Element* VUserDrawCallback(const CALL_DEF_USERDRAW * theUserDraw)
-{
-  Handle(VUserDrawObj) anIObj = (VUserDrawObj*)theUserDraw->Data;
-  if (anIObj.IsNull())
-  {
-    std::cout << "VUserDrawCallback error: null object passed, the custom scene element will not be rendered" << std::endl;
-  }
-
-  return new VUserDrawObj::Element(anIObj, theUserDraw->Bounds);
-}
-
 static Standard_Integer VUserDraw (Draw_Interpretor& di,
                                     Standard_Integer argc,
                                     const char ** argv)
@@ -235,9 +206,6 @@ static Standard_Integer VUserDraw (Draw_Interpretor& di,
   TCollection_AsciiString aName (argv[1]);
   VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
 
-  // register the custom element factory function
-  aDriver->UserDrawCallback() = VUserDrawCallback;
-
   Handle(VUserDrawObj) anIObj = new VUserDrawObj();
   VDisplayAISObject(aName, anIObj);
 
diff --git a/src/Voxel/Voxel_Prs.cxx b/src/Voxel/Voxel_Prs.cxx
index 8615a92e0d..95623cb2c8 100644
--- a/src/Voxel/Voxel_Prs.cxx
+++ b/src/Voxel/Voxel_Prs.cxx
@@ -154,7 +154,8 @@ void Voxel_Prs::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresent
     }
   }
 
-  G->UserDraw(myVisData);
+  ///Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast (G);
+  ///aGroup->AddElement (myVisData);
 }
 
 void Voxel_Prs::ComputeSelection(const Handle(SelectMgr_Selection)& /*theSelection*/,
diff --git a/src/Voxel/Voxel_Prs.hxx b/src/Voxel/Voxel_Prs.hxx
index aba9798c06..05e225e8fc 100644
--- a/src/Voxel/Voxel_Prs.hxx
+++ b/src/Voxel/Voxel_Prs.hxx
@@ -127,7 +127,7 @@ protected:
 
 
 
-private:
+protected:
 
   
   Standard_EXPORT void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, const Standard_Integer theMode);