/********************************************************************************
*                                                                               *
*                         OpenGL Application coding sample                      *
*                                                                               *
*********************************************************************************
* Copyright (C) 1998,2026 by Jeroen van der Zijp.   All Rights Reserved.        *
********************************************************************************/
#include "fx.h"
#include "fx3d.h"
#include "FXGLShape.h"
#include "FXGLPoint.h"
#include "FXGLLine.h"
#include "FXGLCone.h"
#include "FXGLSphere.h"
#include "FXGLCube.h"
#include "FXGLCylinder.h"


#ifdef HAVE_GL_H


// Front view
const unsigned char frontview[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x64,0x00,0xf4,0xa4,0x60,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0x80,0x00,0xff,
  0xff,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x42,0x08,0x0a,0x11,0xfb,0xb0,0xc9,0x29,0x5f,0x10,0x4d,0xe8,0x8d,0x2d,0xbe,0x9c,
  0xe6,0x2c,0x60,0xb8,0x8d,0x24,0x35,0x41,0x43,0x40,0xbc,0xf0,0x8b,0x02,0x43,0x1b,
  0xc7,0xe8,0x44,0x48,0xbb,0x3b,0x15,0x40,0xdf,0xae,0xb7,0x03,0x1a,0x0b,0x42,0x17,
  0x2c,0x70,0x0c,0xaa,0x24,0x4d,0xa3,0x61,0x1a,0xad,0x4e,0x0d,0xd5,0xe8,0x35,0xdb,
  0xdc,0x56,0x13,0x00,0x3b
  };

// Back view
const unsigned char backview[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x64,0x00,0xf4,0xa4,0x60,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0x80,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x41,0x08,0xba,0x1c,0xc1,0xca,0xc9,0x29,0x9b,0xb8,0x38,0xbf,0x15,0xb2,0x17,0x5b,
  0xf4,0x69,0x10,0x35,0x0d,0x10,0x10,0x10,0x6c,0x4b,0x0c,0x70,0xe9,0xb2,0x70,0xad,
  0x4a,0x84,0x93,0xaf,0xb5,0x53,0xfc,0x2b,0x9d,0xae,0xf6,0x2b,0xae,0x66,0x30,0x01,
  0xac,0x58,0x30,0x49,0x04,0xcc,0xa8,0x14,0x2a,0xad,0x16,0xa8,0xd6,0x28,0x36,0x5b,
  0x4d,0x00,0x00,0x3b
  };

// Top view
const unsigned char topview[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0x00,0x80,0x00,
  0x00,0xff,0x00,0x00,0x00,0x00,0xf4,0xa4,0x60,0xa5,0x2a,0x2a,0xff,0xff,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x38,0x08,0xba,0xdc,0x1b,0x2e,0x82,0x40,0x25,0xa3,0xd8,0x3e,0xc1,0xbb,0xe7,0x8c,
  0x30,0x8c,0x64,0x29,0x84,0x65,0x3a,0x9c,0x8b,0x40,0xbc,0x70,0xcc,0x2a,0x2e,0x17,
  0xc3,0x33,0x20,0x72,0xea,0x8a,0xf6,0xa3,0xdc,0x67,0x98,0x5b,0x14,0x8e,0x1a,0x23,
  0x32,0x09,0x38,0x16,0x98,0xcd,0xa5,0x23,0x01,0x00,0x3b
  };

// Bottom view
const unsigned char bottomview[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf1,0x00,0x00,0x80,0x80,0x80,
  0xa9,0xa9,0xa9,0x00,0x64,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,
  0x10,0x00,0x00,0x02,0x2f,0x84,0x11,0x79,0xcb,0xa8,0xdd,0x52,0x80,0xf1,0x51,0x20,
  0xb2,0xde,0x79,0x09,0x09,0x4a,0x82,0x17,0x86,0xe3,0xf1,0x95,0x22,0xa9,0x26,0xe7,
  0x94,0xb6,0x2f,0xd6,0xba,0x47,0xc0,0xe5,0xa7,0x73,0x2d,0x13,0xd2,0x33,0xfc,0x7e,
  0xc1,0xe2,0xa1,0x00,0x00,0x3b
  };

// Left view
const unsigned char leftview[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x64,0x00,0xf4,0xa4,0x60,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0x80,0x00,0xff,
  0xff,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x42,0x08,0xba,0x1b,0xfc,0x2c,0x48,0x08,0x83,0x10,0x8e,0xb6,0x7b,0x33,0xb5,0x5c,
  0x07,0x0d,0x80,0x64,0x9a,0xcf,0xa0,0x06,0x44,0xeb,0x7a,0x80,0x2a,0x13,0x66,0x0b,
  0x07,0x32,0xab,0xdb,0x67,0x91,0xd3,0x12,0x5b,0x61,0xe8,0x93,0x0d,0x5c,0x2f,0x22,
  0x51,0x50,0x38,0x9d,0x0c,0x50,0xc3,0x90,0xa9,0xac,0x56,0xa9,0xd6,0x2c,0x36,0xcb,
  0xed,0x0e,0x13,0x00,0x3b
  };

// Right view
const unsigned char rightview[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x64,0x00,0xf4,0xa4,0x60,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0x80,0x00,0xff,
  0xff,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x42,0x08,0xba,0xb1,0xfe,0x2c,0x34,0x08,0x83,0x10,0x93,0x2a,0x7b,0xb1,0x1a,0x55,
  0xd7,0x05,0x43,0xf9,0x48,0x28,0x5a,0x82,0x4e,0x40,0xbc,0x30,0x29,0xb0,0xcc,0x8b,
  0x12,0x8d,0xb0,0xa5,0x36,0x8e,0x5b,0x92,0x82,0xb0,0xe0,0xfa,0xb9,0x02,0x05,0xc1,
  0x70,0x58,0x84,0xe1,0x96,0x86,0xa8,0x21,0x95,0x5a,0x5a,0xaf,0xd8,0xac,0x76,0xcb,
  0xcd,0x26,0x00,0x00,0x3b
  };


const unsigned char foxicon[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0x7f,0x7f,0x7f,0xa9,0xa9,0xa9,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x37,0x08,0xba,0xdc,0xfe,0x30,0xae,0x40,0x29,0xa8,0xca,0xd6,0xb0,0x04,0x0f,0x02,
  0x30,0x7c,0x23,0x27,0x9a,0xd7,0x70,0xad,0x98,0x37,0x85,0xeb,0x65,0xba,0x19,0x6c,
  0x5a,0xe7,0xa4,0x7e,0x72,0xf7,0x85,0xa3,0x14,0x2e,0x83,0xd3,0xa0,0x24,0x0f,0x82,
  0x72,0x49,0x40,0x3a,0x9f,0xd0,0x45,0x02,0x00,0x3b
  };


// Palette of colors
const unsigned char colorpal[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0x80,0x80,0x80,
  0x00,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x00,0x00,
  0x00,0xff,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x47,0x08,0x0a,0xd1,0xfb,0x30,0x88,0xe9,0xe0,0x92,0x33,0x07,0xcb,0xf2,0xf8,0xd4,
  0xd3,0x64,0xc2,0x37,0x48,0x55,0x83,0x11,0x04,0x83,0x09,0x9b,0x23,0xb1,0x2d,0x49,
  0x6d,0xdd,0x42,0xc6,0x68,0x67,0xdf,0x23,0x58,0xa7,0x40,0x7c,0x05,0x85,0x12,0x62,
  0xe1,0x65,0xc3,0xa1,0x24,0x86,0x68,0x54,0x73,0xc9,0x48,0x0d,0x54,0xd1,0xf1,0x66,
  0x91,0xa9,0x70,0x11,0x30,0x07,0x90,0x00,0x00,0x3b
  };

