/* graphics.pex.c */
/* Graphics functions for PEX */
/* [ SGJ: What is this file for? It seems to be superceded by
graphics.pex.c, and it was never used in the original Makefile ] */
/*
* Vis5D system for visualizing five dimensional gridded data sets.
* Copyright (C) 1990 - 2000 Bill Hibbard, Johan Kellum, Brian Paul,
* Dave Santek, and Andre Battaiola.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* As a special exception to the terms of the GNU General Public
* License, you are permitted to link Vis5D with (and distribute the
* resulting source and executables) the LUI library (copyright by
* Stellar Computer Inc. and licensed for distribution with Vis5D),
* the McIDAS library, and/or the NetCDF library, where those
* libraries are governed by the terms of their own licenses.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "../config.h"
#ifdef HAVE_PEX
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/PEX5/PEXlib.h>
#include <X11/PEX5/PEXHPlib.h>
#include <pexutcmap.h>
#include "globals.h"
#include "graphics.h"
#include "matrix.h"
typedef float Matrix[4][4];
/*** Private Variables: ***/
static float Scale;
static Matrix ModelMat, InvModelMat, ProjMat;
static PEXMatrix IdMat = { {1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0} };
static int Perspective = 0;
static Context current_ctx = NULL;
/******** PEX includes and variables *********/
#define VERTS_PER_CALL 400
static PEXRenderer Renderer;
static PEXRendererAttributes RendererAttrs;
static PEXMatrix InvertYMatrix;
static int InvertY;
static PEXMatrix MCtoDCMatrix;
static PEXMatrix DCtoMCMatrix;
void init_graphics2( void )
{
HQR_available = 0;
Perspec_available = 1;
}
void terminate_graphics( void )
{
}
void free_graphics( Display_Context dtx )
{
/* TODO */
}
void context_init( Context ctx, long win_id, int width, int height )
{
/* nothing for PEX */
}
int CheckAlphaSupport (display, window)
Display *display;
Window window;
{
int status, j, found;
int enum_types[1];
unsigned long *enum_counts;
PEXEnumTypeDesc *enum_values, *p_enum;
/*
Determine whether the Renderer can support alpha blending.
*/
enum_types[0] = PEXHPETTransparencyMethod;
status = PEXGetEnumTypeInfo (display, window,
1, enum_types,
PEXETCounts|PEXETIndex,
&enum_counts, &enum_values);
if (!status) {
fprintf(stderr, "inquiry of enumerated types failed - exiting\n");
exit(1);
}
p_enum = enum_values;
found = False;
for (j=0; j<enum_counts[0]; j++) {
if (((unsigned short) (p_enum++)->index) ==
((unsigned short) PEXHPTransparencyMethodAlphaBlend)) {
found = True;
}
}
PEXFreeEnumInfo (1, enum_counts, enum_values);
return found;
} /* CheckAlphaSupport */
int make_big_window( char *title, int xpos, int ypos, int width, int height)
{
PEXUtVisualCriteria VisualCriteria;
XVisualInfo VisualInfo;
XStandardColormap ColormapInfo;
PEXColorApproxEntry ColorApproxInfo;
unsigned int UnmetCriteria;
Atom StandardPropertyAtom;
int PexUtReturn;
PEXUtWindowSpecification WindowSpecification;
XColor Background;
PEXExtensionInfo *ExtensionInfo;
char Error[81];
XWindowAttributes window_attrs;
Window wmain;
unsigned long RenderMask, PipeMask[3];
PEXPCAttributes PipelineAttrs;
if (BigWindow){
printf("BigWindow already exists, so not making it again!!\n");
return 0;
}
if (PEXInitialize(GfxDpy, &ExtensionInfo, 80, Error) != 0) {
printf("PEXInitialize failed: %s\n", Error);
exit(-1);
}
WindowSpecification.attr_mask = CWEventMask;
WindowSpecification.attrs.event_mask =
ExposureMask | PointerMotionMask | KeyPressMask | ButtonPressMask
| ButtonReleaseMask | StructureNotifyMask | VisibilityChangeMask;
WindowSpecification.title = title;
WindowSpecification.size_hints.x = xpos;
WindowSpecification.size_hints.y = ypos;
WindowSpecification.size_hints.width = width;
WindowSpecification.size_hints.height = height;
WindowSpecification.size_hints.max_width = width;
WindowSpecification.size_hints.max_height = height;
/* WindowSpecification.size_hints.flags = USSize | USPosition | PMaxSize; */
WindowSpecification.size_hints.flags = USSize | USPosition;
if (DisplayMatrix == 11 && BigWindow != NULL){
WindowSpecification.parent = RootWindow(GfxDpy,GfxScr);
}
else {
WindowSpecification.parent = BigWindow;
}
WindowSpecification.parent = RootWindow(GfxDpy,GfxScr);
WindowSpecification.border_width = 0;
WindowSpecification.background_color_name = "black";
WindowSpecification.border_color_name = "black";
VisualCriteria.hard_criteria_mask = 0;
VisualCriteria.soft_criteria_mask = 0;
VisualCriteria.soft_criteria_mask |= PEXUtStandardColormapProperty;
VisualCriteria.standard_colormap_property = True;
VisualCriteria.hard_criteria_mask |= PEXUtDoubleBufferingCapability;
VisualCriteria.double_buffering_capability = True;
/*
** Try to find a visual with PEX double-buffering.
*/
PexUtReturn = PEXUtCreateWindowAndColormap(
GfxDpy,
GfxScr,
&VisualCriteria,
&WindowSpecification,
&wmain,
&VisualInfo,
&ColormapInfo,
&ColorApproxInfo,
&UnmetCriteria,
&StandardPropertyAtom,
&Background);
/*
** If PEXUtCreateWindowAndColormap() was unable to find a visual,
** try again for a visual that doesn't support double-buffering.
*/
if ( PexUtReturn == PEXUtCriteriaFailure ) {
VisualCriteria.hard_criteria_mask = 0;
PexUtReturn = PEXUtCreateWindowAndColormap(
GfxDpy,
GfxScr,
&VisualCriteria,
&WindowSpecification,
&wmain,
&VisualInfo,
&ColormapInfo,
&ColorApproxInfo,
&UnmetCriteria,
&StandardPropertyAtom,
&Background);
}
/*
** If PEXUtCreateWindowAndColormap() was still unable to create a window,
** report an error and exit.
*/
if ( ( PexUtReturn != PEXUtSuccess ) &&
( PexUtReturn != PEXUtQualifiedSuccess ) ) {
printf("Error: couldn't open 3-D window\n");
exit(-1);
}
if (XGetWindowAttributes(GfxDpy, wmain, &window_attrs) == 0) {
printf("Error: couldn't get window attributes\n");
exit(-1);
}
BigWindow = wmain;
BigWinWidth = window_attrs.width;
BigWinHeight = window_attrs.height;
/* set pointer shape */
XDefineCursor( GfxDpy, wmain, XCreateFontCursor(GfxDpy,XC_top_left_arrow) );
PipeMask[0] = PipeMask[1] = PipeMask[2] = 0;
PEXSetPCAttributeMask(PipeMask, PEXPCCharHeight);
PipelineAttrs.char_height = 9.0;
PEXSetPCAttributeMask(PipeMask, PEXPCInteriorStyle);
PipelineAttrs.interior_style = PEXInteriorStyleSolid;
PEXSetPCAttributeMask(PipeMask, PEXPCSurfaceColor);
PipelineAttrs.surface_color.type = PEXColorTypeRGB;
PipelineAttrs.surface_color.value.rgb.red = 1.0;
PipelineAttrs.surface_color.value.rgb.green = 1.0;
PipelineAttrs.surface_color.value.rgb.blue = 1.0;
PEXSetPCAttributeMask(PipeMask, PEXPCReflectionModel);
PipelineAttrs.reflection_model = PEXReflectionSpecular;
PEXSetPCAttributeMask(PipeMask, PEXPCReflectionAttr);
PipelineAttrs.reflection_attr.ambient = 1;
PipelineAttrs.reflection_attr.diffuse = 1;
PipelineAttrs.reflection_attr.transmission = 0;
PipelineAttrs.reflection_attr.specular = 1;
PipelineAttrs.reflection_attr.specular_conc = 30;
PipelineAttrs.reflection_attr.specular_color.type = PEXColorTypeRGB;
PipelineAttrs.reflection_attr.specular_color.value.rgb.red = 1;
PipelineAttrs.reflection_attr.specular_color.value.rgb.green = 1;
PipelineAttrs.reflection_attr.specular_color.value.rgb.blue = 1;
PEXSetPCAttributeMask(PipeMask, PEXPCSurfaceInterp);
PipelineAttrs.surface_interp = PEXSurfaceInterpColor;
PEXSetPCAttributeMask(PipeMask, PEXPCHLHSRIdentifier);
PipelineAttrs.hlhsr_id = PEXHLHSRIDEnable;
PEXSetPCAttributeMask(PipeMask, PEXPCDepthCueIndex);
PipelineAttrs.depth_cue_index = 0;
RendererAttrs.pipeline_context =
PEXCreatePipelineContext(GfxDpy, PipeMask, &PipelineAttrs);
RendererAttrs.clear_image = True;
RendererAttrs.clear_z = True;
RendererAttrs.background_color.type = PEXColorTypeRGB;
RendererAttrs.background_color.value.rgb.red = 0.0;
RendererAttrs.background_color.value.rgb.green = 0.0;
RendererAttrs.background_color.value.rgb.blue = 0.0;
RendererAttrs.hlhsr_mode = PEXHLHSRZBuffer;
RendererAttrs.light_table = PEXCreateLookupTable(GfxDpy, wmain, PEXLUTLight);
if (RendererAttrs.light_table == 0) {
printf( "Unable to create PEX light table\n" );
exit(-1);
}
RendererAttrs.view_table = PEXCreateLookupTable(GfxDpy, wmain, PEXLUTView);
if (RendererAttrs.view_table == 0) {
printf( "Unable to create PEX view table\n" );
exit(-1);
}
RendererAttrs.depth_cue_table = PEXCreateLookupTable(GfxDpy, wmain,
PEXLUTDepthCue);
if (RendererAttrs.depth_cue_table == 0) {
printf( "Unable to create PEX depth cue table\n" );
exit(-1);
}
RenderMask = PEXRAHLHSRMode | PEXRABackgroundColor | PEXRAClearImage
| PEXRAClearZ | PEXRALightTable | PEXRAViewTable | PEXRADepthCueTable
| PEXRAPipelineContext;
{
PEXLightEntry lights[3];
PEXTableIndex lights_on[1];
/* Define the ambient light. */
lights[0].type = PEXLightAmbient;
lights[0].color.type = PEXColorTypeRGB;
lights[0].color.value.rgb.red = 0.2;
lights[0].color.value.rgb.green = 0.2;
lights[0].color.value.rgb.blue = 0.2;
/* Define a directional light. */
lights[1].type = PEXLightWCVector;
lights[1].direction.x = 0;
lights[1].direction.y = 0;
lights[1].direction.z = 10;
lights[1].color.type = PEXColorTypeRGB;
lights[1].color.value.rgb.red = 0.8;
lights[1].color.value.rgb.green = 0.8;
lights[1].color.value.rgb.blue = 0.8;
/* Define another directional light. */
lights[2] = lights[1];
lights[2].direction.z = -10;
/* Add the lights to the light table. */
/*
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table, 1, 1, PEXLUTLight,
lights );
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table, 2, 1, PEXLUTLight,
lights );
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table, 3, 1, PEXLUTLight,
lights );
*/
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table,
1, 3, PEXLUTLight, lights );
/* enable ambient light */
/* lights_on[0] = 1;*/
/*
PEXSetLightSourceState(GfxDpy, Renderer, PEXOCRender, 1, lights_on,
0, (PEXTableIndex*)NULL );
*/
}
{
PEXDepthCueEntry DepthCues[2];
/* Define the no depth cue entry. */
DepthCues[0].mode = False;
DepthCues[0].front_plane = 1.0;
DepthCues[0].front_scaling = 1.0;
DepthCues[0].back_plane = 0.0;
DepthCues[0].back_scaling = 0.2;
DepthCues[0].color.type = PEXColorTypeRGB;
DepthCues[0].color.value.rgb.red = 0.0;
DepthCues[0].color.value.rgb.green = 0.0;
DepthCues[0].color.value.rgb.blue = 0.0;
/* Define the depth cue entry. */
DepthCues[1].mode = True;
DepthCues[1].front_plane = 1.0;
DepthCues[1].front_scaling = 1.0;
DepthCues[1].back_plane = 0.0;
DepthCues[1].back_scaling = 0.2;
DepthCues[1].color.type = PEXColorTypeRGB;
DepthCues[1].color.value.rgb.red = 0.0;
DepthCues[1].color.value.rgb.green = 0.0;
DepthCues[1].color.value.rgb.blue = 0.0;
/* Add the depth cues to the table. */
PEXSetTableEntries(GfxDpy, RendererAttrs.depth_cue_table, 0, 2,
PEXLUTDepthCue, DepthCues);
}
Renderer = PEXCreateRenderer(GfxDpy, wmain, RenderMask, &RendererAttrs);
if (Renderer == 0) {
printf( "Unable to create PEX renderer\n" );
exit(-1);
}
XSync(GfxDpy, False);
resize_3d_window(width, height);
return wmain;
}
/*
* Make a 3-D graphics window.
* Input:
* ctx - the Vis5D context
* title - window title string
* xpos,ypos - position in pixel from upper-left corner
* width, height - width and height of window in pixels
* Return: X window pointer or NULL.
*/
int make_3d_window( Display_Context dtx, char *title, int xpos, int ypos,
int width, int height )
{
PEXUtVisualCriteria VisualCriteria;
XVisualInfo VisualInfo;
XStandardColormap ColormapInfo;
PEXColorApproxEntry ColorApproxInfo;
unsigned int UnmetCriteria;
Atom StandardPropertyAtom;
int PexUtReturn;
PEXUtWindowSpecification WindowSpecification;
XColor Background;
PEXExtensionInfo *ExtensionInfo;
char Error[81];
XWindowAttributes window_attrs;
Window wmain;
unsigned long RenderMask, PipeMask[3];
PEXPCAttributes PipelineAttrs;
current_ctx = ctx;
if (PEXInitialize(GfxDpy, &ExtensionInfo, 80, Error) != 0) {
printf("PEXInitialize failed: %s\n", Error);
exit(-1);
}
WindowSpecification.attr_mask = CWEventMask;
WindowSpecification.attrs.event_mask =
ExposureMask | PointerMotionMask | KeyPressMask | ButtonPressMask
| ButtonReleaseMask | StructureNotifyMask | VisibilityChangeMask;
WindowSpecification.title = title;
WindowSpecification.size_hints.x = xpos;
WindowSpecification.size_hints.y = ypos;
WindowSpecification.size_hints.width = width;
WindowSpecification.size_hints.height = height;
WindowSpecification.size_hints.max_width = width;
WindowSpecification.size_hints.max_height = height;
/* WindowSpecification.size_hints.flags = USSize | USPosition | PMaxSize; */
WindowSpecification.size_hints.flags = USSize | USPosition;
if (DisplayMatrix == 11 && BigWindow != NULL){
WindowSpecification.parent = RootWindow(GfxDpy,GfxScr);
}
else {
WindowSpecification.parent = BigWindow;
}
WindowSpecification.parent = RootWindow(GfxDpy,GfxScr);
WindowSpecification.border_width = 0;
WindowSpecification.background_color_name = "black";
WindowSpecification.border_color_name = "black";
VisualCriteria.hard_criteria_mask = 0;
VisualCriteria.soft_criteria_mask = 0;
VisualCriteria.soft_criteria_mask |= PEXUtStandardColormapProperty;
VisualCriteria.standard_colormap_property = True;
VisualCriteria.hard_criteria_mask |= PEXUtDoubleBufferingCapability;
VisualCriteria.double_buffering_capability = True;
/*
** Try to find a visual with PEX double-buffering.
*/
PexUtReturn = PEXUtCreateWindowAndColormap(
GfxDpy,
GfxScr,
&VisualCriteria,
&WindowSpecification,
&wmain,
&VisualInfo,
&ColormapInfo,
&ColorApproxInfo,
&UnmetCriteria,
&StandardPropertyAtom,
&Background);
/*
** If PEXUtCreateWindowAndColormap() was unable to find a visual,
** try again for a visual that doesn't support double-buffering.
*/
if ( PexUtReturn == PEXUtCriteriaFailure ) {
VisualCriteria.hard_criteria_mask = 0;
PexUtReturn = PEXUtCreateWindowAndColormap(
GfxDpy,
GfxScr,
&VisualCriteria,
&WindowSpecification,
&wmain,
&VisualInfo,
&ColormapInfo,
&ColorApproxInfo,
&UnmetCriteria,
&StandardPropertyAtom,
&Background);
}
/*
** If PEXUtCreateWindowAndColormap() was still unable to create a window,
** report an error and exit.
*/
if ( ( PexUtReturn != PEXUtSuccess ) &&
( PexUtReturn != PEXUtQualifiedSuccess ) ) {
printf("Error: couldn't open 3-D window\n");
exit(-1);
}
if (XGetWindowAttributes(GfxDpy, wmain, &window_attrs) == 0) {
printf("Error: couldn't get window attributes\n");
exit(-1);
}
ctx->GfxWindow = wmain;
ctx->WinWidth = window_attrs.width;
ctx->WinHeight = window_attrs.height;
ctx->FontHeight = (int) 9.0; /*TODO FIX*/
ctx->FontDescent = (int) 0.1;
/* set pointer shape */
XDefineCursor( GfxDpy, wmain, XCreateFontCursor(GfxDpy,XC_top_left_arrow) );
PipeMask[0] = PipeMask[1] = PipeMask[2] = 0;
PEXSetPCAttributeMask(PipeMask, PEXPCCharHeight);
PipelineAttrs.char_height = 9.0;
PEXSetPCAttributeMask(PipeMask, PEXPCInteriorStyle);
PipelineAttrs.interior_style = PEXInteriorStyleSolid;
PEXSetPCAttributeMask(PipeMask, PEXPCSurfaceColor);
PipelineAttrs.surface_color.type = PEXColorTypeRGB;
PipelineAttrs.surface_color.value.rgb.red = 1.0;
PipelineAttrs.surface_color.value.rgb.green = 1.0;
PipelineAttrs.surface_color.value.rgb.blue = 1.0;
PEXSetPCAttributeMask(PipeMask, PEXPCReflectionModel);
PipelineAttrs.reflection_model = PEXReflectionSpecular;
PEXSetPCAttributeMask(PipeMask, PEXPCReflectionAttr);
PipelineAttrs.reflection_attr.ambient = 1;
PipelineAttrs.reflection_attr.diffuse = 1;
PipelineAttrs.reflection_attr.transmission = 0;
PipelineAttrs.reflection_attr.specular = 1;
PipelineAttrs.reflection_attr.specular_conc = 30;
PipelineAttrs.reflection_attr.specular_color.type = PEXColorTypeRGB;
PipelineAttrs.reflection_attr.specular_color.value.rgb.red = 1;
PipelineAttrs.reflection_attr.specular_color.value.rgb.green = 1;
PipelineAttrs.reflection_attr.specular_color.value.rgb.blue = 1;
PEXSetPCAttributeMask(PipeMask, PEXPCSurfaceInterp);
PipelineAttrs.surface_interp = PEXSurfaceInterpColor;
PEXSetPCAttributeMask(PipeMask, PEXPCHLHSRIdentifier);
PipelineAttrs.hlhsr_id = PEXHLHSRIDEnable;
PEXSetPCAttributeMask(PipeMask, PEXPCDepthCueIndex);
PipelineAttrs.depth_cue_index = 0;
RendererAttrs.pipeline_context =
PEXCreatePipelineContext(GfxDpy, PipeMask, &PipelineAttrs);
RendererAttrs.clear_image = True;
RendererAttrs.clear_z = True;
RendererAttrs.background_color.type = PEXColorTypeRGB;
RendererAttrs.background_color.value.rgb.red = 0.0;
RendererAttrs.background_color.value.rgb.green = 0.0;
RendererAttrs.background_color.value.rgb.blue = 0.0;
RendererAttrs.hlhsr_mode = PEXHLHSRZBuffer;
RendererAttrs.light_table = PEXCreateLookupTable(GfxDpy, wmain, PEXLUTLight);
if (RendererAttrs.light_table == 0) {
printf( "Unable to create PEX light table\n" );
exit(-1);
}
RendererAttrs.view_table = PEXCreateLookupTable(GfxDpy, wmain, PEXLUTView);
if (RendererAttrs.view_table == 0) {
printf( "Unable to create PEX view table\n" );
exit(-1);
}
RendererAttrs.depth_cue_table = PEXCreateLookupTable(GfxDpy, wmain,
PEXLUTDepthCue);
if (RendererAttrs.depth_cue_table == 0) {
printf( "Unable to create PEX depth cue table\n" );
exit(-1);
}
RenderMask = PEXRAHLHSRMode | PEXRABackgroundColor | PEXRAClearImage
| PEXRAClearZ | PEXRALightTable | PEXRAViewTable | PEXRADepthCueTable
| PEXRAPipelineContext;
{
PEXLightEntry lights[3];
PEXTableIndex lights_on[1];
/* Define the ambient light. */
lights[0].type = PEXLightAmbient;
lights[0].color.type = PEXColorTypeRGB;
lights[0].color.value.rgb.red = 0.2;
lights[0].color.value.rgb.green = 0.2;
lights[0].color.value.rgb.blue = 0.2;
/* Define a directional light. */
lights[1].type = PEXLightWCVector;
lights[1].direction.x = 0;
lights[1].direction.y = 0;
lights[1].direction.z = 10;
lights[1].color.type = PEXColorTypeRGB;
lights[1].color.value.rgb.red = 0.8;
lights[1].color.value.rgb.green = 0.8;
lights[1].color.value.rgb.blue = 0.8;
/* Define another directional light. */
lights[2] = lights[1];
lights[2].direction.z = -10;
/* Add the lights to the light table. */
/*
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table, 1, 1, PEXLUTLight,
lights );
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table, 2, 1, PEXLUTLight,
lights );
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table, 3, 1, PEXLUTLight,
lights );
*/
PEXSetTableEntries( GfxDpy, RendererAttrs.light_table,
1, 3, PEXLUTLight, lights );
/* enable ambient light */
/* lights_on[0] = 1;*/
/*
PEXSetLightSourceState(GfxDpy, Renderer, PEXOCRender, 1, lights_on,
0, (PEXTableIndex*)NULL );
*/
}
{
PEXDepthCueEntry DepthCues[2];
/* Define the no depth cue entry. */
DepthCues[0].mode = False;
DepthCues[0].front_plane = 1.0;
DepthCues[0].front_scaling = 1.0;
DepthCues[0].back_plane = 0.0;
DepthCues[0].back_scaling = 0.2;
DepthCues[0].color.type = PEXColorTypeRGB;
DepthCues[0].color.value.rgb.red = 0.0;
DepthCues[0].color.value.rgb.green = 0.0;
DepthCues[0].color.value.rgb.blue = 0.0;
/* Define the depth cue entry. */
DepthCues[1].mode = True;
DepthCues[1].front_plane = 1.0;
DepthCues[1].front_scaling = 1.0;
DepthCues[1].back_plane = 0.0;
DepthCues[1].back_scaling = 0.2;
DepthCues[1].color.type = PEXColorTypeRGB;
DepthCues[1].color.value.rgb.red = 0.0;
DepthCues[1].color.value.rgb.green = 0.0;
DepthCues[1].color.value.rgb.blue = 0.0;
/* Add the depth cues to the table. */
PEXSetTableEntries(GfxDpy, RendererAttrs.depth_cue_table, 0, 2,
PEXLUTDepthCue, DepthCues);
}
Renderer = PEXCreateRenderer(GfxDpy, wmain, RenderMask, &RendererAttrs);
if (Renderer == 0) {
printf( "Unable to create PEX renderer\n" );
exit(-1);
}
XSync(GfxDpy, False);
if (PEXUtDBConfig(GfxDpy, wmain, True, &Background, False, &ctx->db_win)) {
ctx->use_db = False;
ctx->db_win = wmain;
} else {
ctx->use_db = True;
}
XSync(GfxDpy, False);
ctx->has_blending = CheckAlphaSupport(GfxDpy, ctx->db_win);
resize_3d_window(width, height);
return wmain;
}
void set_current_window( Context ctx )
{
current_ctx = ctx;
}
int set_3d_font( Context ctx, char *name, int size )
{
/*TODO */
}
void set_pointer( int p )
{
if (p) {
/* make busy cursor */
XDefineCursor( GfxDpy, current_ctx->GfxWindow,
XCreateFontCursor(GfxDpy,XC_watch) );
}
else {
XDefineCursor( GfxDpy, current_ctx->GfxWindow,
XCreateFontCursor(GfxDpy,XC_top_left_arrow) );
}
}
int save_formats( void )
{
return VIS5D_XWD;
}
int save_3d_window( char *filename, int format )
{
FILE *f;
set_pointer(1);
/* Make an X window dump file (.xwd) */
f = fopen(filename,"w");
if (f) {
Window_Dump( GfxDpy, GfxScr, current_ctx->GfxWindow, f );
fclose(f);
set_pointer(0);
return 1;
}
else {
printf("Error unable to open %s for writing\n", filename);
set_pointer(0);
return 0;
}
}
int print_3d_window( void )
{
static char xwd_file[] = "/usr/tmp/Vis5d_image.xwd";
char cmd[1000];
FILE *f;
set_pointer(1);
/* Make an X window dump file (.xwd) */
f = fopen(xwd_file,"w");
if (f) {
printf("Writing X window dump: %s\n", xwd_file);
Window_Dump( GfxDpy, GfxScr, current_ctx->GfxWindow, f );
fclose(f);
/* Use xpr to print the window dump */
if (!installed("xpr")) return 0;
sprintf(cmd,"xpr -device ps %s | lpr\n", xwd_file );
printf("Executing: %s\n", cmd );
system(cmd);
/* delete xwd file */
unlink( xwd_file );
printf("Done.\n");
set_pointer(0);
return 1;
}
else {
printf("Error unable to open %s for writing\n", xwd_file);
set_pointer(0);
return 0;
}
}
void clear_color( unsigned int bgcolor )
{
unsigned long mask = PEXRABackgroundColor;
float r, g, b;
r = UNPACK_RED(bgcolor)/255.0;
g = UNPACK_GREEN(bgcolor)/255.0;
b = UNPACK_BLUE(bgcolor)/255.0;
RendererAttrs.background_color.type = PEXColorTypeRGB;
RendererAttrs.background_color.value.rgb.red = r;
RendererAttrs.background_color.value.rgb.green = g;
RendererAttrs.background_color.value.rgb.blue = b;
PEXChangeRenderer( GfxDpy, Renderer, mask, &RendererAttrs );
}
void clear_3d_window( void )
{
/* Clear is implicit in BeginRendering in set_3d. */
}
/*
* Called when window size changes.
*/
void resize_3d_window( int width, int height )
{
/* printf("resize %d %d\n", width, height );*/
current_ctx->WinWidth = width;
current_ctx->WinHeight = height;
PEXUtDBResize( GfxDpy, current_ctx->GfxWindow );
{
float ratio, delta;
if( width > height)
{
ratio = (float)width / (float)height;
delta = (1.0 / ratio) * 0.5;
RendererAttrs.npc_subvolume.min.x = 0;
RendererAttrs.npc_subvolume.min.y = 0.5 - delta;
RendererAttrs.npc_subvolume.min.z = 0;
RendererAttrs.npc_subvolume.max.x = 1.0;
RendererAttrs.npc_subvolume.max.y = 0.5 + delta;
RendererAttrs.npc_subvolume.max.z = 1.0;
}
else
{
ratio = (float)height / (float)width;
delta = (1.0 / ratio) * 0.5;
RendererAttrs.npc_subvolume.min.x = 0.5 - delta;
RendererAttrs.npc_subvolume.min.y = 0;
RendererAttrs.npc_subvolume.min.z = 0;
RendererAttrs.npc_subvolume.max.x = 0.5 + delta;
RendererAttrs.npc_subvolume.max.y = 1.0;
RendererAttrs.npc_subvolume.max.z = 1.0;
}
PEXChangeRenderer(GfxDpy, Renderer, PEXRANPCSubVolume, &RendererAttrs);
}
{
PEXViewEntry views[2];
PEXCoord2D view_window[2];
double view_plane,
front_plane,
back_plane;
PEXCoord prp;
PEXNPCSubVolume viewport;
static PEXCoord view_ref_pt = {0.0, 0.0, 0.0};
static PEXVector view_plane_normal = {0.0, 0.0, 1.0};
static PEXVector view_up_vec = {0,1,0};
PEXViewOrientationMatrix( &view_ref_pt, &view_plane_normal,
&view_up_vec, views[0].orientation );
PEXViewOrientationMatrix( &view_ref_pt, &view_plane_normal,
&view_up_vec, views[1].orientation );
/*
** The view mapping parameters.
*/
view_window[0].x = 0;
view_window[0].y = 0;
view_window[1].x = width-1;
view_window[1].y = height-1;
prp.x = view_window[1].x / 2.0;
prp.y = view_window[1].y / 2.0;
prp.z = 4.0;
front_plane = 1;
view_plane = 0;
back_plane = -1;
viewport.min.x = RendererAttrs.npc_subvolume.min.x;
viewport.max.x = RendererAttrs.npc_subvolume.max.x;
viewport.min.y = RendererAttrs.npc_subvolume.min.y;
viewport.max.y = RendererAttrs.npc_subvolume.max.y;
viewport.min.z = 0;
viewport.max.z = 1;
PEXViewMappingMatrix(view_window, &viewport, False, &prp, view_plane,
back_plane, front_plane, views[0].mapping);
views[0].clip_flags = PEXClippingAll;
views[0].clip_limits = viewport;
view_window[0].x = -1;
view_window[0].y = -1;
view_window[1].x = 1;
view_window[1].y = 1;
front_plane = 1;
view_plane = 0;
back_plane = -1;
prp.x = 0.0;
prp.y = 0.0;
prp.z = 5.0;
PEXViewMappingMatrix(view_window, &viewport, False, &prp, view_plane,
back_plane, front_plane, views[1].mapping);
views[1].clip_flags = PEXClippingAll;
views[1].clip_limits = viewport;
PEXSetTableEntries(GfxDpy, RendererAttrs.view_table, 0, 2, PEXLUTView,
(PEXPointer) views);
}
}
void swap_3d_window( void )
{
PEXEndRendering(GfxDpy, Renderer, True);
if (current_ctx->use_db) {
current_ctx->db_win = PEXUtDBSwap( GfxDpy, current_ctx->GfxWindow, False);
}
XSync (GfxDpy, False);
}
static void decomposition(xform3, pivot)
PEXMatrix xform3;
int pivot[4];
/* Performs the Lu decomposition for Gaussian elimination with partial
* pivoting. On entry:
* xform3 - array to be decomposed
* On exit:
* xform3 - contains the LU decomposition
* pivot - contains the pivot history...the original position numbers
* of the pivoted rows.
*/
{
register int i, j, step;
register float temp, mfact; /*temp & row multiplication factor*/
register float abs_istep, abs_maxstep; /*used to get absolute values*/
register int itemp, max; /*temp & maximum coefficient*/
for (i = 0; i <= 3; i++)
pivot[i] = i;
for (step = 0; step <= 3; step++) {
max = step;
for (i = step + 1; i <= 3; i++) {
abs_istep = xform3[i][step];
if (abs_istep < 0.0)
abs_istep = -abs_istep;
abs_maxstep = xform3[max][step];
if (abs_maxstep < 0.0)
abs_maxstep = -abs_maxstep;
if (abs_istep > abs_maxstep)
max = i;
}
if (xform3[max][step] == 0.0) {
printf("Couldn't invert a transform.\n");
exit(-1);
}
if (max != step) {
for (j = 0; j <= 3; j++) {
temp = xform3[step][j];
xform3[step][j] = xform3[max][j];
xform3[max][j] = temp;
}
itemp = pivot[step];
pivot[step] = pivot[max];
pivot[max] = itemp;
}
for (i = step + 1; i <= 3; i++) {
mfact = -xform3[i][step] / xform3[step][step];
xform3[i][step] = -mfact;
for (j = step + 1; j <= 3; j++)
xform3[i][j] = mfact * xform3[step][j] + xform3[i][j];
}
}
}
static void solve(xform3, col, result, pivot)
PEXMatrix xform3;
float col[4], result[4];
int pivot[4];
{
register int solv, i;
float sum; /*used for computing a sum while backsolving*/
float y[4]; /*used for computing Ly=Pb*/
/*Solve for y in Ly=Pb*/
for (solv = 0; solv <= 3; solv++) {
sum = 0.0;
for (i = 0; i <= solv - 1; i++)
sum = sum + y[i] * xform3[solv][i];
y[solv] = col[pivot[solv]] - sum;
}
/*Solve for x in Ux=y*/
for (solv = 3; solv >= 0; solv--) {
sum = 0.0;
for (i = solv + 1; i <= 3; i++)
sum += result[i] * xform3[solv][i];
result[solv] = (y[solv] - sum) / xform3[solv][solv];
}
}
static void compute_inverse(xform1, xform2)
PEXMatrix xform1, xform2;
{
int pivot[4]; /*pivot history - used to remember original*/
/*row numbers of the pivoted rows*/
float idcol[4]; /*columns of the identity matrix*/
float result[4]; /*inverse is solved one column at a time*/
register int i, j;
PEXMatrix txform; /*temp copy of xform1*/
memcpy(txform, xform1, sizeof(PEXMatrix));
decomposition(txform, pivot);
/*Solve system with columns of identity matrix as solutions*/
for (i = 0; i <= 3; i++) {
for (j = 0; j <= 3; j++)
idcol[j] = 0.0;
idcol[i] = 1.0;
solve(txform, idcol, result, pivot);
/* Resultant columns are the columns of inverse matrix*/
for (j = 0; j <= 3; j++)
xform2[j][i] = result[j];
}
}
/*
* Setup for 3-D rendering
*/
void set_3d( int perspective, float frontclip, float zoom, float *modelmat )
{
PEXViewEntry view;
PEXCoord2D view_window[2];
double view_plane,
front_plane,
back_plane;
PEXCoord prp;
PEXNPCSubVolume viewport;
static PEXCoord view_ref_pt = {0.0, 0.0, 0.0};
static PEXVector view_plane_normal = {0.0, 0.0, 1.0};
static PEXVector view_up_vec = {0,1,0};
PEXMatrix global;
register int i, j;
PEXTableIndex lights_on[3];
PEXVector ShiftVector,
ScaleVector;
PEXMatrix TranslateMatrix,
ScaleMatrix,
InvertZMatrix,
NPCtoXCMatrix;
PEXDeviceCoord DCViewPort[2];
float FrontClip;
/* This also clears the window */
PEXBeginRendering(GfxDpy, current_ctx->db_win, Renderer);
InvertY = False;
Perspective = perspective;
Scale = zoom;
FrontClip = 1.0 - 2.0*frontclip; /*TODO: verify*/
if (FrontClip < -0.9) {
/* to prevent front plane == back plane */
FrontClip = -0.9;
}
/*
** The view mapping parameters.
*/
prp.x = 0.0;
prp.y = 0.0;
prp.z = 5.0;
front_plane = zoom * 1.75 * FrontClip;
/* prp must be outside front clip plane */
if (front_plane > 4.9) front_plane = 4.9;
view_plane = 0.0;
back_plane = -zoom * 1.75 /* * FrontClip */;
viewport.min.x = 0;
viewport.max.x = 1;
viewport.min.y = 0;
viewport.max.y = 1;
viewport.min.z = 0;
viewport.max.z = 1;
view_window[0].x = -1.5;
view_window[0].y = -1.5;
view_window[1].x = 1.5;
view_window[1].y = 1.5;
PEXViewOrientationMatrix(&view_ref_pt, &view_plane_normal,
&view_up_vec, view.orientation);
PEXViewMappingMatrix(view_window, &viewport, Perspective, &prp, view_plane,
back_plane, front_plane, view.mapping);
view.clip_flags = PEXClippingAll;
view.clip_limits = viewport;
PEXSetTableEntries(GfxDpy, RendererAttrs.view_table, 1, 1, PEXLUTView,
(PEXPointer) &view);
PEXSetViewIndex(GfxDpy, Renderer, PEXOCRender, 1);
RendererAttrs.hlhsr_mode = PEXHLHSRZBuffer;
PEXChangeRenderer(GfxDpy, Renderer, PEXRAHLHSRMode, &RendererAttrs);
if ( current_ctx->has_blending ) {
unsigned long mask[2];
PEXHPRendererAttributes hp_attrs;
mask[0] = 0;
mask[1] = 0;
PEXHPSetRendererAttributeMask(mask, PEXHPRATransparencyMethod);
if (current_ctx->AlphaBlend) {
hp_attrs.transparency_method =
(unsigned long) PEXHPTransparencyMethodAlphaBlend;
} else {
hp_attrs.transparency_method =
(unsigned long) PEXHPTransparencyMethodScreenDoor;
}
PEXHPChangeRenderer( GfxDpy, Renderer, mask, &hp_attrs);
PEXHPSetAlphaBlendFunction( GfxDpy, Renderer, PEXOCRender,
PEXHPAlphaBlendFunctionSimpleAlpha);
}
/* Turn the lights on. */
lights_on[0] = 1;
lights_on[1] = 2;
lights_on[2] = 3;
PEXSetLightSourceState(GfxDpy, Renderer, PEXOCRender, 3, lights_on,
0, (PEXTableIndex*)NULL );
/* Transpose matrix. */
for (i=0; i<4; i++) {
for (j=0; j<4; j++) {
global[i][j] = modelmat[j*4+i];
}
}
/* Change the model matrix so a z range of 0 to 1 becomes 1 to 0 */
ScaleVector.x = ScaleVector.y = ScaleVector.z = Scale;
PEXScale(&ScaleVector, ScaleMatrix);
PEXMatrixMult(ScaleMatrix, global, global);
PEXSetGlobalTransform(GfxDpy, Renderer, PEXOCRender, global);
/* Create inverse matrix to use in project and unproject. */
DCViewPort[0].x = DCViewPort[0].y = DCViewPort[0].z = 0.0;
DCViewPort[1].x = current_ctx->WinWidth;
DCViewPort[1].y = current_ctx->WinHeight;
DCViewPort[1].z = 1.0;
PEXNPCToXCTransform(&viewport, DCViewPort, current_ctx->WinHeight, NPCtoXCMatrix);
PEXMatrixMult(view.orientation, global, MCtoDCMatrix);
PEXMatrixMult(view.mapping, MCtoDCMatrix, MCtoDCMatrix);
PEXMatrixMult(NPCtoXCMatrix, MCtoDCMatrix, MCtoDCMatrix);
compute_inverse(MCtoDCMatrix, DCtoMCMatrix);
}
/*** set_2d ***********************************************************
This is to be called prior to any 2-D rendering calls.
**********************************************************************/
void set_2d( void )
{
PEXVector ShiftVector, ScaleVector;
PEXMatrix TranslateMatrix, ScaleMatrix;
/* Change the model matrix so a y range of 0 to Height becomes Height to 0 */
InvertY = True;
ScaleVector.x = 1.0; ScaleVector.y = -1.0; ScaleVector.z = 1.0;
PEXScale(&ScaleVector, ScaleMatrix);
ShiftVector.x = 0.0; ShiftVector.y = current_ctx->WinHeight; ShiftVector.z = 0.0;
PEXTranslate(&ShiftVector, TranslateMatrix);
PEXMatrixMult(TranslateMatrix, ScaleMatrix, InvertYMatrix);
PEXSetGlobalTransform(GfxDpy, Renderer, PEXOCRender, InvertYMatrix);
PEXSetViewIndex(GfxDpy, Renderer, PEXOCRender, 0);
RendererAttrs.hlhsr_mode = PEXHLHSROff;
PEXChangeRenderer(GfxDpy, Renderer, PEXRAHLHSRMode, &RendererAttrs);
}
/*** project **********************************************************
Use current transformation and viewing information to project a
point p from 3-D graphics coordinates to 2-D window coordinates
in [0,WinWidth-1]x[0,WinHeight-1].
Input: p - 3-D point in graphics space
Output: x, y - 2-D point in window pixel coordinates.
**********************************************************************/
void project( float p[3], float *x, float *y )
{
PEXCoord DC[1], MC[1];
MC[0].x = p[0];
MC[0].y = p[1];
MC[0].z = p[2];
PEXTransformPoints(MCtoDCMatrix, 1, MC, DC);
*x = DC[0].x;
*y = DC[0].y;
}
/*** unproject ********************************************************
Given a 2-D window coordinate in [0,WinWidth-1]x[0,WinHeight-1],
return the parametric equation of a line in 3-D such that the
projection of the line from 3-D to 2-D is a point at the window
coordinate.
Input: x, y - window coordinate.
Output: p, d - parametric equation of line: l = p + t*d
NOTE, d will have unit length
**********************************************************************/
void unproject( float x, float y, float p[3], float d[3] )
{
PEXCoord DC[2], MC[2];
float scale;
DC[0].x = x;
DC[0].y = y;
DC[0].z = 1.0;
DC[1].x = x;
DC[1].y = y;
DC[1].z = 0.0;
PEXTransformPoints(DCtoMCMatrix, 2, DC, MC);
p[0] = MC[0].x;
p[1] = MC[0].y;
p[2] = MC[0].z;
d[0] = MC[1].x - MC[0].x;
d[1] = MC[1].y - MC[0].y;
d[2] = MC[1].z - MC[0].z;
scale = 1.0 / sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
d[0] *= scale;
d[1] *= scale;
d[2] *= scale;
}
static void enable_lighting( int onoff )
{
PEXTableIndex lights[3];
lights[0] = 1;
lights[1] = 2;
lights[2] = 3;
if (onoff) {
PEXSetReflectionModel( GfxDpy, Renderer, PEXOCRender,
PEXReflectionDiffuse /*Specular*/ );
}
else {
PEXSetReflectionModel( GfxDpy, Renderer,
PEXOCRender, PEXReflectionNone );
}
}
void transparency_mode( Context ctx, int mode )
{
if (mode==1) {
ctx->AlphaBlend = 1;
}
else {
ctx->AlphaBlend = 0;
}
}
void set_color( unsigned int c )
{
PEXColor color;
PEXReflectionAttributes reflection;
float alpha;
color.rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
color.rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
color.rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
PEXSetLineColor(GfxDpy, Renderer, PEXOCRender, PEXColorTypeRGB, &color);
PEXSetSurfaceColor(GfxDpy, Renderer, PEXOCRender, PEXColorTypeRGB, &color);
PEXSetTextColor(GfxDpy, Renderer, PEXOCRender, PEXColorTypeRGB, &color);
alpha = UNPACK_ALPHA(c) * 1.0 / 255.0;
reflection.ambient = 1;
reflection.diffuse = 1;
reflection.transmission = 1.0 - alpha;
reflection.specular = 1;
reflection.specular_conc = 30;
reflection.specular_color.type = PEXColorTypeRGB;
reflection.specular_color.value.rgb.red = 1;
reflection.specular_color.value.rgb.green = 1;
reflection.specular_color.value.rgb.blue = 1;
PEXSetReflectionAttributes(GfxDpy, Renderer, PEXOCRender, &reflection);
if (reflection.transmission > 0.0) {
if (RendererAttrs.hlhsr_mode == PEXHLHSRZBuffer) {
/* Make transparent primitives not update the Z buffer
so they won't completely obscure later transparent primitives. */
{
static int init=False, hsroff;
if(!init){init=True; hsroff=(getenv("HSROFF")!=NULL);}
if(hsroff) {
RendererAttrs.hlhsr_mode = PEXHLHSROff;
PEXChangeRenderer(GfxDpy, Renderer, PEXRAHLHSRMode, &RendererAttrs);
}
}
RendererAttrs.hlhsr_mode = PEXHPHLHSRZBufferReadOnly;
PEXChangeRenderer(GfxDpy, Renderer, PEXRAHLHSRMode, &RendererAttrs);
}
} else {
if (RendererAttrs.hlhsr_mode == PEXHPHLHSRZBufferReadOnly) {
/* Make opaque primitives update the Z buffer. */
RendererAttrs.hlhsr_mode = PEXHLHSRZBuffer;
PEXChangeRenderer(GfxDpy, Renderer, PEXRAHLHSRMode, &RendererAttrs);
}
}
}
void set_depthcue( int onoff )
{
if (onoff) {
PEXSetDepthCueIndex(GfxDpy, Renderer, PEXOCRender, 1);
} else {
PEXSetDepthCueIndex(GfxDpy, Renderer, PEXOCRender, 0);
}
}
void set_line_width( double w )
{
PEXSetLineWidth(GfxDpy, Renderer, PEXOCRender, w);
}
void set_pretty( int onoff )
{
}
void start_aa_pass( int n )
{
/* nothing */
}
void end_aa_pass( int n )
{
/* nothing */
}
/**********************************************************************/
/*** Drawing Functions ***/
/**********************************************************************/
void draw_isosurface( int n,
#ifdef BIG_GFX
uint_4 *index,
#else
uint_2 *index,
#endif
int_2 verts[][3],
int_1 norms[][3],
unsigned int color )
{
int i, j, k, remaining_points;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
PEXVertexNormal vertex_data[VERTS_PER_CALL];
float vscale = 1.0/VERTEX_SCALE;
float nscale = 1.0/NORMAL_SCALE;
enable_lighting(1);
set_color( color );
remaining_points = n;
k = 0;
data.normal = vertex_data;
facet_data.normal = NULL;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
j = index[k+i];
vertex_data[i].point.x = verts[j][0] * vscale;
vertex_data[i].point.y = verts[j][1] * vscale;
vertex_data[i].point.z = verts[j][2] * vscale;
vertex_data[i].normal.x = norms[j][0] * nscale;
vertex_data[i].normal.y = norms[j][1] * nscale;
vertex_data[i].normal.z = norms[j][2] * nscale;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANormal, PEXColorTypeRGB, facet_data,
VERTS_PER_CALL, data);
k += VERTS_PER_CALL-2; /* Triangles overlap by two points. */
remaining_points -= VERTS_PER_CALL-2;
}
if (remaining_points > 2) {
for (i=0; i<remaining_points; i++) {
j = index[k+i];
vertex_data[i].point.x = verts[j][0] * vscale;
vertex_data[i].point.y = verts[j][1] * vscale;
vertex_data[i].point.z = verts[j][2] * vscale;
vertex_data[i].normal.x = norms[j][0] * nscale;
vertex_data[i].normal.y = norms[j][1] * nscale;
vertex_data[i].normal.z = norms[j][2] * nscale;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANormal, PEXColorTypeRGB, facet_data,
remaining_points, data);
}
enable_lighting(0);
}
void draw_colored_isosurface( int n,
#ifdef BIG_GFX
uint_4 *index,
#else
uint_2 *index,
#endif
int_2 verts[][3],
int_1 norms[][3],
uint_1 color_indexes[],
unsigned int color_table[],
int alphavalue)
{
int i, j, k, remaining_points;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
PEXVertexRGBNormal vertex_data[VERTS_PER_CALL];
float vscale = 1.0/VERTEX_SCALE;
float nscale = 1.0/NORMAL_SCALE;
enable_lighting(1);
#if TODO
if (alphavalue== -1) {
/* variable alpha in the mesh */
}
else {
/* constant alpha */
}
#endif /* TODO */
remaining_points = n;
k = 0;
data.rgb_normal = vertex_data;
facet_data.rgb_normal = NULL;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
unsigned int c;
j = index[k+i];
c = color_table[color_indexes[j]];
vertex_data[i].point.x = verts[j][0] * vscale;
vertex_data[i].point.y = verts[j][1] * vscale;
vertex_data[i].point.z = verts[j][2] * vscale;
vertex_data[i].normal.x = norms[j][0] * nscale;
vertex_data[i].normal.y = norms[j][1] * nscale;
vertex_data[i].normal.z = norms[j][2] * nscale;
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGAColor|PEXGANormal, PEXColorTypeRGB, facet_data,
VERTS_PER_CALL, data);
k += VERTS_PER_CALL-2; /* Triangles overlap by two points. */
remaining_points -= VERTS_PER_CALL-2;
}
if (remaining_points > 2) {
for (i=0; i<remaining_points; i++) {
unsigned int c;
j = index[k+i];
c = color_table[color_indexes[j]];
vertex_data[i].point.x = verts[j][0] * vscale;
vertex_data[i].point.y = verts[j][1] * vscale;
vertex_data[i].point.z = verts[j][2] * vscale;
vertex_data[i].normal.x = norms[j][0] * nscale;
vertex_data[i].normal.y = norms[j][1] * nscale;
vertex_data[i].normal.z = norms[j][2] * nscale;
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGAColor|PEXGANormal, PEXColorTypeRGB, facet_data,
remaining_points, data);
}
enable_lighting(0);
}
void draw_triangle_strip( int n, int_2 verts[][3], int_1 norms[][3],
unsigned int color )
{
register int i, index, remaining_points;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
PEXVertexNormal vertex_data[VERTS_PER_CALL];
float vscale = 1.0/VERTEX_SCALE;
float nscale = 1.0/NORMAL_SCALE;
set_color( color );
remaining_points = n;
index = 0;
data.normal = vertex_data;
facet_data.normal = NULL;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
vertex_data[i].point.x = verts[index+i][0] * vscale;
vertex_data[i].point.y = verts[index+i][1] * vscale;
vertex_data[i].point.z = verts[index+i][2] * vscale;
vertex_data[i].normal.x = norms[index+i][0] * nscale;
vertex_data[i].normal.y = norms[index+i][1] * nscale;
vertex_data[i].normal.z = norms[index+i][2] * nscale;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANormal, PEXColorTypeRGB, facet_data, VERTS_PER_CALL, data);
index += VERTS_PER_CALL-2; /* Triangles overlap by two points. */
remaining_points -= VERTS_PER_CALL-2;
}
if (remaining_points > 2) {
for (i=0; i<remaining_points; i++) {
vertex_data[i].point.x = verts[index+i][0] * vscale;
vertex_data[i].point.y = verts[index+i][1] * vscale;
vertex_data[i].point.z = verts[index+i][2] * vscale;
vertex_data[i].normal.x = norms[index+i][0] * nscale;
vertex_data[i].normal.y = norms[index+i][1] * nscale;
vertex_data[i].normal.z = norms[index+i][2] * nscale;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANormal, PEXColorTypeRGB, facet_data, remaining_points, data);
}
}
void draw_colored_triangle_strip( int n,
int_2 verts[][3], int_1 norms[][3],
uint_1 color_indexes[],
unsigned int color_table[] )
{
int i, j, k, remaining_points;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
PEXVertexRGBNormal vertex_data[VERTS_PER_CALL];
float vscale = 1.0/VERTEX_SCALE;
float nscale = 1.0/NORMAL_SCALE;
enable_lighting(1);
remaining_points = n;
k = 0;
data.rgb_normal = vertex_data;
facet_data.rgb_normal = NULL;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
unsigned int c;
j = k + i;
c = color_table[color_indexes[j]];
vertex_data[i].point.x = verts[j][0] * vscale;
vertex_data[i].point.y = verts[j][1] * vscale;
vertex_data[i].point.z = verts[j][2] * vscale;
vertex_data[i].normal.x = norms[j][0] * nscale;
vertex_data[i].normal.y = norms[j][1] * nscale;
vertex_data[i].normal.z = norms[j][2] * nscale;
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGAColor|PEXGANormal, PEXColorTypeRGB, facet_data,
VERTS_PER_CALL, data);
k += VERTS_PER_CALL-2; /* Triangles overlap by two points. */
remaining_points -= VERTS_PER_CALL-2;
}
if (remaining_points > 2) {
for (i=0; i<remaining_points; i++) {
unsigned int c;
j = k+i;
c = color_table[color_indexes[j]];
vertex_data[i].point.x = verts[j][0] * vscale;
vertex_data[i].point.y = verts[j][1] * vscale;
vertex_data[i].point.z = verts[j][2] * vscale;
vertex_data[i].normal.x = norms[j][0] * nscale;
vertex_data[i].normal.y = norms[j][1] * nscale;
vertex_data[i].normal.z = norms[j][2] * nscale;
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGAColor|PEXGANormal, PEXColorTypeRGB, facet_data,
remaining_points, data);
}
enable_lighting(0);
}
void draw_color_quadmesh( int rows, int columns, int_2 verts[][3],
uint_1 color_indexes[], unsigned int color_table[],
int alphavalue )
{
int i, j, base1, base2, size, temp;
unsigned int color_row1[1000];
unsigned int color_row2[1000];
unsigned int *row1ptr, *row2ptr, *tmp;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
static PEXVertexRGB *vertex_data = NULL;
static int max_size = 0;
float vscale = 1.0/VERTEX_SCALE;
enable_lighting(0);
/* Swap rows and columns to match PEXlib expectations. */
temp = rows;
rows = columns;
columns = temp;
size = rows*columns;
if (max_size < size) {
max_size = size;
vertex_data = (PEXVertexRGB *)
realloc(vertex_data, size*sizeof(PEXVertexRGB));
if (vertex_data == 0) {
printf("Unable to allocate quad mesh buffer\n");
exit(-1);
}
}
for (i=0; i<size; i++) {
unsigned int c;
vertex_data[i].point.x = verts[i][0] * vscale;
vertex_data[i].point.y = verts[i][1] * vscale;
vertex_data[i].point.z = verts[i][2] * vscale;
c = color_table[color_indexes[i]];
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
data.rgb = vertex_data;
facet_data.normal = NULL;
PEXQuadrilateralMesh(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex,
PEXGANone, PEXGAColor, PEXColorTypeRGB, facet_data,
rows, columns, data);
}
void draw_lit_color_quadmesh( int rows, int columns,
float verts[][3],
float norms[][3],
uint_1 color_indexes[],
unsigned int color_table[] )
{
int i, j, base1, base2, size, temp;
unsigned int color_row1[1000];
unsigned int color_row2[1000];
unsigned int *row1ptr, *row2ptr, *tmp;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
static PEXVertexRGBNormal *vertex_data = NULL;
static int max_size = 0;
enable_lighting(1);
/* Swap rows and columns to match PEXlib expectations. */
temp = rows;
rows = columns;
columns = temp;
size = rows*columns;
if (max_size < size) {
vertex_data = (PEXVertexRGBNormal *)
realloc(vertex_data, size*sizeof(PEXVertexRGBNormal));
if (vertex_data == 0) {
printf("Unable to allocate quad mesh buffer\n");
exit(-1);
}
}
if (vertex_data == 0) {
printf("Unable to allocate quad mesh buffer\n");
exit(-1);
}
for (i=0; i<size; i++) {
unsigned int c;
vertex_data[i].point.x = verts[i][0];
vertex_data[i].point.y = verts[i][1];
vertex_data[i].point.z = verts[i][2];
vertex_data[i].normal.x = norms[i][0];
vertex_data[i].normal.y = norms[i][1];
vertex_data[i].normal.z = norms[i][2];
c = color_table[color_indexes[i]];
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
data.rgb_normal = vertex_data;
facet_data.normal = NULL;
PEXQuadrilateralMesh(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex,
PEXGANone, PEXGAColor|PEXGANormal,
PEXColorTypeRGB, facet_data,
rows, columns, data);
enable_lighting(0);
}
void draw_wind_lines( int nvectors, int_2 verts[][3], unsigned int color )
{
int i, j;
PEXCoord vertex_data[3];
float vscale = 1.0/VERTEX_SCALE;
set_color( color );
for (i=0;i<nvectors;i++) {
j = i * 4;
/* main vector */
vertex_data[0].x = verts[j][0] * vscale;
vertex_data[0].y = verts[j][1] * vscale;
vertex_data[0].z = verts[j][2] * vscale;
vertex_data[1].x = verts[j+1][0] * vscale;
vertex_data[1].y = verts[j+1][1] * vscale;
vertex_data[1].z = verts[j+1][2] * vscale;
PEXPolyline(GfxDpy, Renderer, PEXOCRender, 2, vertex_data);
/* head vectors */
vertex_data[0].x = verts[j+2][0] * vscale;
vertex_data[0].y = verts[j+2][1] * vscale;
vertex_data[0].z = verts[j+2][2] * vscale;
vertex_data[2].x = verts[j+3][0] * vscale;
vertex_data[2].y = verts[j+3][1] * vscale;
vertex_data[2].z = verts[j+3][2] * vscale;
PEXPolyline(GfxDpy, Renderer, PEXOCRender, 3, vertex_data);
}
}
void draw_disjoint_lines( int n, int_2 verts[][3], unsigned int color )
{
int i;
PEXCoord vertex_data[2];
float vscale = 1.0/VERTEX_SCALE;
set_color( color );
for (i=0;i<n;i+=2 ) {
vertex_data[0].x = verts[i][0] * vscale;
vertex_data[0].y = verts[i][1] * vscale;
vertex_data[0].z = verts[i][2] * vscale;
vertex_data[1].x = verts[i+1][0] * vscale;
vertex_data[1].y = verts[i+1][1] * vscale;
vertex_data[1].z = verts[i+1][2] * vscale;
PEXPolyline(GfxDpy, Renderer, PEXOCRender, 2, vertex_data);
}
}
void draw_polylines( int n, int_2 verts[][3], unsigned int color )
{
register int i, index, remaining_points;
PEXCoord vertex_data[VERTS_PER_CALL];
float vscale = 1.0/VERTEX_SCALE;
set_color( color );
remaining_points = n;
index = 0;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
vertex_data[i].x = verts[index+i][0] * vscale;
vertex_data[i].y = verts[index+i][1] * vscale;
vertex_data[i].z = verts[index+i][2] * vscale;
}
PEXPolyline(GfxDpy, Renderer, PEXOCRender, VERTS_PER_CALL,
vertex_data);
index += VERTS_PER_CALL-1; /* Polylines overlap by one point. */
remaining_points -= VERTS_PER_CALL-1;
}
if (remaining_points > 1) {
for (i=0; i<remaining_points; i++) {
vertex_data[i].x = verts[index+i][0] * vscale;
vertex_data[i].y = verts[index+i][1] * vscale;
vertex_data[i].z = verts[index+i][2] * vscale;
}
PEXPolyline(GfxDpy, Renderer, PEXOCRender, remaining_points,
vertex_data);
}
}
void draw_colored_polylines( int n, int_2 verts[][3],
uint_1 color_indexes[],
unsigned int color_table[] )
{
register int i, index, remaining_points;
PEXVertexRGB vertex_data[VERTS_PER_CALL];
float vscale = 1.0/VERTEX_SCALE;
PEXListOfVertex polylines;
polylines.vertices.rgb = vertex_data;
remaining_points = n;
index = 0;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
unsigned int color;
vertex_data[i].point.x = verts[index+i][0] * vscale;
vertex_data[i].point.y = verts[index+i][1] * vscale;
vertex_data[i].point.z = verts[index+i][2] * vscale;
color = color_table[color_indexes[index+i]];
vertex_data[i].rgb.red = UNPACK_RED(color) * (1.0 / 255.0);
vertex_data[i].rgb.green = UNPACK_GREEN(color) * (1.0 / 255.0);
vertex_data[i].rgb.blue = UNPACK_BLUE(color) * (1.0 / 255.0);
}
polylines.count = VERTS_PER_CALL;
PEXPolylineSetWithData( GfxDpy, Renderer, PEXOCRender,
PEXGAColor, PEXColorTypeRGB,
1, &polylines );
index += VERTS_PER_CALL-1; /* Polylines overlap by one point. */
remaining_points -= VERTS_PER_CALL-1;
}
if (remaining_points > 1) {
for (i=0; i<remaining_points; i++) {
unsigned int color;
vertex_data[i].point.x = verts[index+i][0] * vscale;
vertex_data[i].point.y = verts[index+i][1] * vscale;
vertex_data[i].point.z = verts[index+i][2] * vscale;
color = color_table[color_indexes[index+i]];
vertex_data[i].rgb.red = UNPACK_RED(color) * (1.0 / 255.0);
vertex_data[i].rgb.green = UNPACK_GREEN(color) * (1.0 / 255.0);
vertex_data[i].rgb.blue = UNPACK_BLUE(color) * (1.0 / 255.0);
}
polylines.count = remaining_points;
PEXPolylineSetWithData( GfxDpy, Renderer, PEXOCRender,
PEXGAColor, PEXColorTypeRGB,
1, &polylines );
}
}
void draw_multi_lines( int n, float verts[][3], unsigned int color )
{
register int i, index, remaining_points;
PEXCoord vertex_data[VERTS_PER_CALL];
int vcount;
float vscale = 1.0/VERTEX_SCALE;
set_color( color );
vcount = 0;
for (i=0;i<n;i++) {
if (verts[i][0]==-999.0) {
PEXPolyline(GfxDpy, Renderer, PEXOCRender, vcount, vertex_data);
vcount = 0;
}
else {
vertex_data[vcount].x = verts[i][0];
vertex_data[vcount].y = verts[i][1];
vertex_data[vcount].z = verts[i][2];
vcount++;
assert(vcount<=VERTS_PER_CALL); /* if this fails this code */
/* will need some work. */
}
}
}
void draw_cursor( Context current_ctx, int style, float x, float y, float z, unsigned int c )
{
if (style == 1) {
/* polygon-based cursor */
PEXVector ShiftVector;
PEXMatrix TranslateMatrix;
static PEXCoord xa1[4] = {
{ -0.05, -0.005, 0.005 },
{ -0.05, 0.005, -0.005 },
{ 0.05, 0.005, -0.005 },
{ 0.05, -0.005, 0.005 },
};
static PEXCoord xa2[4] = {
{ -0.05, -0.005, -0.005 },
{ -0.05, 0.005, 0.005 },
{ 0.05, 0.005, 0.005 },
{ 0.05, -0.005, -0.005 },
};
static PEXCoord ya1[4] = {
{ -0.005, -0.05, 0.005 },
{ 0.005, -0.05, -0.005 },
{ 0.005, 0.05, -0.005 },
{ -0.005, 0.05, 0.005 },
};
static PEXCoord ya2[4] = {
{ -0.005, -0.05, -0.005 },
{ 0.005, -0.05, 0.005 },
{ 0.005, 0.05, 0.005 },
{ -0.005, 0.05, -0.005 },
};
static PEXCoord za1[4] = {
{ -0.005, -0.005, 0.05 },
{ 0.005, 0.005, 0.05 },
{ 0.005, 0.005, -0.05 },
{ -0.005, -0.005, -0.05 },
};
static PEXCoord za2[4] = {
{ -0.005, 0.005, 0.05 },
{ 0.005, -0.005, 0.05 },
{ 0.005, -0.005, -0.05 },
{ -0.005, 0.005, -0.05 },
};
ShiftVector.x = x; ShiftVector.y = y; ShiftVector.z = z;
PEXTranslate(&ShiftVector, TranslateMatrix);
PEXSetLocalTransform(GfxDpy, Renderer, PEXOCRender, PEXReplace,
TranslateMatrix);
PEXFillArea(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex, False,
4, xa1);
PEXFillArea(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex, False,
4, xa2);
PEXFillArea(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex, False,
4, ya1);
PEXFillArea(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex, False,
4, ya2);
PEXFillArea(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex, False,
4, za1);
PEXFillArea(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex, False,
4, za2);
PEXIdentityMatrix(TranslateMatrix);
PEXSetLocalTransform(GfxDpy, Renderer, PEXOCRender, PEXReplace,
TranslateMatrix);
}
if (style == 0 ) {
/* line segment cursor */
PEXCoord vertex_data[2];
PEXColor color;
color.rgb.red = UNPACK_RED(c) / 255.0;
color.rgb.green = UNPACK_GREEN(c) / 255.0;
color.rgb.blue = UNPACK_BLUE(c) / 255.0;
PEXSetLineColor(GfxDpy, Renderer, PEXOCRender, PEXColorTypeRGB, &color);
vertex_data[0].x = x-0.05;
vertex_data[0].y = y;
vertex_data[0].z = z;
vertex_data[1].x = x+0.05;
vertex_data[1].y = y;
vertex_data[1].z = z;
PEXPolyline( GfxDpy, Renderer, PEXOCRender, 2, vertex_data );
vertex_data[0].x = x;
vertex_data[0].y = y-0.05;
vertex_data[0].z = z;
vertex_data[1].x = x;
vertex_data[1].y = y+0.05;
vertex_data[1].z = z;
PEXPolyline( GfxDpy, Renderer, PEXOCRender, 2, vertex_data );
vertex_data[0].x = x;
vertex_data[0].y = y;
vertex_data[0].z = z-0.05;
vertex_data[1].x = x;
vertex_data[1].y = y;
vertex_data[1].z = z+0.05;
PEXPolyline( GfxDpy, Renderer, PEXOCRender, 2, vertex_data );
}
if (style == 2) {
/* sounding cursor */
PEXCoord vertex_data[2];
PEXColor color;
color.rgb.red = UNPACK_RED(c) / 255.0;
color.rgb.green = UNPACK_GREEN(c) / 255.0;
color.rgb.blue = UNPACK_BLUE(c) / 255.0;
PEXSetLineColor(GfxDpy, Renderer, PEXOCRender, PEXColorTypeRGB, &color);
vertex_data[0].x = x;
vertex_data[0].y = y;
vertex_data[0].z = z - current_ctx->Zmin;
vertex_data[1].x = x;
vertex_data[1].y = y;
vertex_data[1].z = z + current_ctx->Zmin;
PEXPolyline( GfxDpy, Renderer, PEXOCRender, 2, vertex_data );
vertex_data[0].x = x-0.05;
vertex_data[0].y = y;
vertex_data[0].z = z + current_ctx->Zmax;
vertex_data[1].x = x+0.05;
vertex_data[1].y = y;
vertex_data[1].z = z + current_ctx->Zmax;
PEXPolyline( GfxDpy, Renderer, PEXOCRender, 2, vertex_data );
vertex_data[0].x = x;
vertex_data[0].y = y-0.05;
vertex_data[0].z = z + current_ctx->Zmax;
vertex_data[1].x = x;
vertex_data[1].y = y+0.05;
vertex_data[1].z = z + current_ctx->Zmax;
PEXPolyline( GfxDpy, Renderer, PEXOCRender, 2, vertex_data );
}
}
#ifdef JUNK
/*** polytrinorm ******************************************************
Draw a polytriangle strip with normals.
**********************************************************************/
void polytrinorm( vert, norm, n )
float vert[][3];
float norm[][3];
int n;
{
register int i, index, remaining_points;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
PEXVertexNormal vertex_data[VERTS_PER_CALL];
remaining_points = n;
index = 0;
data.normal = vertex_data;
facet_data.normal = NULL;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
vertex_data[i].point.x = vert[index+i][0];
vertex_data[i].point.y = vert[index+i][1];
vertex_data[i].point.z = vert[index+i][2];
vertex_data[i].normal.x = norm[index+i][0];
vertex_data[i].normal.y = norm[index+i][1];
vertex_data[i].normal.z = norm[index+i][2];
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANormal, PEXColorTypeRGB, facet_data, VERTS_PER_CALL, data);
index += VERTS_PER_CALL-2; /* Triangles overlap by two points. */
remaining_points -= VERTS_PER_CALL-2;
}
if (remaining_points > 2) {
for (i=0; i<remaining_points; i++) {
vertex_data[i].point.x = vert[index+i][0];
vertex_data[i].point.y = vert[index+i][1];
vertex_data[i].point.z = vert[index+i][2];
vertex_data[i].normal.x = norm[index+i][0];
vertex_data[i].normal.y = norm[index+i][1];
vertex_data[i].normal.z = norm[index+i][2];
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANormal, PEXColorTypeRGB, facet_data, remaining_points, data);
}
}
#endif
#ifdef JUNK
/*** polytri **********************************************************
Draw a polytriangle strip without shading.
**********************************************************************/
void polytri( vert, n )
float vert[][3];
int n;
{
register int i, index, remaining_points;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
PEXCoord vertex_data[VERTS_PER_CALL];
remaining_points = n;
index = 0;
data.no_data = vertex_data;
facet_data.normal = NULL;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
vertex_data[i].x = vert[index+i][0];
vertex_data[i].y = vert[index+i][1];
vertex_data[i].z = vert[index+i][2];
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANone, PEXColorTypeRGB, facet_data, VERTS_PER_CALL, data);
index += VERTS_PER_CALL-2; /* Triangles overlap by two points. */
remaining_points -= VERTS_PER_CALL-2;
}
if (remaining_points > 2) {
for (i=0; i<remaining_points; i++) {
vertex_data[i].x = vert[index+i][0];
vertex_data[i].y = vert[index+i][1];
vertex_data[i].z = vert[index+i][2];
}
PEXTriangleStrip(GfxDpy, Renderer, PEXOCRender, PEXGANone,
PEXGANone, PEXColorTypeRGB, facet_data, remaining_points, data);
}
}
#endif
void polyline( float vert[][3], int n )
{
register int i, index, remaining_points;
PEXCoord vertex_data[VERTS_PER_CALL];
remaining_points = n;
index = 0;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
vertex_data[i].x = vert[index+i][0];
vertex_data[i].y = vert[index+i][1];
vertex_data[i].z = vert[index+i][2];
}
PEXPolyline(GfxDpy, Renderer, PEXOCRender, VERTS_PER_CALL, vertex_data);
index += VERTS_PER_CALL-1; /* Polylines overlap by one point. */
remaining_points -= VERTS_PER_CALL-1;
}
if (remaining_points > 1) {
for (i=0; i<remaining_points; i++) {
vertex_data[i].x = vert[index+i][0];
vertex_data[i].y = vert[index+i][1];
vertex_data[i].z = vert[index+i][2];
}
PEXPolyline(GfxDpy, Renderer, PEXOCRender, remaining_points, vertex_data);
}
}
void disjointpolyline( float vert[][3], int n )
{
register int i;
PEXCoord vertex_data[2];
for (i=0; i<n; i+=2) {
vertex_data[0].x = vert[i][0];
vertex_data[0].y = vert[i][1];
vertex_data[0].z = vert[i][2];
vertex_data[1].x = vert[i+1][0];
vertex_data[1].y = vert[i+1][1];
vertex_data[1].z = vert[i+1][2];
PEXPolyline(GfxDpy, Renderer, PEXOCRender, 2, vertex_data);
}
}
#ifdef JUNK
/*** quadmesh *********************************************************
Draw a quadrilateral mesh with colors at each vertex.
**********************************************************************/
void quadmesh( vert, color, rows, cols )
float vert[][3];
unsigned int color[];
int rows, cols;
{
register int i;
unsigned long c;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
int size;
static PEXVertexRGB *vertex_data = NULL;
static int max_size = 0;
int temp;
/* Swap rows and columns to match PEXlib expectations. */
temp = rows;
rows = cols;
cols = temp;
size = rows*cols;
if (max_size < size) {
max_size = size;
vertex_data = (PEXVertexRGB *)
realloc(vertex_data, size*sizeof(PEXVertexRGB));
if (vertex_data == 0) {
printf("Unable to allocate quad mesh buffer\n");
exit(-1);
}
}
for (i=0; i<size; i++) {
vertex_data[i].point.x = vert[i][0];
vertex_data[i].point.y = vert[i][1];
vertex_data[i].point.z = vert[i][2];
c = color[i];
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
data.rgb = vertex_data;
facet_data.normal = NULL;
PEXQuadrilateralMesh(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex,
PEXGANone, PEXGAColor, PEXColorTypeRGB, facet_data,
rows, cols, data);
}
#endif
void quadmeshnorm( float vert[][3], float norm[][3], unsigned int color[],
int rows, int cols )
{
int i, size, temp;
PEXArrayOfVertex data;
PEXArrayOfFacetData facet_data; /* a dummy */
static PEXVertexRGBNormal *vertex_data = NULL;
static int max_size = 0;
enable_lighting(0);
/* Swap rows and columns to match PEXlib expectations. */
temp = rows;
rows = cols;
cols = temp;
size = rows*cols;
if (max_size < size) {
max_size = size;
vertex_data = (PEXVertexRGBNormal *)
realloc(vertex_data, size*sizeof(PEXVertexRGBNormal));
if (vertex_data == 0) {
printf("Unable to allocate quad mesh buffer\n");
exit(-1);
}
}
for (i=0; i<size; i++) {
unsigned int c;
vertex_data[i].point.x = vert[i][0];
vertex_data[i].point.y = vert[i][1];
vertex_data[i].point.z = vert[i][2];
vertex_data[i].normal.x = norm[i][0];
vertex_data[i].normal.y = norm[i][1];
vertex_data[i].normal.z = norm[i][2];
c = color[i];
vertex_data[i].rgb.red = UNPACK_RED(c) * 1.0 / 255.0;
vertex_data[i].rgb.green = UNPACK_GREEN(c) * 1.0 / 255.0;
vertex_data[i].rgb.blue = UNPACK_BLUE(c) * 1.0 / 255.0;
}
data.rgb_normal = vertex_data;
facet_data.normal = NULL;
PEXQuadrilateralMesh(GfxDpy, Renderer, PEXOCRender, PEXShapeConvex,
PEXGANone, PEXGAColor|PEXGANormal, PEXColorTypeRGB, facet_data,
rows, cols, data);
}
/*** polyline2d *******************************************************
Draw a 2-D poly line. Coordinates are in pixels with the origin
in the upper-left corner of the window. NOTE: vertices are shorts.
**********************************************************************/
void polyline2d( short vert[][2], int n )
{
register int i, index, remaining_points;
PEXCoord2D vertex_data[VERTS_PER_CALL];
remaining_points = n;
index = 0;
while (remaining_points > VERTS_PER_CALL) {
for (i=0; i<VERTS_PER_CALL; i++) {
vertex_data[i].x = vert[index+i][0];
vertex_data[i].y = vert[index+i][1];
}
PEXPolyline2D(GfxDpy, Renderer, PEXOCRender, VERTS_PER_CALL, vertex_data);
index += VERTS_PER_CALL-1; /* Polylines overlap by one point. */
remaining_points -= VERTS_PER_CALL-1;
}
if (remaining_points > 1) {
for (i=0; i<remaining_points; i++) {
vertex_data[i].x = vert[index+i][0];
vertex_data[i].y = vert[index+i][1];
}
PEXPolyline2D(GfxDpy, Renderer, PEXOCRender, remaining_points,
vertex_data);
}
}
void draw_text( int xpos, int ypos, char *str )
{
PEXCoord2D origin;
/* Don't invert text, instead compute inverted Y position. */
if (InvertY)
PEXSetGlobalTransform(GfxDpy, Renderer, PEXOCRender, IdMat);
origin.x = xpos;
origin.y = current_ctx->WinHeight - ypos;
PEXText2D(GfxDpy, Renderer, PEXOCRender, &origin, strlen(str), str);
if (InvertY)
PEXSetGlobalTransform(GfxDpy, Renderer, PEXOCRender, InvertYMatrix);
}
int text_width( char *str )
{
PEXStringData strings[1];
PEXTextExtent *extents;
int width;
strings[0].length = strlen(str);
strings[0].ch = str;
extents = PEXQueryTextExtents(GfxDpy, Renderer, 1, PEXPathRight,
1.0, 0.0, 9.0, PEXHAlignNormal, PEXVAlignNormal, 1, strings);
if (extents == NULL) {
printf("Unable to inquire text extent\n");
exit(-1);
}
width = extents->upper_right.x - extents->lower_left.x + 1;
XFree(extents);
return width;
}
int begin_object( void )
{
return 0;
}
void end_object( void )
{
}
void call_object( int obj )
{
}
void delete_object( int objnum )
{
}
#endif /* HAVE_PEX */
syntax highlighted by Code2HTML, v. 0.9.1