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

Вход на сайт

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

Построения
на плоскости (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

Сначала посмотрим диспетчер задач с программой из исходного когда урока 16.
Приложение имеет имя testapp.exe в диспетчере задач и занимает приблизительно 13 процентов системного времени. Но CPU - AMD 8 core, а значит наше приложение загружает одно ядро на 100%.

На рисунке это видно:

Итоговый код с использованием glutPostRedisplay.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <glut.h>
 
// угол поворота камеры
float angle = 0.0f;
// координаты вектора направления движения камеры
float lx=0.0f,lz=-1.0f, ly = 0.0f;
// XZ позиция камеры
float x=0.0f, z=5.5f, y = 1.65f;
//Ключи статуса камеры. Переменные инициализируются нулевыми значениями
//когда клавиши не нажаты
float deltaAngle = 0.0f;
float deltaMove = 0;
int xOrigin = -1;
//ширина и высота окна
int h,w;
//переменные для вычисления кадров в секунду
int frame;
long time, timebase;
char s[50];
// переменные для хранения идентификаторв окна
int mainWindow, subWindow1,subWindow2,subWindow3;
//Граница между подокнами
int border = 6;
 
void setProjection(int w1, int h1)
{
	float ratio;
	// На ноль не делим
	ratio = 1.0f * w1 / h1;
	// обнуляем координаты матрицы перед модификацией
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//устанавливаем камеру
	glViewport(0, 0, w1, h1);
 
	// Установить объем отсечения
	gluPerspective(45,ratio,0.1,1000);
	glMatrixMode(GL_MODELVIEW);
}
 
void changeSize(int w1,int h1) {
 
	if(h1 == 0)
		h1 = 1;
 
	// сохраним эти значения
	w = w1;
	h = h1;
 
	// установить активным подокно 1
	glutSetWindow(subWindow1);
	// resize and reposition the sub window
	glutPositionWindow(border,border);
	glutReshapeWindow(w-2*border, h/2 - border*3/2);
	setProjection(w-2*border, h/2 - border*3/2);
 
	// установить активным подокно 2
	glutSetWindow(subWindow2);
	// изменить размеры и позиция подокна
	glutPositionWindow(border,(h+border)/2);
	glutReshapeWindow(w/2-border*3/2, h/2 - border*3/2);
	setProjection(w/2-border*3/2,h/2 - border*3/2);
 
	// установить активным подокно 3
	glutSetWindow(subWindow3);
	// изменить размеры и позиция подокна
	glutPositionWindow((w+border)/2,(h+border)/2);
	glutReshapeWindow(w/2-border*3/2,h/2 - border*3/2);
	setProjection(w/2-border*3/2,h/2 - border*3/2);
}
 
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);
	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 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 renderScene2() {
 
// нарисуем "землю"
 
	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 снеговика
	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();
			glPopMatrix();
		}
}
 
//функция рендеринга основного окна
void renderScene() {
	glutSetWindow(mainWindow);
	glClear(GL_COLOR_BUFFER_BIT);
	glutSwapBuffers();
}
 
// функция рендеринга для подокна 1
void renderScenesw1() {
 
	glutSetWindow(subWindow1);
 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glLoadIdentity();
	gluLookAt(x, y, z,
		  x + lx,y + ly,z + lz,
		  0.0f,1.0f,0.0f);
 
	renderScene2();
 
	// счётчик кадров в секунду
 	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();
 
	glPushMatrix();
	glLoadIdentity();
	renderBitmapString(5,30,0,GLUT_BITMAP_HELVETICA_12,s);
	glPopMatrix();
 
	restorePerspectiveProjection();
 
	glutSwapBuffers();
}
 
// функция рендеринга для подокна 2
void renderScenesw2() {
 
	glutSetWindow(subWindow2);
 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glLoadIdentity();
	gluLookAt(x, y+15, z,
		  x ,y - 1,z,
		  lx,0,lz);
 
	// нарисовать красный конус в области основной камеры
	glPushMatrix();
	glColor3f(1.0,0.0,0.0);
	glTranslatef(x,y,z);
	glRotatef(180-(angle+deltaAngle)*180.0/3.14,0.0,1.0,0.0);
	glutSolidCone(0.2,0.8f,4,4);
	glPopMatrix();
 
	renderScene2();
 
	glutSwapBuffers();
}
 
