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

Вход на сайт

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

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

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

Спасибо за реализацию, она действительно быстрая. Но не все линии отрисовывает в нужную сторону... Необходимо добавить проверку для случая X-линии if(y1 "<" y0) grad=-grad; и аналогично для Y-линии if(x1 "<" x0) grad=-grad; P.S. На...
Отличные уроки(учу GL по ним), только в renderScene нужно добавить очистку буфера цвета и буфера глубины. При изменении размеров треугольники размножаются)
как исправить это , сделал все по инструкции
Timer1 - выдает ошибку. Использовал IdleTimer1, работает! unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, OpenGLContext, GL, GLU; type { TForm1 } TForm1 =...
в коде присутствуют ошибки! // Считываем координаты procedure TForm1.getCoords(Sender: TObject); var j1:longint; begin n:= StrToInt(Edit2.Text); //число точек s1:=Edit1.Text; s2:=''; i := 1; j:=1; k:=0...

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

Яндекс.Метрика Рейтинг@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' меню появляется опять, но во втором пункте уже нет подменю. Не подскажете, почему так?

Спасибо