/*
 GNU Maverik - a system for managing display and interaction in 
               Virtual Environment applications.
 Copyright (C) 1999 Advanced Interfaces Group

 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.

 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


 The authors can be contacted via:
 www   - http://aig.cs.man.ac.uk
 email - maverik@aig.cs.man.ac.uk
 mail  - Advanced Interfaces Group, Room 2.90, Computer Science Building, 
         University of Manchester, Manchester, M13 9PL, UK
*/


#include "mavlib_gfx.h"
#include <stdio.h>
#include <stdlib.h>

#ifndef MAV_NONE
#ifdef MAV_IRISGL
#include <gl/gl.h>
float mavlib_bk[4];
#else
#include "GL/glu.h"
#ifdef GL_EXT_texture_object
GLuint *mavlib_bindTextureIndex;
#endif
#endif
#endif

int mav_opt_bindTextures= MAV_TRUE;
int mav_opt_shareContexts= MAV_TRUE;
int mav_opt_trackMatrix= MAV_FALSE;

int mavlib_matrixmode= MAV_MODELVIEW;



/* Option for tracking matrix transformations */

void mavlib_trackMatrix(void)
{
  mav_win_current->viewMat= mav_gfxMatrixGet();

  if (mav_opt_trackMatrix==MAV_PROJANDVIEW) mav_win_current->pdvMat= mav_matrixMult(mav_win_current->projMat, mav_win_current->viewMat);
}



/* These routines are no more than wrappers to OpenGL and IrisGL */

void mav_gfxClipPlaneSet(int id, MAV_clipPlane cp)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  float params[4];

  params[0]= cp.norm.x;
  params[1]= cp.norm.y;
  params[2]= cp.norm.z;
  params[3]= cp.d;

  clipplane (id, CP_DEFINE, params);
#else
  GLdouble params[4];

  params[0]= cp.norm.x;
  params[1]= cp.norm.y;
  params[2]= cp.norm.z;
  params[3]= cp.d;

  glClipPlane (GL_CLIP_PLANE0 + id, params);
#endif
#endif
}

void mav_gfxClipPlanesSet(MAV_clipPlanes *cp)
{
#ifndef MAV_NONE
  int index;

  for (index= 0; index < cp->num; index ++)
    mav_gfxClipPlaneSet(index, cp->planes[index]);
#endif
}

void mav_gfxClipPlaneEnable (int id)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  float dummy_params[4];

  clipplane (id, CP_ON, dummy_params);
#else
  glEnable (GL_CLIP_PLANE0 + id);
#endif
#endif
}

void mav_gfxClipPlaneDisable (int id)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  float dummy_params[4];

  clipplane (id, CP_OFF, dummy_params);
#else
  glDisable (GL_CLIP_PLANE0 + id);
#endif
#endif
}

void mav_gfxBackgroundColourSet(float r, float g, float b)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  mavlib_bk[0]= r;
  mavlib_bk[1]= g;
  mavlib_bk[2]= b;
  mavlib_bk[3]= 0.0;
#else
  glClearColor(r,g,b,0.0);
#endif
#endif
}

void mav_gfxClearC(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  c3f(mavlib_bk);
  clear();
#else
  glClear(GL_COLOR_BUFFER_BIT);
#endif
#endif
}

void mav_gfxClearZ(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  zclear();
#else
  glClear(GL_DEPTH_BUFFER_BIT);
#endif
#endif
}

void mav_gfxClearA(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glClear(GL_ACCUM_BUFFER_BIT);
#endif
#endif
}

void mav_gfxClearCZ(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  c3f(mavlib_bk);
  clear();
  zclear();
#else
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
#endif
}

void mav_gfxPolygonModeSet(int i)
{
#ifndef MAV_NONE
  if (i==MAV_POLYGON_LINE)
  {
#ifdef MAV_IRISGL
    polymode(PYM_LINE);
#else
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
#endif
  }
  else
  {
#ifdef MAV_IRISGL
    polymode(PYM_FILL);
#else
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
  }
#endif
}

void mav_gfxMultiSampleSet(int i)
{
#ifdef GL_SGIS_multisample
  if (mav_opt_multiSample) 
  {
    if (i==MAV_TRUE)
    {
      glEnable(GL_MULTISAMPLE_SGIS);
    }
    else
    {
      glDisable(GL_MULTISAMPLE_SGIS);
    }
  }
  else
  {
    if (mav_opt_output==MAV_VERBOSE) fprintf(stderr, "Warning: Multisample option not selected, ignoring.\n");
  }
#else
  if (mav_opt_output==MAV_VERBOSE) fprintf(stderr, "Warning: Multisample option not available, ignoring.\n");
#endif
}

