X

Help Articles are product support tips and information straight from the NV5 Geospatial Technical Support team developed to help you use our products to their fullest potential.



4597 Rate this article:
No rating

Window Coloring Does Not Change After LOADCT/XLOADCT

Topic
IDL programmers, who are working with color tables in Direct Graphics (using the DEVICE,DECOMPOSED=0 setting), are frequently surprised that the scene on their graphics window does not change color automatically after a LOADCT or XLOADCT call. Some such users might recall that in the past IDL was immediately updating color (true on most UNIX machines built before year 2000), and they think that IDL must have changed its functionality. In fact, the change that occurred was in the operating systems and their video cards, which moved almost universally in the late 1990's to defaulting their displays to the RGB True Color model. This model can use the 256-element color table for display, but it does not refresh its graphics windows based on values in that table. Thus, changes in the color table do not automatically impact on True Color displays.

This Help Article discusses various strategies the IDL Direct Graphics programmer can use to effect automatic recoloring of their current graphics window after any LOADCT or XLOADCT call. It also provides an example demonstrating XLOADCT's somewhat complicated UPDATECALLBACK keyword and demonstrating _REF_EXTRA in practical use.

Discussion
A little background: There are two basic kinds of color models for video monitors [relevant to IDL] in computer operating systems: True Color and Direct Color. These color models implement one of two approaches to refreshing the coloring of the pixels on their display windows. The True Color "RGB" model, the model that has become ubiquitous as the default for modern display monitors, uses a "backing store" that holds the last known RGB values of each of the pixels in the graphics window. Direct Color, which was a common default throughout the 1990's, holds color table indexes. Older IDL users probably experienced Direct Color as the model in place when their monitors offered just 256 colors. Eventually, Direct Color developed capabilities to store and display 4,096, later 16,777,216 colors in their color tables, but, by that time True Color was becoming a more popular default model for O.S. manufacturers.

For the purposes of recoloring, Direct Color has the behavior that IDL users might recall from earlier years: the display uses values in the color table with every refresh (refreshing, by the way, is automatic and frequent on all monitors). True Color, however, never queries the color table during a refresh. Rather, for any given graphics window, it queries a buffer that is holding a 32-bit snapshot of the graphics in the state they had the last time the program explicitly called for a redraw. Thus, on a True Color display, if the color table changes, it does not affect the buffer that the video card is using for its routine cyclic repainting.

Pseudocolor, the name IDL documentation has given to the 256-element color table model that IDL uses when a user has called "DEVICE,DECOMPOSED=0", does not change the O.S.'s color model. It simply instructs the windows that are using it to get all their colors from the video card's 256-element color table each time a new IDL drawing command is issued. Thus, on True Color monitors only an IDL drawing command (e.g. PLOT, SURFACE, TV, XYOUTS, etc.) can get the IDL graphics windows to use a new color table setting. Below are the strategies you can use to get this redrawing to work optimally.

Approach 1 - Redraw All the Relevant Graphics Commands After Every LOADCT
The most efficient way to implement this would be to wrap all the graphics commands that recreate your visualization in a separate procedure. Such a procedure might have a prototype like this:

    ; The '_REF_EXTRA' keyword is one way to pass through any keywords you want
    PRO do_my_visualization, data, _REF_EXTRA=_extra
    ; [Your plotting or imaging commands go here]
    END

Later, whenever there is a LOADCT call, ...

    loadct, 5
    do_my_visualization, mydata, COLOR=100, BACKGROUND=200

This approach is the paradigm for programmers using XLOADCT's UPDATECALLBACK keyword, where the syntax would be:

    xloadct, UPDATECALLBACK='do_my_visualization', UPDATECBDATA=mydata

See the example code below for a complete demonstration of how to use XLOADCT's UPDATECALLBACK approach.


Approach 2 - Build Your Graphics Scene in the 8-bit Z Buffer and Store a Snapshot
This is particularly valid, if the graphics scene remains unchanged through LOADCT executions. The idea here is to build your graphics scene in the off-screen Z buffer, take a snapshot of the Z buffer "window" when the graphics scene is complete, and just call a TV of that snapshot right after every LOADCT is executed. The reason to use the Z buffer is that it is the offscreen graphics buffer which, by default, stores TVRD() snapshots in color table index values rather than in RGB values. Here, then, is example code for this approach:

    oldDevice = !d.name
    set_plot, 'Z'
    ; [Your plotting or imaging commands go here]
    snapshot = tvrd()
    set_plot, oldDevice ; Go back to 'WIN' or 'X' monitor device

    ; ...

    ; Later, whenever there is a LOADCT call, ...
    loadct, 5
    tv, snapshot ; all you need to update the display with new colors

