Уроки, алгоритмы, программы, примеры

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

У меня проблема вот с этим: gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);. Вылезает ошибка: CS1061 "object" не содержит определения "GL_COLOR_BUFFER_BIT", и не удалось найти доступный метод расширения "GL_COLOR_BUFFER_BIT",...
Большое спасибо. Единственный код который прошел без каких либо ошибок. Ура!!!
Скажите пожалуйста, подскажите алгоритм по которому по заданным точкам можно определить тип многогранника, скажем это куб или прямоугольный параллелепипед. Нашел теорию по этим фигурам: https://www.mat... https://www.mat... Акцентировать внимание...
Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Среда программирования: 
Visual C

Режим для игр GLUT предназначен для обеспечения высокопроизводительного рендеринга в полном экране. В этом режиме некоторые функции GLUT, такие как всплывающие меню и окна, отключены для увеличения производительности.
Первое, что мы должны сделать, это задать параметры игрового режима, то есть параметры экрана. Эти параметры могут включать в себя разрешение экрана, глубину пикселя и частота обновления.
Формат настроек выглядит следующим образом:

“WxH:Bpp@Rr”

Параметры:

W - ширина экрана в пикселях.
H - высота экрана в пикселях.
Bpp - количество бит на пиксель.
RR - частота кадровой развертки в герцах.

Прежде, чем мы пойдем дальше, обратите внимание, что эти настройки доступны только по запросу к аппаратному обеспечению. Если указанный режим не доступен, то настройки игнорируются.

Examples:

“800×600:32@100″ – разрешение 800×600; глубина цвета (32 bits); 100Hz
“640×480:16@75″ – разрешение 640×480; глубина цвета (16 bits); 75Hz

Хотя мы обычно имеем четкое представление о разрешении экрана и всех параметрах, к счастью, мы не должны указывать их все. Мы можем оставить некоторые поля, и пусть GLUT заполнит пробелы сам. Следующие строки шаблона являются допустимым частичным указанием настроек экрана:

“WxH”
“WxH:Bpp”
“WxH@Rr”
“@Rr”
“:Bpp”
“Bpp:@Rr”

GLUT может обрабатывать все комбинации до тех пор, пока порядок между ними сохраняется. Так, например, указания частоты обновления перед глубиной цвета не допускается.

Предположим, мы хотим установить разрешение экрана, но не заботимся о глубине пиксела или частоты обновления, то мы можем написать что-то вроде "800 × 600".

Если, с другой стороны, мы просто хотели установить полноэкранный режим при текущем разрешении, но с глубиной цвета 32 бит, мы могли бы написать ": 32".

Эти несколько примеров не показывают все возможности полной строки экрана настроек. Мы можем использовать любую из строк шаблонов, представленных выше.

Прежде всего мы должны настроить GLUT в соответствие с запрашиваемыми параметрам для полноэкранного режима. Функции GLUT, устанавливающая режим игры - glutGameModeString. Синтаксис выглядит следующим образом:

void glutGameModeString(const char *string);

Параметры:

*string – строка, содержащая нужные настройки.

GLUT выполняет проверку аргумента glutGameModeString. Хотя функция не возвращает код ошибки, мы можем убедиться, что режим указан в правильном порядке. GLUT предоставляет функцию, которая, среди прочих возможностей, позволяет нам проверить, если указанный режим является действительным. Синтаксис функции:

int glutGameModeGet(GLenum info);

Параметры:

info – запрашиваемая информация.

Для того, чтобы проверить, что предоставленный режим активен, информационная переменная принимает значение предварительно определенных констант: GLUT_GAME_MODE_POSSIBLE.

В этом случае, возвращаемое значение указывает, является ли заданный режим действительным, ненулевое значение означает говорит об активности именно заданного режима. Если предположить, что мы получили ненулевое значение в качестве возвращаемого значения, то мы можем войти, или, по крайней мере, попытаться войти, в режим игры с glutEnterGameMode. Эта функция фактически устанавливает для экрана нужную настройку, если они действительны. Синтаксис выглядит следующим образом:

void glutEnterGameMode(void);

Функция main для инициализации GLUT c применением режима игры с настройками разрешения 800 на 600 может иметь примерно такой вид:

