Шаг 43 - Сложная поверхность

В этом шаге попробуем загрузить из файла координаты вершин и нормалей и нарисовать сложную поверхность. Возьмем чистый Win32 проект. Для упрощения жизни будем cчитывать все вершины в статический массив (хотя по уму надо читать в более сложную систему данных, но это пример и только) Не спрашивайте меня откуда я взял файл данных. Признаюсь чесно, я его своровал где-то в сети с какого-то из многочисленных примеров по OpenGL, так что не бейте сильно.

Итак, предположим, что у нас не более чем 20000 вершин:

#define MAX_VERTS	20000

Создадим массивы вершин и нормалей:

GLfloat verts[MAX_VERTS][3];
GLfloat norms[MAX_VERTS][3];

Создадим переменную списка модели и переменную для хранения реального количества вершин и нормалей:

GLuint shape;
GLuint shape_max_verts;

Справедливости ради объявим переменную - дескриптор файла:

FILE* fd;

В StartRC() добавим строки для чтения данных из файла:

GLvoid StartRC(HWND hWnd)
{
	glClearColor (0.5, 0.5, 0.75, 1.0);

	glEnable(GL_LIGHTING);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_LIGHT0);

	fd = fopen("Sample.dat", "r+");

	for(int i=0; i<MAX_VERTS; i++)
	{
		int end = fscanf(fd, "%f", &verts[i][0]);
		if(end==EOF)
		{
			shape_max_verts = i;
			break;
		}
		fscanf(fd, "%f", &verts[i][1]);
		fscanf(fd, "%f", &verts[i][2]);

		fscanf(fd, "%f", &norms[i][0]);
		fscanf(fd, "%f", &norms[i][1]);
		fscanf(fd, "%f", &norms[i][2]);
	}
	CalcList();
}

В функции формирования списка воспользуемся полученной переменной shape_max_verts:

GLvoid CalcList(void)
{
	shape = glGenLists(1);
	glNewList(shape, GL_COMPILE);
	glBegin(GL_TRIANGLE_STRIP);
		for(unsigned int i=0; i<shape_max_verts; i++)
		{
			glNormal3fv(norms[i]);
			glVertex3fv(verts[i]);
		}
	glEnd();
	glEndList();
}

Вот и вся подготовка, теперь просто отображаем сгенерированный список:

GLvoid Draw()
{
	static GLfloat rot;
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glRotatef(rot, 1.0f, 1.0f, 1.0f);
	glCallList(shape);
	glPopMatrix();
	rot++;
	SwapBuffers(hDC);
}

Осталось только удалить список в StopRC():

GLvoid StopRC(HWND hWnd)
{
	glDeleteLists(shape, 1);
	fclose(fd);

	glDisable(GL_LIGHTING);
	glDisable(GL_LIGHT0);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_COLOR_MATERIAL);
}

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Kirill V. Ratkin - 5.06.2000