void mav_gfxMatrixPush(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  pushmatrix();
#else
  glPushMatrix();
#endif
#endif
}

void mav_gfxMatrixPop(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  popmatrix();
#else
  glPopMatrix();
#endif
  if (mav_opt_trackMatrix) mavlib_trackMatrix();
#endif
}

void mav_gfxMatrixMult(MAV_matrix m)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#ifdef MAV_IRIX5
  multmatrix(m.mat);
#endif
#ifdef MAV_IRIX6
  multmatrix((const float (*)[4]) m.mat);
#endif
#else
  glMultMatrixf((float *) m.mat);
#endif
  if (mav_opt_trackMatrix) mavlib_trackMatrix();
#endif
}

void mav_gfxMatrixMode(int mode)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  if (mode==MAV_PROJECTION) mmode(MPROJECTION);
  if (mode==MAV_MODELVIEW) mmode(MVIEWING);
#else
  if (mode==MAV_PROJECTION) glMatrixMode(GL_PROJECTION);
  if (mode==MAV_MODELVIEW) glMatrixMode(GL_MODELVIEW);  
#endif
#endif

  mavlib_matrixmode= mode;
}

MAV_matrix mav_gfxMatrixGet(void)
{
  MAV_matrix rv;

#ifdef MAV_NONE
  rv= MAV_ID_MATRIX;
#else
#ifdef MAV_IRISGL
  getmatrix(rv.mat);
#else
  if (mavlib_matrixmode==MAV_PROJECTION) glGetFloatv(GL_PROJECTION_MATRIX, (float *) rv.mat);
  if (mavlib_matrixmode==MAV_MODELVIEW) glGetFloatv(GL_MODELVIEW_MATRIX, (float *) rv.mat);
#endif
#endif

  return rv;
}

void mav_gfxMatrixLoad(MAV_matrix mat)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#ifdef MAV_IRIX5
  loadmatrix(mat.mat);
#endif
#ifdef MAV_IRIX6
  loadmatrix((const float (*)[4]) mat.mat);
#endif
#else
  glLoadMatrixf((float *) mat.mat);
#endif
  if (mav_opt_trackMatrix) mavlib_trackMatrix();
#endif
}

void mav_gfxMatrixTranslate(MAV_vector t)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  translate(t.x, t.y, t.z);
#else
  glTranslatef(t.x, t.y, t.z);
#endif
  if (mav_opt_trackMatrix) mavlib_trackMatrix();
#endif
}

void mav_gfxMatrixScale(float x, float y, float z)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  scale(x, y, z);
#else
  glScalef(x, y, z);
#endif
  if (mav_opt_trackMatrix) mavlib_trackMatrix();
#endif
}

void mav_gfxPerspectiveSet(float ncp, float fcp, float fov, float aspect)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  perspective(fov*10, aspect, ncp, fcp);
#else
  gluPerspective(fov, aspect, ncp, fcp);
#endif
#endif
}

void mav_gfxPolygonBegin(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  bgnpolygon();
#else
  glBegin(GL_POLYGON);
#endif
#endif
}

void mav_gfxPolygonEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  endpolygon();
#else
  glEnd();
#endif
#endif
}

void mav_gfxTrianglesBegin(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  fprintf(stderr, "Warning: No triangle support, ignoring.\n");
#else
  glBegin(GL_TRIANGLES);
#endif
#endif
}

void mav_gfxTrianglesEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  fprintf(stderr, "Warning: No triangle support, ignoring.\n");
#else
  glEnd();
#endif
#endif
}

void mav_gfxVertex(MAV_vector v)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  v3f((float *) &v);
#else
  glVertex3fv((float *) &v);
#endif
#endif
}

void mav_gfxNormal(MAV_vector v)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  n3f((float *) &v);
#else
  glNormal3fv((float *) &v);
#endif
#endif
}

