#include <GL/glut.h>
#include <stdlib.h>

// stałe do obsługi menu podręcznego

enum
{
	FULL_WINDOW, // aspekt obrazu - całe okno
	ASPECT_1_1, // aspekt obrazu 1:1
	WIRE_SPHERE, // kula
	WIRE_CONE, // stożek
	WIRE_CUBE, // sześcian
	WIRE_TORUS, // torus
	WIRE_DODECAHEDRON, // dwunastościan
	WIRE_TEAPOT, // czajnik
	WIRE_OCTAHEDRON, // ośmiościan
	WIRE_TETRAHEDRON, // czworościan
	WIRE_ICOSAHEDRON, // dwudziestościan
	EXIT // wyjście
};

// aspekt obrazu

int aspect = ASPECT_1_1;

// rodzaj obiektu

int object = WIRE_SPHERE;

// rozmiary bryły obcinania

const GLdouble left = -40.0;
const GLdouble right = 40.0;
const GLdouble bottom = -70.0;
const GLdouble top = 70.0;
const GLdouble Near = 200.0;
const GLdouble Far = 70.0;

// współczynnik skalowania

GLfloat scale = 1.0;

// kąty obrotu

GLfloat rotatex = 0.0;
GLfloat rotatey = 0.0;

// przesunięcie

GLfloat translatex = 0.0;
GLfloat translatey = 0.0;

// wskaźnik naciśnięcia lewego przycisku myszki

int button_state = GLUT_UP;

// położenie kursora myszki

int button_x, button_y;

// funkcja generująca scenę 3D

void DrawCube(int x, int y, int z, int c)
{
	glTranslatef(x, y, z);
	glColor3f(0.0f, 0.0f, c);
	glutSolidCube(1);
	glTranslatef(-x, -y, -z);

}

void DrawWireCube(int x, int y, int z, int c)
{
	glTranslatef(x, y, z);
	glColor3f(0.0f, c, 0.0f);
	glutWireCube(1);
	glTranslatef(-x, -y, -z);
}