// Save as
const unsigned char filesaveas[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf3,0x00,0x00,0x80,0x80,0x80,
  0xb2,0xc0,0xdc,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,
  0x00,0xff,0x00,0xff,0xff,0x00,0x00,0x80,0xc0,0xc0,0xc0,0x00,0x80,0x80,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,
  0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x04,0x5a,0x10,0xc8,0x19,0xaa,0xbd,0x40,0x0c,
  0x91,0xc1,0xfd,0xc0,0x36,0x10,0x24,0xf1,0x59,0x99,0x58,0x4c,0x2c,0xba,0x19,0x5a,
  0x26,0xcc,0x9c,0x17,0x64,0xc6,0x01,0xcb,0x74,0x77,0xe7,0x07,0x9d,0x0c,0xc6,0x99,
  0x49,0x04,0x40,0x1d,0x12,0xd1,0x29,0x85,0x90,0x41,0xdd,0x81,0x39,0x4b,0x24,0x08,
  0x29,0x68,0x94,0x4a,0xc3,0x8a,0xb4,0x53,0x9e,0x00,0x5b,0x4a,0x86,0x69,0xe3,0x89,
  0x01,0xc1,0x6e,0x8b,0x4d,0x16,0x85,0x02,0x3b,0x41,0xc3,0x31,0x68,0xfb,0x09,0x50,
  0xea,0x93,0x22,0x00,0x3b
  };

// File Save
const unsigned char filesave[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x80,0x80,0x80,0xff,0xff,0xff,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x42,0x08,0xaa,0xb1,0xfe,0x4c,0x34,0x06,0xa3,0x90,0x20,0xcc,0x1a,0xae,0xc4,0x95,
  0x75,0x6d,0x8f,0xa6,0x79,0x64,0xa6,0x0d,0x44,0x87,0x9a,0x0c,0xc1,0x9a,0xb4,0x3c,
  0x05,0x33,0xad,0xd7,0x43,0x50,0x0c,0xbf,0x20,0x10,0xb8,0x6a,0x0d,0x85,0x42,0x8d,
  0x11,0x79,0xec,0x65,0x7a,0x4c,0x64,0x23,0xb0,0x6c,0x26,0x55,0xd6,0xe6,0x6d,0xc7,
  0x55,0x24,0x00,0x00,0x3b
  };


// File Open
const unsigned char fileopen[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0x00,0xff,0x00,0xff,0xff,0x00,0x80,0x80,0x80,0xff,0xff,0xff,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x45,0x08,0xba,0x1c,0xfe,0x2c,0xae,0x20,0x44,0x90,0x91,0xd6,0x8b,0x95,0xb6,0x1c,
  0x00,0x79,0x95,0x25,0x3e,0x03,0x31,0x3c,0xa5,0x73,0xaa,0xf0,0xda,0xae,0x5e,0xfa,
  0xdc,0xb8,0xa3,0x06,0xc5,0xd0,0xff,0x3e,0x9f,0xc3,0x16,0x04,0x02,0x75,0x81,0xa2,
  0xb2,0x77,0x49,0xf2,0x96,0xc5,0x26,0x21,0x69,0x54,0x36,0xa9,0x50,0xa6,0xe7,0x59,
  0xfd,0x71,0x72,0x60,0x4e,0x02,0x00,0x3b
  };

// Print
const unsigned char print[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x80,0x80,0x80,0x00,0x80,0x80,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x49,0x08,0x0a,0xd1,0xbd,0x10,0x06,0x41,0x5f,0x94,0x62,0xea,0xbb,0x66,0x75,0x1c,
  0x93,0x09,0x43,0x19,0x84,0x1e,0x55,0x5d,0x8e,0x40,0x04,0x6f,0x66,0x29,0x41,0x91,
  0xaa,0xf5,0x49,0x3b,0x7c,0x7f,0x06,0x25,0x92,0x70,0x30,0x24,0x35,0x0a,0xc8,0xa4,
  0x52,0x79,0xb4,0x39,0x99,0x35,0x5b,0x74,0x49,0x95,0xfa,0xae,0x8f,0x1a,0xa1,0xb0,
  0xed,0x72,0xb9,0xba,0x17,0xd6,0x41,0x00,0x24,0x00,0x00,0x3b
  };


// Zoom
const unsigned char zoom[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xbf,0xbf,0xbf,
  0x80,0x80,0x80,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x4a,0x08,0x1a,0xd2,0x1d,0x2a,0xc6,0x17,0x46,0x60,0x42,0x2a,0x51,0x89,0x1d,0x20,
  0x23,0x31,0x03,0x61,0x82,0x28,0x37,0x05,0xa6,0x87,0x96,0xe2,0x66,0xb9,0x2f,0x98,
  0x6d,0x55,0x0d,0x7a,0x37,0x20,0x7c,0x3a,0xde,0x4a,0x57,0x22,0xc4,0x00,0xa4,0xda,
  0x49,0x35,0x6c,0x9d,0x18,0x10,0xc9,0x03,0x85,0x81,0x6a,0x30,0x8e,0x0b,0x87,0xa9,
  0xb9,0x0a,0x08,0xdc,0x6e,0x84,0x01,0x16,0x77,0xa1,0x09,0x00,0x3b
  };



// File new
const unsigned char filenew[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0xff,0xff,0x00,0xff,0xff,0xff,0x80,0x80,0x80,0x00,0x00,0x00,0xc0,0xc0,0xc0,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x48,0x08,0x0a,0xb1,0xfe,0xab,0x41,0x28,0x18,0xa8,0xd3,0x85,0x3d,0xfa,0x80,0x5b,
  0x28,0x0e,0x44,0x16,0x16,0x82,0x30,0x08,0xe5,0xa3,0x06,0x68,0xba,0xb2,0xd0,0x10,
  0x08,0x31,0x49,0xec,0x8f,0x9d,0xfe,0x85,0x20,0xe1,0xb3,0xf0,0xfd,0x8e,0x43,0xc7,
  0xec,0xf8,0x4b,0x16,0x99,0x48,0xa2,0x62,0x09,0x75,0x4e,0xa1,0x4d,0x29,0x40,0xb7,
  0xeb,0x76,0xb5,0x5b,0x8f,0xd8,0x03,0x48,0x00,0x00,0x3b
  };

// Cut
const unsigned char cut[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf1,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,
  0x10,0x00,0x00,0x02,0x29,0x84,0x8f,0xa9,0x10,0xd7,0xeb,0x22,0x34,0x8f,0x4d,0xda,
  0x42,0x9d,0xf9,0x3a,0xed,0x49,0xa1,0x10,0x08,0x21,0x60,0x0a,0xea,0xa4,0xa6,0x86,
  0xa9,0xc0,0x2e,0xba,0xc8,0xf4,0x9d,0xd8,0x28,0x5c,0xf3,0xe7,0x54,0x00,0x00,0x3b
  };

// Copy
const unsigned char copy[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf1,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x80,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,
  0x10,0x00,0x00,0x02,0x38,0x84,0x8f,0x69,0xc1,0xad,0x18,0x84,0x14,0xec,0xad,0x49,
  0xa9,0x8d,0x8c,0x8e,0x0f,0x42,0x98,0x30,0x60,0xdf,0xc1,0x35,0xe5,0x54,0x0e,0x97,
  0x49,0x45,0xa0,0x9b,0x32,0xeb,0x48,0xe3,0x71,0x43,0x02,0x8d,0x3a,0x92,0xb8,0x14,
  0xa5,0x9f,0xec,0x71,0x33,0x21,0x67,0x33,0x8b,0xf3,0x99,0x28,0x00,0x00,0x3b
  };