void mav_gfxLightSet(MAV_light info)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  float ldef[9];

  ldef[0]= AMBIENT;
  ldef[1]= info.ambient[0];
  ldef[2]= info.ambient[1];
  ldef[3]= info.ambient[2];
  ldef[4]= LCOLOR;
  ldef[5]= info.diffuse[0];
  ldef[6]= info.diffuse[1];
  ldef[7]= info.diffuse[2];
  ldef[8]= LMNULL;

  lmdef(DEFLIGHT, info.id+1, 0, ldef);
#endif  
#endif
}

void mav_gfxLightUse(MAV_light info)
{
#ifndef MAV_NONE
  int whichlight=-1;
#ifdef MAV_IRISGL
  if (info.index==0) whichlight=LIGHT0;
  if (info.index==1) whichlight=LIGHT1;
  if (info.index==2) whichlight=LIGHT2;
  if (info.index==3) whichlight=LIGHT3;
  if (info.index==4) whichlight=LIGHT4;

  lmbind(whichlight, 0);

  if (info.defined) lmbind(whichlight, info.id+1);
#else  
  if (info.index==0) whichlight=GL_LIGHT0;
  if (info.index==1) whichlight=GL_LIGHT1;
  if (info.index==2) whichlight=GL_LIGHT2;
  if (info.index==3) whichlight=GL_LIGHT3;
  if (info.index==4) whichlight=GL_LIGHT4;

  glDisable(whichlight);

  if (info.defined) {
    glEnable(whichlight);
    glLightfv(whichlight, GL_AMBIENT, info.ambient);
    glLightfv(whichlight, GL_DIFFUSE, info.diffuse);
    glLightfv(whichlight, GL_SPECULAR, info.specular);
  }
#endif
#endif
}

void mav_gfxLightPos(MAV_light info)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  if (info.defined) {
    float ldef[6];
    
    ldef[0]= POSITION;
    ldef[1]= info.pos.x;
    ldef[2]= info.pos.y;
    ldef[3]= info.pos.z;
    ldef[4]= 1.0;
    ldef[5]= LMNULL;

    lmdef(DEFLIGHT, info.id+1, 0, ldef);
  }
#else
  int whichlight=-1;
     
  if (info.index == 0) whichlight=GL_LIGHT0;
  if (info.index == 1) whichlight=GL_LIGHT1;
  if (info.index == 2) whichlight=GL_LIGHT2;
  if (info.index == 3) whichlight=GL_LIGHT3;
  if (info.index == 4) whichlight=GL_LIGHT4;

  if (info.defined) {
    float pv[4];

    pv[0]=info.pos.x;
    pv[1]=info.pos.y;
    pv[2]=info.pos.z;
    pv[3]=1.0;

    glLightfv(whichlight, GL_POSITION, pv);
  }
#endif
#endif
}

void mav_gfxTextureEnv1Set(int v)
{
#ifdef MAV_OPENGL
  switch (v) {
    case 1:
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      break;
    case 2:
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      break;
  }
#endif
}

void mav_gfxTextureEnv2Set(int v)
{
#ifdef MAV_OPENGL
  switch (v) {
    case 1:
      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
      break;
    case 2:
      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
      break;
  }
#endif
}

void mav_gfxColouringModeUse(MAV_palette *p, int mode)
{
  if (mode==MAV_COLOUR) 
  {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    lmbind(LMODEL, 0);
    tevbind(TV_ENV0, 0);
#else
    glDisable(GL_LIGHTING);
    glDisable(GL_TEXTURE_2D);
#endif
#endif
  } 
  else if (mode==MAV_MATERIAL) 
  {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    lmbind(LMODEL, p->lm.id+1);
    tevbind(TV_ENV0, 0);
#else
    glEnable(GL_LIGHTING);
    glDisable(GL_TEXTURE_2D);
#endif
#endif
  }
  else if (mode==MAV_TEXTURE) 
  {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    lmbind(LMODEL, 0);
    tevbind(TV_ENV0, 2);
#else
    glDisable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);
#endif
#endif
  }
  else if (mode==MAV_BLENDED_TEXTURE) 
  {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    lmbind(LMODEL, p->lm.id+1);
    tevbind(TV_ENV0, 1);
#else
    glEnable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);
#endif
#endif
  }
  else if (mode==MAV_LIT_TEXTURE) 
  {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    lmbind(LMODEL, p->lm.id+1);
    tevbind(TV_ENV0, 2);
#else
    glEnable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);
#endif
#endif
  }
}

