; docformat = 'rst' ;+ ; Example of how the order of atoms effects the rendering of transparent ; atoms. ;- ;+ ; Handle all events. ; ; :Params: ; event : in, required, type=structure ; event structure for any event generated by this program ;- pro mg_render_order_event, event compile_opt strictarr widget_control, event.top, get_uvalue=pstate uname = widget_info(event.id, /uname) case uname of 'draw' : begin update = (*pstate).otrack->update(event, transform=rotation) if (update) then begin ; normal trackball code (*pstate).omodel->getProperty, transform=transform newTransform = transform # rotation (*pstate).omodel->setProperty, transform=newTransform ; swap render order if necessary front = newTransform[0, 2] gt 0 ? 'blue' : 'red' if (front ne (*pstate).front) then begin (*pstate).front = front if ((*pstate).swap) then begin (*pstate).omodel->move, 0, 1 ; this is the swap print, 'Swapping, ' + front + ' now in front' endif else begin print, 'Not swapping, red is always in front.' endelse endif ; make sure to render the view or you won't see any changes (*pstate).owindow->draw, (*pstate).oview endif end endcase end ;+ ; Cleanup resources. ; ; :Params: ; tlb : in, required, type=long ; widget identifier of the top-level base ;- pro mg_render_order_cleanup, tlb compile_opt strictarr widget_control, tlb, get_uvalue=pstate obj_destroy, [(*pstate).oview, (*pstate).otrack] ptr_free, pstate end ;+ ; Example of how the order of atoms effects the rendering of transparent ; atoms. ; ; :Keywords: ; swap : in, optional, type=boolean ; set to have MG_RENDER_ORDER swap the planes as necessary to keep the ; transparent plane in the foreground ; renderer : in, optional, type=long ; set to 0 for hardware rendering, 1 for software rendering ;- pro mg_render_order, swap=swap, renderer=renderer compile_opt strictarr ; create simple widget hierarchy title = 'Render order demo: ' + (keyword_set(swap) ? '' : 'not ') + 'swapping' tlb = widget_base(title=title, /column) draw = widget_draw(tlb, xsize=400, ysize=400, $ graphics_level=2, renderer=renderer, $ /button_events, /motion_events, uname='draw') widget_control, tlb, /realize widget_control, draw, get_value=owindow ; create object graphics hierarchy oview = obj_new('IDLgrView', color=[0, 0, 0]) omodel = obj_new('IDLgrModel') oview->add, omodel ; coordinates of left and right polygons right = fltarr(5) + 0.5 left = fltarr(5) - 0.5 y = [1.0, 1.0, -1.0, -1.0, 1.0] / 2.0 z = [1.0, -1.0, -1.0, 1.0, 1.0] / 2.0 ; oright is added to omodel first, so it should be in the back oright = obj_new('IDLgrPolygon', right, y, z, color=[0, 0, 255], $ alpha_channel=0.5, name='right') omodel->add, oright ; oleft is added after oright, so you can see through it to see oright oleft = obj_new('IDLgrPolygon', left, y, z, color=[255, 0, 0], $ alpha_channel=0.5, name='left') omodel->add, oleft olightmodel = obj_new('IDLgrModel') oview->add, olightmodel ; ambient light olight = obj_new('IDLgrLight', type=0) olightmodel->add, olight ; rotation to make the 3d orientation more apparent omodel->rotate, [0, 1, 0], 60 omodel->rotate, [1, 0, 0], 15 ; initial rendering owindow->draw, oview ; trackball handles conversion of mouse movements to transformation otrack = obj_new('Trackball', [200, 200], 200) ; pstate data passing strategy for a widget program state = { oview: oview, $ omodel: omodel, $ owindow: owindow, $ otrack: otrack, $ swap: keyword_set(swap), $ front: 'red' $ } pstate = ptr_new(state, /no_copy) widget_control, tlb, set_uvalue=pstate xmanager, 'mg_render_order', tlb, /no_block, $ cleanup='mg_render_order_cleanup', $ event_handler='mg_render_order_event' end