Choice of optimal strategy depends on how quick and efficient it is to execute all the graphics commands that make up your current window. If the graphics commands that draw your scene are not too numerous. too time-consuming or too memory-demanding - and they usually are not - then Approach 1 is usually the most sensible.


Below - EXAMPLE DEMONSTRATING APPROACH 1 - REDRAW THE WHOLE SCENE

Solution:

; The wrapper function responsible for drawing the plot anew.
; Plots a two-line plot in 4 index-defined colors.
; This example is a little unrealistic, because it is overkill
; to be using all these keywords, if their values are not
; changing.
PRO do_my_visualization, data, $
    COLOR=color, PLOTLINE_COLOR=plotline_color, $
    OPLOT_LINESTYLE=oplot_linestyle, TEXT_COLOR=text_color, $
    _REF_EXTRA=_extra
; Note that settings for CHARSIZE and [XY]MARGIN are being
; passed via '_extra'
plot, data, /NODATA, XCHARSIZE=0.25, YCHARSIZE=0.25, _EXTRA=_extra
oplot, data, COLOR=plotline_color, _EXTRA=_extra
oplot, sqrt(data), COLOR=plotline_color, $
    LINESTYLE=oplot_linestyle, _EXTRA=_extra
xyouts, 0.5, 0.8, 'My Title', /NORMAL, ALIGNMENT=0.5, $
    COLOR=text_color, _EXTRA=_extra
END


; The function called by XLOADCT's 'UPDATECALLBACK' keyword.
; Simply calls the above drawing routine
PRO do_my_visualization_callback, DATA=dataStruct
; Notice how this 'dataStruct' approach allowed us to pass a
; large number of parameters through one variable.
do_my_visualization, dataStruct.data, BACKGROUND=dataStruct.bgColor, $
    PLOTLINE_COLOR=dataStruct.plotlineColor, $
    OPLOT_LINESTYLE=dataStruct.oplotLinestyle, $
    TEXT_COLOR=dataStruct.textColor, $
    CHARSIZE=4.0, XMARGIN=[2,1], YMARGIN=[1,1]
END


; Our main program routine.
; Gives in sequence an example of how XLOADCT can be set up
; to update automatically, followed by an example of how
; LOADCT can do the same.
PRO ex_pseudocolor_auto_update
device, GET_DECOMPOSED=originalDCstate   ; standard setup
device, DECOMPOSED=0
loadct, 5
mydata = findgen(30)
; DO_MY_VISUALIZATION executes all the drawing routines
do_my_visualization, mydata, BACKGROUND=20, $
    PLOTLINE_COLOR=150, OPLOT_LINESTYLE=3, TEXT_COLOR=200, $
    CHARSIZE=4.0, XMARGIN=[2,1], YMARGIN=[1,1]
; Define the struct that can be passed via UPDATECBDATA
callbackDataParameters = {data:mydata, bgColor:20, $
    plotlineColor:150, oplotLinestyle:3, textColor:200}
; Demonstrate the XLOADCT approach
xloadct, UPDATECALLBACK='do_my_visualization_callback', $
    UPDATECBDATA=callbackDataParameters, /BLOCK
; Demonstrate a LOADCT equivalent
void = dialog_message(['When you click OK', 'window will update', $
    'in Rainbow colors'], /INFO)
loadct, 13
do_my_visualization, mydata, BACKGROUND=20, $
    PLOTLINE_COLOR=150, OPLOT_LINESTYLE=3, TEXT_COLOR=200, $
    CHARSIZE=4.0, XMARGIN=[2,1], YMARGIN=[1,1]
device, DECOMPOSED=originalDCstate   ; standard restore
END
Please login or register to post comments.
Featured

End-of-Life Policy Enforcement for ENVI 5.3 / IDL 8.5 and Earlier Versions

5/6/2024

April 1, 2024 Dear ENVI/IDL Customer,  We are reaching out to notify you of our supported... more »

How to Upgrade licenses to ENVI 6.x / IDL 9.x

12/5/2023

What is the new Upgrade function? Starting with ENVI 6.0 and IDL 9.0, we have implemented an... more »

What to do if the 'License Administrator - License Server' for the Next-Generation License Server does not start?

6/13/2023

Background: With the release of ENVI 5.7 & IDL 8.9 and the corresponding Next-Generation licensing... more »

Next-Generation Licensing FAQ

4/28/2023

  NV5 Geospatial has adopted a new licensing technology for all future releases of our ENVI, IDL... more »

The IDL Virtual Machine

6/6/2013

What is the IDL Virtual Machine? An IDL Virtual Machine is a runtime version of IDL that can... more »