void mav_gfxVisualInfoGet(int *r, int *g, int *b, int *d, int *db, int *ar, int *ag, int *ab)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  *r=getgconfig(GC_BITS_RED);
  *g=getgconfig(GC_BITS_GREEN);
  *b=getgconfig(GC_BITS_BLUE); 
  *d= abs(getgconfig(GC_BITS_ZBUFFER));
  *db= getgconfig(GC_DOUBLE);
  *ar=0;
  *ag=0;
  *ab=0;
#else
  glGetIntegerv(GL_RED_BITS, r);
  glGetIntegerv(GL_GREEN_BITS, g);
  glGetIntegerv(GL_BLUE_BITS, b);
  glGetIntegerv(GL_DEPTH_BITS, d);
  glGetIntegerv(GL_DOUBLEBUFFER, db);
  glGetIntegerv(GL_ACCUM_RED_BITS, ar);
  glGetIntegerv(GL_ACCUM_GREEN_BITS, ag);
  glGetIntegerv(GL_ACCUM_BLUE_BITS, ab);
#endif
#endif
}

void mav_gfxStripQBegin(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  bgnqstrip();
#else
  glBegin(GL_QUAD_STRIP);
#endif
#endif
}

void mav_gfxStripQEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  endqstrip();
#else
  glEnd();
#endif
#endif
}

void mav_gfxStripTBegin(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glBegin(GL_TRIANGLE_STRIP);
#endif
#endif
}

void mav_gfxStripTEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glEnd();
#endif
#endif
}

void mav_gfxTexCoord(MAV_texCoord t)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  t2f((float *) &t);
#else
  glTexCoord2fv((float *) &t);
#endif
#endif
}

void mav_gfxLineClosedBegin(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  bgnclosedline();
#else
  glBegin(GL_LINE_LOOP);
#endif
#endif
}

void mav_gfxLineClosedEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  endclosedline();
#else
  glEnd();
#endif
#endif
}

void mav_gfxLineBegin(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  bgnline();
#else
  glBegin(GL_LINE_STRIP);
#endif
#endif
}

void mav_gfxLineEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  endline();
#else
  glEnd();
#endif
#endif
}

void mav_gfxMeshTBegin(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  bgntmesh();
#else
  glBegin(GL_TRIANGLE_STRIP);
#endif
#endif
}

void mav_gfxMeshTEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  endtmesh();
#else
  glEnd();
#endif
#endif
}


void mav_gfxColourSet(MAV_colour col)
{
}

void mav_gfxColourUse(MAV_colour col)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  c4f(col.colour);
#else
  glColor4fv(col.colour);
#endif
#endif
}

void mav_gfxMaterialSet(MAV_material mat)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  float mat_def[21];

  mat_def[0] = AMBIENT;
  mat_def[1] = mat.ambient[0];
  mat_def[2] = mat.ambient[1];
  mat_def[3] = mat.ambient[2];
  mat_def[4] = DIFFUSE;
  mat_def[5] = mat.diffuse[0];
  mat_def[6] = mat.diffuse[1];
  mat_def[7] = mat.diffuse[2];
  mat_def[8] = SPECULAR;
  mat_def[9] = mat.specular[0];
  mat_def[10] = mat.specular[1];
  mat_def[11] = mat.specular[2];
  mat_def[12] = EMISSION;
  mat_def[13] = mat.emission[0];
  mat_def[14] = mat.emission[1];
  mat_def[15] = mat.emission[2];
  mat_def[16] = ALPHA;
  mat_def[17] = mat.diffuse[3];
  mat_def[18] = SHININESS;
  mat_def[19] = mat.shine;
  mat_def[20] = LMNULL;

  lmdef(DEFMATERIAL, mat.id+1, 0, mat_def);
#endif
#endif
}

void mav_gfxMaterialUse(MAV_material mat)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  lmbind(MATERIAL, mat.id+1);
#else
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat.ambient);
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat.diffuse);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat.specular);
  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat.emission);
  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mat.shine);
#endif
#endif
}

void mav_gfxTextureSet(MAV_texture tex, MAV_texEnvFn pTexEnv)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  float texprops[]= {TX_MINFILTER, TX_BILINEAR, TX_NULL, TX_MAGFILTER, TX_BILINEAR, TX_NULL, TX_WRAP, TX_REPEAT, TX_NULL};
  texdef2d(tex.id+1, 4, tex.width, tex.height, tex.mem, 0, texprops);