int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
 
 
/*	glutInitWindowPosition(100,100);
	glutInitWindowSize(640,480);
	glutCreateWindow("Snegoviki from TNU");
*/
	// Установка режима игры меняет настройки свыше
	// Вызов, чтобы установить размер и положение окна
	glutGameModeString("800x600:32");
	if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
		glutEnterGameMode();
	else {
		printf("Rezhim ne dostupen\n");
		exit(1);
	}
 
	// регистрация
	init();
 
	glutMainLoop();
 
	return 1;
}

Функция инициализации должна зарегистрировать все необходимые обратные вызовы, а также выполнить необходимую инициализацию OpenGL. Например, мы могли бы написать следующее:

void init() {
 	//регистрация вызовов
	glutDisplayFunc(renderScene);
	glutReshapeFunc(changeSize);
	glutIdleFunc(renderScene);
 
	glutIgnoreKeyRepeat(1);
	glutKeyboardFunc(processNormalKeys);
	glutSpecialFunc(pressKey);
	glutSpecialUpFunc(releaseKey);
	glutMouseFunc(mouseButton);
	glutMotionFunc(mouseMove);
 
	// OpenGL инициализация
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
}

Это может быть так, если мы хотим иметь возможность переключения между режимами игры и оконным режимом во время исполнения приложения. Следующий фрагмент кода предполагает, что мы начинаем в оконном режиме. Затем пользователь может нажать F1 для перехода в игровой режим. F6 приносит пользователя обратно в режим окна. В этом случае main() должна определять свойства окна, регистрацию функций и обратных вызовов и войти в основной цикл.

Функция, которая сообщает GLUT покинуть игровой режим.

void glutLeaveGameMode(void);

Функция, которая будет обрабатывать специальными клавишами переключение режимов:

void pressKey(int key, int x, int y) {
	switch (key) {
		...
		case GLUT_KEY_F1:  
			// переопределить разрешение, глубину цвета
			glutGameModeString("640x480:32");
			// перейти в полный экран
			if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
				glutEnterGameMode();
				// новая регистрация вызовов
				init();
			}
			break;
		case GLUT_KEY_F6:
			// вернуться в оконный режим
			glutLeaveGameMode();
			break;
	}
}

Существует такая мелочь, которая очень важна в функции выше, когда мы входим в режим игры с glutEnterGameMode мы должны зарегистрировать обратные вызовы снова, и переопределить контекст OpenGL. Режим игры равносилен новому окну, с другими настройками OpenGL и GLUT. Это означает, что функции обратного вызова в режим окна не будут работать в игровом режиме. Для того чтобы использовать функции обратного вызова мы должны зарегистрировать их снова. Кроме того, OpenGL инициализация должна быть определена снова. Например дисплей списков, созданных для окна режим должны быть определены еще раз при входе в игровом режиме.

GLUT имеет специальную функцию для запроса параметров состояния для режима игры , glutGameModeGet. Синтаксис этой функции указан выше, когда мы упомянули, что одним из возможных значение для аргумента было GLUT_GAME_MODE_POSSIBLE.

Есть несколько возможностей для аргумента glutGameModeGet, которые охватывают все потребности в правильном режиме программирования игры. Возвращаемые значения для каждого случая представлены ниже:

GLUT_GAME_MODE_ACTIVE - Если приложение работает в режиме игры, glutGameModeGet затем вернет ненулевое значение, если в оконном режиме он вернет ноль.
GLUT_GAME_MODE_POSSIBLE - Как уже упоминалось выше, это может быть использовано для проверки строки, которая определяет настройки режима игры. Это хороший тон обратиться к glutGameModeGet с этим значением перед входом игровой режим.
GLUT_GAME_MODE_DISPLAY_CHANGED - Как упоминалось ранее при входе в режим игры нет никакой гарантии, что режим отображения действительно изменился. Это значение может быть использовано для проверки, если режим игры был действительно активирован.
GLUT_GAME_MODE_WIDTH - возвращает ширину экрана.
GLUT_GAME_MODE_HEIGHT - возвращает высоту экрана.
GLUT_GAME_MODE_PIXEL_DEPTH - возвращает глубину цвета бит на пиксель от текущего режима.
GLUT_GAME_MODE_REFRESH - фактическая частота обновления в герцах.
Последние четыре варианта имеют смысл только тогда, когда мы находимся в игровом режиме. Эти варианты будут вызывать glutGameModeGet со значением -1, если последняя строка, определяющая режим настройки игры не действует, даже если мы уже находимся в игровом режиме. Так, например, если мы из запущенного приложения в режиме игры с разрешением 640 х 480 и захотели его изменить на 1600 х 1200, и режим не совпадает с фактическими аппаратными конфигурациями , то GLUT не изменит разрешение и режим игры останется с разрешением 640 на 480. Однако при выяснении текущей высоту , мы получим -1 , а не 480, хотя фактическая высота 480.

