// Bildschirmschoner
// Projekt für GDV - Herr Messer
// bearbeitet von Michael Schlagmüller
// V1.0 - 16.03.2003

/**************************************
*                                     *
*   Jeff Molofee's Basecode Example   *
*          nehe.gamedev.net           *
*                2001                 *
*                                     *
**************************************/

#include <math.h>												// Header File For Math
#include <windows.h>											// Header File For Windows
#include <iostream>

#include <basetsd.h>
#include <commdlg.h>
#include <mmreg.h>
#include <dxerr8.h>
#include <dsound.h>
#include "resource.h"
#include "DSUtil.h"
#include "WaveForm.h"
#include "WaveFFT.h"

#include <stdio.h>												// Header File For Standard Input/Output
#include <winbase.h>											
#include <gl\gl.h>												// Header File For The OpenGL32 Library
#include <gl\glu.h>												// Header File For The GLu32 Library
#include <gl\glaux.h>											// Header File For The GLaux Library
#include "NeHeGL.h"												// Header File For NeHeGL
#include "GLFont.h"												// Header File For Font Module
#include "ResourceIO.h"	
#include "Camera.h"
#include "Settings.h"

#pragma comment( lib, "opengl32.lib" )							// Search For OpenGL32.lib While Linking
#pragma comment( lib, "glu32.lib" )								// Search For GLu32.lib While Linking
#pragma comment( lib, "glaux.lib" )								// Search For GLaux.lib While Linking

#ifndef CDS_FULLSCREEN											// CDS_FULLSCREEN Is Not Defined By Some
#define CDS_FULLSCREEN 4										// Compilers. By Defining It This Way,
#endif															// We Can Avoid Errors

// Displaylists 
#define TEX_WINDOW		1
#define TEX_WHEEL		2
#define TEX_AUFHAENGUNG	3
#define TEX_GROUND		4
#define TEX_SAIL		5
#define TEX_PILLARBIG	6
#define TEX_PILLARSMALL	7
#define TEX_BACKGROUND	8
#define TEX_EQ			9
#define TEX_LIGHT		10
#define BALOGO_3D		11

int dlWheel[3];
int dlRing[3];
int dlRingWindow[3];
int dlRingAufhaengungSub[2];
int dlRingAufhaengung[2];
int dlSailCyl[3];
int dlSail;
int dlLightIsle;
int dlGround;
int dlLight;


// User Defined Variables
#ifdef ShowNormals
float g_normals[6][5000];
#endif

int		countnormals;
__int64 iPerformanceFrequency;
float	timeangle, xangle, yangle, zangle, xspeed, yspeed, zspeed, z, timespeed;
LARGE_INTEGER liLastPerformanceCounter;
CCamera* Camera;
char    g_wavefile[80];
int		globaltime;
int		ActTime;
double	light0_power;
double	light1_power;
double	 light2_power;
double	 light3_power;
double	Light1_Base_Color[4];
double	 Light2_Base_Color[4];
double	 Light3_Base_Color[4];
double	 Light0_Ambient[4];
GL_Window*	g_window;
Keys*		g_keys;
BITMAPINFO *BitmapInfo;		/* Bitmap information */
GLubyte    *BitmapBits;		/* Bitmap data */
float		 angle;												// Used To Rotate The Triangles
GLuint       texture[20];
AUX_RGBImageRec *Texs[1];
GLFont       fNeHe;												// Font Class
int nPartList;

// Sound...
#define NUM_PLAY_NOTIFICATIONS 1
#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

CSoundManager*      g_pSoundManager         = NULL;
CStreamingSound*    g_pStreamingSound       = NULL;
CWaveForm*			g_pWaveForm				= NULL;
CWaveFFT*			g_pWaveFFT				= NULL;
HANDLE              g_hNotificationEvent    = NULL;
DWORD               g_dwNotifyThreadID      = 0;
HANDLE              g_hNotifyThread         = NULL;
HINSTANCE           g_hInst                 = NULL;

////////////////////////////////////////////////////////////////////
/// void DrawLight(float red, float green, float blue)
////////////////////////////////////////////////////////////////////
//  zeichnet einen Lampenhalter
void DrawLight(float red, float green, float blue) {
#define SPOT_SCALE			1.0
#define SPOT_FRONT_WIDTH	0.7
#define SPOT_FRONT_HEIGHT	0.5
#define SPOT_BACK_WIDTH		0.5
#define SPOT_BACK_HEIGHT	0.3
#define SPOT_FATNESS		0.07
#define SPOT_DIAMETER		0.4
#define SPOT_ANGLE			33.3
#define SPOT_DEPT			0.2
#define SPOT_MOUNT_RAD		0.2
#define SPOT_ABOVE_ZERO		0.5
	glPushMatrix();
	glPushMatrix();
	glRotated(SPOT_ANGLE, -1.0, 0.0, 0.0);
	glDisable(GL_LIGHTING);
	glDisable(GL_TEXTURE_2D);
	glColor4f(red, green, blue, 1.0f);
	glBegin(GL_QUADS);
	//innen
		glNormal3d(0.0f, 0.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
		glVertex3d(
					(+SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
		glVertex3d(
					(+SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
	glEnd();
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glEnable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[TEX_LIGHT]);		
	glCallList(dlLight);
	glPopMatrix();
	glTranslated(0.0, -SPOT_ABOVE_ZERO / 2.0 - 0.14, 0.0);
	glRotatef(90.0f, -1.0f, 0.0f, 0.0f);
	DrawCylinder2(0.13, 0.085, SPOT_ABOVE_ZERO, 10, 4, 1.0, 1.0);
	glPopMatrix();
}

////////////////////////////////////////////////////////////////////
/// InitCameraMovement() 
////////////////////////////////////////////////////////////////////
//  Kamerabewegung im Automatik-Modus
void InitCameraMovement() {
	Camera = new CCamera();
	Camera->AddEvent(6.3); // 1
	Camera->SetValue(CAMVALUE_POS_Z, CAM_CONSTANT,  -15.0, 0.0, 0.0);
	Camera->AddEvent(4.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,  -13.0, 1.0, 0.0);
	Camera->AddEvent(7.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_LINEAR, -6.0, 0.0, 0.0);
	Camera->AddEvent(4.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,  -4.0, 0.2, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED,  10.0, 8.0, 0.0);
	Camera->AddEvent(9.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_LINEAR, 82.0, 0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_LINEAR, -2.2, 0.0, 0.0);
	Camera->AddEvent(1.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_LINEAR, 90.0, 0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_LINEAR, -2.0,  0.0, 0.0);
	Camera->AddEvent(4.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_LINEAR, 132.0, 0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED, -1.2,  0.4, 0.0);
	Camera->AddEvent(5.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_LINEAR, 172.0, 0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,    0.0,  0.0, 0.0);
	Camera->AddEvent(2.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED, 180.0, 0.0, 0.0);
	Camera->AddEvent(5.0);  // 10
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,  25.0, 10.0, 0.0);
	Camera->AddEvent(6.5);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_LINEAR, 65.0, 10.0, 0.0);
	Camera->AddEvent(7.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,  90.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,  -5.0, -2.0, 0.0);
	Camera->AddEvent(8.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED,  30.0,  6.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED, -10.0,  0.5, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,  45.0, -2.0, 0.0);
	Camera->AddEvent(5.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED,  10.0,  1.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,  10.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,  -9.0,  1.0, 0.0);
	Camera->AddEvent(10.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED,  90.0, 15.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->AddEvent(15.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_LINEAR,315.0,  0.0, 0.0);
	Camera->AddEvent(15.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED, 300.0, 10.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,  -8.0, -0.5, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED, -10.0, -1.0, 0.0);
	Camera->AddEvent(15.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_LINEAR,450.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED, -10.0, -0.0, 0.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,  -7.0,  0.0, 0.0);
	Camera->AddEvent(15.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED, 160.0, 10.0, 0.0);
	Camera->AddEvent(15.0); // 20
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->AddEvent(15.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,  30.0, -5.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED, -85.0,  5.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Z, CAM_SPEED,  30.0,  0.0, 0.0);
	Camera->AddEvent(15.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED,  -2.2,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED, -30.0,  5.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED,  30.0, -5.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Z, CAM_SPEED, -30.0,  0.0, 0.0);
	Camera->AddEvent(20.0);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED, -10.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,  10.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED, 180.0, 10.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Z, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->AddEvent(7.5);
	Camera->SetValue(CAMVALUE_POS_Z, CAM_SPEED, -15.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_X, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Y, CAM_SPEED,   0.0,  0.0, 0.0);
	Camera->SetValue(CAMVALUE_ROT_Z, CAM_SPEED,   0.0,  0.0, 0.0);

}

////////////////////////////////////////////////////////////////////
/// BOOL Initialize (GL_Window* window, Keys* keys)
////////////////////////////////////////////////////////////////////
//  alle Initialisierungen....
BOOL Initialize (GL_Window* window, Keys* keys)					// Any GL Init Code & User Initialiazation Goes Here
{
	InitCameraMovement();
	ActTime = 0;
//  DirectSound....
	g_hNotificationEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

#ifdef EnableSound

	HRESULT hr;
    g_pSoundManager = new CSoundManager();
	
	char wavename[80];
	char fftname[80];
	char waveformname[80];
	char selectedfile[80];
	strcpy(selectedfile, g_wavefile);
	
	strcpy(wavename, selectedfile);
	strcpy(waveformname, selectedfile);
	strcpy(fftname, selectedfile);
	strcat(wavename, ".wav\0");
	strcat(waveformname, ".wf\0");
	strcat(fftname, ".fft\0");
	if( FAILED( hr = g_pSoundManager->Initialize( window->hWnd, DSSCL_PRIORITY, 2, 22050, 16 ) ) )
    {
        DXTRACE_ERR( TEXT("Initialize"), hr );
        MessageBox( window->hWnd, "Error initializing DirectSound.  Sample will now exit.", 
                          "DirectSound Sample", MB_OK | MB_ICONERROR );
	}

	HWND WinFFT = NULL;
	g_pWaveForm = new CWaveForm();
	bool rawAvail = false;
#ifndef doWAVEFORM
	if (!g_pWaveForm->LoadFromFile(waveformname)) 
#endif
	{
		WinFFT = CreateDialog(window->init.application->hInstance, MAKEINTRESOURCE(IDD_DIALOG_FFT), HWND_DESKTOP, NULL);
		ShowWindow(WinFFT, SW_SHOW);	
		UpdateWindow(WinFFT);
		
		g_pWaveForm->LoadWaveAndConvert(wavename);
		g_pWaveForm->SaveToFile(waveformname);
		rawAvail = true;
	}
	g_pWaveFFT = new CWaveFFT();
	g_pWaveFFT->Init(44100, 8192, 1024, true);			// FFTSize = 8192 = 180 ms
	int	piStopFreq[3];
	piStopFreq[0] =  250;								// Übernahmefrequenzen
	piStopFreq[1] = 2000;
	piStopFreq[2] =22100;
	g_pWaveFFT->SetStopFreq(3, piStopFreq);
#ifndef doFFT
	if (!g_pWaveFFT->LoadFromFile(fftname)) 
#endif
	{
		if (!rawAvail) g_pWaveForm->LoadWave(wavename);
		g_pWaveFFT->AnalyzeData(g_pWaveForm->GetRawWaveForm(), g_pWaveForm->GetRawSize());
		g_pWaveFFT->SaveToFile(fftname);
		g_pWaveForm->FreeRawWaveForm();
	}

	LoadWaveAndCreateBuffer( window->hWnd, wavename);
	g_pSoundManager->GetDirectSound();

	if (WinFFT != NULL) DestroyWindow(WinFFT);
	
#endif

	// Start Of User Initialization
	g_window	= window;
	g_keys		= keys;

	LARGE_INTEGER PerformanceFrequency;
	QueryPerformanceFrequency(&PerformanceFrequency);
	iPerformanceFrequency = PerformanceFrequency.QuadPart;
	QueryPerformanceCounter(&liLastPerformanceCounter);
	
	countnormals = 0;
	angle		= 0.0f;											// Set Starting Angle To Zero
	yspeed = zspeed = timeangle, zangle = xspeed = xangle = yangle = 0.0f;
	timespeed = 1.0f;
	z = -15.0f;
	
	if (!LoadGLTextures())							// Jump To Texture Loading Routine ( NEW )
	{
		return FALSE;							// If Texture Didn't Load Return FALSE ( NEW )
	}

    Texs[0]=auxDIBImageLoad("Data/font1.bmp");					// Load Font Texture
	glGenTextures(1, &texture[0]);								// Create Font Texture
    glBindTexture(GL_TEXTURE_2D, texture[0]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, Texs[0]->sizeX , Texs[0]->sizeY , 0, GL_RGB, GL_UNSIGNED_BYTE, Texs[0]->data);
    if(Texs[0]->data != NULL) free(Texs[0]->data);				// Free Data Allocated

	
	// Set Font Texture, How Many Characters Per Row And How Many Columns
	fNeHe.SetTexture(texture[0],16,16);
	// Set Font Width And Font Height In Texture, And Character Spacing
	fNeHe.SetFontProperties(16,16,10);
	// Adjust Fonts 2D Drawing Rectangle Size 
	fNeHe.SetDisplayMode(window->init.width,window->init.height);
	fNeHe.BuildFont();											// Build The Font

	glClearColor (0.0f, 0.0f, 0.0f, 0.5f);						// Black Background
	glClearDepth (1.0f);										// Depth Buffer Setup
	glDepthFunc (GL_LEQUAL);									// The Type Of Depth Testing (Less Or Equal)
	glEnable (GL_DEPTH_TEST);									// Enable Depth Testing
	glShadeModel (GL_SMOOTH);									// Select Smooth Shading
	glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);			// Set Perspective Calculations To Most Accurate
    glBlendFunc(GL_SRC_ALPHA,GL_ONE);							// Enable Blending
	glEnable(GL_TEXTURE_2D);									// Enable Texture Mapping

	LightInit();
		
	dlSetup();

    glEnable(GL_LINE_SMOOTH);
	return TRUE;												// Return TRUE (Initialization Successful)
}

void Deinitialize (void)										// Any User DeInitialization Goes Here
{
	CloseHandle( g_hNotificationEvent );
}

void InitGlobals (LPSTR WaveFile) {
	strcpy(g_wavefile, WaveFile);
}

////////////////////////////////////////////////////////////////////
/// void Update (DWORD milliseconds)
////////////////////////////////////////////////////////////////////
//  wird nach jedem Frame aufgerufen
void Update (DWORD milliseconds)								// Perform Motion Updates Here
{
	static int playing = 0;
	if (playing < 25) milliseconds = 0;
#ifdef EnableSound
	if (playing == 25) {
		DWORD b1;		
		g_pStreamingSound->GetBuffer(0)->GetCurrentPosition(&b1, NULL);
		milliseconds = (int)(b1 / 44100.0 / 16.0 / 2.0 * 1000);
	}
#ifndef BmpOutput
	if (playing == 0) {
		HRESULT hr;
		if( FAILED( hr = PlayBuffer( true ) ) )
		{
			DXTRACE_ERR( TEXT("PlayBuffer"), hr );
	/*
			MessageBox( window->hWnd, "Error playing DirectSound buffer."
						"Sample will now exit.", "DirectSound Sample", 
						MB_OK | MB_ICONERROR );
	*/
	//                        EndDialog( hDlg, IDABORT );
		}
	}
#endif
#endif
	playing++;

	if (g_keys->keyDown [VK_ESCAPE] == TRUE)					// Is ESC Being Pressed?
	{
		TerminateApplication (g_window);						// Terminate The Program
	}

	if (g_keys->keyDown [VK_F1] == TRUE)						// Is F1 Being Pressed?
	{
		ToggleFullscreen (g_window);							// Toggle Fullscreen Mode
	}

	if (g_keys->keyDown [VK_PRIOR])
	{
		z-=0.02f;
	}
	if (g_keys->keyDown [VK_NEXT])
	{
		z+=0.02f;
	}
	if (g_keys->keyDown [VK_UP])
	{
		xspeed-=1.0;
	}
	if (g_keys->keyDown [VK_DOWN])
	{
		xspeed+=1.0f;
	}
	if (g_keys->keyDown [VK_RIGHT])
	{
		yspeed+=1.0f;
	}
	if (g_keys->keyDown [VK_LEFT])
	{
		yspeed-=1.0f;
	}
	if (g_keys->keyDown ['A'])
	{
		zspeed-=1.0f;
	}
	if (g_keys->keyDown ['S'])
	{
		zspeed+=1.0f;
	}
	if (g_keys->keyDown [VK_SPACE])
	{
		xspeed = 0.0f;
		yspeed = 0.0f;
		zspeed = 0.0f;
	}
#ifndef BmpOutput
	angle += (float)(milliseconds / 5.0);						// Update angle Based On The Clock
	ActTime += milliseconds;
	Camera->SetActTime(ActTime / 1000.0);
#endif
#ifdef BmpOutput
#define AVI_FRAMERATE 25.0
	ActTime += (int) (1000   / AVI_FRAMERATE);
	angle += (float) (1000.0 / AVI_FRAMERATE / 5.0);			// Update angle Based On FPS
	Camera->IncActTime(1/AVI_FRAMERATE);
#endif
}

////////////////////////////////////////////////////////////////////
/// void preRotateRing(int ringno)
////////////////////////////////////////////////////////////////////
//  dreht die drei Ringe in der Mitte
//  Funktion 2x verwendet - einmal ohne Blend & einmal mit 
void preRotateRing(int ringno) {
	switch (ringno) {
		case 0:	{
					glRotatef(angle / 7.0f, 1.0f, 0.0f, 0.0f);
					glRotatef(angle / 6.0f, 0.0f, 1.0f, 0.0f);
					break;
				}

		case 1: {
					glRotatef(angle / 5.0f, 1.0f, 0.0f, 0.0f);
					glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
					break;
				}
		case 2:	{
					glRotatef(angle / 4.0f, 1.0f, 0.0f, 0.0f);
					break;
				}
	}
}

////////////////////////////////////////////////////////////////////
/// void WheelTextureAdjust(void)
////////////////////////////////////////////////////////////////////
//  da die Objekte nicht rechteckig sind können Texturkoordinaten
//  korregiert werden
void WheelTextureAdjust(void) {
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glScalef(2.9f, 0.25f, 1.0f);
	glMatrixMode(GL_MODELVIEW);
}

////////////////////////////////////////////////////////////////////
/// void WheelTextureRestore(void)
////////////////////////////////////////////////////////////////////
//  stellt normale Texturkoordinaten wieder her
void WheelTextureRestore(void) {
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
}

////////////////////////////////////////////////////////////////////
/// void DrawSail(bool left)
////////////////////////////////////////////////////////////////////
//  zeich net die großen beiden Bezierkörper links und rechts
#define Sail_INNERWIDTH	0.02
#define Sail_OUTERWIDTH	0.09
#define Sail_DISTANCE	0.135
#define Sail_INNERSEGMENTS 10
#define Sail_OUTERSEGMENTS 20
#define Sail_HEIGHT		6.0
#define Sail_TOPBOTTOMDIFF 0.025
#define Sail_TESS		5
void DrawSail(bool left) {
	double	innerWidth =	Sail_INNERWIDTH;
	double	outerWidth =	Sail_OUTERWIDTH;
	double	distance =		Sail_DISTANCE;
	int		innerSegments = Sail_INNERSEGMENTS;
	int		outerSegments = Sail_OUTERSEGMENTS;
	double	Height =		Sail_HEIGHT;
	double	TopBottomDiff = Sail_TOPBOTTOMDIFF;
	double	Angle =			-atan(TopBottomDiff / (Height / 2.0)) * 180.0 / M_PI;

	glPushMatrix();
	switch (left) {
		case true:  { glTranslatef(-2.0f,0.0f, 0.0f); break; } // linke Säulen
		case false: { glTranslatef( 2.0f,0.0f, 0.0f); break; } // rechte Säulen
	}

	glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
	glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
	glPushMatrix();

	glTranslatef((float)(-distance * 3.0) ,0.0f, 0.0f);
	glRotated(6.0 * Angle, 0.0, 1.0, 0.0);
	glBindTexture(GL_TEXTURE_2D, texture[TEX_PILLARBIG]);			
	glCallList(dlSailCyl[0]);
	//DrawCylinder(outerWidth, Height / cos(6.0 * Angle / 180.0 * M_PI), outerSegments, true);
	glPopMatrix();
	glPushMatrix();
	glTranslatef((float)(distance * 3.0) ,0.0f, 0.0f);
	glRotated(-6.0 * Angle, 0.0, 1.0, 0.0);
	glCallList(dlSailCyl[0]);
	//DrawCylinder(outerWidth, Height / cos(6.0 * Angle / 180.0 * M_PI), outerSegments, true);

	glPopMatrix();

	glPushMatrix();
	glTranslatef((float)(-distance * 1.5) ,0.0f, 0.0f);
	glRotated(3.0 * Angle, 0.0, 1.0, 0.0);
	glBindTexture(GL_TEXTURE_2D, texture[TEX_PILLARSMALL]);			
	glCallList(dlSailCyl[1]);
	//DrawCylinder(innerWidth, Height / cos(3.0 * Angle / 180.0 * M_PI), innerSegments, true);
	glPopMatrix();
	glPushMatrix();
	glTranslatef((float)(distance * 1.5) ,0.0f, 0.0f);
	glRotated(-3.0 * Angle, 0.0, 1.0, 0.0);
	glCallList(dlSailCyl[1]);
	//DrawCylinder(innerWidth, Height / cos(1.0 * Angle / 180.0 * M_PI), innerSegments, true);
	glPopMatrix();

	glPushMatrix();
	glTranslatef((float)(-distance * 0.5) ,0.0f, 0.0f);
	glRotated(1.0 * Angle, 0.0, 1.0, 0.0);
	glCallList(dlSailCyl[2]);
	//DrawCylinder(innerWidth, Height / cos(3.0 * Angle / 180.0 * M_PI), innerSegments, true);
	glPopMatrix();
	glPushMatrix();
	glTranslatef((float)(distance * 0.5) ,0.0f, 0.0f);
	glRotated(-1.0 * Angle, 0.0, 1.0, 0.0);
	glCallList(dlSailCyl[2]);
	//DrawCylinder(innerWidth, Height / cos(1.0 * Angle / 180.0 * M_PI), innerSegments, true);
	glPopMatrix();

	glPopMatrix();
}

////////////////////////////////////////////////////////////////////
/// xxxNormalxxx
////////////////////////////////////////////////////////////////////
//  Hilfsfunktionen zum anzeigen der Normalenvektoren (Testroutine)
#ifdef ShowNormals
void ClearNormals() {
	countnormals = 0;
}

void AddNormal6f(float px, float py, float pz, float nx, float ny, float nz) {
	static int skip = 0;
	skip += 1;
	if ((skip % 1) != 0) return;
	g_normals[0][countnormals] = px;
	g_normals[1][countnormals] = py;
	g_normals[2][countnormals] = pz;
	g_normals[3][countnormals] = nx;
	g_normals[4][countnormals] = ny;
	g_normals[5][countnormals] = nz;
	countnormals += 1;
}

void DrawNorm6f(float px, float py, float pz, float nx, float ny, float nz) {
//	glDisable(GL_TEXTURE_2D);
//	glDisable(GL_LIGHTING);
	glBegin(GL_LINES);
	  glVertex3f(px, py, pz);
	  glVertex3f(px + nx, py + ny, pz + nz);
	glEnd();
//	glEnable(GL_TEXTURE_2D);
//	glEnable(GL_LIGHTING);
}

void DrawNormals(){
	for (int i = 0; i < countnormals; i++) DrawNorm6f(g_normals[0][i], g_normals[1][i], g_normals[2][i], g_normals[3][i], g_normals[4][i], g_normals[5][i]);
}

#endif

////////////////////////////////////////////////////////////////////
/// void DrawArrow()
////////////////////////////////////////////////////////////////////
//  Hilfspfeil an der aktuellen Stelle zeichnen
void DrawArrow() {
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_LIGHTING);
	glBegin(GL_LINES);
	  glVertex3f(0.0f, 0.0f, 0.0f);
	  glVertex3f(0.0f, 0.0f, 1.0f);
	  glVertex3f(0.25f, 0.0f, 0.75f);
	  glVertex3f(0.0f, 0.0f, 1.0f);
	  glVertex3f(-0.25f, 0.0f, 0.75f);
	  glVertex3f(0.0f, 0.0f, 1.0f);
	  glVertex3f(0.0f, 0.25f, 0.75f);
	  glVertex3f(0.0f, 0.0f, 1.0f);
	  glVertex3f(0.0f, -0.25f, 0.75f);
	  glVertex3f(0.0f, 0.0f, 1.0f);
	glEnd();
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);
}