#else
#ifndef MAV_SUNOS4
#ifdef GL_EXT_texture_object
  if (mav_opt_bindTextures) {
    glBindTextureEXT(GL_TEXTURE_2D, mavlib_bindTextureIndex[tex.id+1]);
    glEnable(GL_TEXTURE_2D);

    mav_opt_bindTextures=MAV_FALSE;
    mav_gfxTextureUse(tex, pTexEnv);
    mav_opt_bindTextures=MAV_TRUE;

    mav_surfaceParamsUndefine();
  }
#endif
#endif
#endif
#endif
}


void mav_gfxTextureUse(MAV_texture tex, MAV_texEnvFn pTexEnv)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  texbind(TX_TEXTURE_0, tex.id+1);
#else
#ifndef MAV_SUNOS4
#ifdef GL_EXT_texture_object
  if (mav_opt_bindTextures) 
  {
    glBindTextureEXT(GL_TEXTURE_2D, mavlib_bindTextureIndex[tex.id+1]);
  }
  else
#endif
#endif
  {
#ifdef GL_EXT_abgr
    glTexImage2D(GL_TEXTURE_2D, 0, 4, tex.width, tex.height, 0, GL_ABGR_EXT, GL_UNSIGNED_BYTE, tex.mem);
#else
    fprintf(stderr, "Warning: no ABGR texture extension, ignoring.\n");
#endif
  }

  /* call correct texture environment function */
  if (tex.texEnv) 
  {
    (*(tex.texEnv))();
  }
  else
  {
    if (pTexEnv) (*pTexEnv)();
  }
#endif
#endif
}

void mav_gfxLightingModelSet(MAV_lightingModel info)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  float lm_def[7];

  lm_def[0]= AMBIENT;
  lm_def[1]= info.ambient[0];
  lm_def[2]= info.ambient[1];
  lm_def[3]= info.ambient[2];
  lm_def[4]= LOCALVIEWER;
  lm_def[5]= info.localviewer;
  lm_def[6]= LMNULL;

  lmdef(DEFLMODEL, info.id+1, 0, lm_def);
#endif
#endif
}

void mav_gfxLightingModelUse(MAV_lightingModel info)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  lmbind(LMODEL, 0);
#else
  glDisable(GL_LIGHTING);
#endif
#endif

  if (info.defined) {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    lmbind(LMODEL, info.id+1);
#else
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, info.ambient);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, info.localviewer);
    glEnable(GL_LIGHTING);
#endif
#endif
  }
}

void mav_gfxBufferReadSet(int buf)
{
  if (buf==MAV_FRONT)
  {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    readsource(SRC_FRONT);
#else
    glReadBuffer(GL_FRONT);
#endif
#endif
  }
  else
  {
#ifndef MAV_NONE
#ifdef MAV_IRISGL
    readsource(SRC_BACK);
#else
    glReadBuffer(GL_BACK);
#endif
#endif
  }
}

void mav_gfxPixelRead(int x, int y, int width, int height, unsigned long *mem)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  lrectread(x, y, width+x-1, height+y-1, mem);
#else
  float *fmem= mav_malloc(width*height*3*sizeof(float));
  int i,j=0;

  glReadPixels(x, y, width, height, GL_RGB, GL_FLOAT, fmem);

  for (i=0; i<width*height; i++) {
#ifdef MAV_LINUX
    mem[i]= (((int) (fmem[j]*255.0))<<24) + (((int) (fmem[j+1]*255.0))<<16) + (((int) (fmem[j+2]*255.0))<<8) + 255;
#else
    mem[i]= (255<<24) + (((int) (fmem[j+2]*255.0))<<16) + (((int) (fmem[j+1]*255.0))<<8) + ((int) (fmem[j]*255.0));
#endif
    j+=3;
  }

  mav_free(fmem);
#endif
#endif
}

void mav_gfxPixelReadUByte(int x, int y, int width, int height, unsigned char *mem)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL  
#else
  glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, mem);
#endif
#endif
}

void mav_gfxPixelDraw(int w, int h, float *v)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glDrawPixels(w, h, GL_RGB, GL_FLOAT, v);
#endif
#endif
}

void mav_gfxNormalizeSet(int i)
{
#ifndef MAV_NONE
  if (i) 
  {
#ifdef MAV_IRISGL
    nmode(NAUTO);
#else
    glEnable(GL_NORMALIZE);
#endif
  }
  else
  {
#ifdef MAV_IRISGL
    /* Cant do under GL */
#else
    glDisable(GL_NORMALIZE);
#endif
  }
#endif
}