Следующий код иллюстрирует использование glutGameModeGet.

if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) == 0)
		sprintf(currentMode,"Current Mode: Window");
	else
		sprintf(currentMode,
			"Current Mode: Game Mode %dx%d at %d hertz, %d bpp",
			glutGameModeGet(GLUT_GAME_MODE_WIDTH),
			glutGameModeGet(GLUT_GAME_MODE_HEIGHT),
			glutGameModeGet(GLUT_GAME_MODE_REFRESH_RATE),
			glutGameModeGet(GLUT_GAME_MODE_PIXEL_DEPTH));

Итоговый код:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <glut.h>
 
// угол поворота камеры
float angle=0.0;
// координаты вектора направления движения камеры
float lx=0.0f, lz=-1.0f;
// XZ позиция камеры
float x=0.0f, z=5.0f;
//Ключи статуса камеры. Переменные инициализируются нулевыми значениями
//когда клавиши не нажаты
float deltaAngle = 0.0f;
float deltaMove = 0;
int xOrigin = -1;
//Цвет носа снеговика
float red = 1.0f, blue=0.5f, green=0.5f;
//размер снеговика
float scale = 1.0f;
//фрифт по умолчанию
void *font = GLUT_STROKE_ROMAN;
//ширина и высота окна
int h,w;
 
// переменные для вычисления кадров в секунду
int frame;
long time, timebase;
char s[60];
char currentMode[80];
 
// эта строка сохраняет последние настройки
// для игрового режима
char gameModeString[40] = "640x480";
 
void init();
 
void changeSize(int ww, int hh) {
	h = hh;
	w = ww;
	// предотвращение деления на ноль
	if (h == 0)
		h = 1;
	float ratio =  w * 1.0 / h;
	// используем матрицу проекции
	glMatrixMode(GL_PROJECTION);
	// обнуляем матрицу
	glLoadIdentity();
	// установить параметры вьюпорта
	glViewport(0, 0, w, h);
	// установить корректную перспективу
	gluPerspective(45.0f, ratio, 0.1f, 100.0f);
	// вернуться к матрице проекции
	glMatrixMode(GL_MODELVIEW);
}
 
void drawSnowMan() 
{
	glScalef(scale, scale, scale);
	glColor3f(1.0f, 1.0f, 1.0f);
	// тело снеговика
	glTranslatef(0.0f ,0.75f, 0.0f);
	glutSolidSphere(0.75f,20,20);
	// голова снеговика
	glTranslatef(0.0f, 1.0f, 0.0f);
	glutSolidSphere(0.25f,20,20);
	// глаза снеговика
	glPushMatrix();
	glColor3f(0.0f,0.0f,0.0f);
	glTranslatef(0.05f, 0.10f, 0.18f);
	glutSolidSphere(0.05f,10,10);
	glTranslatef(-0.1f, 0.0f, 0.0f);
	glutSolidSphere(0.05f,10,10);
	glPopMatrix();
	// нос снеговика
	glColor3f(red, green, blue);
	glRotatef(0.0f,1.0f, 0.0f, 0.0f);
	glutSolidCone(0.08f,0.5f,10,2);
	glColor3f(1.0f, 1.0f, 1.0f);
}
 
void renderBitmapString(
		float x,
		float y,
		float z,
		void *font,
		char *string) {
 
	char *c;
	glRasterPos3f(x, y,z);
	for (c=string; *c != '\0'; c++) {
		glutBitmapCharacter(font, *c);
	}
}
 
void renderStrokeFontString(
		float x,
		float y,
		float z,
		void *font,
		char *string) {  
 
	char *c;
	glPushMatrix();
	glTranslatef(x, y,z);
	glScalef(0.002f, 0.002f, 0.002f);
	for (c=string; *c != '\0'; c++) {
		glutStrokeCharacter(font, *c);
	}
	glPopMatrix();
}
 
