The Raster Image object displays its images using the texture image facility provided by the OpenGL library. OpenGL requires that the width and height of a texture image be a power of 2. The resizing of the image and the attached material data is handled internally by the Raster Image object, so the application need not be concerned about this restriction. However, set the image_flag attribute argument to True when creating a Material used in conjunction with a Raster Image object.

Figure 12: Intersecting Raster Image Objects


Figure 13: Image orientation
FILE *fp;
XWDFileHeader header;
XintColor4 *colors;
XColor *xcolors;
unsigned char *buffer;
XintView3DMaterial *material;
XintView3DMaterialColor color;
XintView3DMaterialAttributes attributes;
XintView3DColorTable *color_table;
XintColor4 *color_list;
In the case where the XWD file contains an 8 bit image, we use a material of type XintMATERIAL_COLOR_INDEX.
if (header.pixmap_depth == 8 && ncolors != 0) {
if (header.ncolors != 0) {
ncolors = header.ncolors;
xcolors = (XColor *) XtMalloc(sizeof(XColor) * ncolors);
colors = (XintColor4 *) XtMalloc(sizeof(XintColor4) * ncolors);
/* convert xcolors to XintColor4 colors */
for (i=0; i < ncolors; i++) {
colors[i][0] = (float) xcolors[i].red / 65535.;
colors[i][1] = (float) xcolors[i].green / 65535.;
colors[i][2] = (float) xcolors[i].blue / 65535.;
colors[i][3] = 1.0;
}
}
/* create a material of type XintMATERIAL_COLOR_INDEX*/
index_list = (int *) XtMalloc(sizeof(int) *
header.pixmap_width * header.pixmap_height);
for (j=0; j < header.pixmap_height; j++) {
count = j * header.bytes_per_line;
for (i=0; i < header.pixmap_width; i++)
index_list[i+j*header.pixmap_width] = buffer[count+i];
}
/* Create color table */
color.index.table = XintView3DCreateColorTable(colors,ncolors);
color.index.num_indices = header.pixmap_width * header.pixmap_height;
color.index.index = index_list;
attributes.light = False;
attributes.image_flag = True;
material = XintView3DCreateMaterial(NULL, XintMATERIAL_COLOR_INDEX,
&color,
XintMA_LIGHT | XintMA_IMAGE_FLAG,
&attributes);
XtFree((char *) index_list);
XtFree((char *) colors);
}
In the case where the XWD file contains a 24 bit image, we use a material of type XintMATERIAL_MULTI_COLOR.
if (header.pixmap_depth == 24) {
/* create a material of type XintMATERIAL_MULTI_COLOR */
color_list = (XintColor4 *) XtMalloc(sizeof(XintColor4) *
header.pixmap_width * header.pixmap_height);
for (j=0; j < header.pixmap_height; j++) {
count = j * header.bytes_per_line;
for (i=0; i < header.pixmap_width; i++) {
color_list[i + j * header.pixmap_width][0] =
(float) buffer[count + 4 * i + 3] / 255.;
color_list[i + j * header.pixmap_width][1] =
(float) buffer[count + 4 * i + 2] / 255.;
color_list[i + j * header.pixmap_width][2] =
(float) buffer[count + 4 * i + 1] / 255.;
color_list[i + j * header.pixmap_width][3] = 1.0;
}
}
attributes.light = False;
attributes.image_flag = True;
color.multi.num_colors = header.pixmap_height * header.pixmap_width;
color.multi.colors = color_list;
material = XintView3DCreateMaterial(NULL, XintMATERIAL_MULTI_COLOR,
&color,
XintMA_LIGHT | XintMA_IMAGE_FLAG,
&attributes);
XtFree((char *) color_list);
}
Finally, we create the Raster Image object and attach it to the viewer along with the material created as shown above.
XintVector3 upper_left, upper_right, lower_left, lower_right;
XintView3DObject *raster;
...
upper_left[0] = 0.25;
upper_left[1] = 0.75;
upper_left[2] = 0.25;
upper_right[0] = 0.75;
upper_right[1] = 0.75;
upper_right[2] = 0.25;
lower_right[0] = 0.75;
lower_right[1] = 0.25;
lower_right[2] = 0.25;
lower_left[0] = 0.25;
lower_left[1] = 0.25;
lower_left[2] = 0.25;
raster = XintView3DCreateRaster("tulip_image", upper_left, upper_right,
lower_right, lower_left, 0, NULL,
XintORIENT_ROW, True, nx, ny, NULL, NULL);
XintView3DAddObjectAndMaterial(view3d, raster, material, NULL);
...
The output of example imagexwd.c is shown below.

Figure 14: XWDimages displayed as Raster Image objects