void mav_gfxBackfaceCullSet(int i)
{
#ifndef MAV_NONE
  if (i) 
  {
#ifdef MAV_IRISGL
    backface(TRUE);
#else
    glEnable(GL_CULL_FACE);
#endif
  }
  else
  {
#ifdef MAV_IRISGL
    backface(FALSE);
#else
    glDisable(GL_CULL_FACE);
#endif
  }
#endif
}

int mav_gfxBackfaceCullGet()
{
  int rv= MAV_FALSE;

#ifdef MAV_OPENGL
  glGetIntegerv(GL_CULL_FACE, &rv);
#endif
  
  return rv;
}

void mav_gfxDepthTestSet(int i)
{
#ifndef MAV_NONE
  if (i) 
  {
#ifdef MAV_IRISGL
    zbuffer(TRUE);
#else
    glEnable(GL_DEPTH_TEST);
#endif
  }
  else
  {
#ifdef MAV_IRISGL
    zbuffer(FALSE);
#else
    glDisable(GL_DEPTH_TEST);
#endif
  }
#endif
}

void mav_gfxDepthMaskSet(int i)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  if (i) 
  {
    zwritemask(0xffffffff);
  }
  else
  {
    zwritemask(0);
  }
#else
  glDepthMask(i);
#endif
#endif
}

void mav_gfxViewPortSet(int x, int y, int width, int height)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  viewport(x,x+width-1,y,y+height-1);
#else
  glViewport(x,y,width,height);
#endif
#endif
}

void mav_gfxRasterPosSet(MAV_vector v)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  cmov2(v.x,v.y);
#else
  glRasterPos3f(v.x,v.y,v.z);
#endif
#endif
}

void mav_gfxRasterPos2DSet(float x, float y)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  cmov2(x,y);
#else
  glRasterPos2f(x,y);
#endif
#endif
}

void mav_gfxLineWidthSet(float lw)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
  linewidthf(lw);
#else
  glLineWidth(lw);
#endif
#endif
}

float mav_gfxLineWidthGet(void)
{
  float rv=0;

#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glGetFloatv(GL_LINE_WIDTH, &rv);
#endif
#endif

  return rv;
}

void mav_gfxBlendSet(int v)
{
#ifndef MAV_NONE
  switch (v) {
  case MAV_BLEND_OFF:
#ifdef MAV_IRISGL
    blendfunction(BF_ONE, BF_ZERO);
#else
    glDisable(GL_BLEND);
#endif
    break;

  case MAV_BLEND_1:
#ifdef MAV_IRISGL
    blendfunction(BF_SA, BF_MSA);
#else
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
    break;
  }    
#endif
}

void mav_gfxAccumSet(int mode, float val)
{
#ifndef MAV_NONE
  switch (mode) {
  case MAV_ACCUM_ACCUM:
#ifdef MAV_IRISGL
#else
    glAccum(GL_ACCUM, val);
#endif
    break;

  case MAV_ACCUM_RETURN:
#ifdef MAV_IRISGL
#else
    glAccum(GL_RETURN, val);
#endif
    break;
  }
#endif
}

int mav_gfxListsNew(int range)
{
#ifdef MAV_NONE
  return -1;
#else
#ifdef MAV_IRISGL
  return -1;
#else
  return glGenLists(range);
#endif
#endif
}

void mav_gfxListNew(int list, int mode)
{
#ifndef MAV_NONE
  switch (mode) {
  case MAV_DLISTS_COMPILE:
#ifdef MAV_IRISGL
#else
    glNewList(list, GL_COMPILE);
#endif
    break;

  case MAV_DLISTS_COMPILE_AND_EXECUTE:
#ifdef MAV_IRISGL
#else
    glNewList(list, GL_COMPILE_AND_EXECUTE);
#endif
    break;
  }
#endif
}

void mav_gfxListEnd(void)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glEndList();
#endif
#endif
}

void mav_gfxListExec(int list)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glCallList(list);
#endif
#endif
}

void mav_gfxListsExec(int n, int *lists)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glCallLists(n, GL_INT, lists);
#endif
#endif
}

void mav_gfxListsDelete(int list, int range)
{
#ifndef MAV_NONE
#ifdef MAV_IRISGL
#else
  glDeleteLists(list, range);
#endif
#endif
}