void restorePerspectiveProjection() {
	glMatrixMode(GL_PROJECTION);
	//восстановить предыдущую матрицу проекции
	glPopMatrix();
	//вернуться в режим модели
	glMatrixMode(GL_MODELVIEW);
}
 
void setOrthographicProjection() {
	//выбрать режим проекции
	glMatrixMode(GL_PROJECTION);
	//Сохраняем предыдущую матрицу, которая содержит
	//параметры перспективной проекции
	glPushMatrix();
	//обнуляем матрицу
	glLoadIdentity();
	//устанавливаем 2D ортогональную проекцию
	gluOrtho2D(0, w, h, 0);
	//выбираем режим обзора модели
	glMatrixMode(GL_MODELVIEW);
}
 
void computePos(float deltaMove) {
 
	x += deltaMove * lx * 0.1f;
	z += deltaMove * lz * 0.1f;
}
 
void renderScene(void) {
	if (deltaMove)
		computePos(deltaMove);
 
	//очистить буфер цвета и глубины
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	// обнулить трансформацию
	glLoadIdentity();
	// установить камеру
	gluLookAt(	x, 1.0f, z,
			x+lx, 1.0f,  z+lz,
			0.0f, 1.0f,  0.0f);
 
	// нарисуем "землю"
	glColor3f(0.9f, 0.9f, 0.9f);
	glBegin(GL_QUADS);
		glVertex3f(-100.0f, 0.0f, -100.0f);
		glVertex3f(-100.0f, 0.0f,  100.0f);
		glVertex3f( 100.0f, 0.0f,  100.0f);
		glVertex3f( 100.0f, 0.0f, -100.0f);
	glEnd();
 
	// Нарисуем 64 снеговика
	char number[4];
	for(int i = -4; i < 4; i++)
		for(int j=-4; j < 4; j++) {
			glPushMatrix();
			glTranslatef(i*10.0f, 0.0f, j * 10.0f);
			drawSnowMan();
			sprintf(number,"%d",(i+3)*8+(j+4));
			renderStrokeFontString(0.0f, 0.5f, 0.0f, (void *)font ,number);
			glPopMatrix();
		}
	// Код для вычисления кадров в секунду
	frame++;
 
	time=glutGet(GLUT_ELAPSED_TIME);
	if (time - timebase > 1000) {
		sprintf(s,"Informatika.TNU - FPS:%4.2f",
			frame*1000.0/(time-timebase));
		timebase = time;
		frame = 0;
	}
 
	setOrthographicProjection();
	void *font= GLUT_BITMAP_8_BY_13;
	glPushMatrix();
	glLoadIdentity();
	renderBitmapString(30,15,0,font,(char *)"GLUT lib @ Iformatika TNU");
	renderBitmapString(30,30,0,font,s);
	renderBitmapString(30,45,0,font,(char *)"F1 - Game Mode  640x480 32 bits");
	renderBitmapString(30,60,0,font,(char *)"F2 - Game Mode  960x540 32 bits");
	renderBitmapString(30,75,0,font,(char *)"F3 - Game Mode 1280x720 32 bits");
	renderBitmapString(30,90,0,font,(char *)"F4 - Game Mode 1366x768 32 bits");
	renderBitmapString(30,105,0,font,(char *)"F5 - Game Mode 1650x1050 32 bits");
	renderBitmapString(30,120,0,font,(char *)"F6 - Window Mode");
	renderBitmapString(30,135,0,font,(char *)"Esc - Quit");
	renderBitmapString(30,150,0,font,currentMode);
	glPopMatrix();
 
	restorePerspectiveProjection();
 
	glutSwapBuffers();
}
 
// -----------------------------------	//
//            клавиатура				//
// -----------------------------------	//
 
void processNormalKeys(unsigned char key, int xx, int yy) {
 
	switch (key) {
		case 27:
			if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) != 0)
				glutLeaveGameMode();
			exit(0);
			break;
	}
}
 