////////////////////////////////////////////////////////////////////
/// void DrawBackground())
////////////////////////////////////////////////////////////////////
//  zeichnet das Hintergrundbild mit den Soundinformationen
void DrawBackground() {
	glBindTexture(GL_TEXTURE_2D, texture[TEX_BACKGROUND]);			// This Will Select The BG Texture ( NEW )
	glPushMatrix();
		glLoadIdentity();
		glTranslatef(0.0f, 0.0f, -24.0f);
		glBegin(GL_QUADS);
			glNormal3f( 0.0f, 0.0f, 1.0f);
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-13.3f, -10.0f,  0.0f);
			glTexCoord2f(1.0f, 0.0f); glVertex3f( 13.3f, -10.0f,  0.0f);
			glTexCoord2f(1.0f, 1.0f); glVertex3f( 13.3f,  10.0f,  0.0f);
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-13.3f,  10.0f,  0.0f);
		glEnd();
    glDisable(GL_LINE_SMOOTH);
#ifdef EnableSound
#define LIGHT_BACK_PRESS 0.25
#define LIGHT_BACK_ADD   2.00

	float Light0Ambient[]=   {(float) (Light0_Ambient[0] * LIGHT_BACK_PRESS + LIGHT_BACK_ADD), 
							  (float) (Light0_Ambient[1] * LIGHT_BACK_PRESS + LIGHT_BACK_ADD), 
							  (float) (Light0_Ambient[2] * LIGHT_BACK_PRESS + LIGHT_BACK_ADD), 
							           1.0f}; 				 // Ambient Light Values 
	glLightfv(GL_LIGHT0, GL_AMBIENT, Light0Ambient);					// Setup The Ambient Light
	glDisable(GL_TEXTURE_2D);
	DWORD b1;		
	g_pStreamingSound->GetBuffer(0)->GetCurrentPosition(&b1, NULL);
#ifdef BmpOutput
	b1 = (int)((ActTime / 1000.0) * 44100.0 * (16.0 / 8.0) * 2.0);
#endif
	b1 /= 4;

	small* WaveForm = (small*) g_pWaveForm->GetWaveForm();
	glColor4f(0.6f, 0.6f, 0.7f, 1.0f);
#define FRAME_HSPACE    0.33f
#define FRAME_VSPACE	0.33f

#define WAVEPOINTS_SHOWNUM		1024
#define WAVEPOINTS_MIDDLE		7.6f
#define WAVEPOINTS_MAXHEIGHT	2.5f
#define WAVEPOINTS_LEFT			-10.0
#define WAVEPOINTS_WIDTH		22
#define WAVEPOINTS_HEIGHT		2.5
#define WAVEPOINTS_FRONT		1.0
	glTranslatef(0.0f, WAVEPOINTS_MIDDLE, 0.0f);

	GLushort pattern =0x5555;
#ifdef BmpOutput
	pattern =0x3333;
#endif
	glEnable(GL_LINE_STIPPLE);
	glLineStipple(1, pattern);
	glBegin(GL_LINES);
		glVertex3d(WAVEPOINTS_LEFT, 0.0, WAVEPOINTS_FRONT); 
		glVertex3d(WAVEPOINTS_LEFT+WAVEPOINTS_WIDTH, 0.0, WAVEPOINTS_FRONT); 
	glEnd();
	glBegin(GL_LINE_STRIP);
	  glVertex3d(WAVEPOINTS_LEFT-FRAME_HSPACE, -WAVEPOINTS_MAXHEIGHT / 2.0-FRAME_VSPACE, WAVEPOINTS_FRONT); 
	  glVertex3d(WAVEPOINTS_LEFT+FRAME_HSPACE+WAVEPOINTS_WIDTH, -WAVEPOINTS_MAXHEIGHT / 2.0-FRAME_VSPACE, WAVEPOINTS_FRONT); 
	  glVertex3d(WAVEPOINTS_LEFT+FRAME_HSPACE+WAVEPOINTS_WIDTH, +WAVEPOINTS_MAXHEIGHT / 2.0+FRAME_VSPACE, WAVEPOINTS_FRONT); 
	  glVertex3d(WAVEPOINTS_LEFT-FRAME_HSPACE, +WAVEPOINTS_MAXHEIGHT / 2.0+FRAME_VSPACE, WAVEPOINTS_FRONT); 
	  glVertex3d(WAVEPOINTS_LEFT-FRAME_HSPACE, -WAVEPOINTS_MAXHEIGHT / 2.0-FRAME_VSPACE, WAVEPOINTS_FRONT); 
	glEnd();
	glDisable(GL_LINE_STIPPLE);
 
    glEnable(GL_LINE_SMOOTH);
	glBegin(GL_LINE_STRIP);
		for (int i = 0; i <= WAVEPOINTS_SHOWNUM; i++){
			glVertex3f((float)(WAVEPOINTS_LEFT + WAVEPOINTS_WIDTH* ((double)i / (double)WAVEPOINTS_SHOWNUM)),(float)(((double)WaveForm[b1 + i]/236.0) * WAVEPOINTS_HEIGHT), (float)WAVEPOINTS_FRONT);
		}

	glEnd();
    glDisable(GL_LINE_SMOOTH);
	

	__int16* FFTData = g_pWaveFFT->GetAnalysedData();