// Paste
const unsigned char paste[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0x00,0xc0,0xc0,0xc0,0x80,0x80,0x00,0x80,0x80,0x80,0x00,
  0x00,0x80,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x4b,0x08,0xba,0xdc,0x1e,0x30,0x38,0x15,0xa1,0x10,0x55,0x52,0x52,0x48,0xc0,0x5f,
  0xd0,0x15,0x9a,0x48,0x0e,0x68,0x2a,0x7a,0x1b,0x99,0x41,0x05,0x49,0x8d,0x5c,0x4d,
  0x97,0x36,0x61,0xec,0xbc,0x51,0xd2,0x05,0xc3,0x61,0x38,0xdc,0xb5,0x6a,0x42,0xe2,
  0x41,0x68,0x00,0xac,0x46,0xc2,0xc8,0x92,0x17,0xc8,0x25,0x95,0xc5,0x27,0x27,0x9a,
  0x59,0x3a,0x2b,0x57,0x6c,0xb3,0xd1,0x2b,0x8f,0x27,0x93,0x04,0x00,0x3b
  };


// Delete
const unsigned char killobject[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf0,0x00,0x00,0xb2,0xc0,0xdc,
  0xff,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x02,0x24,0x84,
  0x8f,0x79,0xc1,0xba,0xcb,0x82,0x6a,0x28,0x4a,0xe8,0x40,0x34,0x34,0xdb,0x9b,0x71,
  0x5d,0xf8,0x85,0x1a,0x35,0x56,0x63,0x7a,0x82,0x8f,0xca,0x6a,0xb0,0x59,0x99,0x2e,
  0x8d,0x2b,0x05,0x00,0x3b
  };

// No shading
const unsigned char nolight[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xc0,0xc0,0xc0,0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x33,0x08,0x1a,0xac,0xfe,0x2e,0x88,0x19,0x20,0x94,0x02,0x57,0xbb,0xb2,0xdf,0x9c,
  0x24,0x66,0x5c,0x24,0x82,0x25,0xc0,0xa0,0x69,0x30,0xb0,0x0f,0x11,0xbd,0x1c,0x61,
  0x9b,0xb0,0x7d,0x3b,0x85,0xa5,0xef,0xa5,0x1f,0xb0,0x26,0x4c,0x09,0x87,0x90,0xa3,
  0x2c,0x65,0x49,0x00,0x00,0x3b
  };

// Shading
const unsigned char light[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x80,0x80,0x00,0x00,0x00,0xff,0x80,
  0x80,0x80,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x34,0x08,0x10,0xac,0xfe,0x2e,0x88,0x19,0x20,0x94,0x62,0x50,0x1b,0xb3,0xaf,0xdc,
  0xe2,0x69,0x60,0xc8,0x08,0x4d,0x18,0xa5,0xaa,0x12,0x10,0xa5,0x55,0x14,0x2e,0xcc,
  0xcd,0xb3,0xcb,0x3a,0x78,0xae,0x18,0xb2,0x1e,0x2d,0x24,0xf4,0xdd,0x8a,0xc4,0xe2,
  0x30,0x88,0x6c,0x41,0x12,0x00,0x3b
  };

// Smooth shading
const unsigned char smoothlight[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x80,0x80,0x00,0x00,
  0x00,0xff,0x80,0x80,0x80,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x41,0x08,0x10,0xac,0xfe,0x2e,0x88,0x19,0x20,0x94,0x62,0x50,0x1b,0xb3,0xaf,0x16,
  0xb1,0x78,0x1a,0xf8,0x10,0xe8,0x22,0x35,0x9c,0xa8,0x30,0x20,0xea,0x2a,0x73,0x50,
  0xc4,0xb3,0x62,0x18,0xef,0x4d,0x03,0xae,0xdd,0xee,0xc5,0x72,0x10,0x84,0x43,0xc5,
  0xc1,0x82,0x4c,0x72,0x9a,0xce,0x9f,0x0e,0x7a,0x92,0x41,0xa3,0xc0,0x29,0x95,0xc3,
  0x4d,0x00,0x00,0x3b
  };

// Parallel projection
const unsigned char parallel[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf1,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,
  0x10,0x00,0x00,0x02,0x31,0x84,0x6f,0x11,0xc8,0xa7,0xa0,0x56,0x83,0x12,0xa6,0x4a,
  0x19,0x8e,0x6f,0x66,0x25,0x08,0x9d,0x53,0x81,0xa1,0xb8,0x8c,0xd7,0x79,0x62,0x24,
  0x1b,0x4a,0xa3,0xc9,0x6e,0x69,0x00,0x8b,0x0d,0x07,0xdb,0x08,0x2d,0x73,0xbd,0x22,
  0x9e,0x9f,0xb0,0x58,0x2c,0x00,0x00,0x3b
  };

// Perspective projection
const unsigned char perspective[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf1,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,
  0x10,0x00,0x00,0x02,0x2d,0x84,0x8f,0xa9,0x10,0xbb,0x01,0xa1,0x33,0xad,0x51,0x9b,
  0x2c,0xbe,0x08,0x6f,0x26,0x31,0xdd,0x11,0x56,0x1f,0x38,0x06,0x42,0x79,0x56,0xc2,
  0x1b,0xa2,0x14,0xf3,0xae,0x8a,0xa4,0xa9,0x27,0x47,0x46,0xbe,0x3f,0x09,0x0a,0x87,
  0x8b,0x02,0x00,0x3b
  };


// New folder
const unsigned char newfolder[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf1,0x00,0x00,0xb2,0xc0,0xdc,
  0x00,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,
  0x10,0x00,0x00,0x02,0x30,0x84,0x8f,0xa9,0x19,0xeb,0xbf,0x1a,0x04,0xf2,0x54,0x1a,
  0xb2,0x69,0x1c,0x05,0x31,0x80,0x52,0x67,0x65,0xe6,0xb9,0x51,0x54,0xc8,0x82,0xe2,
  0xf5,0xb5,0x2d,0xb9,0xba,0xf2,0xb8,0xd9,0xfa,0x55,0xcb,0x22,0xa3,0x9b,0x31,0x4e,
  0x44,0xde,0x24,0x51,0x00,0x00,0x3b
  };

const unsigned char penguin[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x12,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x80,0x80,0x80,0x00,0x00,0x00,0xc0,0xc0,0xc0,0x10,0x10,0x10,0xff,0xff,0xff,0xe0,
  0xa0,0x08,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x12,0x00,0x00,0x03,
  0x53,0x08,0xba,0x21,0x12,0x2b,0xc6,0xe6,0x9e,0x94,0x62,0x64,0x77,0xa3,0x20,0x4e,
  0x21,0x74,0x8b,0x60,0x9c,0x1a,0xa9,0x98,0xa8,0x45,0xb2,0x85,0x38,0x76,0x4f,0x6c,
  0xbb,0x93,0x60,0xdb,0x0d,0xe4,0xd9,0x83,0x1d,0xe7,0x57,0x18,0x04,0x6f,0xb8,0x4c,
  0xec,0x88,0x9c,0x01,0x0c,0x47,0x66,0xac,0xa2,0x38,0x19,0x76,0x36,0x83,0xc3,0xf0,
  0xb4,0x5e,0x77,0x03,0xaf,0xf8,0x7b,0x13,0x77,0xad,0xd3,0xad,0x75,0x61,0xa5,0x54,
  0x02,0x27,0x45,0x02,0x00,0x3b
  };


// Application icon
const unsigned char winapp[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xf2,0x00,0x00,0xb2,0xc0,0xdc,
  0x80,0x80,0x80,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x00,
  0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x03,
  0x38,0x08,0xba,0xdc,0x10,0x30,0xca,0x09,0x85,0xbd,0xf8,0x86,0x11,0x04,0xf9,0x60,
  0xf8,0x6d,0x9d,0x48,0x14,0x03,0x8a,0x92,0x02,0xe5,0x72,0x42,0x21,0xcf,0xb4,0xcc,
  0xd6,0x78,0x71,0xe7,0xf4,0xce,0xdb,0xb0,0xdf,0xcc,0xf7,0x23,0xf2,0x48,0xae,0xd7,
  0x60,0xc9,0x6c,0x3a,0x07,0x8e,0xe8,0x22,0x01,0x00,0x3b
  };


