for (int i = 0; i < object.nTria; i++)
{
Tria& t = object.t[i];
ReadLine (fp, line);
sscanf (line, "%f %f %f", &t.nx, &t.ny, &t.nz);
for (int j = 0; j < 3; j++)
{
ReadLine (fp, line);
Vertex& v = t.v[j];
sscanf (line, "%f %f %f %f %f", &v.x, &v.y, &v.z, &v.s, &v.t);
}
}
fclose (fp);
return true;
}
С учетом наличия структур Vertex, Tria и Object, а также в предположении, что данные прочитаны из файла, функция перерисовки выглядит довольно просто. Она создает объект, составляя его из множества треугольников, хранимых в объекте object.
void Draw ()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef (upDown, 1, 0, 0); // Вращение головы (взгляд ввер-вниз)
glRotatef (-angleY, 0, 1, 0); // Вращение корпуса (направление движения)
glTranslatef (-xpos, -(ypos + wave), -zpos); // Перемещение
glBindTexture (GL_TEXTURE_2D, texture[filter]); // Выбор одной из 3-х текстур
glBegin (GL_TRIANGLES);
for (int i = 0; i < object.nTria; i++) // По всем треугольникам
{
Tria& t = object.t[i];
glNormal3f (t.nx, t.ny, t.nz); // Одна нормаль
for (int j = 0; j < 3; j++) // и три вершины
{
Vertex& v = t.v[j];
glTexCoord2f (v.s, v.t);
glVertex3f (v.x, v.y, v.z);
}
}
glEnd();
}
Функция LoadTexture имеет тот же вид, что и раньше, а в функцию Init введены изменения, которые учитывают факт того, что стены должны отражать свет с обеих сторон, несмотря на то, что для каждой стены задано только одно направление нормали. Это делает вызов функции.
glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, TRUE);
с параметром TRUE. Убедитесь, что при задании параметра FALSE сцена приобретает совсем другой облик. Правда, этот эффект нивелируется добавкой фонового окружающего освещения.
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, ambModel);
Управляйте этим параметром, как и раньше — с помощью клавиши 'a' (ambient).
bool Init ()
{
::GetCurrentDirectory (MAX_PATH-1, curDir);
if (pFile[0] == 0)
{
pFile[0] = strcpy (new TCHAR[MAX_PATH], curDir);
pFile[0] = gInfo.bFull ? strcat(pFile[0],"/Data/NeHe.bmp") : FileDlg(true);
}
if (!LoadTexture (pFile[0], texture))
return false;
glClearColor (0, 0, 0, 0);
glShadeModel (GL_SMOOTH);
glClearDepth (1);
glDepthFunc (GL_LESS);
glEnable (GL_DEPTH_TEST);
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, FALSE);
glEnable (GL_LIGHT0);
glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv (GL_LIGHT0, GL_SPECULAR, specular);
glLightfv (GL_LIGHT0, GL_POSITION, position);
glEnable (GL_TEXTURE_2D);
glBlendFunc (GL_SRC_ALPHA, GL_ONE);
return SetupWorld();
}
Функция Update должна управлять: фильтрацией текстуры (F), смешением цветов (B), позицией центра сцены (клавиши стрелок), направлением взгляда (PgUp, PgDn), фоновой подсветкой (А). Аккуратно введите изменения в тело предыдущей версии (только в те ветви, которые необходимо).
if (gInfo.keys['A'] && !ap)
{
ap = true; amb = !amb;
if (!amb)
{
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, ambient);
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
}
else
{
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, ambModel);
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, ambModel);
}
return;
}
if (!gInfo.keys['A'])
ap = false;
if (gInfo.keys[VK_PRIOR])
upDown -= 1;
if (gInfo.keys[VK_NEXT])
upDown += 1;
if (gInfo.keys[VK_UP])
{
xpos -= speed * sin (heading);
zpos -= speed * cos (heading);
advance += step;
wave = speed * sin (advance);
}
if (gInfo.keys[VK_DOWN])
{
xpos += speed * sin (heading);
zpos += speed * cos (heading);
advance -= step;
wave = speed * sin (advance);
}
if (gInfo.keys[VK_RIGHT])
{
heading -= speed;
angleY = toDeg * heading;
}
if (gInfo.keys[VK_LEFT])
{
heading += speed;
angleY = toDeg * heading;
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.