// функция рендеринга для подокна 3
void renderScenesw3() {
 
	glutSetWindow(subWindow3);
 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glLoadIdentity();
	gluLookAt(x-lz*10 , y, z+lx*10,
		  x ,y ,z ,
		  0.0f,1.0f,0.0f);
 
	// нарисовать красный конус в области основной камеры
	glPushMatrix();
	glColor3f(1.0,0.0,0.0);
	glTranslatef(x,y,z);
	glRotatef(180-(angle+deltaAngle)*180.0/3.14,0.0,1.0,0.0);
	glutSolidCone(0.2,0.8f,4,4);
	glPopMatrix();
 
	renderScene2();
 
	glutSwapBuffers();
}
 
// Глобальная функция рендеринга
void renderSceneAll() {
 
	// проверить перемещения камеры от клавиатуры
	if (deltaMove) {
		computePos(deltaMove);
		glutSetWindow(mainWindow);
		glutPostRedisplay();
	}
 
	renderScene();
	renderScenesw1();
	renderScenesw2();
	renderScenesw3();
}
 
// -----------------------------------	//
//            клавиатура				//
// -----------------------------------	//
 
void processNormalKeys(unsigned char key, int xx, int yy) {
 
	if (key == 27) {
		glutDestroyWindow(mainWindow);
		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;
	}
	glutSetWindow(mainWindow);
	glutPostRedisplay();
 
}
 
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);
 
		glutSetWindow(mainWindow);
		glutPostRedisplay();
	}
}
 
void mouseButton(int button, int state, int x, int y) {
 
	// только начало движение, если левая кнопка мыши нажата
	if (button == GLUT_LEFT_BUTTON) {
 
		//когда кнопка отпущена
		if (state == GLUT_UP) {
			angle += deltaAngle;
			deltaAngle = 0.0f;
			xOrigin = -1;
		}
		else  {// state = GLUT_DOWN
			xOrigin = x;
 
		}
	}
}
 
// ------------------------------------	//
//             main()					//
// -----------------------------------	//
 
void init() {
 
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	// регистрация вызовов
	glutIgnoreKeyRepeat(1);
	glutKeyboardFunc(processNormalKeys);
	glutSpecialFunc(pressKey);
	glutSpecialUpFunc(releaseKey);
	glutMouseFunc(mouseButton);
	glutMotionFunc(mouseMove);
}
 
int main(int argc, char **argv) {
 
	// инициализация GLUT и создание окна
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(800,800);
	mainWindow = glutCreateWindow("Урок 18");
 
	// регистрация вызовов для главного окна
	glutDisplayFunc(renderSceneAll);
	glutReshapeFunc(changeSize);
 
	// Удаление пустой функции для сохранения ресурсов CPU и GPU
	//glutIdleFunc(renderSceneAll);
	init();
 
	// подокна
	subWindow1 = glutCreateSubWindow(mainWindow, border,border,w-2*border, h/2 - border*3/2);
	glutDisplayFunc(renderScenesw1);
	init();
 
	subWindow2 = glutCreateSubWindow(mainWindow, border,(h+border)/2,w/2-border*3/2, h/2 - border*3/2);
	glutDisplayFunc(renderScenesw2);
	init();
 
	subWindow3 = glutCreateSubWindow(mainWindow, (w+border)/2,(h+border)/2,w/2-border*3/2,h/2 - border*3/2);
	glutDisplayFunc(renderScenesw3);
	init();
 
	// главный цикл
	glutMainLoop();
 
	return 1;
}

Теперь посмотрим диспетчер задач с программой из итогового кода.
Приложение имеет имя testapp.exe в диспетчере задач и занимает приблизительно 00 процентов системного времени в режиме простоя. Метод является очень сильно оптимизирующим ресурсы CPU и GPU.