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

Вход на сайт

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

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

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

Всем у кого не работает. файл 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...
Не получается, емаё
огромное спасибо за подробное объяснение про 3д графику на питоне, в интернете очень мало подобной информации
dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(

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

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

GLUT даже позволяет изменять все меню в середине нашего приложения. Две функции: glutSetMenu и glutGetMenu. Синтаксис:

void glutSetMenu(int menu);

Параметры:

menu - индекс ранее созданного меню.

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

int glutGetMenu(void);

Эта функция возвращает индекс текущего меню. Затем мы приведем пример, где мы используем два меню, которые меняются местами, когда пользователь нажимает клавишу F1.

void processSpecialKeys(int c, int x, int y) {
 
	if (!flag) {
		if (c == GLUT_KEY_F1) {
			int x = glutGetMenu();
			if (x == menu1)
				glutSetMenu(menu2);
			else
				glutSetMenu(menu1);
			// Не забудьте приложить меню!!!
			glutAttachMenu(GLUT_RIGHT_BUTTON);
		}
	}
}
 
void createGLUTMenus() {
 
	menu2 = glutCreateMenu(processMenuEvents);
	glutAddMenuEntry("Blue",BLUE);
	glutAddMenuEntry("Green",GREEN);
	glutAddMenuEntry("Red",RED);
 
	menu1 = glutCreateMenu(processMenuEvents);
	glutAddMenuEntry("Red",RED);
	glutAddMenuEntry("Green",GREEN);
	glutAddMenuEntry("Blue",BLUE);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}

Итоговый код.
Здесь мы включим весь материала, который мы представили ранее в нашем маленьком приложении. Мы собираемся добавить меню для приложений, подменю и заменяемое меню. Просто скопируйте и вставьте следующий код в ваш проект. Правая кнопка мыши должна открыть меню. Клавиши 'S' и 'C' будет влиять на меню.

#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;
 
// Определения констант для меню
#define RED		1
#define GREEN	2
#define BLUE	3
#define ORANGE	4
 
#define FILL	1
#define LINE	2
 
#define SHRINK	1
#define NORMAL	2
 
// идентификаторы меню
int fillMenu, shrinkMenu, mainMenu, colorMenu;
// цвет носа
float red = 1.0f, blue=0.5f, green=0.5f;
// размер снеговика
float scale = 1.0f;
// статус меню
int menuFlag = 0;
 
void changeSize(int w, int h) {
	// предотвращение деления на ноль
	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() {
 	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(1.0f, 0.5f , 0.5f);
	glRotatef(0.0f,1.0f, 0.0f, 0.0f);
	glutSolidCone(0.08f,0.5f,10,2);
}
 
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);
	// полигон (plaine)
	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 снеговика
	for (int i = -4; i < 4; i++)
		for (int j=-4; j < 4; j++)
		{
			glPushMatrix();
			glTranslatef(i*5.0, 0, j * 5.0);
			drawSnowMan();
			glPopMatrix();
		}
 
	glutSwapBuffers();
}
 
// -----------------------------------	//
//            клавиатура				//
// -----------------------------------	//
 
void processNormalKeys(unsigned char key, int xx, int yy) {
 
	glutSetMenu(mainMenu);
	switch (key) {
		case 27:
			glutDestroyMenu(mainMenu);
			glutDestroyMenu(fillMenu);
			glutDestroyMenu(colorMenu);
			glutDestroyMenu(shrinkMenu);
			exit(0);
			break;
 
		case 's':
			if (!menuFlag)
			  glutChangeToSubMenu(2,"Shrink",shrinkMenu);
			break;
		case 'c':
			if (!menuFlag)
				glutChangeToSubMenu(2,"Color",colorMenu);
			break;
	}
	if (key == 27)
		exit(0);
}
 
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;
	}
}
 
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 processMenuStatus(int status, int x, int y) {
	if (status == GLUT_MENU_IN_USE)
		menuFlag = 1;
	else
		menuFlag = 0;
}
 
void processMainMenu(int option) {
 
	//ничего здесь не делаем
	//все действия для подменю
}
 
void processFillMenu(int option) {
	switch (option) {
		case FILL: glPolygonMode(GL_FRONT, GL_FILL); break;
		case LINE: glPolygonMode(GL_FRONT, GL_LINE); break;
	}
}
 
void processShrinkMenu(int option) {
	switch (option) {
		case SHRINK: scale = 0.5f; break;
		case NORMAL: scale = 1.0f; break;
	}
}
 
void processColorMenu(int option) {
	switch (option) {
		case RED :
			red = 1.0f;
			green = 0.0f;
			blue = 0.0f; break;
		case GREEN :
			red = 0.0f;
			green = 1.0f;
			blue = 0.0f; break;
		case BLUE :
			red = 0.0f;
			green = 0.0f;
			blue = 1.0f; break;
		case ORANGE :
			red = 1.0f;
			green = 0.5f;
			blue = 0.5f; break;
	}
}
 
void createPopupMenus() {
	shrinkMenu = glutCreateMenu(processShrinkMenu);
	glutAddMenuEntry("Shrink",SHRINK);
	glutAddMenuEntry("NORMAL",NORMAL);
	fillMenu = glutCreateMenu(processFillMenu);
	glutAddMenuEntry("Fill",FILL);
	glutAddMenuEntry("Line",LINE);
	colorMenu = glutCreateMenu(processColorMenu);
	glutAddMenuEntry("Red",RED);
	glutAddMenuEntry("Blue",BLUE);
	glutAddMenuEntry("Green",GREEN);
	glutAddMenuEntry("Orange",ORANGE);
	mainMenu = glutCreateMenu(processMainMenu);
	glutAddSubMenu("Polygon Mode", fillMenu);
	glutAddSubMenu("Color", colorMenu);
	// прикрепить меню к правой кнопке
	glutAttachMenu(GLUT_RIGHT_BUTTON);
	//статус активности меню
	glutMenuStatusFunc(processMenuStatus);
}
 
// ------------------------------------	//
//             main()					//
// -----------------------------------	//
 
int main(int argc, char **argv) {
 
	// инициализация GLUT и создание окна
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(400,400);
	glutCreateWindow("Урок 10");
 
	//регистрация
	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);
 
	// инициализация меню
	createPopupMenus();
 
	// Главный цикл
	glutMainLoop();
 
	return 1;
}

Должно появляться меню и при нажатии "s" или "c" нижнее меню меняется

Комментарии

Вячеслав аватар
Опубликовано Вячеслав (не проверено) в 7. Ноябрь 2015 - 23:08.

Когда изменяете цвет в функции void processColorMenu(int option), ничего не происходит, вам нужно добавить изменения в функцию, void drawSnowMan(), заменив точные значения цвета на переменные red, green, blue. Так же добавьте где-нибудь использование измененного в меню параметра scale. Я не придираюсь, просто хочется, чтобы код выполнял свои функции.

Горбунов Андрей аватар
Опубликовано Горбунов Андрей в 17. Декабрь 2015 - 10:52.

Работаю на этим

kucanyatko аватар
Опубликовано kucanyatko в 28. Ноябрь 2013 - 18:10.

Здравствуйте,

у меня вопрос
после использования 'c' или 's' меню появляется опять, но во втором пункте уже нет подменю. Не подскажете, почему так?

Спасибо