void pressKey(int key, int xx, int yy) {
 
	switch (key) {
		case GLUT_KEY_UP : deltaMove = 0.5f; break;
		case GLUT_KEY_DOWN : deltaMove = -0.5f; break;
		case GLUT_KEY_F1:
			// установить разрешение и цвет
			glutGameModeString("640x480:32");
			// включить полноэкранный режим
			if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
				glutEnterGameMode();
				sprintf(gameModeString,"640x480:32");
				// регистрация обратных вызовов
				// и инициализация OpenGL
				init();
			}
			else
				glutGameModeString(gameModeString);
			break;
		case GLUT_KEY_F2:
			// установить разрешение и цвет
			glutGameModeString("960x540:32");
			// включить полноэкранный режим
			if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
				glutEnterGameMode();
				sprintf(gameModeString,"960x540:32");
				// регистрация обратных вызовов
				// и инициализация OpenGL
				init();
			}
			else
				glutGameModeString(gameModeString);
			break;
		case GLUT_KEY_F3:
			// установить разрешение и цвет
			glutGameModeString("1280x720:32");
			// включить полноэкранный режим
			if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
				glutEnterGameMode();
				sprintf(gameModeString,"1280x720:32");
				// регистрация обратных вызовов
				// и инициализация OpenGL
				init();
			}
			else
				glutGameModeString(gameModeString);
			break;
		case GLUT_KEY_F4:
			// установить разрешение и цвет
			glutGameModeString("1366x768:32");
			// включить полноэкранный режим
			if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
				glutEnterGameMode();
				sprintf(gameModeString,"1366x768:32");
				// регистрация обратных вызовов
				// и инициализация OpenGL
				init();
			}
			else
				glutGameModeString(gameModeString);
			break;
		case GLUT_KEY_F5:
			// установить разрешение и цвет
			glutGameModeString("1680x1050");
			// включить полноэкранный режим
			if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
				glutEnterGameMode();
				sprintf(gameModeString,"1680x1050");
				// регистрация обратных вызовов
				// и инициализация OpenGL
				init();
			}
			else
				glutGameModeString(gameModeString);
			break;
		case GLUT_KEY_F6:
			//вернуться к окну по умолчанию
			w = 800;h = 600;
			if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) != 0) {
				glutLeaveGameMode();
				//init();
			}
			break;
	}
	if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) == 0)
		sprintf(currentMode,"Window MODE");
	else
		sprintf(currentMode,
			"Mode: Game Mode %dx%d at %d hertz, %d bpp",
			glutGameModeGet(GLUT_GAME_MODE_WIDTH),
			glutGameModeGet(GLUT_GAME_MODE_HEIGHT),
			glutGameModeGet(GLUT_GAME_MODE_REFRESH_RATE),
			glutGameModeGet(GLUT_GAME_MODE_PIXEL_DEPTH));
}
 
void releaseKey(int key, int x, int y) {
 
	switch (key) {
		case GLUT_KEY_UP :
		case GLUT_KEY_DOWN : deltaMove = 0;break;
	}
}
 
// -----------------------------------	//
//            функции мыши				//
// -----------------------------------	//
 
void mouseMove(int x, int y) 
{
	// только когда левая кнопка не активна
	if (xOrigin >= 0) 
	{
		// обновить deltaAngle
		deltaAngle = (x - xOrigin) * 0.001f;
		// обновить направление камеры
		lx = sin(angle + deltaAngle);
		lz = -cos(angle + deltaAngle);
	}
}
 
void mouseButton(int button, int state, int x, int y) 
{
	// только начало движение, если левая кнопка мыши нажата
	if (button == GLUT_LEFT_BUTTON) 
	{
		// когда кнопка отпущена
		if (state == GLUT_UP) 
		{
			angle += deltaAngle;
			xOrigin = -1;
		}
		else  
		{// state = GLUT_DOWN
			xOrigin = x;
		}
	}
}
 
void init() {
 
	// регистрация вызовов
	glutDisplayFunc(renderScene);
	glutReshapeFunc(changeSize);
	glutIdleFunc(renderScene);
 
	glutIgnoreKeyRepeat(1);
	glutKeyboardFunc(processNormalKeys);
	glutSpecialFunc(pressKey);
	glutSpecialUpFunc(releaseKey);
	glutMouseFunc(mouseButton);
	glutMotionFunc(mouseMove);
 
	// OpenGL инициализация
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
}
 
// ------------------------------------	//
//             main()			//
// -----------------------------------	//
 
int main(int argc, char **argv) {
 
	// инициализация GLUT и создание окна
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(800,600);
	glutCreateWindow("Урок 13");
 
	// регистрация вызовов
	init();
 
	// главный цикл
	glutMainLoop();
 
	return 1;
}