Книги

OpenGL / FPC - Глава 11

Опять-таки, давайте взглянем на пример из прошлой главы. Снова есть на что обратить внимание. Я имею ввиду зазубренные края нашей пирамиды. Кажется, будто задняя часть поверхности светится через край. Некрасиво.

Решение состоит в том, чтобы убрать поверхности, расположенные позади других поверхностей. Их вообще не должно быть видно, чтобы ничего ни сияло через края.

Если призадуматься, то можно уловить в этом и рациональное зерно. Представьте сцену, созданную из 100.000 треугольников. Но из этих 100.000 в один момент видны только 40.000 — остальные 60.000 спрятаны за ними. Так что прорисовка всех 100.000 является попросту большой тратой времени CPU/ GPU. Следовательно, если убрать все треугольники, что не видны, это сэкономит 60% времени CPU/ GPU! И ваша программа будет выглядеть намного лучше. Здорово!

И что наиболее приятно: указать OpenGL, чтобы невидимые поверхности не рисовались, совсем несложно. Это достигается в OpenGL_Init.

procedure OpenGL_Init;
begin

  glClearColor( 0.0, 0.0, 0.0, 0.0 );

  glViewport( 0, 0, width, height );
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();

  gluPerspective(45.0,width/height,0.1,100.0);

  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();

  glClearDepth(1.0);              // Depth Buffer Setup
  glEnable(GL_DEPTH_TEST);        // Enables Depth Testing
  glDepthFunc(GL_LEQUAL);         // The Type of Depth Test To do

  glEnable(GL_CULL_FACE);
  glCullFace(GL_BACK);

end;

Первое новшество — это glEnable(GL_CULL_FACE);. Она активирует устранение спрятанных поверхностей. Но как же OpenGL узнает, что что-то спрятано за другой поверхностью? Нет, не из буфера глубины, а по тому, как поверхности рисуются.

Поразмыслите немного — если что-то рисуется против часовой стрелки, мы сможем увидеть его лицевую сторону, а если по — то его тыльную сторону. Так как мы не хотим видеть оборотную сторону наших поверхностей, то мы просто указываем OpenGL убирать все, что показывет нам свой зад.

Это осуществляется при вызове glCullFace();. Параметром может быть либо GL_BACK, либо GL_FRONT (догадайтесь, что они значат).

Поскольку иногда это причинить боль, можно задавать направление, по которому рисуются поверхности. С помощью glFrontFace(GL_CCW) все рисуется против часовой стрелки, а с glFrontFace(GL_CW) все будет иметь front по часовой стрелке.

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

Актуальные версии
FPC3.2.2release
Lazarus3.2release
MSE5.10.0release
fpGUI1.4.1release
links