int tab[20][20] =
{
	{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
	{ 0,1,0,0,0,0,0,0,1,0,0,0,1,1,1,1,0,0,1,0 },
	{ 0,1,1,1,1,1,1,1,1,0,0,0,1,0,0,1,0,0,1,0 },
	{ 0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0 },
	{ 0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0 },
	{ 0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0 },
	{ 0,1,0,1,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0 },
	{ 0,1,0,1,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0 },
	{ 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0 },
	{ 0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0 },
	{ 0,1,1,1,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0 },
	{ 0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,0 },
	{ 0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0 },
	{ 0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0 },
	{ 0,1,0,1,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0 },
	{ 0,1,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0 },
	{ 0,1,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0 },
	{ 0,1,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 },
	{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
};

void DrawBoard()
{
	for (int i = -10; i < 10; ++i)
	{
		for (int j = -10; j < 10; ++j)
		{
			if (tab[i + 10][j + 10] == 0)
			{
				DrawCube(i, j, 0, 1);
				DrawWireCube(i, j, 0, 1);
			}
			else
			{
				DrawCube(i, j, 0, 0);
			}
		}
	}

	for (int i = -10; i < 10; ++i)
	{
		for (int j = -10; j < 10; ++j)
		{
			if (tab[i + 10][j + 10] == 0)
			{
				DrawCube(i, j, 1, 1);
				DrawWireCube(i, j, 1, 1);
			}
		}
	}

	for (int i = -10; i < 10; ++i)
	{
		for (int j = -10; j < 10; ++j)
		{
			if (tab[i + 10][j + 10] == 0)
			{
				DrawCube(i, j, 2, 1);
				DrawWireCube(i, j, 2, 1);
			}
		}
	}
}

void Display()
{
	// kolor tła - zawartość bufora koloru
	glClearColor(1.0, 1.0, 1.0, 1.0);

	// czyszczenie bufora koloru
	glClear(GL_COLOR_BUFFER_BIT);

	// wybór macierzy modelowania
	glMatrixMode(GL_MODELVIEW);

	// macierz modelowania = macierz jednostkowa
	glLoadIdentity();

	// przesunięcie układu współrzędnych obiektu do środka bryły odcinania
	glTranslatef(0, 0, -(Near + Far) / 2);

	// przesunięcie obiektu - ruch myszką
	glTranslatef(translatex, translatey, 0.0);

	// skalowanie obiektu - klawisze "+" i "-"
	glScalef(scale, scale, scale);

	// obroty obiektu - klawisze kursora
	glRotatef(rotatex, 1.0, 0, 0);
	glRotatef(rotatey, 0, 1.0, 0);

	DrawBoard();

	// skierowanie poleceń do wykonania
	glFlush();

	// zamiana buforów koloru
	glutSwapBuffers();
}

// zmiana wielkości okna

void Reshape(int width, int height)
{
	// obszar renderingu - całe okno
	glViewport(0, 0, width, height);

	// wybór macierzy rzutowania
	glMatrixMode(GL_PROJECTION);

	// macierz rzutowania = macierz jednostkowa
	glLoadIdentity();

	// parametry bryły obcinania
	if (aspect == ASPECT_1_1)
	{
		// wysokość okna większa od wysokości okna
		if (width < height && width > 0)
			glFrustum(left, right, bottom * height / width, top * height / width, Near, Far);
		else

			// szerokość okna większa lub równa wysokości okna
			if (width >= height && height > 0)
				glFrustum(left * width / height, right * width / height, bottom, top, Near, Far);

	}
	else
		glFrustum(left, right, bottom, top, Near, Far);

	// generowanie sceny 3D
	Display();
}

// obsługa klawiatury

void Keyboard(unsigned char key, int x, int y)
{
	// klawisz +
	if (key == '+')
		scale += 0.1;
	else

		// klawisz -
		if (key == '-' && scale > 0.1)
			scale -= 0.1;

	// odrysowanie okna
	Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
}

// obsługa klawiszy funkcyjnych i klawiszy kursora

void SpecialKeys(int key, int x, int y)
{
	switch (key)
	{
		// kursor w lewo
	case GLUT_KEY_LEFT:
		rotatey -= 1;
		break;

		// kursor w górę
	case GLUT_KEY_UP:
		rotatex -= 1;
		break;

		// kursor w prawo
	case GLUT_KEY_RIGHT:
		rotatey += 1;
		break;

		// kursor w dół
	case GLUT_KEY_DOWN:
		rotatex += 1;
		break;
	}

	// odrysowanie okna
	Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
}

// obsługa przycisków myszki

void MouseButton(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON)
	{
		// zapamiętanie stanu lewego przycisku myszki
		button_state = state;

		// zapamiętanie położenia kursora myszki
		if (state == GLUT_DOWN)
		{
			button_x = x;
			button_y = y;
		}
	}
}

// obsługa ruchu kursora myszki

void MouseMotion(int x, int y)
{
	if (button_state == GLUT_DOWN)
	{
		translatex += 1.1 *(right - left) / glutGet(GLUT_WINDOW_WIDTH) *(x - button_x);
		button_x = x;
		translatey += 1.1 *(top - bottom) / glutGet(GLUT_WINDOW_HEIGHT) *(button_y - y);
		button_y = y;
		glutPostRedisplay();
	}
}

// obsługa menu podręcznego

void Menu(int value)
{
	switch (value)
	{
		// obszar renderingu - całe okno
	case FULL_WINDOW:
		aspect = FULL_WINDOW;
		Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
		break;

		// obszar renderingu - aspekt 1:1
	case ASPECT_1_1:
		aspect = ASPECT_1_1;
		Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
		break;

		// kula
	case WIRE_SPHERE:
		object = WIRE_SPHERE;
		Display();
		break;

		// cylinder
	case WIRE_CONE:
		object = WIRE_CONE;
		Display();
		break;

		// sześcian
	case WIRE_CUBE:
		object = WIRE_CUBE;
		Display();
		break;

		// torus
	case WIRE_TORUS:
		object = WIRE_TORUS;
		Display();
		break;

		// dwunastościan
	case WIRE_DODECAHEDRON:
		object = WIRE_DODECAHEDRON;
		Display();
		break;

		// czajnik
	case WIRE_TEAPOT:
		object = WIRE_TEAPOT;
		Display();
		break;

		// ośmiościan
	case WIRE_OCTAHEDRON:
		object = WIRE_OCTAHEDRON;
		Display();
		break;

		// czworościan
	case WIRE_TETRAHEDRON:
		object = WIRE_TETRAHEDRON;
		Display();
		break;

		// dwudziestościan
	case WIRE_ICOSAHEDRON:
		object = WIRE_ICOSAHEDRON;
		Display();
		break;

		// wyjście
	case EXIT:
		exit(0);
	}
}

int main(int argc, char * argv[])
{
	// inicjalizacja biblioteki GLUT
	glutInit(&argc, argv);

	// inicjalizacja bufora ramki
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

	// rozmiary głównego okna programu
	glutInitWindowSize(400, 400);

	// utworzenie głównego okna programu
#ifdef WIN32

	glutCreateWindow("Przekształcenia");
#else

	glutCreateWindow("Przeksztalcenia");
#endif

	// dołączenie funkcji generującej scenę 3D
	glutDisplayFunc(Display);

	// dołączenie funkcji wywoływanej przy zmianie rozmiaru okna
	glutReshapeFunc(Reshape);

	// dołączenie funkcji obsługi klawiatury
	glutKeyboardFunc(Keyboard);

	// dołączenie funkcji obsługi klawiszy funkcyjnych i klawiszy kursora
	glutSpecialFunc(SpecialKeys);

	// obsługa przycisków myszki
	glutMouseFunc(MouseButton);

	// obsługa ruchu kursora myszki
	glutMotionFunc(MouseMotion);

	// utworzenie podmenu - aspekt obrazu
	int MenuAspect = glutCreateMenu(Menu);
#ifdef WIN32

	glutAddMenuEntry("Aspekt obrazu - całe okno", FULL_WINDOW);
#else

	glutAddMenuEntry("Aspekt obrazu - cale okno", FULL_WINDOW);
#endif

	glutAddMenuEntry("Aspekt obrazu 1:1", ASPECT_1_1);

	// utworzenie podmenu - obiekt
	int MenuObject = glutCreateMenu(Menu);
	glutAddMenuEntry("Kula", WIRE_SPHERE);
#ifdef WIN32

	glutAddMenuEntry("Stożek", WIRE_CONE);
	glutAddMenuEntry("Sześcian", WIRE_CUBE);
	glutAddMenuEntry("Torus", WIRE_TORUS);
	glutAddMenuEntry("Dwunastościan", WIRE_DODECAHEDRON);
	glutAddMenuEntry("Czajnik", WIRE_TEAPOT);
	glutAddMenuEntry("Ośmiościan", WIRE_OCTAHEDRON);
	glutAddMenuEntry("Czworościan", WIRE_TETRAHEDRON);
	glutAddMenuEntry("Dwudziestościan", WIRE_ICOSAHEDRON);
#else

	glutAddMenuEntry("Stozek", WIRE_CONE);
	glutAddMenuEntry("Szescian", WIRE_CUBE);
	glutAddMenuEntry("Torus", WIRE_TORUS);
	glutAddMenuEntry("Dwunastoscian", WIRE_DODECAHEDRON);
	glutAddMenuEntry("Czajnik", WIRE_TEAPOT);
	glutAddMenuEntry("Osmioscian", WIRE_OCTAHEDRON);
	glutAddMenuEntry("Czworoscian", WIRE_TETRAHEDRON);
	glutAddMenuEntry("Dwudziestoscian", WIRE_ICOSAHEDRON);
#endif

	// menu główne
	glutCreateMenu(Menu);
	glutAddSubMenu("Aspekt obrazu", MenuAspect);
	glutAddSubMenu("Obiekt", MenuObject);
#ifdef WIN32

	glutAddMenuEntry("Wyjście", EXIT);
#else

	glutAddMenuEntry("Wyjscie", EXIT);
#endif

	// określenie przycisku myszki obsługującego menu podręczne
	glutAttachMenu(GLUT_RIGHT_BUTTON);

	// wprowadzenie programu do obsługi pętli komunikatów
	glutMainLoop();
	return 0;
} 

Mam tu program w OpenGL (starym) który generuje labirynt. Klikając myszką na labirynt można go przesuwać. Naciskając na klawiaturze "+" i "-" można go przybliżać i oddalać, a naciskając strzałki w lewo i prawo można go obracać. Obróćcie teraz labirynt do takiego położenia jak jest na screenie? Dlaczego tak strasznie obcina te ściany? Jak to naprawić? Zwiększałem Near i far w programie, ale nic nie daje.