#define EQ_HIGHT_DIV	2800.0
#define EQ_LEFTBASE		-12.0
#define	EQ_LOWERBASE	0.0
#define EQ_SPACEHOR		0.5
#define EQ_ZEROHEIGHT	0.05
#define EQ_FRONT		1.0
#define EQ_MAXHEIGHT	2.5
#define EQ_WIDTH		0.25
#define EQ_BOOST		1.1


	glEnable(GL_LINE_STIPPLE);
	glBegin(GL_LINE_STRIP);
	  glVertex3d(EQ_LEFTBASE-FRAME_HSPACE, EQ_LOWERBASE-EQ_MAXHEIGHT/2.0-FRAME_VSPACE, EQ_FRONT); 
	  glVertex3d(EQ_LEFTBASE+2*EQ_SPACEHOR+FRAME_HSPACE, EQ_LOWERBASE-EQ_MAXHEIGHT/2.0-FRAME_VSPACE, EQ_FRONT); 
	  glVertex3d(EQ_LEFTBASE+2*EQ_SPACEHOR+FRAME_HSPACE, EQ_LOWERBASE+EQ_MAXHEIGHT/2.0+FRAME_VSPACE, EQ_FRONT); 
	  glVertex3d(EQ_LEFTBASE-FRAME_HSPACE, EQ_LOWERBASE+EQ_MAXHEIGHT/2.0+FRAME_VSPACE, EQ_FRONT); 
	  glVertex3d(EQ_LEFTBASE-FRAME_HSPACE, EQ_LOWERBASE-EQ_MAXHEIGHT/2.0-FRAME_VSPACE, EQ_FRONT); 
	glEnd();
	glDisable(GL_LINE_STIPPLE);

	float height;
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[TEX_EQ]);			
	glBegin(GL_QUADS);

		glTexCoord2f(1.0f, 0.0f);
		glVertex3f( (float)(EQ_LEFTBASE + 0 * EQ_SPACEHOR  + EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE-EQ_ZEROHEIGHT-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		height = (float)((1.0 * EQ_BOOST / EQ_MAXHEIGHT)*(FFTData[(b1 / 1024) * 3 + 0]/ EQ_HIGHT_DIV));
		if (height < 0.01f) height = 0.01f;
		glTexCoord2f(1.0f, height);
		glVertex3f( (float)(EQ_LEFTBASE + 0 * EQ_SPACEHOR + EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE + FFTData[(b1 / 1024) * 3 + 0] / EQ_HIGHT_DIV-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		glTexCoord2f(0.0f, height);
		glVertex3f( (float)(EQ_LEFTBASE + 0 * EQ_SPACEHOR - EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE + FFTData[(b1 / 1024) * 3 + 0] / EQ_HIGHT_DIV-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		glTexCoord2f(0.0f, 0.0f);
		glVertex3f( (float)(EQ_LEFTBASE + 0 * EQ_SPACEHOR - EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE-EQ_ZEROHEIGHT-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		
		glTexCoord2f(1.0f, 0.0f);
		glVertex3f( (float)(EQ_LEFTBASE + 1 * EQ_SPACEHOR  + EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE-EQ_ZEROHEIGHT-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		height = (float)((1.0 * EQ_BOOST / EQ_MAXHEIGHT)*(FFTData[(b1 / 1024) * 3 + 1]/ EQ_HIGHT_DIV));
		if (height < 0.01f) height = 0.01f;
		glTexCoord2f(1.0f, height);
		glVertex3f( (float)(EQ_LEFTBASE + 1 * EQ_SPACEHOR + EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE + FFTData[(b1 / 1024) * 3 + 1] / EQ_HIGHT_DIV-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		glTexCoord2f(0.0f, height);
		glVertex3f( (float)(EQ_LEFTBASE + 1 * EQ_SPACEHOR - EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE + FFTData[(b1 / 1024) * 3 + 1] / EQ_HIGHT_DIV-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		glTexCoord2f(0.0f, 0.0f);
		glVertex3f( (float)(EQ_LEFTBASE + 1 * EQ_SPACEHOR - EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE-EQ_ZEROHEIGHT-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));

		glTexCoord2f(1.0f, 0.0f);
		glVertex3f( (float)(EQ_LEFTBASE + 2 * EQ_SPACEHOR  + EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE-EQ_ZEROHEIGHT-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		height = (float)((1.0 * EQ_BOOST / EQ_MAXHEIGHT)*(FFTData[(b1 / 1024) * 3 + 2]/ EQ_HIGHT_DIV));
		if (height < 0.01f) height = 0.01f;
		glTexCoord2f(1.0f, height);
		glVertex3f( (float)(EQ_LEFTBASE + 2 * EQ_SPACEHOR + EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE + FFTData[(b1 / 1024) * 3 + 2] / EQ_HIGHT_DIV-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		glTexCoord2f(0.0f, height);
		glVertex3f( (float)(EQ_LEFTBASE + 2 * EQ_SPACEHOR - EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE + FFTData[(b1 / 1024) * 3 + 2] / EQ_HIGHT_DIV-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
		glTexCoord2f(0.0f, 0.0f);
		glVertex3f( (float)(EQ_LEFTBASE + 2 * EQ_SPACEHOR - EQ_WIDTH / 2.0), 
					(float)(EQ_LOWERBASE-EQ_ZEROHEIGHT-EQ_MAXHEIGHT/2.0),
					(float)(EQ_FRONT));
	glEnd();
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glEnable(GL_TEXTURE_2D);
	Light0Ambient[0]=   (float) (Light0_Ambient[0]);
	Light0Ambient[1]=   (float) (Light0_Ambient[1]);
	Light0Ambient[2]=   (float) (Light0_Ambient[2]);
	Light0Ambient[3]=   (float) (Light0_Ambient[3]);

	glLightfv(GL_LIGHT0, GL_AMBIENT, Light0Ambient);					// Setup The Ambient Light
#endif
	glPopMatrix();
    glEnable(GL_LINE_SMOOTH);
    glDisable(GL_LINE_STIPPLE);
	pattern =0xFFFF;
	glLineStipple(1, pattern);
}


////////////////////////////////////////////////////////////////////
/// void Draw())
////////////////////////////////////////////////////////////////////
//  Hauptzeichenroutine
//  von dort aus werden alle Unterzeichenfunktionenen aufgerufen
void Draw (void)
{

	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear Screen And Depth Buffer
	glLoadIdentity();
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	// Reset The View	

	char time[80];
	LARGE_INTEGER newPerformanceCounter;
	QueryPerformanceCounter(&newPerformanceCounter);

//  FPS Berechnung
	if (newPerformanceCounter.QuadPart != liLastPerformanceCounter.QuadPart) {
		int fps = ((int)iPerformanceFrequency * 100) / (int)(newPerformanceCounter.QuadPart - liLastPerformanceCounter.QuadPart);
		liLastPerformanceCounter.QuadPart = newPerformanceCounter.QuadPart;
#ifndef BmpOutput
		sprintf(time, "fps: %5.1f", (fps/100.0));
#endif
#ifdef  BmpOutput
		sprintf(time, "rfps: %4.1f", (fps/100.0));
		fps = 2500;
#endif
#ifdef	ShowTime
		sprintf(time, "t %4.2f %2d", Camera->GetActTime(), Camera->GetActEvent());
#endif
#ifndef CameraMovement
		xangle += (float)(xspeed * 1.0 / ((double)fps / 100));
		yangle += (float)(yspeed * 1.0 / ((double)fps / 100));
		zangle += (float)(zspeed * 1.0 / ((double)fps / 100));
#endif
#ifdef	CameraMovement
		xangle = (float)Camera->GetActValue(CAMVALUE_ROT_X);
		yangle = (float)Camera->GetActValue(CAMVALUE_ROT_Y);
		zangle = (float)Camera->GetActValue(CAMVALUE_ROT_Z);
		z = (float)Camera->GetActValue(CAMVALUE_POS_Z);
#endif
		timeangle += (float)(timespeed * 1.0 / ((double)fps / 100));

	} 

	glEnable(GL_LIGHTING);									
	glEnable(GL_TEXTURE_2D);									// Enable Texture Mapping

#define TOP_POS 0.25f
	glTranslatef(0.0f, -TOP_POS, 0.0f);
	glTranslatef(0.0f,0.0f, z);


	glRotatef(xangle, 1.0f, 0.0f, 0.0f);
	glRotatef(yangle, 0.0f, 1.0f, 0.0f);
	glRotatef(zangle, 0.0f, 0.0f, 1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	LightPar();

	DrawBackground();


#define LIGHT_ISLE_DISTANCE 6.0f
#define LIGHT_MIN_POWER 0.10
	glPushMatrix();
	glTranslatef(0.0f, TOP_POS, 0.0f);
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, texture[TEX_GROUND]);			

	glPushMatrix();
	glTranslatef(0.0f, -3.0f, 0.0f);
	glCallList(dlGround);	
	glRotatef(-angle / 17.0f, 0.0f, 1.0f, 0.0f);
	glPushMatrix();
	glPushMatrix();
	
	glTranslatef(0.0f, 0.0f , -LIGHT_ISLE_DISTANCE);
	glCallList(dlLightIsle);
	glTranslatef(0.0f, SPOT_ABOVE_ZERO, 0.0f);
	DrawLight((float) (Light1_Base_Color[0] * (light1_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)), 
			  (float) (Light1_Base_Color[1] * (light1_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)), 
			  (float) (Light1_Base_Color[2] * (light1_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)));

	glPopMatrix();
	glRotatef(120, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0f, 0.0f , -LIGHT_ISLE_DISTANCE);
	glCallList(dlLightIsle);
	glTranslatef(0.0f, SPOT_ABOVE_ZERO, 0.0f);
	DrawLight((float) (Light2_Base_Color[0] * (light2_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)), 
			  (float) (Light2_Base_Color[1] * (light2_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)), 
			  (float) (Light2_Base_Color[2] * (light2_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)));
	glPopMatrix();
	glRotatef(-120, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0f, 0.0f , -LIGHT_ISLE_DISTANCE);
	glCallList(dlLightIsle);
	glTranslatef(0.0f, SPOT_ABOVE_ZERO, 0.0f);
	DrawLight((float) (Light3_Base_Color[0] * (light3_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)), 
			  (float) (Light3_Base_Color[1] * (light3_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)), 
			  (float) (Light3_Base_Color[2] * (light3_power * (1.0 - LIGHT_MIN_POWER) + LIGHT_MIN_POWER)));
	glPopMatrix();


	glPushMatrix();
	DrawSail(true);
	DrawSail(false);
	glPopMatrix();

// inneren Kreise
	glPushMatrix();
	glTranslatef(0.0f, TOP_POS, 0.0f);

	preRotateRing(0);
	glBindTexture(GL_TEXTURE_2D, texture[TEX_WHEEL]);			
	WheelTextureAdjust();
	glCallList(dlRing[0]);
	WheelTextureRestore();
	glBindTexture(GL_TEXTURE_2D, texture[TEX_AUFHAENGUNG]);			
	glCallList(dlRingAufhaengung[0]);
	preRotateRing(1);
	WheelTextureAdjust();
	glBindTexture(GL_TEXTURE_2D, texture[TEX_WHEEL]);			
	glCallList(dlRing[1]);
	WheelTextureRestore();
	glBindTexture(GL_TEXTURE_2D, texture[TEX_AUFHAENGUNG]);			
	glCallList(dlRingAufhaengung[1]);
	preRotateRing(2);
	WheelTextureAdjust();
	glBindTexture(GL_TEXTURE_2D, texture[TEX_WHEEL]);			
	glCallList(dlRing[2]);
	WheelTextureRestore();

	glPopMatrix();

	glPushMatrix();
	glPushMatrix();
	glRotatef(90, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0f,0.0f, -2.0f);
	glBindTexture(GL_TEXTURE_2D, texture[TEX_SAIL]);			
	glCallList(dlSail);
	glPopMatrix();
	glRotatef(-90, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0f,0.0f, -2.0f);
	glCallList(dlSail);
	glPopMatrix();
	
	glTranslatef(0.0f, TOP_POS, 0.0f);
	BlendDraw();

#ifdef SHOWBALOGO

	glDisable(GL_TEXTURE_2D);
	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -1.0f);
	glTranslatef(7.6f, 5.7f, -14.0f);
	glDisable(GL_LINE_SMOOTH);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glRotatef((float) (-angle / 2.6), 1.0f, 0.0f, 0.0f);
#define BA_LOGO_LIGHT 0.7f
	float Light0Ambient[]=   {BA_LOGO_LIGHT, BA_LOGO_LIGHT, BA_LOGO_LIGHT, 1.0f}; 				 // Ambient Light Values 
	glLightfv(GL_LIGHT0, GL_AMBIENT, Light0Ambient);					// Setup The Ambient Light
	glClear (GL_DEPTH_BUFFER_BIT);		// Clear Screen And Depth Buffer
	glCallList(BALOGO_3D);
	glEnable(GL_LINE_SMOOTH);
#endif

	glEnable(GL_TEXTURE_2D);									// Enable Texture Mapping
	glDisable(GL_LIGHTING);
	glColor3f(1.0f,1.0f,0.0f);
#ifdef ShowFPS
	fNeHe.SetBase(32 - 128);									// Adjust Base Start Pos (Second Set of Fonts)
	fNeHe.Print(window.init.width-110,15, time);									// Print GL Text To The Screen
#endif


#ifndef SkipBmpSave
#ifdef BmpOutput
	CreateDirectory("bmpout", 0);
	char filename[80];
	char tmpstr[16];
	char zerostr[16];
	char ch;
	static int picno = 0;
	picno++;
	if (picno >= 0) {
     // Framedaten als .bmp-Datei ablegen:
	 BitmapBits = ReadDIBitmap( &(BitmapInfo)); //Framedaten lesen
	 sprintf(tmpstr, "%d", picno);
	 int zeropos = 7;
	 int stlen = strlen(tmpstr);
	 sprintf(zerostr, "00000000");
	 for (int strpos = strlen(tmpstr) - 1; strpos >= 0; strpos--) {
		 ch = tmpstr[strpos];
		 zerostr[zeropos] = ch;
         zeropos--;
	 }
	 sprintf(filename, "bmpout\\%s.bmp\0", zerostr);
	 if ( SaveDIBitmap(filename,  BitmapInfo, BitmapBits) == -2) //Daten ablegen
	 {
	 }; 
	 Sleep(200);
	 free(BitmapBits);
	 free(BitmapInfo);
	}
#endif
#endif
	glFlush ();													// Flush The GL Rendering Pipeline
}


////////////////////////////////////////////////////////////////////
/// void BlendDraw(void))
////////////////////////////////////////////////////////////////////
//  zeichnet alle Objekte mit glEnable(GL_BLEND)
void BlendDraw (void) {
	glEnable(GL_BLEND);

	glPushMatrix();

	glBindTexture(GL_TEXTURE_2D, texture[TEX_WINDOW]);			

	preRotateRing(0);
	glCallList(dlRingWindow[0]);
	preRotateRing(1);
	glCallList(dlRingWindow[1]);
	preRotateRing(2);
	glCallList(dlRingWindow[2]);

	glPopMatrix();

	glDisable(GL_BLEND);
}

////////////////////////////////////////////////////////////////////
/// DrawRinge(double innerRadius, double innerWidth, double sideHeight, double sideWidth, double sideRound, int Faces, int Segments)
////////////////////////////////////////////////////////////////////
//  zeichnet einen Doppelring
void DrawRinge(double innerRadius, double innerWidth, double sideHeight, double sideWidth, double sideRound, int Faces, int Segments){
	glTranslatef(0.0f, 0.0f, (float)-((innerWidth+sideWidth)/2.0));
	DrawWheel(innerRadius, sideHeight, sideWidth, sideRound, Faces, Segments);

	glTranslatef(0.0f, 0.0f, (float) ((innerWidth+sideWidth)/2.0));
	DrawWheel(innerRadius, sideHeight, sideWidth, sideRound, Faces, Segments);
}

////////////////////////////////////////////////////////////////////
/// DrawAufhaengung(double innerRadius, double outerRadius, double width, int Faces, int Segments)
////////////////////////////////////////////////////////////////////
//  zeichnet Verbindung zwischen den Ringen
#define AUFHAENUNG_ROUND_ADJ 0.15 // Anpassung des Winkels, damit nicht nach durch das Glas hindurch gemalt wird
void DrawAufhaengung(double innerRadius, double outerRadius, double width, int Faces, int Segments) {
	glPushMatrix();
	glPushMatrix();
	DrawCylinder2(innerRadius, innerRadius, (width - (outerRadius - innerRadius) * 2.0), Segments, 1);
	glTranslatef(0.0f,0.0f, (float) -(width/2.0));
	DrawTorusPart(innerRadius, outerRadius - innerRadius, 0, M_2PI, 0.0 + AUFHAENUNG_ROUND_ADJ, M_PIH, 0, 0, Faces, Segments);
	glPopMatrix();
	glTranslatef(0.0f,0.0f, (float)  (width/2.0));
	DrawTorusPart(innerRadius, outerRadius - innerRadius, 0, M_2PI, M_3PIH, M_2PI - AUFHAENUNG_ROUND_ADJ, 0, 0, Faces, Segments);
	glPopMatrix();
}

////////////////////////////////////////////////////////////////////
/// DrawTorus(double innerRadius, double outerRadius, int Faces, int Segments)
////////////////////////////////////////////////////////////////////
//  zeichnet einen Torus
void DrawTorus(double innerRadius, double outerRadius, int Faces, int Segments) {
	DrawTorusPart(innerRadius, outerRadius, 0.0, M_2PI, 0.0, M_2PI, 0.0, 0.0, Faces, Segments);
}

////////////////////////////////////////////////////////////////////
/// DrawPlate(double Radius, int Rows, int Segments)
////////////////////////////////////////////////////////////////////
//  zeichnet eine ebene Fläche
void DrawPlate(double Radius, int Rows, int Segments) {
	double pdNorm[3];
	double vec[3];
#ifdef ShowNormals
	ClearNormals();
#endif
	glBegin(GL_TRIANGLE_FAN);
		pdNorm[0] = 0.0;
		pdNorm[1] = 0.0; 
 		pdNorm[2] = -1.0;  
	glNormal3d((float)pdNorm[0], (float)pdNorm[1], (float)pdNorm[2]);
	glTexCoord2f(0.5, 0.5);
	glVertex3f(0.0f, 0.0f, 0.0f);
	for (int i = 0; i < Segments + 1; i++) {
		vec[0] = sin((M_2PI / Segments) * i) * (Radius / Rows);
		vec[1] = cos((M_2PI / Segments) * i) * (Radius / Rows);
		vec[2] = 0.0;
		pdNorm[0] = 0.0;
		pdNorm[1] = 0.0; 
 		pdNorm[2] = -1.0;  
		ReduceToUnit(pdNorm);
		glNormal3d((float)pdNorm[0], (float)pdNorm[1], (float)pdNorm[2]);
		glTexCoord2f((float)(0.5 + vec[0] / 2.0 / Radius), (float)(0.5 + vec[1] / 2.0 / Radius));
		glVertex3f((float) vec[0], (float) vec[1], (float) vec[2]);
#ifdef ShowNormals
			AddNormal6f(
				(float)(vec[0]),
				(float)(vec[1]),
				(float)(vec[2]),
				(float)pdNorm[0],
				(float)pdNorm[1],
				(float)pdNorm[2]
				);
#endif
	}
	glEnd();
	for (int j = 1; j < Rows; j++) {
		glBegin(GL_QUAD_STRIP);
		for (int i = 0; i < Segments + 1; i++) {
			vec[0] = sin((M_2PI / Segments) * i) * (Radius / Rows) * (j);
			vec[1] = cos((M_2PI / Segments) * i) * (Radius / Rows) * (j);;
			vec[2] = 0.0;
			pdNorm[0] = 0.0;
			pdNorm[1] = 0.0; 
 			pdNorm[2] = -1.0;  
			ReduceToUnit(pdNorm);
			glNormal3d((float)pdNorm[0], (float)pdNorm[1], (float)pdNorm[2]);
			glTexCoord2f((float)(0.5 + vec[0] / 2.0 / Radius), (float)(0.5 + vec[1] / 2.0 / Radius));
			glVertex3f((float) vec[0], (float) vec[1], (float) vec[2]);
#ifdef ShowNormals
			AddNormal6f(
				(float)(vec[0]),
				(float)(vec[1]),
				(float)(vec[2]),
				(float)pdNorm[0],
				(float)pdNorm[1],
				(float)pdNorm[2]
				);
#endif
			vec[0] = sin((M_2PI / Segments) * i) * (Radius / Rows) * (j+1);
			vec[1] = cos((M_2PI / Segments) * i) * (Radius / Rows) * (j+1);
			vec[2] = 0.0;
			pdNorm[0] = 0.0;
			pdNorm[1] = 0.0; 
 			pdNorm[2] = -1.0;  
			ReduceToUnit(pdNorm);
			glNormal3d((float)pdNorm[0], (float)pdNorm[1], (float)pdNorm[2]);
			glTexCoord2f((float)(0.5 + vec[0] / 2.0 / Radius), (float)(0.5 + vec[1] / 2.0 / Radius));
			glVertex3f((float) vec[0], (float) vec[1], (float) vec[2]);
#ifdef ShowNormals
			AddNormal6f(
				(float)(vec[0]),
				(float)(vec[1]),
				(float)(vec[2]),
				(float)pdNorm[0],
				(float)pdNorm[1],
				(float)pdNorm[2]
				);
#endif
		}
		glEnd();
#ifdef ShowNormals
		DrawNormals();
#endif
	}
}

////////////////////////////////////////////////////////////////////
/// DrawCylinder2(double lowerRadius, double upperRadius, double height, int Segments, int Tess, double texXadj, double texYadj)
////////////////////////////////////////////////////////////////////
//  zeichnet einen Zylinder - verbesserte Version von DrawCylinder
//  DrawCylinder beibehalten wegen Seiteneffektnutzung
//  Normalenvektoranpassung bei unterschiedlichen Radien nicht gegeben
void DrawCylinder2(double lowerRadius, double upperRadius, double height, int Segments, int Tess) {
  DrawCylinder2(lowerRadius, upperRadius, height, Segments, Tess, 1.0, 1.0);
}

void DrawCylinder2(double lowerRadius, double upperRadius, double height, int Segments, int Tess, double texXadj, double texYadj) {
	double pdNorm[3];
	double vec[3];
//	double wink;
//	wink = M_PIH - atan(height / (upperRadius - lowerRadius));

#ifdef ShowNormals
	ClearNormals();
#endif
	double radeff;
	for (int j = 0; j < Tess; j++) {
		glBegin(GL_QUAD_STRIP);
		for (int i = 0; i <= Segments; i++) {
			for (int k = j; k <= j+1; k++) {
				vec[0] = -sin((M_2PI / (double)Segments) * (double)i);
				vec[1] = -cos((M_2PI / (double)Segments) * (double)i);
				vec[2] = 0.0;
				pdNorm[0] = vec[0];
				pdNorm[1] = vec[1]; 
		 		pdNorm[2] = 0.0; // <<wrong  
				ReduceToUnit(pdNorm);
		// 		pdNorm[2] = 0.0; // <<wrong  
		//		ReduceToUnit(pdNorm);
				glNormal3d((float)pdNorm[0], (float)pdNorm[1], (float)pdNorm[2]);
				glTexCoord2f((float)(((double)texXadj / (double)Segments) * i), (float)(((double)texYadj / (double)Tess) * k));
				radeff = lowerRadius + (upperRadius - lowerRadius) * ((1.0 / (double) Tess) * k);
				glVertex3f((float) (vec[0] * radeff), (float) (vec[1] * radeff), (float) ((((1.0 / (double) Tess) * k)-0.5)*height) );
#ifdef ShowNormals
			AddNormal6f(
				(float)(vec[0]* radeff),
				(float)(vec[1]* radeff),
				(float)(((((1.0 / (double) Tess) * k)-1.0)*2.0*height)),
				(float)pdNorm[0],
				(float)pdNorm[1],
				(float)pdNorm[2]
				);
#endif
			}
		}
		glEnd();
#ifdef ShowNormals
		DrawNormals();
#endif
	}
}

////////////////////////////////////////////////////////////////////
/// DrawCylinder(double innerRadius, double outerWidth, int Segments, bool SkipInside, bool sfx) {
////////////////////////////////////////////////////////////////////
//  Ursprüngliche Zylinder-Funktion verwendet DrawTorusPart als primitive
//  sfx - beinhaltet bewusst den Programmierfehler als optischen Effekt
void DrawCylinder(double innerRadius, double outerWidth, int Segments, bool SkipInside) {
	DrawTorusPart(innerRadius, outerWidth / 2.0, 0.0, M_2PI, M_PIH, M_5PIH, 0.0, 0.0, 2, Segments, SkipInside);
}

void DrawCylinder(double innerRadius, double outerWidth, int Segments, bool SkipInside, bool sfx) {
	if (!sfx) DrawTorusPart(innerRadius, outerWidth / 2.0, 0.0, M_2PI, M_PIH, M_5PIH, 0.0, 0.0, 2, Segments, SkipInside);
      else DrawTorusPart(innerRadius, outerWidth / 2.0, 0.0, M_2PI, M_3PIH, M_7PIH, 0.0, 0.0, 2, Segments, SkipInside);
}

////////////////////////////////////////////////////////////////////
/// DrawWheel(double innerRadius, double outerHeight, double outerWidth, double outerRound, int Faces, int Segments) {
////////////////////////////////////////////////////////////////////
//  zeichnet eine Art Rad, wobei das Seiten und Vorder/Hinterseitenprofil flach sein kann
void DrawWheel(double innerRadius, double outerHeight, double outerWidth, double outerRound, int Faces, int Segments) {

	double hRadius = (outerHeight - outerRound * 2.0) * M_1SQRT2;
	if (!((hRadius > -0.0001) && (hRadius < 0.0001))) {
		DrawTorusPart(innerRadius, hRadius, 0.0, M_2PI, M_PIV,  M_3PIV, 0.0,  ((outerWidth / 2.0) - (outerHeight / 2.0)) + outerRound , 1, Segments); 
		DrawTorusPart(innerRadius, hRadius, 0.0, M_2PI, M_5PIV, M_7PIV, 0.0, -((outerWidth / 2.0) - (outerHeight / 2.0)) - outerRound , 1, Segments); 
	}

	double vRadius = (outerWidth - outerRound * 2.0) * M_1SQRT2;
	if (!((vRadius > -0.0001) && (vRadius < 0.0001))) {
		DrawTorusPart(innerRadius, vRadius, 0.0, M_2PI, -M_PIV,  M_PIV,   ((outerHeight / 2.0) - (outerWidth / 2.0)) + outerRound , 0.0, 1, Segments); 
		DrawTorusPart(innerRadius, vRadius, 0.0, M_2PI,  M_3PIV, M_5PIV, -((outerHeight / 2.0) - (outerWidth / 2.0)) - outerRound , 0.0, 1, Segments); 
	}

	if (!((outerRound > -0.0001) && (outerRound < 0.0001))) {
		DrawTorusPart(innerRadius, outerRound, 0.0, M_2PI, 0.0,    M_PIH,   (outerHeight / 2.0 - outerRound),  (outerWidth / 2.0 - outerRound), Faces, Segments);
		DrawTorusPart(innerRadius, outerRound, 0.0, M_2PI, M_PIH,  M_PI,   -(outerHeight / 2.0 - outerRound),  (outerWidth / 2.0 - outerRound), Faces, Segments);
		DrawTorusPart(innerRadius, outerRound, 0.0, M_2PI, M_PI,   M_3PIH, -(outerHeight / 2.0 - outerRound), -(outerWidth / 2.0 - outerRound), Faces, Segments);
		DrawTorusPart(innerRadius, outerRound, 0.0, M_2PI, M_3PIH, M_2PI,   (outerHeight / 2.0 - outerRound), -(outerWidth / 2.0 - outerRound), Faces, Segments);
	}
}

////////////////////////////////////////////////////////////////////
/// ReduceToUnit(double vector[3])
////////////////////////////////////////////////////////////////////
//  Formt den Vektor in einen Vektor mit Länge eins um
void ReduceToUnit(double vector[3])
	{
	double length;
	
	// Calculate the length of the vector		
	length = sqrt((vector[0]*vector[0]) + 
				  (vector[1]*vector[1]) +
				  (vector[2]*vector[2]));

	// Keep the program from blowing up by providing an exceptable
	// value for vectors that may calculated too close to zero.
	if(length == 0.0)
		length = 1.0;

	// Dividing each element by the length will result in a
	// unit normal vector.
	vector[0] /= length;
	vector[1] /= length;
	vector[2] /= length;
	}

////////////////////////////////////////////////////////////////////
/// DrawDisc(double Radius, double Angle, int Segments, bool topface)
////////////////////////////////////////////////////////////////////
//  zeichnet eine Scheibe (wird nicht mehr verwendet)
void DrawDisc(double Radius, double Angle, int Segments, bool topface)
{
	glPushMatrix();
	Radius *= M_1SQRT2;
	if  (topface) glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
		else glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); 
	glRotated(Angle, 0.0, 0.0, 1.0); 
	DrawTorusPart(Radius - 2.0f, Radius - 1.0f, 0, M_2PI, 0, M_2PI, 1.0, 0.0, 2, Segments, true, true);
	glPopMatrix();
}

////////////////////////////////////////////////////////////////////
/// DrawTorusPart(double innerRadius, double outerRadius, double innerStartAngle, double innerEndAngle, double outerStartAngle, double outerEndAngle, double innerScale, double zoff, int Faces, int Segments, bool SkipInside, bool Disc)
////////////////////////////////////////////////////////////////////
//  Hauptzeichenprimitive, worauf viele der Zeichenfunktionen aufbauen
void DrawTorusPart(double innerRadius, double outerRadius, double innerStartAngle, double innerEndAngle, double outerStartAngle, double outerEndAngle, double innerScale, double zoff, int Faces, int Segments) {
	DrawTorusPart(innerRadius, outerRadius, innerStartAngle, innerEndAngle, outerStartAngle, outerEndAngle, innerScale, zoff, Faces, Segments, true);
}

void DrawTorusPart(double innerRadius, double outerRadius, double innerStartAngle, double innerEndAngle, double outerStartAngle, double outerEndAngle, double innerScale, double zoff, int Faces, int Segments, bool SkipInside) {
	DrawTorusPart(innerRadius, outerRadius, innerStartAngle, innerEndAngle, outerStartAngle, outerEndAngle, innerScale, zoff, Faces, Segments, SkipInside, false);
}

void DrawTorusPart(double innerRadius, double outerRadius, double innerStartAngle, double innerEndAngle, double outerStartAngle, double outerEndAngle, double innerScale, double zoff, int Faces, int Segments, bool SkipInside, bool Disc) {
	for (int l_Face = 0; l_Face < Faces; l_Face++) {
		if ((Faces == 2) && (l_Face != 1) && (SkipInside == true)) continue;
#ifdef ShowNormals
		ClearNormals();
#endif
		glBegin(GL_QUAD_STRIP);
		double l_FaceAngle0 = outerStartAngle + (outerEndAngle - outerStartAngle) * ((double) l_Face    / (double)Faces);
		double l_FaceAngle1 = outerStartAngle + (outerEndAngle - outerStartAngle) * ((double)(l_Face+1) / (double)Faces);
		// oben starten - nach hinten weiter
		double z0_face = sin(l_FaceAngle0);
		double z1_face = sin(l_FaceAngle1);
		double xy0_face = cos(l_FaceAngle0);
		double xy1_face = cos(l_FaceAngle1);
		
		chkfloat(z0_face);
		chkfloat(z1_face);
		chkfloat(xy0_face);
		chkfloat(xy1_face);

		z0_face *= outerRadius;
		z1_face *= outerRadius;
		xy0_face *= outerRadius;
		xy1_face *= outerRadius;
 		for (int l_Segment = 0; l_Segment <= Segments; l_Segment++) {
			double l_SegAngle = innerStartAngle + (innerEndAngle - innerStartAngle) * ((double)l_Segment / (double)Segments);
			// oben starten - gegen den Uhrzeigersinn
			double x = -sin(l_SegAngle);
			double y =  cos(l_SegAngle);
			chkfloat(x);
			chkfloat(y);

			double z = 1.0;

			if ((Faces == 2) && (outerStartAngle == M_PIH) && (outerEndAngle == M_5PIH) && (SkipInside == false))
			{
				if (l_Face == 0) { x*=0.99, y*=0.99;}
				if (l_Face == 1) { x*=1.01, y*=1.01;}
				z = 1.05;
			}
			
			// zuerst punkt1
			double pdNorm[3];
			pdNorm[0] = x * xy1_face;
			pdNorm[1] = y * xy1_face;
			pdNorm[2] = z1_face;
			if ((Faces == 2) && (outerStartAngle == M_PIH) && (outerEndAngle == M_5PIH)) {
				if (l_Face == 0) {
					pdNorm[0] = sin(l_SegAngle);
					pdNorm[1] = -cos(l_SegAngle);
					pdNorm[2] = 0.0;
				}
				if (l_Face == 1) {
					pdNorm[0] = -sin(l_SegAngle);
					pdNorm[1] = cos(l_SegAngle);
					pdNorm[2] = 0.0;
					}
			}
			if (Faces == 1) {
				pdNorm[2] = 0.0;
			}
			if (Disc) {
				pdNorm[0] = 0.0;
				pdNorm[1] = 0.0;
				pdNorm[2] = 0.0;
			}
			ReduceToUnit(pdNorm);
			glNormal3d((float)pdNorm[0], (float)pdNorm[1], (float)pdNorm[2]);
			glTexCoord2f((float) (1.0 - 1.0 * (double)(l_Segment) / (double) Segments), (float) (1.0 * (double)(l_Face+1) / (double)Faces));

			glVertex3f((float)(x * (innerRadius + innerScale) + x * xy1_face), (float)(y * (innerRadius + innerScale) + y * xy1_face) , (float)((zoff + z1_face) * z)); 
#ifdef ShowNormals
			AddNormal6f(
				(float)(x * (innerRadius + innerScale) + x * xy1_face),
				(float)(y * (innerRadius + innerScale) + y * xy1_face),
				(float)((zoff + z1_face) * z),
				(float)pdNorm[0],
				(float)pdNorm[1],
				(float)pdNorm[2]
				);
#endif

			// dann punkt0
			pdNorm[0] = x * xy0_face;
			pdNorm[1] = y * xy0_face;
			pdNorm[2] = (z0_face);
			if ((Faces == 2) && (outerStartAngle == M_PIH) && (outerEndAngle == M_5PIH)) {
				if (l_Face == 0) {
					pdNorm[0] = sin(l_SegAngle);
					pdNorm[1] = -cos(l_SegAngle);
					pdNorm[2] = 0.0;
				}
				if (l_Face == 1) {
					pdNorm[0] = -sin(l_SegAngle);
					pdNorm[1] = cos(l_SegAngle);
					pdNorm[2] = 0.0;
					}
			}
			if (Faces == 1) {
				pdNorm[2] = 0.0;
			}
			if (Disc) {
				pdNorm[0] = 0.0;
				pdNorm[1] = 0.0;
				pdNorm[2] = -1.0;
			}
			ReduceToUnit(pdNorm);
			glNormal3d((float)pdNorm[0], (float)pdNorm[1], (float)pdNorm[2]);
			glTexCoord2f((float) (1.0 - 1.0 * (double)(l_Segment) / (double) Segments), (float) (1.0 * (double)l_Face / (double)Faces));

			glVertex3f((float)(x * (innerRadius + innerScale) + x * xy0_face), (float)(y * (innerRadius + innerScale) + y * xy0_face) , (float)((zoff + z0_face) * z)); 

#ifdef ShowNormals
			AddNormal6f(
				(float)(x * (innerRadius + innerScale) + x * xy0_face),
				(float)(y * (innerRadius + innerScale) + y * xy0_face),
				(float)((zoff + z0_face) * z),
				(float)pdNorm[0],
				(float)pdNorm[1],
				(float)pdNorm[2]
				);
#endif

		}

		glEnd();
#ifdef ShowNormals
		DrawNormals();
#endif
	}
}		

////////////////////////////////////////////////////////////////////
/// AUX_RGBImageRec *LoadBMP(char *Filename)
////////////////////////////////////////////////////////////////////
//  Hilfsfunktion zum laden von Texturen
AUX_RGBImageRec *LoadBMP(char *Filename)				// Loads A Bitmap Image
{
	FILE *File=NULL;									// File Handle

	if (!Filename)										// Make Sure A Filename Was Given
	{
		return NULL;									// If Not Return NULL
	}

	File=fopen(Filename,"r");							// Check To See If The File Exists

	if (File)											// Does The File Exist?
	{
		fclose(File);									// Close The Handle
		return auxDIBImageLoad(Filename);				// Load The Bitmap And Return A Pointer
	}

	return NULL;										// If Load Failed Return NULL
}

////////////////////////////////////////////////////////////////////
/// LoadGLTexturesHelp(int texno, char* Filename)
////////////////////////////////////////////////////////////////////
//  Hilfsfunktion zum laden von Texturen
int LoadGLTexturesHelp(int texno, char* Filename) {
	int Status=FALSE;							// Status Indicator

	AUX_RGBImageRec *TextureImage[1];					// Create Storage Space For The Texture

	memset(TextureImage,0,sizeof(void *));				// Set The Pointer To NULL

	if (TextureImage[0]=LoadBMP(Filename))
	{
		Status=TRUE;							// Set The Status To TRUE

		glGenTextures(1, &texture[texno]);					// Create One Textures

		// Create MipMapped Texture
		glBindTexture(GL_TEXTURE_2D, texture[texno]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); // bilinear
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);  // trilinear

		if (texno != TEX_EQ) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		  else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

	}

	if (TextureImage[0])							// If Texture Exists
	{
		if (TextureImage[0]->data)					// If Texture Image Exists
		{
			free(TextureImage[0]->data);				// Free The Texture Image Memory
		}

		free(TextureImage[0]);						// Free The Image Structure
	}
	
	return Status;								// Return The Status
}

////////////////////////////////////////////////////////////////////
/// LoadGLTextures()
////////////////////////////////////////////////////////////////////
//  laden von Texturen...
int LoadGLTextures()								// Load Bitmaps And Convert To Textures
{
	LoadGLTexturesHelp(TEX_WINDOW,		"DATA/glas512.bmp");
	LoadGLTexturesHelp(TEX_WHEEL,		"DATA/holzwheel.bmp");
	LoadGLTexturesHelp(TEX_AUFHAENGUNG,	"DATA/aufhaengung.bmp");
	LoadGLTexturesHelp(TEX_SAIL,		"DATA/sail.bmp");
	LoadGLTexturesHelp(TEX_PILLARBIG,	"DATA/pillarbig.bmp");
	LoadGLTexturesHelp(TEX_PILLARSMALL,	"DATA/pillarsmall.bmp");
	LoadGLTexturesHelp(TEX_GROUND,		"DATA/ground.bmp");
	LoadGLTexturesHelp(TEX_BACKGROUND,	"DATA/back.bmp");
	LoadGLTexturesHelp(TEX_EQ,			"DATA/eq.bmp");
	LoadGLTexturesHelp(TEX_LIGHT,		"DATA/light.bmp");
	return TRUE;
}



////////////////////////////////////////////////////////////////////
/// dlSetup()
////////////////////////////////////////////////////////////////////
//  initialisieren der Displaylisten
void dlSetup(){

	nPartList = glGenLists(17);
	
	double innerWidthSail =		Sail_INNERWIDTH;
	double outerWidthSail =		Sail_OUTERWIDTH;
	double distanceSail =		Sail_DISTANCE;
	int    innerSegmentsSail =	Sail_INNERSEGMENTS;
	int	   outerSegmentsSail =	Sail_OUTERSEGMENTS;
	double HeightSail =			Sail_HEIGHT;
	double TopBottomDiffSail =	Sail_TOPBOTTOMDIFF;
	double AngleSail = -atan(TopBottomDiffSail / (HeightSail / 2.0)) * 180.0 / M_PI;

	double dScaleRing = 1.3;

	double innerRadiusRing = 1.0  * dScaleRing;
	double innerWidthRing = 0.15  * dScaleRing;
	double sideHeightRing = 0.05  * dScaleRing;
	double sideWidthRing = 0.075  * dScaleRing;
	double sideRoundRing = 0.025  * dScaleRing;
	int FacesRing = 3;
	int SegmentsRing = 50;

	dlWheel[0] = nPartList++;
	glNewList(dlWheel[0], GL_COMPILE);
		DrawWheel(innerRadiusRing, sideHeightRing, sideWidthRing, sideRoundRing, FacesRing, SegmentsRing);
	glEndList();

	dlRing[0] = nPartList++;
	glNewList(dlRing[0], GL_COMPILE);
		glPushMatrix();
		glPushMatrix();

		glTranslatef(0.0f, 0.0f, (float)-((innerWidthRing+sideWidthRing)/2.0));
		glCallList(dlWheel[0]);
		glPopMatrix();
		
		glTranslatef(0.0f, 0.0f, (float) ((innerWidthRing+sideWidthRing)/2.0));
		glCallList(dlWheel[0]);
		glPopMatrix();
	glEndList();

	dlRingWindow[0] = nPartList++;
	glNewList(dlRingWindow[0], GL_COMPILE);
   		glPolygonMode(GL_FRONT,GL_FILL);
		glPolygonMode(GL_BACK,GL_LINE);

		DrawCylinder(innerRadiusRing, innerWidthRing, SegmentsRing, false, true);

		glPolygonMode(GL_FRONT,GL_FILL);
		glPolygonMode(GL_BACK,GL_FILL);
	glEndList();

	innerRadiusRing = 0.85 * dScaleRing; // << changed
	
	dlWheel[1] = nPartList++;
	glNewList(dlWheel[1], GL_COMPILE);
		DrawWheel(innerRadiusRing, sideHeightRing, sideWidthRing, sideRoundRing, FacesRing, SegmentsRing);
	glEndList();

	dlRing[1] = nPartList++;
	glNewList(dlRing[1], GL_COMPILE);
		glPushMatrix();
		glPushMatrix();

		glTranslatef(0.0f, 0.0f, (float)-((innerWidthRing+sideWidthRing)/2.0));
		glCallList(dlWheel[1]);
		glPopMatrix();

		glTranslatef(0.0f, 0.0f, (float) ((innerWidthRing+sideWidthRing)/2.0));
		glCallList(dlWheel[1]);
		glPopMatrix();
	glEndList();

	dlRingWindow[1] = nPartList++;
	glNewList(dlRingWindow[1], GL_COMPILE);
		glPolygonMode(GL_FRONT,GL_FILL);
		glPolygonMode(GL_BACK,GL_LINE);
	    
		DrawCylinder(innerRadiusRing, innerWidthRing, SegmentsRing, false, true);

		glPolygonMode(GL_FRONT,GL_FILL);
		glPolygonMode(GL_BACK,GL_FILL);
	glEndList();

	innerRadiusRing = 0.7  * dScaleRing;   // << changed
	
	dlWheel[2] = nPartList++;
	glNewList(dlWheel[2], GL_COMPILE);
		DrawWheel(innerRadiusRing, sideHeightRing, sideWidthRing, sideRoundRing, FacesRing, SegmentsRing);
	glEndList();

	dlRing[2] = nPartList++;
	glNewList(dlRing[2], GL_COMPILE);
		glPushMatrix();
		glPushMatrix();
		
		glTranslatef(0.0f, 0.0f, (float)-((innerWidthRing+sideWidthRing)/2.0));
		glCallList(dlWheel[2]);
		glPopMatrix();

		glTranslatef(0.0f, 0.0f, (float) ((innerWidthRing+sideWidthRing)/2.0));
		glCallList(dlWheel[2]);
		glPopMatrix();
	glEndList();


	dlRingWindow[2] = nPartList++;
	glNewList(dlRingWindow[2], GL_COMPILE);
		glPolygonMode(GL_FRONT,GL_FILL);
		glPolygonMode(GL_BACK,GL_LINE);
	    
		DrawCylinder(innerRadiusRing, innerWidthRing, SegmentsRing, false, true);

		glPolygonMode(GL_FRONT,GL_FILL);
		glPolygonMode(GL_BACK,GL_FILL);
	glEndList();

	int		AufhaengungSegments = 20;
	int		AufhaengungFaces = 4;
	double	AufhaengungWidth = 0.15;

	dlRingAufhaengungSub[0] = nPartList++;
	glNewList(dlRingAufhaengungSub[0], GL_COMPILE);
		DrawAufhaengung(AufhaengungWidth * (0.3 / 2.0) * dScaleRing, AufhaengungWidth / 4.0 * dScaleRing, AufhaengungWidth * dScaleRing, AufhaengungFaces, AufhaengungSegments);
	glEndList();

	dlRingAufhaengung[0] = nPartList++;
	glNewList(dlRingAufhaengung[0], GL_COMPILE);
		glPushMatrix();
		glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
		glPushMatrix();
		glTranslatef(0.0f, 0.0f, (float)(-(1.0 - AufhaengungWidth / 2.0) * dScaleRing));
		glCallList(dlRingAufhaengungSub[0]);
		glPopMatrix();
		glTranslatef(0.0f, 0.0f, (float) ((1.0 - AufhaengungWidth / 2.0) * dScaleRing));
		glCallList(dlRingAufhaengungSub[0]);
		glPopMatrix();
	glEndList();

	dlRingAufhaengungSub[1] = nPartList++;
	glNewList(dlRingAufhaengungSub[1], GL_COMPILE);
		DrawAufhaengung(AufhaengungWidth * (0.3 / 2.0) * dScaleRing, AufhaengungWidth / 4.0 * dScaleRing, AufhaengungWidth * dScaleRing, AufhaengungFaces, AufhaengungSegments);
	glEndList();

	dlRingAufhaengung[1] = nPartList++;
	glNewList(dlRingAufhaengung[1], GL_COMPILE);
		glPushMatrix();
		glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
		glPushMatrix();

		glTranslatef(0.0f, 0.0f, (float)(-(0.85 - AufhaengungWidth / 2.0) * dScaleRing));
		glCallList(dlRingAufhaengungSub[1]);
		glPopMatrix();

		glTranslatef(0.0f, 0.0f, (float) ((0.85 - AufhaengungWidth / 2.0) * dScaleRing));
		glCallList(dlRingAufhaengungSub[1]);
		glPopMatrix();	
	glEndList();

	dlSailCyl[0] = nPartList++;
	glNewList(dlSailCyl[0], GL_COMPILE);
		DrawCylinder2(0.0025, outerWidthSail, HeightSail / cos(6.0 * AngleSail / 180.0 * M_PI), outerSegmentsSail, Sail_TESS, 0.25, 1.0);
	glEndList();

	dlSailCyl[1] = nPartList++;
	glNewList(dlSailCyl[1], GL_COMPILE);
		DrawCylinder2(0.0025, innerWidthSail, HeightSail / cos(3.0 * AngleSail / 180.0 * M_PI), innerSegmentsSail, Sail_TESS, 0.25, 1.0);
	glEndList();
	
	dlSailCyl[2] = nPartList++;
	glNewList(dlSailCyl[2], GL_COMPILE);
		DrawCylinder2(0.0025, innerWidthSail, HeightSail / cos(AngleSail / 180.0 * M_PI), innerSegmentsSail, Sail_TESS, 0.25, 1.0);
	glEndList();


	dlSail = nPartList++;
	glNewList(dlSail, GL_COMPILE);
	glFrontFace(GL_CW);
	glEnable(GL_AUTO_NORMAL);
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glTranslatef(-0.4975f, -0.5f, 0.0f);
	glMatrixMode(GL_MODELVIEW);

	GLfloat	fTexturScale = 4.0f;

	GLint nNumPoints = 3;

	GLfloat fScale = 2.0f;

	// Vorderseite
	GLfloat bupperwidth= 0.26f;
	GLfloat blowerwidth= 0.7f;
	GLfloat bround= 0.46f;
	GLfloat broundmid= 1.3f;
	GLfloat bhround = -0.3f; // 1..-1
	GLfloat bheight = 3.0f;
	GLfloat bsround = 1.05f;
	GLfloat bloweroffset = -0.05f;

	bupperwidth*= fScale;
	blowerwidth*= fScale;
	bround*= fScale;
	broundmid*= fScale;
	bhround*= fScale;
	bheight*= fScale;
	bsround*= fScale;
	bloweroffset*= fScale;
	
	GLfloat ctrlPoints[3][3][3]=  {{
		{  -bupperwidth / 2.0f,  bheight / 2.0f,  0.0f},	
		{  -((bupperwidth+blowerwidth) / 2.0f + (bupperwidth-blowerwidth) /2.0f *bround) * bsround,  (bheight / 2.0f) * bhround, -bround + bloweroffset * ((-bhround + 1) / 2.0f)},	
		{  -blowerwidth / 2.0f, -bheight / 2.0f,   bloweroffset}
		},

		{
		{ 0.0f,  bheight / 2.0f,  0.0f},	
		{  0.0f,  (bheight / 2.0f) * bhround,  -bround * broundmid + bloweroffset * ((-bhround + 1) / 2.0f)} ,	
		{  0.0f,  -bheight / 2.0f,  bloweroffset}
		},
		
		{
		{ bupperwidth / 2.0f,  bheight / 2.0f,  0.0f},	
		{  ((bupperwidth+blowerwidth) / 2.0f + (bupperwidth-blowerwidth) /2.0f *bround) * bsround,  (bheight / 2.0f) * bhround,  -bround + bloweroffset * ((-bhround + 1) / 2.0f)},	
		{  blowerwidth / 2.0f, -bheight / 2.0f,  bloweroffset}
		}};

#ifdef ShowBezierPoints
	int i,j;	// Counting variables

	// Set point size larger to make more visible
	glPointSize(5.0f);

	// Loop through all control points for this example
	glDisable(GL_TEXTURE);
	glBegin(GL_POINTS);
		for(i = 0; i < nNumPoints; i++)
			for(j = 0; j < 3; j++)
				glVertex3fv(ctrlPoints[i][j]);
	glEnd();
#endif
	// Sets up the Bezier
	// This actually only needs to be called once and could go in
	// the setup function

	glMap2f(GL_MAP2_VERTEX_3,	// Type of data generated
	0.0f,						// Lower u range
	25.0f,						// Upper u range
	3,							// Distance between points in the data
	3,							// Dimension in u direction (order)
	0.0f,						// Lover v range
	25.0f,						// Upper v range
	9,							// Distance between points in the data
	3,							// Dimension in v direction (order)
	&ctrlPoints[0][0][0]);		// array of control points

	// Enable the evaluator
	glEnable(GL_MAP2_VERTEX_3);

	// Use higher level functions to map to a grid, then evaluate the
	// entire thing.
   
	static GLfloat s_vector[4] = { 0.22f, 0.0, 0.0, 0.0 };
    static GLfloat t_vector[4] = { 0.0, 0.165f, 0.0, 0.0 };
//	static GLfloat s_vector[4] = { 0.24, 0.0, 0.0, 0.0 };
//    static GLfloat t_vector[4] = { 0.0, 0.165, 0.0, 0.0 };
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_vector);

    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_vector);

    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);

	// Map a grid of 10 points from 0 to 10
	glMapGrid2f(25,0.0f,25.0f,25,0.0f,25.0f);

	// Evaluate the grid, using lines
	glEvalMesh2(GL_FILL,0,25,0,25);

    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);

	// Rückseite
	bloweroffset = -0.3f;
	bloweroffset*= fScale;

	GLfloat ctrlPoints2[3][3][3]=  {{
		{  bupperwidth / 2.0f,  bheight / 2.0f,  0.0f},
		{  ((bupperwidth+blowerwidth) / 2.0f + (bupperwidth-blowerwidth) /2.0f *bround) * bsround,  (bheight / 2.0f) * bhround,  -bround + bloweroffset * ((-bhround + 1) / 2.0f)},	
		{  blowerwidth / 2.0f, -bheight / 2.0f,  bloweroffset}
		},

		{
		{  0.0f,  bheight / 2.0f,  0.0f},
		{  0.0f,  (bheight / 2.0f) * bhround,  -bround * broundmid + bloweroffset * ((-bhround + 1) / 2.0f)} ,	
		{  0.0f,  -bheight / 2.0f,  bloweroffset}
		},
		
		{
		{  -bupperwidth / 2.0f,  bheight / 2.0f,  0.0f},
		{  -((bupperwidth+blowerwidth) / 2.0f + (bupperwidth-blowerwidth) /2.0f *bround) * bsround,  (bheight / 2.0f) * bhround, -bround + bloweroffset * ((-bhround + 1) / 2.0f)},	
		{  -blowerwidth / 2.0f, -bheight / 2.0f,   bloweroffset}
		}};




#ifdef ShowBezierPoints
	// Set point size larger to make more visible
	glPointSize(5.0f);

	// Loop through all control points for this example
	glDisable(GL_TEXTURE);
	glBegin(GL_POINTS);
		for(i = 0; i < nNumPoints; i++)
			for(j = 0; j < 3; j++)
				glVertex3fv(ctrlPoints2[i][j]);
	glEnd();
#endif

	// Sets up the Bezier
	// This actually only needs to be called once and could go in
	// the setup function

	glMap2f(GL_MAP2_VERTEX_3,	// Type of data generated
	0.0f,						// Lower u range
	25.0f,						// Upper u range
	3,							// Distance between points in the data
	3,							// Dimension in u direction (order)
	0.0f,						// Lover v range
	25.0f,						// Upper v range
	9,							// Distance between points in the data
	3,							// Dimension in v direction (order)
	&ctrlPoints2[0][0][0]);		// array of control points

	// Enable the evaluator
	glEnable(GL_MAP2_VERTEX_3);

	// Use higher level functions to map to a grid, then evaluate the
	// entire thing.
   
// 	static GLfloat s_vector[4] = { 2.0, 0.0, 0.0, 0.0 };
//  static GLfloat t_vector[4] = { 0.0, 1.0, 0.0, 0.0 };
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_vector);

    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_vector);

    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);

	// Map a grid of 25 points from 0 to 25
	glMapGrid2f(25,0.0f,25.0f,25,0.0f,25.0f);

	// Evaluate the grid, using lines
	glEvalMesh2(GL_FILL,0,25,0,25);

    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);

	GLfloat ctrlPoints3[3][3][3];
	
	GLfloat lowerround = 0.4f;

	ctrlPoints3[0][0][0] = ctrlPoints[2][0][0];
	ctrlPoints3[0][0][1] = ctrlPoints[2][0][1];
	ctrlPoints3[0][0][2] = ctrlPoints[2][0][2];
	ctrlPoints3[0][1][0] = ctrlPoints[2][1][0];
	ctrlPoints3[0][1][1] = ctrlPoints[2][1][1];
	ctrlPoints3[0][1][2] = ctrlPoints[2][1][2];
	ctrlPoints3[0][2][0] = ctrlPoints[2][2][0];
	ctrlPoints3[0][2][1] = ctrlPoints[2][2][1];
	ctrlPoints3[0][2][2] = ctrlPoints[2][2][2];

	ctrlPoints3[2][0][0] = ctrlPoints2[0][0][0];
	ctrlPoints3[2][0][1] = ctrlPoints2[0][0][1];
	ctrlPoints3[2][0][2] = ctrlPoints2[0][0][2];
	ctrlPoints3[2][1][0] = ctrlPoints2[0][1][0];
	ctrlPoints3[2][1][1] = ctrlPoints2[0][1][1];
	ctrlPoints3[2][1][2] = ctrlPoints2[0][1][2];
	ctrlPoints3[2][2][0] = ctrlPoints2[0][2][0];
	ctrlPoints3[2][2][1] = ctrlPoints2[0][2][1];
	ctrlPoints3[2][2][2] = ctrlPoints2[0][2][2];

	ctrlPoints3[1][0][0] = (ctrlPoints3[0][0][0] + ctrlPoints3[2][0][0]) * 0.5f;
	ctrlPoints3[1][0][1] = (ctrlPoints3[0][0][1] + ctrlPoints3[2][0][1]) * 0.5f;
	ctrlPoints3[1][0][2] = (ctrlPoints3[0][0][2] + ctrlPoints3[2][0][2]) * 0.5f;
	ctrlPoints3[1][1][0] = (ctrlPoints3[0][1][0] + ctrlPoints3[2][1][0]) * 0.5f + lowerround * 0.5f;
	ctrlPoints3[1][1][1] = (ctrlPoints3[0][1][1] + ctrlPoints3[2][1][1]) * 0.5f;
	ctrlPoints3[1][1][2] = (ctrlPoints3[0][1][2] + ctrlPoints3[2][1][2]) * 0.5f;
	ctrlPoints3[1][2][0] = (ctrlPoints3[0][2][0] + ctrlPoints3[2][2][0]) * 0.5f + lowerround;
	ctrlPoints3[1][2][1] = (ctrlPoints3[0][2][1] + ctrlPoints3[2][2][1]) * 0.5f;
	ctrlPoints3[1][2][2] = (ctrlPoints3[0][2][2] + ctrlPoints3[2][2][2]) * 0.5f;

#ifdef ShowBezierPoints
	int i,j;	// Counting variables

	// Set point size larger to make more visible
	glPointSize(5.0f);

	// Loop through all control points for this example
	glDisable(GL_LIGHTING);
	glDisable(GL_TEXTURE);
	glBegin(GL_POINTS);
		for(i = 0; i < nNumPoints; i++)
			for(j = 0; j < 3; j++)
				glVertex3fv(ctrlPoints3[i][j]);
	glEnd();
#endif

	// Sets up the Bezier
	// This actually only needs to be called once and could go in
	// the setup function

	glMap2f(GL_MAP2_VERTEX_3,	// Type of data generated
	0.0f,						// Lower u range
	15.0f,						// Upper u range
	3,							// Distance between points in the data
	3,							// Dimension in u direction (order)
	0.0f,						// Lover v range
	15.0f,						// Upper v range
	9,							// Distance between points in the data
	3,							// Dimension in v direction (order)
	&ctrlPoints3[0][0][0]);		// array of control points

	// Enable the evaluator
	glEnable(GL_MAP2_VERTEX_3);

	// Use higher level functions to map to a grid, then evaluate the
	// entire thing.
   
// 	static GLfloat s_vector[4] = { 2.0, 0.0, 0.0, 0.0 };
//  static GLfloat t_vector[4] = { 0.0, 1.0, 0.0, 0.0 };
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_vector);

    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_vector);

    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);

	// Map a grid of 20 points from 0 to 20
	glMapGrid2f(15,0.0f,15.0f,15,0.0f,15.0f);

	// Evaluate the grid, using lines
	glEvalMesh2(GL_FILL,0,15,0,15);

    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);	

	GLfloat ctrlPoints4[3][3][3];
	
	ctrlPoints4[2][0][0] = ctrlPoints[0][0][0];
	ctrlPoints4[2][0][1] = ctrlPoints[0][0][1];
	ctrlPoints4[2][0][2] = ctrlPoints[0][0][2];
	ctrlPoints4[2][1][0] = ctrlPoints[0][1][0];
	ctrlPoints4[2][1][1] = ctrlPoints[0][1][1];
	ctrlPoints4[2][1][2] = ctrlPoints[0][1][2];
	ctrlPoints4[2][2][0] = ctrlPoints[0][2][0];
	ctrlPoints4[2][2][1] = ctrlPoints[0][2][1];
	ctrlPoints4[2][2][2] = ctrlPoints[0][2][2];

	ctrlPoints4[0][0][0] = ctrlPoints2[2][0][0];
	ctrlPoints4[0][0][1] = ctrlPoints2[2][0][1];
	ctrlPoints4[0][0][2] = ctrlPoints2[2][0][2];
	ctrlPoints4[0][1][0] = ctrlPoints2[2][1][0];
	ctrlPoints4[0][1][1] = ctrlPoints2[2][1][1];
	ctrlPoints4[0][1][2] = ctrlPoints2[2][1][2];
	ctrlPoints4[0][2][0] = ctrlPoints2[2][2][0];
	ctrlPoints4[0][2][1] = ctrlPoints2[2][2][1];
	ctrlPoints4[0][2][2] = ctrlPoints2[2][2][2];

	ctrlPoints4[1][0][0] = (ctrlPoints4[0][0][0] + ctrlPoints4[2][0][0]) * 0.5f;
	ctrlPoints4[1][0][1] = (ctrlPoints4[0][0][1] + ctrlPoints4[2][0][1]) * 0.5f;
	ctrlPoints4[1][0][2] = (ctrlPoints4[0][0][2] + ctrlPoints4[2][0][2]) * 0.5f;
	ctrlPoints4[1][1][0] = (ctrlPoints4[0][1][0] + ctrlPoints4[2][1][0]) * 0.5f - lowerround * 0.5f;
	ctrlPoints4[1][1][1] = (ctrlPoints4[0][1][1] + ctrlPoints4[2][1][1]) * 0.5f;
	ctrlPoints4[1][1][2] = (ctrlPoints4[0][1][2] + ctrlPoints4[2][1][2]) * 0.5f;
	ctrlPoints4[1][2][0] = (ctrlPoints4[0][2][0] + ctrlPoints4[2][2][0]) * 0.5f - lowerround;
	ctrlPoints4[1][2][1] = (ctrlPoints4[0][2][1] + ctrlPoints4[2][2][1]) * 0.5f;
	ctrlPoints4[1][2][2] = (ctrlPoints4[0][2][2] + ctrlPoints4[2][2][2]) * 0.5f;


#ifdef ShowBezierPoints
	int i,j;	// Counting variables

	// Set point size larger to make more visible
	glPointSize(5.0f);

	// Loop through all control points for this example
	glDisable(GL_LIGHTING);
	glDisable(GL_TEXTURE);
	glBegin(GL_POINTS);
		for(i = 0; i < nNumPoints; i++)
			for(j = 0; j < 3; j++)
				glVertex3fv(ctrlPoints4[i][j]);
	glEnd();
#endif

	// Sets up the Bezier
	// This actually only needs to be called once and could go in
	// the setup function

	glMap2f(GL_MAP2_VERTEX_3,	// Type of data generated
	0.0f,						// Lower u range
	15.0f,						// Upper u range
	3,							// Distance between points in the data
	3,							// Dimension in u direction (order)
	0.0f,						// Lover v range
	15.0f,						// Upper v range
	9,							// Distance between points in the data
	3,							// Dimension in v direction (order)
	&ctrlPoints4[0][0][0]);		// array of control points

	// Enable the evaluator
	glEnable(GL_MAP2_VERTEX_3);

	// Use higher level functions to map to a grid, then evaluate the
	// entire thing.
   
// 	static GLfloat s_vector[4] = { 2.0, 0.0, 0.0, 0.0 };
//  static GLfloat t_vector[4] = { 0.0, 1.0, 0.0, 0.0 };
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_S, GL_OBJECT_PLANE, s_vector);

    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenfv(GL_T, GL_OBJECT_PLANE, t_vector);

    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);

	// Map a grid of 15 points from 0 to 15
	glMapGrid2f(15,0.0f,15.0f,15,0.0f,15.0f);

	// Evaluate the grid, using lines
	glEvalMesh2(GL_FILL,0,15,0,15);

    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_AUTO_NORMAL);
	
	glFrontFace(GL_CCW);
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glEndList();



	dlLightIsle = nPartList++;
	glNewList(dlLightIsle, GL_COMPILE);
#define LIGHT_ISLE_EDGES 35
#define LIGHT_ISLE_TESS  3
#define LIGHT_ISLE_RADIUS 0.7
		glPushMatrix();
		glRotatef(90, 1.0f, 0.0f, 0.0f);
		DrawPlate(LIGHT_ISLE_RADIUS, LIGHT_ISLE_TESS, LIGHT_ISLE_EDGES);
		glRotatef(180, 1.0f, 0.0f, 0.0f);
		glTranslatef(0.0f, 0.0f , -0.25f);
		DrawPlate(LIGHT_ISLE_RADIUS, LIGHT_ISLE_TESS, LIGHT_ISLE_EDGES);
		glRotatef(180, 1.0f, 0.0f, 0.0f);
		glTranslatef(0.0f, 0.0f, -0.125f);
		DrawCylinder(LIGHT_ISLE_RADIUS, 0.25, LIGHT_ISLE_EDGES, true);
		glPopMatrix();
	glEndList();
	
#define GROUND_EDGES  64
#define GROUND_TESS   7
#define GROUND_RADIUS 3.5
	dlGround = nPartList++;
	glNewList(dlGround, GL_COMPILE);
		glPushMatrix();
		glRotatef(90, 1.0f, 0.0f, 0.0f);
		DrawPlate(GROUND_RADIUS, GROUND_TESS, GROUND_EDGES);
		glRotatef(180, 1.0f, 0.0f, 0.0f);
		glTranslatef(0.0f, 0.0f , -0.25f);
		DrawPlate(GROUND_RADIUS, GROUND_TESS, GROUND_EDGES);
		glRotatef(180, 1.0f, 0.0f, 0.0f);
		glTranslatef(0.0f, 0.0f, -0.125f);
		DrawCylinder(GROUND_RADIUS, 0.25, GROUND_EDGES, true);
		glPopMatrix();
	glEndList();

	dlLight = nPartList++;
	glNewList(dlLight, GL_COMPILE);
	glBegin(GL_QUADS);
	//rechts vorne
		glNormal3d(0.0f, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
	//rechts innen
		glNormal3d(-1.0f, 0.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(SPOT_FRONT_WIDTH / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
	//links vorne
		glNormal3d(0.0f, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
	//rechts innen
		glNormal3d(1.0f, 0.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				   );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				   );

	// oben vorne
		glNormal3d(0.0f, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	// oben innen
		glNormal3d(0.0f, -1.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	// unten vorne
		glNormal3d(0.0f, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	// unten innen
		glNormal3d(0.0f, 1.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH /2.0 - SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH /2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0 + SPOT_FATNESS) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0 - SPOT_DEPT) * SPOT_SCALE
				  );
	// LINKE SEITE
		glNormal3d(-1.0f, 0.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(-SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(-SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(-SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	// RECHTE SEITE
		glNormal3d(1.0f, 0.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d(
					(+SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d(
					(+SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d(
					(+SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	// OBEN
		glNormal3d(0.0f, 1.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d( 
					(-SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d( 
					(+SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d( 
					(+SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d( 
					(-SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	// UNTEN
		glNormal3d(0.0f, -1.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d( 
					(-SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d( 
					(+SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d( 
					(+SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d( 
					(-SPOT_FRONT_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_FRONT_HEIGHT / 2.0) * SPOT_SCALE,
					(SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	// HINTEN
		glNormal3d(0.0f, 0.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d( 
					(-SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d( 
					(+SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(+SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d( 
					(+SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d( 
					(-SPOT_BACK_WIDTH / 2.0) * SPOT_SCALE,
					(-SPOT_BACK_HEIGHT / 2.0) * SPOT_SCALE,
					(-SPOT_DIAMETER / 2.0) * SPOT_SCALE
				  );
	glEnd();
	glEndList();

	InitBALogo();
}

////////////////////////////////////////////////////////////////////
/// void LightInit()
////////////////////////////////////////////////////////////////////
//  Setzen der Lichtparameter
void LightInit() {
#define SPOT_CUTOFF 60.0f
#define SPOT_EXPONENT 10.0f
	GLfloat Light0Ambient[]=  { 0.5f, 0.5f, 0.5f, 1.0f }; 				 // Ambient Light Values 
	GLfloat Light0Diffuse[]=  { 0.0f, 0.0f, 0.0f, 1.0f };				 // Diffuse Light Values 
	GLfloat Light0Specular[]= { 0.0f, 0.0f, 0.0f, 1.0f };				 // Diffuse Light Values 
	GLfloat Light0Position[]= { 0.0f, -3.0f, -3.0f, 1.0f };				 // Light Position 

	GLfloat LiSp1[]= { 1.0f, 1.0f, 1.0f, 1.0f };	

	glLightfv(GL_LIGHT0, GL_AMBIENT,  Light0Ambient);				// Setup The Ambient Light
	glLightfv(GL_LIGHT0, GL_DIFFUSE,  Light0Diffuse);				// Setup The Diffuse Light
	glLightfv(GL_LIGHT0, GL_SPECULAR, Light0Specular);				// Setup The Specular Light
	glLightfv(GL_LIGHT0, GL_POSITION, Light0Position);				// Position The Light

	// Specular light color
	// BASS = red
	Light1_Base_Color[0] =  1.0f;
	Light1_Base_Color[1] =  0.0f;
	Light1_Base_Color[2] =  0.0f;
	Light1_Base_Color[3] =  1.0f;

	// MID = yellow
	Light2_Base_Color[0] =  1.0f;
	Light2_Base_Color[1] =  1.0f;
	Light2_Base_Color[2] =  0.0f;
	Light2_Base_Color[3] =  1.0f;

	// HIGH = ?pink?
	Light3_Base_Color[0] =  1.0f;
	Light3_Base_Color[1] =  0.78f;
	Light3_Base_Color[2] =  0.58f;
	Light3_Base_Color[3] =  1.0f;

	GLfloat LightAmbient[]=   { 0.0f, 0.0f, 0.0f, 1.0f }; 				 // Ambient Light Values 
	GLfloat LightDiffuse[]=   { 0.0f, 0.0f, 0.0f, 1.0f };				 // Diffuse Light Values 
	GLfloat LightSpecular[]=  { 0.0f, 0.0f, 0.0f, 1.0f };				 // Diffuse Light Values 

	glLightfv(GL_LIGHT1, GL_AMBIENT,  LightAmbient);				// Setup The Ambient Light
	glLightfv(GL_LIGHT1, GL_DIFFUSE,  LightDiffuse);				// Setup The Diffuse Light
	glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular);				// Setup The Diffuse Light
	glLightfv(GL_LIGHT2, GL_AMBIENT,  LightAmbient);				// Setup The Ambient Light
	glLightfv(GL_LIGHT2, GL_DIFFUSE,  LightDiffuse);				// Setup The Diffuse Light
	glLightfv(GL_LIGHT2, GL_SPECULAR, LightSpecular);				// Setup The Diffuse Light
	glLightfv(GL_LIGHT3, GL_AMBIENT,  LightAmbient);				// Setup The Ambient Light
	glLightfv(GL_LIGHT3, GL_DIFFUSE,  LightDiffuse);				// Setup The Diffuse Light
	glLightfv(GL_LIGHT3, GL_SPECULAR, LightSpecular);				// Setup The Diffuse Light

	GLfloat MatSpecular[]=  { 1.0f, 1.0f, 1.0f, 1.0f };				 // Diffuse Light Values 
	glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpecular);
	glMateriali(GL_FRONT, GL_SHININESS, 128);

	glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, SPOT_CUTOFF);
	glLightf(GL_LIGHT1, GL_SPOT_EXPONENT,SPOT_EXPONENT);
	glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, SPOT_CUTOFF);
	glLightf(GL_LIGHT2, GL_SPOT_EXPONENT,SPOT_EXPONENT);
	glLightf(GL_LIGHT3, GL_SPOT_CUTOFF, SPOT_CUTOFF);
	glLightf(GL_LIGHT3, GL_SPOT_EXPONENT,SPOT_EXPONENT);

	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHT2);
	glEnable(GL_LIGHT3);

	light0_power = 0.0;
	light1_power = 0.0;
	light2_power = 0.0;
	light3_power = 0.0;
}

////////////////////////////////////////////////////////////////////
/// void LightPar()
////////////////////////////////////////////////////////////////////
//  Lichtparameter
void LightPar() {
#define LIGHT_CORR 0.05f
#define LIGHT_AMBIENT_MIN 0.8
#define LIGHT_EQ_ADD	  0.8
#define LIGHT_EQ_AMBIENT  0.6
#define LIGHT1_OLD		  3.0
#define LIGHT2_OLD		  3.0
#define LIGHT3_OLD		  3.0


#ifdef EnableSound
	DWORD b1;		
	g_pStreamingSound->GetBuffer(0)->GetCurrentPosition(&b1, NULL);
#ifdef BmpOutput
	b1 = (int)((ActTime / 1000.0) * 44100.0 * (16.0 / 8.0) * 2.0);
#endif
	b1 /= 4;
	__int16* FFTData = g_pWaveFFT->GetAnalysedData();
	light1_power = ((double) (FFTData[(b1 / 1024) * 3]     / EQ_MAXHEIGHT / EQ_HIGHT_DIV) + light1_power * LIGHT1_OLD) / (1.0 + LIGHT1_OLD);
	light2_power = ((double) (FFTData[(b1 / 1024) * 3 + 1] / EQ_MAXHEIGHT / EQ_HIGHT_DIV) + light2_power * LIGHT2_OLD) / (1.0 + LIGHT2_OLD);
	light3_power = ((double) (FFTData[(b1 / 1024) * 3 + 2] / EQ_MAXHEIGHT / EQ_HIGHT_DIV) + light3_power * LIGHT3_OLD) / (1.0 + LIGHT3_OLD); 
/*
	light1_power = ((double) sqrt(FFTData[(b1 / 1024) * 3]     / EQ_MAXHEIGHT / EQ_HIGHT_DIV) + light1_power * LIGHT1_OLD) / (1.0 + LIGHT1_OLD);
	light2_power = ((double) sqrt(FFTData[(b1 / 1024) * 3 + 1] / EQ_MAXHEIGHT / EQ_HIGHT_DIV) + light2_power * LIGHT2_OLD) / (1.0 + LIGHT2_OLD);
	light3_power = ((double) sqrt(FFTData[(b1 / 1024) * 3 + 2] / EQ_MAXHEIGHT / EQ_HIGHT_DIV) + light3_power * LIGHT3_OLD) / (1.0 + LIGHT3_OLD); 
*/
    light0_power = sqrt(sqrt((light1_power * light1_power * light1_power * light1_power + light2_power * light2_power * light2_power * light2_power + light3_power * light3_power *  light3_power * light3_power))) / 3.0;
	light0_power = LIGHT_AMBIENT_MIN + light0_power * LIGHT_EQ_ADD;

	float Light0Ambient[]=   {(float) (Light0_Ambient[0] = (light0_power + light1_power * LIGHT_EQ_AMBIENT)), 
							  (float) (Light0_Ambient[1] = (light0_power + light2_power * LIGHT_EQ_AMBIENT)), 
							  (float) (Light0_Ambient[2] = (light0_power + light3_power * LIGHT_EQ_AMBIENT)), 
							           1.0f}; 							// Ambient Light Values 
	glLightfv(GL_LIGHT0, GL_AMBIENT, Light0Ambient);					// Setup The Ambient Light
#endif

#ifndef EnableSound
	light0_power = 1.0;
	light1_power = 1.0;
	light2_power = 1.0;
	light3_power = 1.0;
	Light0_Ambient[0] = 1.0;
	Light0_Ambient[1] = 1.0;
	Light0_Ambient[2] = 1.0;
	Light0_Ambient[3] = 1.0;
#endif

	glPushMatrix();
	glTranslatef(0.0f, -3.0f, 0.0f);
	glRotatef(-angle / 17.0f, 0.0f, 1.0f, 0.0f);
	glPushMatrix();
	glPushMatrix();
	glTranslatef(0.0f, SPOT_ABOVE_ZERO, -LIGHT_ISLE_DISTANCE);
	glRotated(SPOT_ANGLE, -1.0, 0.0, 0.0);

	GLfloat Light1Position[]=  { 0.0f, 0.0f, LIGHT_CORR, 1.0f };		 // Light Position 
	GLfloat Light1Diffuse[]=   { (float) (Light1_Base_Color[0] * light1_power),
								 (float) (Light1_Base_Color[1] * light1_power),
								 (float) (Light1_Base_Color[2] * light1_power),
										  1.0f };							// Diffuse Light Values 
	GLfloat Light1Specular[]=  { (float) (Light1_Base_Color[0] * light1_power),
								 (float) (Light1_Base_Color[1] * light1_power), 
								 (float) (Light1_Base_Color[2] * light1_power), 
										  1.0f };							// Specular Light Values 
	GLfloat Light1Direction[]= { 0.0f, 0.0f, 1.0f, 1.0f};				 // Light Direction
	glLightfv(GL_LIGHT1, GL_DIFFUSE,		Light1Diffuse);
	glLightfv(GL_LIGHT1, GL_SPECULAR,		Light1Specular);			 // Setup The Specular Light
	glLightfv(GL_LIGHT1, GL_POSITION,		Light1Position);
	glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, Light1Direction);
#ifdef ShowLights
	glDisable(GL_LIGHTING);
	glDisable(GL_TEXTURE_2D);
	glPointSize(4.0f);	
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glBegin(GL_POINTS);
		glVertex3fv(Light1Position);
	glEnd();
	glBegin(GL_LINES);
		glVertex3fv(Light1Position);
		glVertex3f( Light1Position[0] + Light1Direction[0],
					Light1Position[1] + Light1Direction[1],
					Light1Position[2] + Light1Direction[2]);
	glEnd();
#endif
	glPopMatrix();
	glRotatef(120, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0f, SPOT_ABOVE_ZERO , -LIGHT_ISLE_DISTANCE);
	glRotated(SPOT_ANGLE, -1.0, 0.0, 0.0);
	GLfloat Light2Position[]=	{ 0.0f, 0.0f, LIGHT_CORR, 1.0f };		 // Light Position 
	GLfloat Light2Diffuse[]=	{ (float) (Light2_Base_Color[0] * light2_power), 
								  (float) (Light2_Base_Color[1] * light2_power), 
								  (float) (Light2_Base_Color[2] * light2_power), 
										   1.0f };						 // Diffuse Light Values 
	GLfloat Light2Specular[]=	{ (float) (Light2_Base_Color[0] * light2_power), 
								  (float) (Light2_Base_Color[1] * light2_power), 
								  (float) (Light2_Base_Color[2] * light2_power), 
										   1.0f };						 // Specular Light Values 
	GLfloat Light2Direction[]=	{ 0.0f, 0.0f, 1.0f, 1.0f};				 // Light Direction
	glLightfv(GL_LIGHT2, GL_DIFFUSE,		Light2Diffuse);
	glLightfv(GL_LIGHT2, GL_SPECULAR,		Light2Specular);			 // Setup The Specular Light
	glLightfv(GL_LIGHT2, GL_POSITION,		Light2Position);
	glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION, Light2Direction);
#ifdef ShowLights
	glBegin(GL_POINTS);
		glVertex3fv(Light2Position);
	glEnd();
	glBegin(GL_LINES);
		glVertex3fv(Light2Position);
		glVertex3f( Light2Position[0] + Light2Direction[0],
					Light2Position[1] + Light2Direction[1],
					Light2Position[2] + Light2Direction[2]);
	glEnd();
#endif

	glPopMatrix();
	glRotatef(-120, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0f, SPOT_ABOVE_ZERO , -LIGHT_ISLE_DISTANCE);
	glRotated(SPOT_ANGLE, -1.0, 0.0, 0.0);
	GLfloat Light3Position[]=	{ 0.0f, 0.0f, LIGHT_CORR, 1.0f };		 // Light Position 
	GLfloat Light3Diffuse[]=	{ (float) (Light3_Base_Color[0] * light3_power),
								  (float) (Light3_Base_Color[1] * light3_power),
								  (float) (Light3_Base_Color[2] * light3_power),
										   1.0f };						// Diffuse Light Values 
	GLfloat Light3Specular[]=	{ (float) (Light3_Base_Color[0] * light3_power),
								  (float) (Light3_Base_Color[1] * light3_power),
								  (float) (Light3_Base_Color[2] * light3_power), 
										   1.0f };						 // Specular Light Values 
	GLfloat Light3Direction[]=	{ 0.0f, 0.0f, 1.0f, 1.0f};				 // Light Direction
	glLightfv(GL_LIGHT3, GL_DIFFUSE,		Light3Diffuse);
	glLightfv(GL_LIGHT3, GL_SPECULAR,		Light3Specular);			 // Setup The Specular Light
	glLightfv(GL_LIGHT3, GL_POSITION,		Light3Position);
	glLightfv(GL_LIGHT3,GL_SPOT_DIRECTION,	Light3Direction);
#ifdef ShowLights
	glBegin(GL_POINTS);
		glVertex3fv(Light3Position);
	glEnd();
	glBegin(GL_LINES);
		glVertex3fv(Light3Position);
		glVertex3f( Light3Position[0] + Light3Direction[0],
					Light3Position[1] + Light3Direction[1],
					Light3Position[2] + Light3Direction[2]);
	glEnd();
	glEnable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glPointSize(1.0f);	
#endif
	glPopMatrix();
}

/*
 * SaveDIBitmap() - Save a BMP file to disk.
 *
 * Returns 0 on success or -1 or -2 on failure...
 */

int                                /* O - 0 = success, -1 = failure, -2 File kann nicht geoeffnet werden */
SaveDIBitmap(const char *filename, /* I - File to load */
             BITMAPINFO *info,     /* I - Bitmap information */
	         GLubyte    *bits)     /* I - Bitmap data */
    {
    FILE             *fp;          /* Open file pointer */
    int              size,         /* Size of file */
                     infosize,     /* Size of bitmap info */
                     bitsize;      /* Size of bitmap pixels */
    BITMAPFILEHEADER header;       /* File header */


    /* Try opening the file; use "wb" mode to write this *binary* file. */
    if ((fp = fopen(filename, "wb")) == NULL)
        return (-2);

    /* Figure out the bitmap size */
    if (info->bmiHeader.biSizeImage == 0)
	bitsize = (info->bmiHeader.biWidth *
        	   info->bmiHeader.biBitCount + 7) / 8 *
		  abs(info->bmiHeader.biHeight);
    else
	bitsize = info->bmiHeader.biSizeImage;

    /* Figure out the header size */
    infosize = sizeof(BITMAPINFOHEADER);
    switch (info->bmiHeader.biCompression)
	{
	case BI_BITFIELDS :
            infosize += 12; /* Add 3 RGB doubleword masks */
            if (info->bmiHeader.biClrUsed == 0)
	      break;
	case BI_RGB :
            if (info->bmiHeader.biBitCount > 8 &&
        	info->bmiHeader.biClrUsed == 0)
	      break;
	case BI_RLE8 :
	case BI_RLE4 :
            if (info->bmiHeader.biClrUsed == 0)
              infosize += (1 << info->bmiHeader.biBitCount) * 4;
	    else
              infosize += info->bmiHeader.biClrUsed * 4;
	    break;
	}

    size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;

    /* Write the file header, bitmap information, and bitmap pixel data... */
    header.bfType      = 'MB'; /* Non-portable... sigh */
    header.bfSize      = size;
    header.bfReserved1 = 0;
    header.bfReserved2 = 0;
    header.bfOffBits   = sizeof(BITMAPFILEHEADER) + infosize;

    if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER))
        {
        /* Couldn't write the file header - return... */
        fclose(fp);
        return (-1);
        }

    if ((signed)fwrite(info, 1, infosize, fp) < infosize)
        {
        /* Couldn't write the bitmap header - return... */
        fclose(fp);
        return (-1);
        }

    if ((signed)fwrite(bits, 1, bitsize, fp) < bitsize)
        {
        /* Couldn't write the bitmap - return... */
        fclose(fp);
        return (-1);
        }

    /* OK, everything went fine - return... */
    fclose(fp);
    return (0);
    }


/* ReadDIBitmap() - Read the current OpenGL viewport into a 24-bit RGB bitmap.
   Returns the bitmap pixels if successful and NULL otherwise.*/

GLubyte *	/* 0 - Bitmap data */ 
ReadDIBitmap(BITMAPINFO **info) /* 0 - Bitmap information */
{
	long	
	bitsize,	/* Total size of bitmap */
	width;	/* Aligned width of a scanline */
	GLint	viewport[4];	/* Current viewport */
	GLubyte *bits;	/* RGB bits */

/* Grab the current viewport... */ 
glGetIntegerv(GL_VIEWPORT, viewport);

/* Allocate memory for the header and bitmap... */

if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER))) == NULL) 
	{
	/* Couldn't allocate memory for bitmap info - return NULL... */ 
	return (NULL);
	}

width	= viewport[2] * 3;	/* Real width of scanline */ 
width	= (width + 3) & -3;	/* Aligned to 4 bytes */ 
bitsize = width * viewport[3]; /* Size of bitmap, aligned */
if ((bits = (GLubyte*)calloc(bitsize, 1)) == NULL)
	{
	//Couldn't allocate memory for bitmap pixels - return NULL...
	free(*info);
	return (NULL);
	}
/*if ((bits = (GLubyte*)malloc(bitsize)) == NULL)
	{
	//Couldn't allocate memory for bitmap pixels - return NULL...
	free(*info);
	return (NULL);
	}*/
/* Read pixels from the frame buffer...	*/
glFinish();	/* Finish all OpenGL commands */ 
glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */ 
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0); 
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

glReadPixels(0, 0, viewport[2], viewport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, bits) ;

/* Finally, initialize the bitmap header information... */ 
(*info)->bmiHeader.biSize	= sizeof(BITMAPINFOHEADER); 
(*info)->bmiHeader.biWidth	= viewport[2];
(*info)->bmiHeader.biHeight	= viewport[3];
(*info)->bmiHeader.biPlanes	= 1;
(*info)->bmiHeader.biBitCount	= 24;
(*info)->bmiHeader.biCompression	= BI_RGB; 
(*info)->bmiHeader.biSizeImage	= bitsize; 
(*info)->bmiHeader.biXPelsPerMeter = 2952; /* 75 DPI */ 
(*info)->bmiHeader.biYPelsPerMeter = 2952; /* 75 DPI */ 
(*info)->bmiHeader.biClrUsed	= 0; 
(*info)->bmiHeader.biClrImportant = 0;
return (bits);
}


//-----------------------------------------------------------------------------
// Name: LoadWaveAndCreateBuffer()
// Desc: Loads the wave file, and create a DirectSound buffer.  Since we are
//       streaming data into the buffer, the buffer will be filled with data 
//       when the sound is played, and as notification events are signaled
//-----------------------------------------------------------------------------
VOID LoadWaveAndCreateBuffer( HWND hDlg, TCHAR* strFileName )
{
    HRESULT   hr;
    CWaveFile waveFile;
    DWORD     dwNotifySize;

    // Load the wave file
    if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) )
    {
        DXTRACE_ERR( TEXT("Open"), hr );
        waveFile.Close();
//        SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Bad wave file.") );
        return;
    }

    if( waveFile.GetSize() == 0 )
    {
        waveFile.Close();
//        SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Wave file blank.") );
        return;
    }

    // The wave file is valid, and waveFile.m_pwfx is the wave's format
    // so we are done with the reader.
    waveFile.Close();

    // This samples works by dividing a 3 second streaming buffer into 
    // NUM_PLAY_NOTIFICATIONS (16) pieces.  It creates a notification for each
    // piece and when a notification arrives then it fills the circular streaming 
    // buffer with new wav data over the sound data which was just played

    // Determine the g_dwNotifySize.  It should be an integer multiple of nBlockAlign
    DWORD nBlockAlign = (DWORD)waveFile.m_pwfx->nBlockAlign;
    INT nSamplesPerSec = waveFile.m_pwfx->nSamplesPerSec;
//m    dwNotifySize = nSamplesPerSec * 3 * nBlockAlign / NUM_PLAY_NOTIFICATIONS;
//m    dwNotifySize -= dwNotifySize % nBlockAlign;   
	dwNotifySize = waveFile.GetSize();

    // Create a new sound
    SAFE_DELETE( g_pStreamingSound );

    // Set up the direct sound buffer.  Request the NOTIFY flag, so
    // that we are notified as the sound buffer plays.  Note, that using this flag
    // may limit the amount of hardware acceleration that can occur. 
    if( FAILED( hr = g_pSoundManager->CreateStreaming( &g_pStreamingSound, strFileName, 
                                                  DSBCAPS_GETCURRENTPOSITION2, 
                                                  GUID_NULL, NUM_PLAY_NOTIFICATIONS, 
                                                  dwNotifySize, g_hNotificationEvent ) ) )
    {
        if( hr != DSERR_BADFORMAT && hr != E_INVALIDARG )
            DXTRACE_ERR( TEXT("CreateStreaming"), hr );

//        SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Could not create sound buffer.") );
        return;
    }

    // Update the UI controls to show the sound as the file is loaded
//    EnablePlayUI( hDlg, TRUE );
//    SetDlgItemText( hDlg, IDC_FILENAME, strFileName );
}




//-----------------------------------------------------------------------------
// Name: PlayBuffer()
// Desc: Reset the buffer, fill it with sound, and starting it playing
//-----------------------------------------------------------------------------
HRESULT PlayBuffer( BOOL bLooped )
{
    HRESULT hr;
    
    if( NULL == g_pStreamingSound )
        return E_FAIL; // Sanity check

    if( FAILED( hr = g_pStreamingSound->Reset() ) )
        return DXTRACE_ERR( TEXT("Reset"), hr );

    // Fill the entire buffer with wave data, and if the wav file is small then
    // repeat the wav file if the user wants to loop the file, otherwise fill in
    // silence 
    LPDIRECTSOUNDBUFFER pDSB = g_pStreamingSound->GetBuffer( 0 );
    if( FAILED( hr = g_pStreamingSound->FillBufferWithSound( pDSB, bLooped ) ) )
        return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );

    // Always play with the LOOPING flag since the streaming buffer
    // wraps around before the entire WAV is played
    if( FAILED( hr = g_pStreamingSound->Play( 0, DSBPLAY_LOOPING ) ) )
        return DXTRACE_ERR( TEXT("Play"), hr );

    return S_OK;
}



/* initialisiert das balogo (definiert displaylisten) */
/* Punkteliste und erstes 2d von Klaus Heske und Hendrik Jahnke*/
/* Anpassungen, 3D und Farben von Andreas Moosbrugger */
/* Modified by Snubnose 15.03.03 */

void InitBALogo() {
#ifndef BALOGO_B
#define BALOGO_B 111
#endif
#ifndef BALOGO_A
#define BALOGO_A 1111
#endif
#ifndef BALOGO_AUSSEN
#define BALOGO_AUSSEN 11111
#endif
#ifndef BALOGO_INNEN
#define BALOGO_INNEN 22222
#endif
#ifndef BREITE
#define BREITE (-0.06)
#endif
#ifndef SHINEVAL
#define SHINEVAL 20.0
#endif
  
  // CallList(BALOGO_3D) verwenden um BA_LOGO anzuzeigen
  
  // skalierungsfaktor
  double _x=0.01;
  double _y=0.01;
  
  //Lichtfarben
  GLfloat red[]={1.0f, 0.0f, 0.0f, 1.0f}; 
  GLfloat blue[]={0.0f, 0.0f, 1.0f, 1.0f}; 
  GLfloat green[]={0.0f, 1.0f, 0.0f, 1.0f};
  GLfloat white[]={1.0f, 1.0f, 1.0f, 1.0f}; 
  GLfloat black[]={0.0f, 0.0f, 0.0f, 1.0f};
  
  //punkte
  double  a0[] = {_x*19,_y*1,0.0},
    a1[] = {_x*19,_y*1.5,0.0},
    a2[] = {_x*21,_y*1.5,0.0},
    a3[] = {_x*22,_y*2.5,0.0},
    a4[] = {_x*23,_y*1.5,0.0},
    a5[] = {_x*25.5,_y*1,0.0},
    a6[] = {_x*25.5,_y*1.5,0.0},
    a7[] = {_x*25,_y*9,0.0},
    a8[] = {_x*26,_y*9,0.0},
    a9[] = {_x*26,_y*12.5,0.0},
    a10[] = {_x*27,_y*12.5,0.0},
    a11[] = {_x*29.5,_y*22,0.0},
    a12[] = {_x*29.5,_y*24,0.0},
    a13[] = {_x*30.5,_y*21,0.0},
    a14[] = {_x*30,_y*13,0.0},
    a15[] = {_x*30,_y*10,0.0},
    a16[] = {_x*33,_y*24,0.0},
    a17[] = {_x*33,_y*14,0.0},
    a18[] = {_x*34,_y*11.5,0.0},
    a19[] = {_x*36.5,_y*15,0.0},
    a20[] = {_x*37.5,_y*13,0.0},
    a21[] = {_x*35.5,_y*1.5,0.0},
    a22[] = {_x*35.5,_y*1,0.0},
    a23[] = {_x*37,_y*1.5,0.0},
    a24[] = {_x*37.5,_y*2,0.0},
    a25[] = {_x*41,_y*3,0.0},
    a26[] = {_x*42.5,_y*1.5,0.0},
    a27[] = {_x*45,_y*1.5,0.0},
    a28[] = {_x*45,_y*1,0.0},
    a29[] = {_x*40.5,_y*16.5,0.0},
    a30[] = {_x*41,_y*15.5,0.0},
    a31[] = {_x*44.5,_y*18.5,0.0};
  
  double  b0[] = {_x*0.5,_y*1,0.0},
    b1[] = {_x*0.5,_y*1.5,0.0},
    b2[] = {_x*0.5,_y*23.5,0.0},
    b3[] = {_x*0.5,_y*24,0.0},
    b4[] = {_x*2.5,_y*1.5,0.0},
    b5[] = {_x*3.0,_y*23.5,0.0},
    b6[] = {_x*4,_y*1,0.0},
    b7[] = {_x*4,_y*1.5,0.0},
    b8[] = {_x*4,_y*5.5,0.0},
    b9[] = {_x*4,_y*21.5,0.0},
    b10[] = {_x*4,_y*24,0.0},
    b11[] = {_x*7.5,_y*1,0.0},
    b12[] = {_x*7.5,_y*3.5,0.0},
    b13[] = {_x*7.5,_y*23,0.0},
    b14[] = {_x*7.5,_y*24,0.0},
    b15[] = {_x*8.5,_y*1.5,0.0},
    b16[] = {_x*9,_y*23.5,0.0},
    b17[] = {_x*12,_y*12.5,0.0},
    b18[] = {_x*12,_y*14.5,0.0},
    b19[] = {_x*11.5,_y*23.5,0.0},
    b20[] = {_x*13.5,_y*1.5,0.0},
    b21[] = {_x*13.5,_y*11.5,0.0},
    b22[] = {_x*13,_y*15.5,0.0},
    b23[] = {_x*14.5,_y*15.5,0.0},
    b24[] = {_x*15,_y*24,0.0},
    b25[] = {_x*16,_y*3,0.0},
    b26[] = {_x*16,_y*14.5,0.0},
    b27[] = {_x*16,_y*22,0.0},
    b28[] = {_x*16.5,_y*1,0.0},
    b29[] = {_x*17,_y*14,0.0},
    b30[] = {_x*17,_y*17.5,0.0},
    b31[] = {_x*17,_y*19.5,0.0},
    b32[] = {_x*17.5,_y*10,0.0},
    b33[] = {_x*18.5,_y*6,0.0},
    b34[] = {_x*18.5,_y*9,0.0},
    b35[] = {_x*18.5,_y*10,0.0},
    b36[] = {_x*19,_y*15.5,0.0},
    b37[] = {_x*18,_y*23,0.0},
    b38[] = {_x*20,_y*20.5,0.0},
    b39[] = {_x*20.5,_y*19.5,0.0},
    b40[] = {_x*20.5,_y*18,0.0},
    b41[] = {_x*20,_y*13,0.0},
    b42[] = {_x*22,_y*12.5,0.0},
    b43[] = {_x*22,_y*9,0.0},
    b44[] = {_x*22,_y*6,0.0},
    b45[] = {_x*21.5,_y*4.5,0.0},
    b46[] = {_x*19.5,_y*2.5,0.0};
  
  
  //2d-liste
  glNewList(BALOGO_B, GL_COMPILE); //B
  
   

  glBegin(GL_QUADS);
  // Polygon Nummer 1
  glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
  glVertex3dv(b2); glVertex3dv(b5); glVertex3dv(b10); glVertex3dv(b3);
		glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 2
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b0); glVertex3dv(b6); glVertex3dv(b7); glVertex3dv(b1);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 3
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b7); glVertex3dv(b8); glVertex3dv(b4);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 4
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b9); glVertex3dv(b10); glVertex3dv(b5);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 5 
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b6); glVertex3dv(b11); glVertex3dv(b14); glVertex3dv(b10);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 6
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b13); glVertex3dv(b16); glVertex3dv(b14);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 7
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b11); glVertex3dv(b15); glVertex3dv(b12);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 8
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b11); glVertex3dv(b28); glVertex3dv(b20); glVertex3dv(b15);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 9
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b20); glVertex3dv(b28); glVertex3dv(b25);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 10
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b28); glVertex3dv(b46); glVertex3dv(b33); glVertex3dv(b25);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 11
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b46); glVertex3dv(b45); glVertex3dv(b33);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 12
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b45);	glVertex3dv(b44);	glVertex3dv(b33);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 13
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b44);	glVertex3dv(b43);	glVertex3dv(b35);	glVertex3dv(b33);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 14
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b34);	glVertex3dv(b35);	glVertex3dv(b32);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 15
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(b35);	glVertex3dv(b42);	glVertex3dv(b41);	glVertex3dv(b32);		
    glEnd();
    
    glBegin(GL_POLYGON);
    // Polygon Nummer 16		
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(b32);	glVertex3dv(b41);	glVertex3dv(b29);	glVertex3dv(b26);	glVertex3dv(b21);		
    glEnd();
    
    glBegin(GL_POLYGON);
    // Polygon Nummer 17
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(b21);	glVertex3dv(b26);	glVertex3dv(b23);	glVertex3dv(b22);	glVertex3dv(b18);	glVertex3dv(b17);		
    glEnd();
    
    glBegin(GL_POLYGON);
    // Polygon Nummer 18
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b29);	glVertex3dv(b36);	glVertex3dv(b40);	glVertex3dv(b30);	glVertex3dv(b26);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 19
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b40);	glVertex3dv(b39);	glVertex3dv(b31);	glVertex3dv(b30);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 20
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b39);	glVertex3dv(b38);	glVertex3dv(b31);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 21
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b38);	glVertex3dv(b37);	glVertex3dv(b27);	glVertex3dv(b31);	
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 22
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b27);	glVertex3dv(b37);	glVertex3dv(b24);	glVertex3dv(b19);
    glEnd();
    
    glBegin(GL_QUADS);
  		// Polygon Nummer 23		
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b19);	glVertex3dv(b24);	glVertex3dv(b14);	glVertex3dv(b16);
    glEnd();
    
    glEndList();  //BA_LOGO_B
    
    
    glNewList(BALOGO_A, GL_COMPILE); //A
    
    glBegin(GL_POLYGON);
    // Polygon Nummer 24		
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(b43);	glVertex3dv(a7);	glVertex3dv(a9);	glVertex3dv(b42);	glVertex3dv(b35);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 25
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(a8);	glVertex3dv(a10);	glVertex3dv(a9);	glVertex3dv(a7);	
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 26
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a10);	glVertex3dv(a13);	glVertex3dv(a11);	glVertex3dv(a9);	
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 27
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a4);	glVertex3dv(a8);	glVertex3dv(a7);	glVertex3dv(a3);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 28	
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a4);	glVertex3dv(a3);	glVertex3dv(a2);	
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 29
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a5);	glVertex3dv(a6);	glVertex3dv(a1);	glVertex3dv(a0);		
    glEnd(); 
    
    glBegin(GL_QUADS);
    // Polygon Nummer 30
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(a15);	glVertex3dv(a14);	glVertex3dv(a10);	glVertex3dv(a8);		
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 31	
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(a18);	glVertex3dv(a17);	glVertex3dv(a14);	glVertex3dv(a15);		
    glEnd(); 
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 32_A
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a13);	glVertex3dv(a16);	glVertex3dv(a11);		
    glEnd(); 
    
    glBegin(GL_TRIANGLES);
		  // Polygon Nummer 32_B
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a16);	glVertex3dv(a12);	glVertex3dv(a11);		
    glEnd(); 
    
    glBegin(GL_TRIANGLES);	
    // Polygon Nummer 33_A
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a19);	glVertex3dv(a16);	glVertex3dv(a13);		
    glEnd();
    
    glBegin(GL_TRIANGLES);
		  // Polygon Nummer 33_B
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a19);	glVertex3dv(a13);	glVertex3dv(a17);		
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 34_A
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(a18);	glVertex3dv(a20);	glVertex3dv(a19);		
    glEnd();
    
    glBegin(GL_TRIANGLES);
		  // Polygon Nummer 34_B
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(a19);	glVertex3dv(a17);	glVertex3dv(a18);		
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 35
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a25);	glVertex3dv(a20);	glVertex3dv(a18);	glVertex3dv(a24);
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 36
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a26); glVertex3dv(a25);	glVertex3dv(a24);	glVertex3dv(a23);		
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 37		
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(a28);	glVertex3dv(a27);	glVertex3dv(a21);	glVertex3dv(a22);		
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer 38
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(a20);	glVertex3dv(a30);	glVertex3dv(a29);	glVertex3dv(a19);		
    glEnd();
    
    glBegin(GL_TRIANGLES);
    // Polygon Nummer 39
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(a31);	glVertex3dv(a29);	glVertex3dv(a30);		
    glEnd();
    
    glEndList(); //BALOGO_B
    
    
    //liste für die aüßeren flächen des logos
    glNewList(BALOGO_AUSSEN, GL_COMPILE); //AUSSEN
    
    glBegin(GL_QUADS);
    glNormal3d(0, 1., 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b3); glVertex3dv(b24);	
    glVertex3dv(BALogomyTrans(b24)); glVertex3dv(BALogomyTrans(b3));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.5, 1., 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b24); glVertex3dv(b37);	
    glVertex3dv(BALogomyTrans(b37)); glVertex3dv(BALogomyTrans(b24));		
    glEnd();
    
    
    glBegin(GL_QUADS);
    glNormal3d(1.5, 0.8, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b37); glVertex3dv(b38);	
    glVertex3dv(BALogomyTrans(b38)); glVertex3dv(BALogomyTrans(b37));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1.7, 1., 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b38); glVertex3dv(b39);	
    glVertex3dv(BALogomyTrans(b39)); glVertex3dv(BALogomyTrans(b38));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1., 0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b39); glVertex3dv(b40);	
    glVertex3dv(BALogomyTrans(b40)); glVertex3dv(BALogomyTrans(b39));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1, -0.3, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b40); glVertex3dv(b36);	
    glVertex3dv(BALogomyTrans(b36)); glVertex3dv(BALogomyTrans(b40));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1, -0.5, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);			
    glVertex3dv(b36); glVertex3dv(b29);	
    glVertex3dv(BALogomyTrans(b29)); glVertex3dv(BALogomyTrans(b36));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.2, 1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(b29); glVertex3dv(b41);	
    glVertex3dv(BALogomyTrans(b41)); glVertex3dv(BALogomyTrans(b29));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.2, 1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(b41); glVertex3dv(b42);	
    glVertex3dv(BALogomyTrans(b42)); glVertex3dv(BALogomyTrans(b41));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0, 1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);			
    glVertex3dv(b42); glVertex3dv(a9);	
    glVertex3dv(BALogomyTrans(a9)); glVertex3dv(BALogomyTrans(b42));		
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1, 0.7, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a9); glVertex3dv(a11);
    glVertex3dv(BALogomyTrans(a11)); glVertex3dv(BALogomyTrans(a9));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1, 0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a11); glVertex3dv(a12);
    glVertex3dv(BALogomyTrans(a12)); glVertex3dv(BALogomyTrans(a11));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.2, 0.7, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a12); glVertex3dv(a16);
    glVertex3dv(BALogomyTrans(a16)); glVertex3dv(BALogomyTrans(a12));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1, 0.5, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a16); glVertex3dv(a19);
    glVertex3dv(BALogomyTrans(a19)); glVertex3dv(BALogomyTrans(a16));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.3, 1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a19); glVertex3dv(a29);
    glVertex3dv(BALogomyTrans(a29)); glVertex3dv(BALogomyTrans(a19));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.3, 1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a29); glVertex3dv(a31);
    glVertex3dv(BALogomyTrans(a31)); glVertex3dv(BALogomyTrans(a29));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.3, -0.8, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a31); glVertex3dv(a30);
    glVertex3dv(BALogomyTrans(a30)); glVertex3dv(BALogomyTrans(a31));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.3, -0.8, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a30); glVertex3dv(a20);
    glVertex3dv(BALogomyTrans(a20)); glVertex3dv(BALogomyTrans(a30));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1, 0.5, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a20); glVertex3dv(a25);
    glVertex3dv(BALogomyTrans(a25)); glVertex3dv(BALogomyTrans(a20));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1, 0.5, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a25); glVertex3dv(a26);
    glVertex3dv(BALogomyTrans(a26)); glVertex3dv(BALogomyTrans(a25));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a26); glVertex3dv(a27);
    glVertex3dv(BALogomyTrans(a27)); glVertex3dv(BALogomyTrans(a26));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a27); glVertex3dv(a28);
    glVertex3dv(BALogomyTrans(a28)); glVertex3dv(BALogomyTrans(a27));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a28); glVertex3dv(a22);
    glVertex3dv(BALogomyTrans(a22)); glVertex3dv(BALogomyTrans(a28));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a22); glVertex3dv(a21);
    glVertex3dv(BALogomyTrans(a21)); glVertex3dv(BALogomyTrans(a22));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a21); glVertex3dv(a23);
    glVertex3dv(BALogomyTrans(a23)); glVertex3dv(BALogomyTrans(a21));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a23); glVertex3dv(a24);
    glVertex3dv(BALogomyTrans(a24)); glVertex3dv(BALogomyTrans(a23));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.7,-0.5, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a24); glVertex3dv(a18);
    glVertex3dv(BALogomyTrans(a18)); glVertex3dv(BALogomyTrans(a24));
    glEnd();
    
    glBegin(GL_QUADS);
    // Polygon Nummer A1
    glNormal3d(0.3,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a18); glVertex3dv(a15);
    glVertex3dv(BALogomyTrans(a15)); glVertex3dv(BALogomyTrans(a18));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.3,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a15); glVertex3dv(a8);
    glVertex3dv(BALogomyTrans(a8)); glVertex3dv(BALogomyTrans(a15));
    glEnd();
    
    glBegin(GL_QUADS);    
    glNormal3d(1,-0.2, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a8); glVertex3dv(a4);
    glVertex3dv(BALogomyTrans(a4)); glVertex3dv(BALogomyTrans(a8));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a4); glVertex3dv(a6);
    glVertex3dv(BALogomyTrans(a6)); glVertex3dv(BALogomyTrans(a4));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a6); glVertex3dv(a5);
    glVertex3dv(BALogomyTrans(a5)); glVertex3dv(BALogomyTrans(a6));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a5); glVertex3dv(a0);
    glVertex3dv(BALogomyTrans(a0)); glVertex3dv(BALogomyTrans(a5));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a0); glVertex3dv(a1);
    glVertex3dv(BALogomyTrans(a1)); glVertex3dv(BALogomyTrans(a0));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a1); glVertex3dv(a2);
    glVertex3dv(BALogomyTrans(a2)); glVertex3dv(BALogomyTrans(a1));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a2); glVertex3dv(a3);
    glVertex3dv(BALogomyTrans(a3)); glVertex3dv(BALogomyTrans(a2));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0.3, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a3); glVertex3dv(a7);
    glVertex3dv(BALogomyTrans(a7)); glVertex3dv(BALogomyTrans(a3));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a7); glVertex3dv(b43);
    glVertex3dv(BALogomyTrans(b43)); glVertex3dv(BALogomyTrans(a7));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b43); glVertex3dv(b44);
    glVertex3dv(BALogomyTrans(b44)); glVertex3dv(BALogomyTrans(b43));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,-0.1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b44); glVertex3dv(b45);
    glVertex3dv(BALogomyTrans(b45)); glVertex3dv(BALogomyTrans(b44));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,-0.6, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b45); glVertex3dv(b46);
    glVertex3dv(BALogomyTrans(b46)); glVertex3dv(BALogomyTrans(b45));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b46); glVertex3dv(b28);
    glVertex3dv(BALogomyTrans(b28)); glVertex3dv(BALogomyTrans(b46));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b28); glVertex3dv(b0);
    glVertex3dv(BALogomyTrans(b0)); glVertex3dv(BALogomyTrans(b28));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b0); glVertex3dv(b1);
    glVertex3dv(BALogomyTrans(b1)); glVertex3dv(BALogomyTrans(b0));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b1); glVertex3dv(b4);
    glVertex3dv(BALogomyTrans(b4)); glVertex3dv(BALogomyTrans(b1));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.3,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b4); glVertex3dv(b8);
    glVertex3dv(BALogomyTrans(b8)); glVertex3dv(BALogomyTrans(b4));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b8); glVertex3dv(b9);
    glVertex3dv(BALogomyTrans(b9)); glVertex3dv(BALogomyTrans(b8));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,-0.2, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b9); glVertex3dv(b5);
    glVertex3dv(BALogomyTrans(b5)); glVertex3dv(BALogomyTrans(b9));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b5); glVertex3dv(b2);
    glVertex3dv(BALogomyTrans(b2)); glVertex3dv(BALogomyTrans(b5));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b2); glVertex3dv(b3);
    glVertex3dv(BALogomyTrans(b3)); glVertex3dv(BALogomyTrans(b2));
    glEnd();
    
    glEndList(); // BALOGO_AUSSEN
    

    //die inneren flächen des logos
    glNewList(BALOGO_INNEN, GL_COMPILE);
    
    
    glBegin(GL_QUADS);
    glNormal3d(-0.2,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a10); glVertex3dv(a14);
    glVertex3dv(BALogomyTrans(a14)); glVertex3dv(BALogomyTrans(a10));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.2,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(a14); glVertex3dv(a17);
    glVertex3dv(BALogomyTrans(a17)); glVertex3dv(BALogomyTrans(a14));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,-0.2, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a17); glVertex3dv(a13);
    glVertex3dv(BALogomyTrans(a13)); glVertex3dv(BALogomyTrans(a17));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,-0.2, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(a13); glVertex3dv(a10);
    glVertex3dv(BALogomyTrans(a10)); glVertex3dv(BALogomyTrans(a13));
    glEnd();
    
    
    glFrontFace(GL_CW);
    
    glBegin(GL_QUADS);
    glNormal3d(1,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b13); glVertex3dv(b16);
    glVertex3dv(BALogomyTrans(b16)); glVertex3dv(BALogomyTrans(b13));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b16); glVertex3dv(b19);
    glVertex3dv(BALogomyTrans(b19)); glVertex3dv(BALogomyTrans(b16));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.30,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b19); glVertex3dv(b27);
    glVertex3dv(BALogomyTrans(b27)); glVertex3dv(BALogomyTrans(b19));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,-0.2, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b27); glVertex3dv(b31);
    glVertex3dv(BALogomyTrans(b31)); glVertex3dv(BALogomyTrans(b27));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b31); glVertex3dv(b30);
    glVertex3dv(BALogomyTrans(b30)); glVertex3dv(BALogomyTrans(b31));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0.4, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b30); glVertex3dv(b26);
    glVertex3dv(BALogomyTrans(b26)); glVertex3dv(BALogomyTrans(b30));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(b26); glVertex3dv(b23);
    glVertex3dv(BALogomyTrans(b23)); glVertex3dv(BALogomyTrans(b26));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(b23); glVertex3dv(b22);
    glVertex3dv(BALogomyTrans(b22)); glVertex3dv(BALogomyTrans(b23));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(b22); glVertex3dv(b18);
    glVertex3dv(BALogomyTrans(b18)); glVertex3dv(BALogomyTrans(b22));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(b18); glVertex3dv(b17);
    glVertex3dv(BALogomyTrans(b17)); glVertex3dv(BALogomyTrans(b18));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(b17); glVertex3dv(b21);
    glVertex3dv(BALogomyTrans(b21)); glVertex3dv(BALogomyTrans(b17));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.2,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
    glVertex3dv(b21); glVertex3dv(b32);
    glVertex3dv(BALogomyTrans(b32)); glVertex3dv(BALogomyTrans(b21));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b32); glVertex3dv(b34);
    glVertex3dv(BALogomyTrans(b34)); glVertex3dv(BALogomyTrans(b32));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b34); glVertex3dv(b33);
    glVertex3dv(BALogomyTrans(b33)); glVertex3dv(BALogomyTrans(b34));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.8,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b33); glVertex3dv(b25);
    glVertex3dv(BALogomyTrans(b25)); glVertex3dv(BALogomyTrans(b33));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.8,-1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b25); glVertex3dv(b20);
    glVertex3dv(BALogomyTrans(b20)); glVertex3dv(BALogomyTrans(b25));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0,1, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b20); glVertex3dv(b15);
    glVertex3dv(BALogomyTrans(b15)); glVertex3dv(BALogomyTrans(b20));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,-0.4, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b15); glVertex3dv(b12);
    glVertex3dv(BALogomyTrans(b12)); glVertex3dv(BALogomyTrans(b15));
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(1,0, 0);
    glMaterialf(GL_FRONT, GL_SHININESS, (float)SHINEVAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
    glVertex3dv(b12); glVertex3dv(b13);
    glVertex3dv(BALogomyTrans(b13)); glVertex3dv(BALogomyTrans(b12));
    glEnd();
    
    glFrontFace(GL_CCW);
    
    glEndList(); // BALOGO_INNEN
    
    
    //liste, die die äußeren, inneren und seitlcihen flächen zusammenfügt
    glNewList(BALOGO_3D, GL_COMPILE);
    glTranslated(-_x*44.5/2.0, -_y*24/2.0, -BREITE / 2.0);
	    
    // Spiegelungen in Weiß spec
    glMaterialfv(GL_FRONT, GL_SPECULAR, white);
    // Spiegelungen in Weiß amb
    glMaterialfv(GL_FRONT, GL_AMBIENT, white);
    // Exponent der Spiegelungen 
    glMaterialf(GL_FRONT, GL_SHININESS, 10.0f);
    // Eigenlichtemission des Körpers 
    glMaterialfv(GL_FRONT, GL_EMISSION, black);
  
    glNormal3d(0., 0., 1.);    
    glCallList(BALOGO_B);
    glCallList(BALOGO_A);
    
    glCallList(BALOGO_AUSSEN);
    glCallList(BALOGO_INNEN);
    
    glTranslated(0.0, 0.0, BREITE);
    
    glFrontFace(GL_CW);
    
    glNormal3d(0., 0., -1.);        
    glCallList(BALOGO_A);
    glCallList(BALOGO_B);
    
    glFrontFace(GL_CCW);
    
    glTranslated(0.0, 0.0, -BREITE);
    
	GLfloat MatSpecular[]=  { 1.0f, 1.0f, 1.0f, 1.0f };				 // Diffuse Light Values 
	glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpecular);
	glMateriali(GL_FRONT, GL_SHININESS, 128);
    GLfloat diffuse[]={1.0f, 1.0f, 1.0f, 1.0f}; 
    GLfloat ambient[]={0.2f, 0.2f, 0.2f, 1.0f};
    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);			
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);			

    glEndList(); // BALOGO_3D
    
}

double* BALogomyTrans(double *v)
{
  
  static double vector[3];
  
  vector[0] = v[0];
  vector[1] = v[1];
  vector[2] = (double)BREITE;
  //  printf("%lf %lf \n", vector[0] , vector[2] );
  return vector;
}
