Войти
ПрограммированиеСтатьиГрафика

Делаем простой редактор бликов. (2 стр)

Вывод бликов с помощью OpenGL

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

Думаю, что инициализировать OpenGL может уже каждый, но все-таки я напомню:

void SetupOpenGL ( window_t &wnd )
{
  unsigned int PixelFormat = 0;

  static  PIXELFORMATDESCRIPTOR pfd=
  {
    sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW |
    PFD_SUPPORT_OPENGL |  PFD_DOUBLEBUFFER, PFD_TYPE_RGBA,
    32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0,
    PFD_MAIN_PLANE, 0, 0, 0, 0
  };

  PixelFormat = ChoosePixelFormat ( wnd.hDC, &pfd );
  SetPixelFormat ( wnd.hDC, PixelFormat, &pfd );
  hRC = wglCreateContext ( wnd.hDC );
  wglMakeCurrent ( wnd.hDC, hRC );
}

Далее разберем две структуры, отвечающие за наши блики:

struct LensStage_t
{
  vector4   Color;
  Pointf_t  Pos;
  uint      TexID;
  int       Size;
};

struct Lens_t
{
  int Count;
  int Size;
  LensStage_t Lens[999];

  void SetLens ( int ind, LensStage_t &lens );
  void SetAllLensSize ( int size );
  void LoadDefault ( void );
};

Вторая структура отвечает за наш проект, то есть здесь есть вся информация о бликах: количество, размер всех бликов (если он одинаковый), блики.

Первая структура отвечает за каждый блик и имеет следующие поля: цвет, положение, идентификатор текстуры, размер блика.

Теперь разберем нашу супер FlexTextureDatabase :)

Принцип загрузки текстур прост. Программа ищет все текстуры в папке Data, отвечающие требованиям поиска, то есть имя lens*.jpg. Где вместо звездочки идет цифра от 1 до 999. То есть для подключения новых текстур нужно всего лишь добавить эти самые текстуры и дать им соответствующие имена.

Теперь ближе к графике. Для обрисовки бликов мы будем использовать

glBlendFunc ( GL_SRC_ALPHA, GL_ONE );

Хотя есть способ и лучше, но мы разберем лишь простейший рендер, заменить его на более продвинутый не составляет труда.

Для вывода двумерных картинок у нас есть три полезные функции:

void Begin2D ( void )
{
  glDisable ( GL_DEPTH_TEST );
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  gluOrtho2D(0, GLWindow.Width, 0, GLWindow.Height);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
}

void End2D ( void )
{
  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glEnable ( GL_DEPTH_TEST );
}

void DrawQuad ( float x, float y, float w, float h, unsigned int texture )
{
  glBindTexture ( GL_TEXTURE_2D, texture );
  y = (float)GLWindow.Height - y - h;
  glBegin ( GL_TRIANGLE_STRIP );
    glTexCoord2f ( 0.0f, 0.0f );  glVertex2f ( x,     y );
    glTexCoord2f ( 1.0f, 0.0f );  glVertex2f ( x + w, y );
    glTexCoord2f ( 0.0f, 1.0f );  glVertex2f ( x,     y + h );
    glTexCoord2f ( 1.0f, 1.0f );  glVertex2f ( x + w, y + h );
  glEnd();
}

Для рисования двумерных картинок нам нужно всего лишь перейти в двумерный режим, вызвав функцию Begin2D, затем мы рисуем прямоугольник заданный экранными координатами и шириной/высотой. После того как мы закончили рисование, нужно выйти из плоского режима вызвав функцию End2D. Если у вас трехмерное приложение, то эти функции не тронут настройки вашей перспективы.

И теперь функция для вывода бликов на экран.

void RenderLens ( float lx, float ly, Lens_t &l )
{
  int i = 0;
  float cx = (float)(GLWindow.Width  / 2);
  float cy = (float)(GLWindow.Height / 2);
  float vx = cx - lx;
  float vy = cy - ly;

  l.Lens[0].Pos.x = lx;
  l.Lens[0].Pos.y = ly;
  l.Lens[1].Pos.x = lx + vx / 4.0f;
  l.Lens[1].Pos.y = ly + vy / 4.0f;
  l.Lens[2].Pos.x = lx + vx / 2.0f;
  l.Lens[2].Pos.y = ly + vy / 2.0f;
  l.Lens[3].Pos.x = lx + vx / 1.5f;
  l.Lens[3].Pos.y = ly + vy / 1.5f;
  l.Lens[4].Pos.x = lx + vx / 1.1f;
  l.Lens[4].Pos.y = ly + vy / 1.1f;
  l.Lens[5].Pos.x = lx + vx * 1.1f;
  l.Lens[5].Pos.y = ly + vy * 1.1f;
  l.Lens[6].Pos.x = lx + vx * 1.5f;
  l.Lens[6].Pos.y = ly + vy * 1.5f;
  l.Lens[7].Pos.x = lx + vx * 2.5f;
  l.Lens[7].Pos.y = ly + vy * 2.5f;
  l.Lens[8].Pos.x = lx + vx * 3.0f;
  l.Lens[8].Pos.y = ly + vy * 3.0f;

  for ( i = 0; i < l.Count; i++ )
  {
    l.Lens[i].Pos.x -= l.Lens[i].Size / 2;
    l.Lens[i].Pos.y -= l.Lens[i].Size / 2;
  }

  glColor4fv ( color );
  glEnable ( GL_TEXTURE_2D );
  glEnable ( GL_BLEND );
  glBlendFunc ( GL_SRC_ALPHA, GL_ONE );
  Begin2D();
    for ( i = 0; i < l.Count; i++ )
    {
      glColor4fv ( l.Lens[i].Color );
      DrawQuad   ( (float)l.Lens[i].Pos.x, (float)l.Lens[i].Pos.y, 
                   (float)l.Lens[i].Size, (float)l.Lens[i].Size, l.Lens[i].TexID  );
    }
  End2D();
  glDisable ( GL_BLEND );
  glDisable ( GL_TEXTURE_2D );
}

Так как в нашей программе положения главного блика задается координатами мышки, то и передавать в функцию мы будем координаты мышки. Еще нужно передать нашу переменную-проект типа Lens_t, где хранятся все наши параметры бликов. Сам метод создания бликов достаточно прост, на gamedev.ru давали адрес, на статью где рассматривается метод создания бликов.

Страницы: 1 2 3 Следующая »

#эффекты, #OpenGL, #tools

26 марта 2003

Комментарии [3]