// Camera picture
const unsigned char camera[]={
  0x47,0x49,0x46,0x38,0x37,0x61,0x10,0x00,0x10,0x00,0xe3,0x00,0x00,0xd1,0xee,0xee,
  0x00,0x00,0x00,0x68,0x67,0x68,0xff,0xff,0xff,0x84,0x84,0x84,0xbf,0xbf,0xc0,0x80,
  0x80,0x80,0xa2,0xa2,0xa3,0x47,0x47,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,
  0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x04,0x47,0x10,0xc8,0x49,0xab,0x05,0x21,0xe7,
  0xaa,0xbb,0xd7,0x80,0x10,0x0c,0x64,0x46,0x14,0x44,0x66,0x18,0x45,0x70,0x08,0x88,
  0xd6,0x66,0x73,0xd0,0xbe,0xb1,0x6d,0x17,0xed,0x7c,0xc3,0x81,0x54,0x81,0x34,0x68,
  0x09,0x5d,0xc0,0x1e,0xb1,0xa7,0xc3,0x05,0x6d,0xcb,0xe7,0x2f,0xd7,0xe3,0xe9,0x9a,
  0x40,0x9a,0x6c,0x2b,0xc8,0x9a,0x50,0x9f,0xb0,0xf8,0x42,0x2e,0x9b,0xcf,0x94,0x08,
  0x00,0x3b
  };

/*******************************************************************************/


// Main Window
class GLViewWindow : public FXMainWindow {
  FXDECLARE(GLViewWindow)
private:
  FXMenuBar         *menubar;                 // Menu bar
  FXToolBar         *toolbar1;                // Tool bar
  FXToolBar         *toolbar2;                // Tool bar
  FXDockBar         *dockbar;                 // Dock bar
  FXToolBarShell    *dragshell1;              // Shell for floating menubar
  FXToolBarShell    *dragshell2;              // Shell for floating toolbar
  FXToolBarShell    *dragshell3;              // Shell for floating toolbar
  FXToolBarShell    *dragshell4;              // Shell for floating toolbar
  FXDockSite        *topdock;
  FXDockSite        *bottomdock;
  FXDockSite        *leftdock;
  FXDockSite        *rightdock;
  FXMDIClient       *mdiclient;               // MDI Client area
  FXStatusBar       *statusbar;               // Status bar
  FXGLGroup         *scene;                   // Scene to watch
  FXMenuPane        *mdimenu;                 // MDI Window Menu
  FXGLVisual        *glvisual;                // Visual for OpenGL
  FXMenuPane        *filemenu;
  FXMenuPane        *editmenu;
  FXMenuPane        *viewmenu;
  FXMenuPane        *rendermenu;
  FXMenuPane        *windowmenu;
  FXMenuPane        *helpmenu;
  FXIcon            *frontviewicon;
  FXIcon            *backviewicon;
  FXIcon            *topviewicon;
  FXIcon            *bottomviewicon;
  FXIcon            *leftviewicon;
  FXIcon            *rightviewicon;
  FXIcon            *foxiconicon;
  FXIcon            *colorpalicon;
  FXIcon            *filesaveasicon;
  FXIcon            *filesaveicon;
  FXIcon            *fileopenicon;
  FXIcon            *printicon;
  FXIcon            *zoomicon;
  FXIcon            *filenewicon;
  FXIcon            *cuticon;
  FXIcon            *copyicon;
  FXIcon            *pasteicon;
  FXIcon            *killobjecticon;
  FXIcon            *nolighticon;
  FXIcon            *lighticon;
  FXIcon            *smoothlighticon;
  FXIcon            *parallelicon;
  FXIcon            *perspectiveicon;
  FXIcon            *newfoldericon;
  FXIcon            *penguinicon;
  FXIcon            *winappicon;
  FXIcon            *cameraicon;
protected:
  GLViewWindow(){}
public:

  // We define additional ID's, starting from the last one used by the base class+1.
  // This way, we know the ID's are all unique for this particular target.
  enum{
    ID_ABOUT=FXMainWindow::ID_LAST,
    ID_OPEN,
    ID_NEWVIEWER,
    ID_QUERY_MODE,
    ID_GLVIEWER
    };

  // Message handlers
  long onCmdOpen(FXObject*,FXSelector,void*);
  long onCmdNewViewer(FXObject*,FXSelector,void*);
  long onCmdAbout(FXObject*,FXSelector,void*);
  long onUpdMode(FXObject*,FXSelector,void*);
  long onQueryMenu(FXObject*,FXSelector,void*);

public:

  // GLViewWindow constructor
  GLViewWindow(FXApp* a);

  // Initialize
  virtual void create() override;

  // GLViewWindow destructor
  virtual ~GLViewWindow();
  };


/*******************************************************************************/


// Message Map GLViewWindow class
FXDEFMAP(GLViewWindow) GLViewWindowMap[]={

  //__Message_Type_____________ID________________________Message_Handler_____
  FXMAPFUNC(SEL_COMMAND,     GLViewWindow::ID_ABOUT,      GLViewWindow::onCmdAbout),
  FXMAPFUNC(SEL_COMMAND,     GLViewWindow::ID_OPEN,       GLViewWindow::onCmdOpen),
  FXMAPFUNC(SEL_COMMAND,     GLViewWindow::ID_NEWVIEWER,  GLViewWindow::onCmdNewViewer),
  FXMAPFUNC(SEL_UPDATE,      GLViewWindow::ID_QUERY_MODE, GLViewWindow::onUpdMode),
  FXMAPFUNC(SEL_COMMAND,     FXWindow::ID_QUERY_MENU,	  GLViewWindow::onQueryMenu)
  };



// Macro for the GLViewWindow class hierarchy implementation
FXIMPLEMENT(GLViewWindow,FXMainWindow,GLViewWindowMap,ARRAYNUMBER(GLViewWindowMap))


/*******************************************************************************/

