Каркас Windows-приложения. Особенности нового каркаса. Перемещение в пространстве (с текстурированными стенами), страница 14

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;

}