Делаем простой редактор бликов. (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 давали адрес, на статью где рассматривается метод создания бликов.
26 марта 2003
Комментарии [3]