// Construct a GLViewWindow
GLViewWindow::GLViewWindow(FXApp* a):FXMainWindow(a,"OpenGL Test Application",nullptr,nullptr,DECOR_ALL,0,0,800,600){
  penguinicon=new FXGIFIcon(getApp(),penguin);

  setIcon(penguinicon);

  FXColorDialog *colordlg=new FXColorDialog(this,"Color Dialog",DECOR_TITLE|DECOR_BORDER,100,100);

  // Make status bar
  statusbar=new FXStatusBar(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER);

  // Site where to dock
  topdock=new FXDockSite(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
  bottomdock=new FXDockSite(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X);
  leftdock=new FXDockSite(this,LAYOUT_SIDE_LEFT|LAYOUT_FILL_Y);
  rightdock=new FXDockSite(this,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y);

  // Menubar 1
  dragshell1=new FXToolBarShell(this,FRAME_RAISED);
  menubar=new FXMenuBar(topdock,dragshell1,LAYOUT_DOCK_SAME|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|FRAME_RAISED|LAYOUT_FILL_Y);
  new FXToolBarGrip(menubar,menubar,FXMenuBar::ID_TOOLBARGRIP,TOOLBARGRIP_DOUBLE);

  // Tool bar 2
  dragshell2=new FXToolBarShell(this,FRAME_RAISED);
  toolbar1=new FXToolBar(topdock,dragshell2,LAYOUT_DOCK_NEXT|LAYOUT_SIDE_TOP|FRAME_RAISED);
  new FXToolBarGrip(toolbar1,toolbar1,FXToolBar::ID_TOOLBARGRIP,TOOLBARGRIP_DOUBLE);

  // Tool bar 3
  dragshell3=new FXToolBarShell(this,FRAME_RAISED);
  toolbar2=new FXToolBar(topdock,dragshell3,LAYOUT_DOCK_SAME|LAYOUT_SIDE_TOP|FRAME_RAISED);
  new FXToolBarGrip(toolbar2,toolbar2,FXToolBar::ID_TOOLBARGRIP,TOOLBARGRIP_DOUBLE);

  // The good old penguin, what would we be without it?
  new FXButton(statusbar,"\tHello, I'm Tux...\nThe symbol for the Linux Operating System.\nAnd all it stands for.",penguinicon,nullptr,0,LAYOUT_RIGHT);

  // Contents
  FXHorizontalFrame *frame=new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0, 4,4);

  // Nice sunken box around GL viewer
  FXVerticalFrame *box=new FXVerticalFrame(frame,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0);

  // MDI Client
  mdiclient=new FXMDIClient(box,LAYOUT_FILL_X|LAYOUT_FILL_Y);

  // Icon for MDI Child
  winappicon=new FXGIFIcon(getApp(),winapp);

  // Make MDI Window Menu
  mdimenu=new FXMDIMenu(this,mdiclient);

  // MDI buttons in menu:- note the message ID's!!!!!
  // Normally, MDI commands are simply sensitized or desensitized;
  // Under the menubar, however, they're hidden if the MDI Client is
  // not maximized.  To do this, they must have different ID's.
  new FXMDIWindowButton(menubar,mdimenu,mdiclient,FXMDIClient::ID_MDI_MENUWINDOW,LAYOUT_LEFT|LAYOUT_CENTER_Y);
  new FXMDIDeleteButton(menubar,mdiclient,FXMDIClient::ID_MDI_MENUCLOSE,FRAME_RAISED|LAYOUT_RIGHT|LAYOUT_CENTER_Y);
  new FXMDIRestoreButton(menubar,mdiclient,FXMDIClient::ID_MDI_MENURESTORE,FRAME_RAISED|LAYOUT_RIGHT|LAYOUT_CENTER_Y);
  new FXMDIMinimizeButton(menubar,mdiclient,FXMDIClient::ID_MDI_MENUMINIMIZE,FRAME_RAISED|LAYOUT_RIGHT|LAYOUT_CENTER_Y);

  // Make an MDI Child
  FXMDIChild* mdichild=new FXMDIChild(mdiclient,"FOX GL Viewer",winappicon,mdimenu,MDI_TRACKING|MDI_MAXIMIZED,30,30,300,200);

  // A visual to drag OpenGL in double-buffered mode; note the glvisual is
  // shared between all windows which need the same depths and numbers of buffers
  // Thus, while the first visual may take some time to initialize, each subsequent
  // window can be created very quickly; we need to determine grpaphics hardware
  // characteristics only once.
  glvisual=new FXGLVisual(getApp(),VISUAL_DOUBLE_BUFFER);

  // Make it active
  mdiclient->setActiveChild(mdichild);

  // Drawing gl canvas
  FXGLViewer *viewer=new FXGLViewer(mdichild,glvisual,this,ID_GLVIEWER,LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT);


  // Tool bar 4
  dragshell4=new FXToolBarShell(this,FRAME_RAISED|FRAME_THICK);
//  dockbar=new FXDockBar(rightdock,dragshell4,LAYOUT_FILL_Y|LAYOUT_SIDE_RIGHT, 0,0,0,0, 2,2,2,2, 2,2);
  dockbar=new FXDockBar(rightdock,dragshell4,LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_SIDE_RIGHT, 0,0,300,400, 2,2,2,2, 2,2);

  // Only dock left and right
  dockbar->allowedSides(FXDockBar::ALLOW_LEFT|FXDockBar::ALLOW_RIGHT);

  // Nice caption over dock
  FXHorizontalFrame *dockframe=new FXHorizontalFrame(dockbar,LAYOUT_SIDE_TOP|LAYOUT_FILL_X, 0,0,0,0, 0,0,0,0, 0,0);
  new FXDockTitle(dockframe,"Controls",dockbar,FXToolBar::ID_TOOLBARGRIP,LAYOUT_FILL_X|FRAME_SUNKEN|JUSTIFY_CENTER_X);
  new FXMDIDeleteButton(dockframe,dockbar,FXWindow::ID_HIDE,LAYOUT_FILL_Y);

  // Tab book with switchable panels
  FXTabBook* panels=new FXTabBook(dockbar,nullptr,0,LAYOUT_FILL_Y|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);

  new FXTabItem(panels,"Angles\tCamera Angles\tSwitch to camera angles panel.");

  // Angles
  FXMatrix *angles=new FXMatrix(panels,3,FRAME_THICK|FRAME_RAISED|MATRIX_BY_COLUMNS|LAYOUT_FILL_Y|LAYOUT_FILL_X,0,0,0,0,5,50,5,5);
  new FXLabel(angles,"X:");
  FXTextField* rolltext=new FXTextField(angles,6,mdiclient,FXGLViewer::ID_ROLL,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  rolltext->setNumColumns(8);
  FXDial* x_dial=new FXDial(angles,mdiclient,FXGLViewer::ID_DIAL_X,FRAME_SUNKEN|FRAME_THICK|DIAL_CYCLIC|DIAL_HORIZONTAL|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_CENTER_Y,0,0,150,14,0,0,0,0);
  x_dial->setTipText("Rotate about X");
  x_dial->setNotchOffset(900);

  new FXLabel(angles,"Y:");
  FXTextField* pitchtext=new FXTextField(angles,6,mdiclient,FXGLViewer::ID_PITCH,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  pitchtext->setNumColumns(8);
  FXDial* y_dial=new FXDial(angles,mdiclient,FXGLViewer::ID_DIAL_Y,FRAME_SUNKEN|FRAME_THICK|DIAL_CYCLIC|DIAL_HORIZONTAL|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_CENTER_Y,0,0,150,14,0,0,0,0);
  y_dial->setTipText("Rotate about Y");
  y_dial->setNotchOffset(900);

  new FXLabel(angles,"Z:");
  FXTextField* yawtext=new FXTextField(angles,6,mdiclient,FXGLViewer::ID_YAW,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  yawtext->setNumColumns(8);
  FXDial* z_dial=new FXDial(angles,mdiclient,FXGLViewer::ID_DIAL_Z,FRAME_SUNKEN|FRAME_THICK|DIAL_CYCLIC|DIAL_HORIZONTAL|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_CENTER_Y,0,0,150,14,0,0,0,0);
  z_dial->setTipText("Rotate about Z");
  z_dial->setNotchOffset(900);

  new FXLabel(angles,"FOV:");
  FXTextField* fov=new FXTextField(angles,5,mdiclient,FXGLViewer::ID_FOV,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  new FXFrame(angles,0);
  fov->setTipText("Field of view");
  fov->setNumColumns(8);

  new FXLabel(angles,"Zoom:");
  FXTextField* zz=new FXTextField(angles,5,mdiclient,FXGLViewer::ID_ZOOM,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  new FXFrame(angles,0);
  zz->setTipText("Zooming");
  zz->setNumColumns(8);

  new FXLabel(angles,"Scale X:");
  FXTextField* scalex=new FXTextField(angles,5,mdiclient,FXGLViewer::ID_SCALE_X,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  scalex->setNumColumns(8);
  new FXFrame(angles,0);
  new FXLabel(angles,"Scale Y:");
  FXTextField* scaley=new FXTextField(angles,5,mdiclient,FXGLViewer::ID_SCALE_Y,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  scaley->setNumColumns(8);
  new FXFrame(angles,0);
  new FXLabel(angles,"Scale Z:");
  FXTextField* scalez=new FXTextField(angles,5,mdiclient,FXGLViewer::ID_SCALE_Z,TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK);
  scalez->setNumColumns(8);
  new FXFrame(angles,0);

  // Colors
  new FXTabItem(panels,"Colors\tColors\tSwitch to color panel.");
  FXMatrix *colors=new FXMatrix(panels,2,MATRIX_BY_COLUMNS|FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,10,10);
  new FXLabel(colors,"Background:",nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT);
  new FXColorWell(colors,0,mdiclient,FXGLViewer::ID_BACK_COLOR,COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0 ,0,0,0,0);

  new FXLabel(colors,"Top Back:",nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT);
  new FXColorWell(colors,0,mdiclient,FXGLViewer::ID_TOP_COLOR,COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0 ,0,0,0,0);
  new FXLabel(colors,"Bottom Back:",nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT);
  new FXColorWell(colors,0,mdiclient,FXGLViewer::ID_BOTTOM_COLOR,COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0 ,0,0,0,0);


  new FXLabel(colors,"Ambient:",nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT);
  new FXColorWell(colors,0,mdiclient,FXGLViewer::ID_AMBIENT_COLOR,COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0 ,0,0,0,0);


  new FXLabel(colors,"Light Amb:",nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT);
  new FXColorWell(colors,0,mdiclient,FXGLViewer::ID_LIGHT_AMBIENT,COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0 ,0,0,0,0);
  new FXLabel(colors,"Light Diff:",nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT);
  new FXColorWell(colors,0,mdiclient,FXGLViewer::ID_LIGHT_DIFFUSE,COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0 ,0,0,0,0);
  new FXLabel(colors,"Light Spec:",nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y|JUSTIFY_RIGHT);
  new FXColorWell(colors,0,mdiclient,FXGLViewer::ID_LIGHT_SPECULAR,COLORWELL_OPAQUEONLY|LAYOUT_TOP|LAYOUT_LEFT|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0 ,0,0,0,0);

  // Switches
  new FXTabItem(panels,"Settings\tSettings\tSwitche to settings panel.");
  FXVerticalFrame *settings=new FXVerticalFrame(panels,FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,10,10);
  new FXCheckButton(settings,"Lighting",mdiclient,FXGLViewer::ID_LIGHTING,ICON_BEFORE_TEXT);
  new FXCheckButton(settings,"Fog",mdiclient,FXGLViewer::ID_FOG,ICON_BEFORE_TEXT);
  new FXCheckButton(settings,"Dither",mdiclient,FXGLViewer::ID_DITHER,ICON_BEFORE_TEXT);
  new FXCheckButton(settings,"Turbo",mdiclient,FXGLViewer::ID_TURBO,ICON_BEFORE_TEXT);


  filenewicon=new FXGIFIcon(getApp(),filenew);
  fileopenicon=new FXGIFIcon(getApp(),fileopen);
  filesaveicon=new FXGIFIcon(getApp(),filesave);
  filesaveasicon=new FXGIFIcon(getApp(),filesaveas,0,IMAGE_ALPHAGUESS);
  newfoldericon=new FXGIFIcon(getApp(),newfolder);

  // File Menu
  filemenu=new FXMenuPane(this);
  new FXMenuTitle(menubar,"&File",nullptr,filemenu,LAYOUT_CENTER_Y);
  new FXMenuCommand(filemenu,"&New...\tCtl-N\tCreate new document.",filenewicon);
  new FXMenuCommand(filemenu,"&Open...\tCtl-O\tOpen document file.",fileopenicon,this,ID_OPEN);
  new FXMenuCommand(filemenu,"&Save\tCtl-S\tSave document.",filesaveicon);
  new FXMenuCommand(filemenu,"Save &As...\t\tSave document to another file.",filesaveasicon);
  new FXMenuCommand(filemenu,"&Print Image...\t\tPrint snapshot image.",nullptr,mdiclient,FXGLViewer::ID_PRINT_IMAGE,MENU_AUTOGRAY);
  new FXMenuCommand(filemenu,"&Print Vector...\t\tPrint geometry.",nullptr,mdiclient,FXGLViewer::ID_PRINT_VECTOR,MENU_AUTOGRAY);
  new FXMenuCommand(filemenu,"&Dump...\t\tDump widgets.",nullptr,getApp(),FXApp::ID_DUMP);
  new FXMenuCommand(filemenu,"&Quit\tCtl-Q\tQuit the application.",nullptr,getApp(),FXApp::ID_QUIT);

  // Edit Menu
  editmenu=new FXMenuPane(this);
  new FXMenuTitle(menubar,"&Edit",nullptr,editmenu,LAYOUT_CENTER_Y);
  new FXMenuCommand(editmenu,"Lasso",nullptr,mdiclient,FXGLViewer::ID_LASSO_SELECT,MENU_AUTOGRAY);
  new FXMenuCommand(editmenu,"Copy\tCtl-C",nullptr,mdiclient,FXGLViewer::ID_COPY_SEL,MENU_AUTOGRAY);
  new FXMenuCommand(editmenu,"Cut\tCtl-X",nullptr,mdiclient,FXGLViewer::ID_CUT_SEL,MENU_AUTOGRAY);
  new FXMenuCommand(editmenu,"Paste\tCtl-V",nullptr,mdiclient,FXGLViewer::ID_PASTE_SEL,MENU_AUTOGRAY);
  new FXMenuCommand(editmenu,"Delete",nullptr,mdiclient,FXGLViewer::ID_DELETE_SEL,MENU_AUTOGRAY);


  // File manipulation
  new FXButton(toolbar1,"\tNew\tCreate new document.",filenewicon,nullptr,0,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar1,"\tOpen\tOpen document file.",fileopenicon,this,ID_OPEN,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar1,"\tSave\tSave document.",filesaveicon,nullptr,0,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar1,"\tSave As\tSave document to another file.",filesaveasicon,this,ID_OPEN,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar1,"\tNew Folder\tNo comment",newfoldericon,nullptr,0,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  printicon=new FXGIFIcon(getApp(),print);

  // Print
  new FXSeparator(toolbar1,SEPARATOR_GROOVE);
  new FXButton(toolbar1,"\tPrint Image\tPrint shapshot image.",printicon,mdiclient,FXGLViewer::ID_PRINT_IMAGE,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  cuticon=new FXGIFIcon(getApp(),cut);
  copyicon=new FXGIFIcon(getApp(),copy);
  pasteicon=new FXGIFIcon(getApp(),paste);

  // Editing
  new FXSeparator(toolbar1,SEPARATOR_GROOVE);
  new FXButton(toolbar1,"\tCut",cuticon,mdiclient,FXGLViewer::ID_CUT_SEL,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar1,"\tCopy",copyicon,mdiclient,FXGLViewer::ID_COPY_SEL,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar1,"\tPaste",pasteicon,mdiclient,FXGLViewer::ID_PASTE_SEL,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  perspectiveicon=new FXGIFIcon(getApp(),perspective);
  parallelicon=new FXGIFIcon(getApp(),parallel);

  // Projections
  new FXButton(toolbar2,"\tPerspective\tSwitch to perspective projection.",perspectiveicon,mdiclient,FXGLViewer::ID_PERSPECTIVE,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tParallel\tSwitch to parallel projection.",parallelicon,mdiclient,FXGLViewer::ID_PARALLEL,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  nolighticon=new FXGIFIcon(getApp(),nolight);
  lighticon=new FXGIFIcon(getApp(),light);
  smoothlighticon=new FXGIFIcon(getApp(),smoothlight);

  // Shading model
  new FXSeparator(toolbar2,SEPARATOR_GROOVE);
  new FXButton(toolbar2,"\tNo shading\tTurn light sources off.",nolighticon,mdiclient,FXGLShape::ID_SHADEOFF,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tFlat shading\tTurn on faceted (flat) shading.",lighticon,mdiclient,FXGLShape::ID_SHADEON,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tSmooth shading\tTurn on smooth shading.",smoothlighticon,mdiclient,FXGLShape::ID_SHADESMOOTH,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  new FXSeparator(toolbar2,SEPARATOR_GROOVE);
  new FXToggleButton(toolbar2,"\tToggle Light\tToggle light source.",FXString::null,nolighticon,lighticon,nullptr,0,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  frontviewicon=new FXGIFIcon(getApp(),frontview);
  backviewicon=new FXGIFIcon(getApp(),backview);
  topviewicon=new FXGIFIcon(getApp(),topview,0,IMAGE_OPAQUE);
  bottomviewicon=new FXGIFIcon(getApp(),bottomview,0,IMAGE_OPAQUE);
  leftviewicon=new FXGIFIcon(getApp(),leftview);
  rightviewicon=new FXGIFIcon(getApp(),rightview);

  // View orientation
  new FXSeparator(toolbar2,SEPARATOR_GROOVE);
  new FXButton(toolbar2,"\tFront View\tView objects from the front.",frontviewicon,mdiclient,FXGLViewer::ID_FRONT,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tBack View\tView objects from behind.",backviewicon,mdiclient,FXGLViewer::ID_BACK,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tLeft View\tView objects from the left.",leftviewicon,mdiclient,FXGLViewer::ID_LEFT,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tRight View\tView objects from the right.",rightviewicon,mdiclient,FXGLViewer::ID_RIGHT,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tTop View\tView objects from the top.",topviewicon,mdiclient,FXGLViewer::ID_TOP,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tBottom View\tView objects from below.",bottomviewicon,mdiclient,FXGLViewer::ID_BOTTOM,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);


  colorpalicon=new FXGIFIcon(getApp(),colorpal);
  zoomicon=new FXGIFIcon(getApp(),zoom);
  foxiconicon=new FXGIFIcon(getApp(),foxicon);
  cameraicon=new FXGIFIcon(getApp(),camera);

  // Miscellaneous buttons
  new FXSeparator(toolbar2,SEPARATOR_GROOVE);
  new FXButton(toolbar2,FXString::null,zoomicon,nullptr,0,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,"\tColors\tDisplay color dialog.",colorpalicon,colordlg,FXWindow::ID_SHOW,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,FXString::null,cameraicon,nullptr,0,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
  new FXButton(toolbar2,FXString::null,foxiconicon,nullptr,0,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  killobjecticon=new FXGIFIcon(getApp(),killobject);

  // Dangerous delete a bit on the side
  new FXSeparator(toolbar1,SEPARATOR_GROOVE);
  new FXButton(toolbar1,"\tDelete\tDelete the selected object.",killobjecticon,mdiclient,FXGLViewer::ID_DELETE_SEL,BUTTON_AUTOGRAY|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);

  // View menu
  viewmenu=new FXMenuPane(this);
  new FXMenuTitle(menubar,"&View",nullptr,viewmenu,LAYOUT_CENTER_Y);
  new FXMenuRadio(viewmenu,"Parallel\t\tSwitch to parallel projection.",mdiclient,FXGLViewer::ID_PARALLEL,MENU_AUTOGRAY);
  new FXMenuRadio(viewmenu,"Perspective\t\tSwitch to perspective projection.",mdiclient,FXGLViewer::ID_PERSPECTIVE,MENU_AUTOGRAY);
  new FXMenuSeparator(viewmenu);
  new FXMenuRadio(viewmenu,"&Front\tCtl-F\tFront view.",mdiclient,FXGLViewer::ID_FRONT,MENU_AUTOGRAY);
  new FXMenuRadio(viewmenu,"&Back\tCtl-B\tBack view.",mdiclient,FXGLViewer::ID_BACK,MENU_AUTOGRAY);
  new FXMenuRadio(viewmenu,"&Left\tCtl-L\tLeft view.",mdiclient,FXGLViewer::ID_LEFT,MENU_AUTOGRAY);
  new FXMenuRadio(viewmenu,"&Right\tCtl-R\tRight view.",mdiclient,FXGLViewer::ID_RIGHT,MENU_AUTOGRAY);
  new FXMenuRadio(viewmenu,"&Top\tCtl-T\tTop view.",mdiclient,FXGLViewer::ID_TOP,MENU_AUTOGRAY);
  new FXMenuRadio(viewmenu,"&Bottom\tCtl-K\tBottom view.",mdiclient,FXGLViewer::ID_BOTTOM,MENU_AUTOGRAY);
  new FXMenuSeparator(viewmenu);
  new FXMenuCommand(viewmenu,"F&it\t\tFit to view.",nullptr,mdiclient,FXGLViewer::ID_FITVIEW,MENU_AUTOGRAY);
  new FXMenuCommand(viewmenu,"R&eset\tCtl-G\tReset all viewing parameters",nullptr,mdiclient,FXGLViewer::ID_RESETVIEW,MENU_AUTOGRAY);
  new FXMenuCommand(viewmenu,"Zoom\t\tZoom in on area",nullptr,mdiclient,FXGLViewer::ID_LASSO_ZOOM,MENU_AUTOGRAY);
  new FXMenuCommand(viewmenu,"Select\t\tZoom in on area",nullptr,mdiclient,FXGLViewer::ID_LASSO_SELECT,MENU_AUTOGRAY);

  // Rendering menu
  rendermenu=new FXMenuPane(this);
  new FXMenuTitle(menubar,"&Rendering",nullptr,rendermenu,LAYOUT_CENTER_Y);
  new FXMenuCheck(rendermenu,"Points\t\tRender as points.",mdiclient,FXGLShape::ID_STYLE_POINTS,MENU_AUTOGRAY);
  new FXMenuCheck(rendermenu,"Wire Frame\t\tRender as wire frame.",mdiclient,FXGLShape::ID_STYLE_WIREFRAME,MENU_AUTOGRAY);
  new FXMenuCheck(rendermenu,"Surface \t\tRender solid surface.",mdiclient,FXGLShape::ID_STYLE_SURFACE,MENU_AUTOGRAY);
  new FXMenuCheck(rendermenu,"Bounding Box\t\tRender bounding box only.",mdiclient,FXGLShape::ID_STYLE_BOUNDINGBOX,MENU_AUTOGRAY);

  // Window menu
  windowmenu=new FXMenuPane(this);
  new FXMenuTitle(menubar,"&Windows",nullptr,windowmenu,LAYOUT_CENTER_Y);
  new FXMenuCommand(windowmenu,"New Viewer\t\tCreate new viewer window.",nullptr,this,ID_NEWVIEWER);
  new FXMenuCommand(windowmenu,"Tile Horizontally\t\tTile windows horizontally.",nullptr,mdiclient,FXMDIClient::ID_MDI_TILEHORIZONTAL);
  new FXMenuCommand(windowmenu,"Tile Vertically\t\tTile windows vertically.",nullptr,mdiclient,FXMDIClient::ID_MDI_TILEVERTICAL);
  new FXMenuCommand(windowmenu,"Cascade\t\tCascade windows.",nullptr,mdiclient,FXMDIClient::ID_MDI_CASCADE);
  new FXMenuCommand(windowmenu,"Delete\t\tDelete current viewer window.",nullptr,mdiclient,FXMDIClient::ID_MDI_CLOSE);
  new FXMenuSeparator(windowmenu);
  new FXMenuCheck(windowmenu,"Main Toolbar",toolbar1,FXWindow::ID_TOGGLESHOWN);
  new FXMenuCheck(windowmenu,"Graphic Toolbar",toolbar2,FXWindow::ID_TOGGLESHOWN);
  new FXMenuCheck(windowmenu,"Control panel",dockbar,FXWindow::ID_TOGGLESHOWN);
  new FXMenuSeparator(windowmenu,mdiclient,FXMDIClient::ID_MDI_ANY);
  new FXMenuRadio(windowmenu,FXString::null,mdiclient,FXMDIClient::ID_MDI_1);
  new FXMenuRadio(windowmenu,FXString::null,mdiclient,FXMDIClient::ID_MDI_2);
  new FXMenuRadio(windowmenu,FXString::null,mdiclient,FXMDIClient::ID_MDI_3);
  new FXMenuRadio(windowmenu,FXString::null,mdiclient,FXMDIClient::ID_MDI_4);

  // Help menu
  helpmenu=new FXMenuPane(this);
  new FXMenuTitle(menubar,"&Help",nullptr,helpmenu,LAYOUT_RIGHT|LAYOUT_CENTER_Y);
  new FXMenuCommand(helpmenu,"&About FOX...\t\tDisplay FOX about panel.",nullptr,this,ID_ABOUT,0);

  // Make a tool tip
  new FXToolTip(getApp(),TOOLTIP_PERMANENT);

  // The status bar shows our mode
  statusbar->getStatusLine()->setTarget(this);
  statusbar->getStatusLine()->setSelector(ID_QUERY_MODE);

  // Make a scene!
  scene=new FXGLGroup;
//   scene->append(new FXGLPoint(2,0,0));
//   scene->append(new FXGLPoint(0,2,0));
//   scene->append(new FXGLPoint(2,2,0));
//   scene->append(new FXGLPoint(0,0,0));
//   scene->append(new FXGLLine(0,0,0, 1,0,0));
//   scene->append(new FXGLLine(0,0,0, 0,1,0));
//   scene->append(new FXGLLine(0,0,0, 0,0,1));
//   scene->append(new FXGLLine(0,0,0, 1,1,1));
  FXGLGroup *gp2=new FXGLGroup;
  scene->append(gp2);
  FXGLSphere *sphere=new FXGLSphere(1.0f, 1.0f, 0.0f, 0.5f);
  sphere->setTipText("Sphere");
  FXGLSphere *sphere2=new FXGLSphere(0.0f, 0.0f, 0.0f, 0.8f);
  sphere2->setTipText("Sphere2");
  gp2->append(new FXGLCube(-1.0f, 0.0f, 0.0f,  1.0f, 1.0f, 1.0f));
  gp2->append(new FXGLCube( 1.0f, 0.0f, 0.0f,  1.0f, 1.0f, 1.0f));
  gp2->append(new FXGLCube( 0.0f,-1.0f, 0.0f,  1.0f, 1.0f, 1.0f));
  gp2->append(new FXGLCube( 0.0f, 1.0f, 0.0f,  1.0f, 1.0f, 1.0f));
  gp2->append(new FXGLCone(1.0f,-1.5f, 0.0f, 1.0f, 0.5f));
  gp2->append(new FXGLCylinder(-1.0f, 0.5f, 0.0f, 1.0f, 0.5f));
  gp2->append(sphere);
  gp2->append(sphere2);

  // Add scene to GL viewer
  viewer->setScene(scene);

  }


// Destructor
GLViewWindow::~GLViewWindow(){
  delete glvisual;
  delete dragshell1;
  delete dragshell2;
  delete dragshell3;
  delete dragshell4;
  delete filemenu;
  delete editmenu;
  delete viewmenu;
  delete rendermenu;
  delete windowmenu;
  delete helpmenu;
  delete mdimenu;
  delete frontviewicon;
  delete backviewicon;
  delete topviewicon;
  delete bottomviewicon;
  delete leftviewicon;
  delete rightviewicon;
  delete foxiconicon;
  delete colorpalicon;
  delete filesaveasicon;
  delete filesaveicon;
  delete fileopenicon;
  delete printicon;
  delete zoomicon;
  delete filenewicon;
  delete cuticon;
  delete copyicon;
  delete pasteicon;
  delete killobjecticon;
  delete nolighticon;
  delete lighticon;
  delete smoothlighticon;
  delete parallelicon;
  delete perspectiveicon;
  delete newfoldericon;
  delete penguinicon;
  delete winappicon;
  delete cameraicon;
  }



// Create and initialize
void GLViewWindow::create(){
  FXMainWindow::create();
  dragshell1->create();
  dragshell2->create();
  dragshell3->create();
  show(PLACEMENT_SCREEN);
  }


// About
long GLViewWindow::onCmdAbout(FXObject*,FXSelector,void*){
  FXMessageBox::information(this,MBOX_OK,"About FOX","FOX OpenGL Example.\nCopyright (C) 1998,2006 Jeroen van der Zijp");
  return 1;
  }


// Open
long GLViewWindow::onCmdOpen(FXObject*,FXSelector,void*){
  const FXchar patterns[]="All Files (*)\nC++ Source Files (*.cpp,*.cxx,*.c++,*.C)\nC++ Header Files (*.hpp,*.hxx,*.h++,*.H,*.h)\nObject Files (*.o)\nHTML Header Files (*.html,*.htm)";
  FXFileDialog open(this,"Open some file");
  open.setPatternList(patterns);
  if(open.execute()){
    fxmessage("File=%s\n",open.getFilename().text());
    }
  return 1;
  }



// Make new viewer
long GLViewWindow::onCmdNewViewer(FXObject*,FXSelector,void*){
  static int no=1;

  // Make new MDI child widget
  FXMDIChild* mdichild=new FXMDIChild(mdiclient,FXString::value("GL Viewer #%d",no),winappicon,mdimenu,MDI_TRACKING,30,30,300,200);

  FXGLViewer *view=new FXGLViewer(mdichild,glvisual,this,ID_GLVIEWER);

  // Change of scenery
  view->setScene(scene);

  // Create the new window
  mdichild->create();

  // Next number
  no++;
  return 1;
  }


// Statusbar wanted to know about mode
// We fake it here for the purpose of demonstration...
long GLViewWindow::onUpdMode(FXObject* sender,FXSelector,void*){
  FXStatusLine *statusline=(FXStatusLine*)sender;
  statusline->setText("Ready.");
  return 1;
  }


/*
*  When the user right-clicks in the GLViewer background, the viewer first sends
*  a SEL_COMMAND message with identifier FXWindow::ID_QUERY_MENU to the selected
*  GLObject (if any). If that message isn't handled, it tries to send it to the
*  GLViewer's target (which in our case is the main window).
*/
long GLViewWindow::onQueryMenu(FXObject* sender,FXSelector,void* ptr){
  FXEvent *event=(FXEvent*)ptr;
  FXMenuPane pane(this);
  new FXMenuRadio(&pane,"Parallel\t\tSwitch to parallel projection.",sender,FXGLViewer::ID_PARALLEL);
  new FXMenuRadio(&pane,"Perspective\t\tSwitch to perspective projection.",sender,FXGLViewer::ID_PERSPECTIVE);
  new FXMenuSeparator(&pane);
  new FXMenuRadio(&pane,"&Front\t\tFront view.",sender,FXGLViewer::ID_FRONT);
  new FXMenuRadio(&pane,"&Back\t\tBack view.",sender,FXGLViewer::ID_BACK);
  new FXMenuRadio(&pane,"&Left\t\tLeft view.",sender,FXGLViewer::ID_LEFT);
  new FXMenuRadio(&pane,"&Right\t\tRight view.",sender,FXGLViewer::ID_RIGHT);
  new FXMenuRadio(&pane,"&Top\t\tTop view.",sender,FXGLViewer::ID_TOP);
  new FXMenuRadio(&pane,"&Bottom\t\tBottom view.",sender,FXGLViewer::ID_BOTTOM);
  new FXMenuSeparator(&pane);
  new FXMenuCommand(&pane,"F&it\t\tFit to view.",nullptr,sender,FXGLViewer::ID_FITVIEW);
  new FXMenuCommand(&pane,"R&eset\t\tReset all viewing parameters",nullptr,sender,FXGLViewer::ID_RESETVIEW);
  pane.create();
  pane.popup(nullptr,event->root_x,event->root_y);
  getApp()->runModalWhileShown(&pane);
  return 1;
  }


// Here we begin
int main(int argc,char *argv[]){

  // Make application
  FXApp application("GLViewer","FoxTest");

  // Open the display
  application.init(argc,argv);

  // Make window
  new GLViewWindow(&application);

  // Create the application's windows
  application.create();

  // Run the application
  return application.run();
  }



#else


// Here we begin
int main(int,char*[]){
  fxmessage("The FOX Library was compiled without OpenGL\n");
  return 0;
  }


#endif
