КулЛиб - Классная библиотека! Скачать книги бесплатно
Всего книг - 713375 томов
Объем библиотеки - 1405 Гб.
Всего авторов - 274722
Пользователей - 125100

Последние комментарии

Новое на форуме

Новое в блогах

Впечатления

Влад и мир про Семенов: Нежданно-негаданно... (Альтернативная история)

Автор несёт полную чушь. От его рассуждений уши вянут, логики ноль. Ленин был отличным экономистом и умел признавать свои ошибки. Его экономическим творчеством стал НЭП. Китайцы привязали НЭП к новым условиям - уничтожения свободного рынка на основе золота и серебра и существование спекулятивного на основе фантиков МВФ. И поимели все технологии мира в придачу к ввозу промышленности. Сталин частично разрушил Ленинский НЭП, добил его

  подробнее ...

Рейтинг: +3 ( 3 за, 0 против).
Влад и мир про Шенгальц: Черные ножи (Альтернативная история)

Читать не интересно. Стиль написания - тягомотина и небывальщина. Как вы представляете 16 летнего пацана за 180, худого, болезненного, с больным сердцем, недоедающего, работающего по 12 часов в цеху по сборке танков, при этом имеющий силы вставать пораньше и заниматься спортом и тренировкой. Тут и здоровый человек сдохнет. Как всегда автор пишет о чём не имеет представление. Я лично общался с рабочим на заводе Свердлова, производившего

  подробнее ...

Рейтинг: +1 ( 1 за, 0 против).
Влад и мир про Владимиров: Ирландец 2 (Альтернативная история)

Написано хорошо. Но сама тема не моя. Становление мафиози! Не люблю ворьё. Вор на воре сидит и вором погоняет и о ворах книжки сочиняет! Любой вор всегда себя считает жертвой обстоятельств, мол не сам, а жизнь такая! А жизнь кругом такая, потому, что сам ты такой! С арифметикой у автора тоже всё печально, как и у ГГ. Простая задачка. Есть игроки, сдающие определённую сумму для участия в игре и получающие определённое количество фишек. Если в

  подробнее ...

Рейтинг: 0 ( 0 за, 0 против).
DXBCKT про Дамиров: Курсант: Назад в СССР (Детективная фантастика)

Месяца 3-4 назад прочел (а вернее прослушал в аудиоверсии) данную книгу - а руки (прокомментировать ее) все никак не доходили)) Ну а вот на выходных, появилось время - за сим, я наконец-таки сподобился это сделать))

С одной стороны - казалось бы вполне «знакомая и местами изьезженная» тема (чуть не сказал - пластинка)) С другой же, именно нюансы порой позволяют отличить очередной «шаблон», от действительно интересной вещи...

В начале

  подробнее ...

Рейтинг: +2 ( 2 за, 0 против).
DXBCKT про Стариков: Геополитика: Как это делается (Политика и дипломатия)

Вообще-то если честно, то я даже не собирался брать эту книгу... Однако - отсутствие иного выбора и низкая цена (после 3 или 4-го захода в книжный) все таки "сделали свое черное дело" и книга была куплена))

Не собирался же ее брать изначально поскольку (давным давно до этого) после прочтения одной "явно неудавшейся" книги автора, навсегда зарекся это делать... Но потом до меня все-таки дошло что (это все же) не "очередная злободневная" (читай

  подробнее ...

Рейтинг: +1 ( 1 за, 0 против).

MFC и OpenGL (fb2) читать постранично


 [Настройки текста]  [Cбросить фильтры]

MFC и OpenGL

"Подать сюда MFС!!! – кричил он, топая всеми 4-мя лапами."

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

Для начала сделаем приложение MFC как диалог. Я назвал его BitScroll. Как это делать? Смотрите шаги по MFC.

Теперь, при помощи визарда добавим функцию

BOOL CBitScrollDlg::PreCreateWindow(CREATESTRUCT& cs) {

 cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

 return CDialog::PreCreateWindow(cs);

}

Помните, мы устанавливали слиль окна в функции CreateWindow? Так вот это действие по смыслу тоже самое. Напомню как это выглядело в Win32API:

hWnd = CreateWindow("Skeleton", "Skeleton", WS_OVERLAPPEDWINDOW |  WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 50, 50, 700, 400, NULL, NULL, hInst, NULL);

Теперь обратимся к функции OnInitDialog(). В ней сначала вызывается функция базового класса, т.е. CDialog, а потом устанавливаются иконки для диалога. Давайте вставим наш код между иконками и CDialog::OnInitDialog().

SetWindowPos(&wndTop, 0, 0, WIDTH, HEIGHT, SWP_NOMOVE);

pDC = GetDC();

CenterWindow();

Init(); SetTimer(1,SPEED, NULL);

Теперь посмотрим, что мы сделали. Сначала сделаем окно нужного нам размера (макросы WIDTH и HEIGHT объявлены так #define WIDTH 640 и #define HEIGHT 480 в заголовочном файле).

Затем получим контекст для рисования. Установимся в центр вселенной и… вот, тут самое интересное, тут мы вызываем нашу собственную функцию, которая будет инициализировать OpenGL (напоминаю, что тоже самое делала функция Initial в программе на Win32API).

А потом включаем таймер, чтобы обеспечить анимацию. Обратимся теперь к Init(). Выглядит она итак:

void CBitScrollDlg::Init() {

 CRect rect;

 HGLRC hrc;

 if (!bSetupPixelFormat()) return;

 hrc = wglCreateContext(pDC->GetSafeHdc());

 ASSERT(hrc != NULL);

 wglMakeCurrent(pDC->GetSafeHdc(), hrc);

 GetClientRect(&rect);

 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

 glClearDepth(1.0);

 glDepthFunc(GL_LESS);

 glEnable(GL_DEPTH_TEST);

 glShadeModel(GL_SMOOTH);

 glMatrixMode(GL_PROJECTION);

 glLoadIdentity();

 gluPerspective(45.0f, (GLfloat)rect.right / (GLfloat)rect.bottom, 0.1f, 100.0f);

 glMatrixMode(GL_MODELVIEW);

}

Что мы тут делаем? Прежде всего вызываем ф-ию SetupPixelFormat(), это опять наша функция и мы посмотрим ее чуть позже.

Далее, как и раньше, получаем контекст рендеринга (маленькая деталь, ранее pDC(а точнее эта переменная называлась hDC) была объявлена как static HDC hDC, сейчас контекст рисования является пременной типа CDC, а ф-ция wglCreateContext и другие функции OpenGL требуют в качестве аргумента переменную типа HDC. Поэтому мы получаем этот hardware context с помощью pDC->GetSafeHdc()).

Затем делаем этот контекст текущим и настраиваем область отображения, так как это делалось в Initial() (Win32API)

Функция bSetupPixelFormat() содержит следующее:

BOOL CBitScrollDlg::bSetupPixelFormat() {

 static PIXELFORMATDESCRIPTOR pfd = {

  sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd

  1, // version number

  PFD_DRAW_TO_WINDOW | // support window

  PFD_SUPPORT_OPENGL | // support OpenGL

  PFD_DOUBLEBUFFER, // double buffered

  PFD_TYPE_RGBA, // RGBA type

  24, // 24-bit color depth

  0, 0, 0, 0, 0, 0, // color bits ignored

  0, // no alpha buffer

  0, // shift bit ignored

  0, // no accumulation buffer

  0, 0, 0, 0, // accum bits ignored

  32, // 32-bit z-buffer

  0, // no stencil buffer

  0, // no auxiliary buffer

  PFD_MAIN_PLANE, // main layer

  0, // reserved

  0, 0, 0 // layer masks ignored

 };

 int pixelformat;

 if ((pixelformat = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd)) == 0) {

  MessageBox("ChoosePixelFormat failed");

  return FALSE;

 }

 if (SetPixelFormat(pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) {

  MessageBox("SetPixelFormat failed");

  return FALSE;

 }

 return TRUE;

}

Как не трудно заметить, она почти полностью взята из Win32API приложения за исключением того, что hDC заменена на pDC->GetSafeHdc().

Теперь добавим в нашу программку обработчик от таймера (мы его недавно сделали в ф-ции Init())

void CBitScrollDlg::OnTimer(UINT nIDEvent) {

 DrawScene();

 CDialog::OnTimer(nIDEvent);

}

Все тривиально. По смыслу ясно, что каждый раз, когда срабатывает обработчик таймера (а делает он это часто) рисуется сцена. Таким образом получается анимация. Посмотрим на эту функцию:

void CBitScrollDlg::DrawScene() {

 static GLfloat angle = 0;

 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 glLoadIdentity();

 glTranslatef(0.0f, 0.0f, –2.0f);

 glRotatef(angle, 1.0f, 0.5f, 0.3f);

 glBegin(GL_QUADS);

 glColor3f(1.0f, 0.0f, 1.0f);

 glVertex3f(-0.5f, 0.5f, 0.0f);

 glColor3f(1.0f, 1.0f, 1.0f);

 glVertex3f(0.5f, 0.5f, 0.0f);

 glColor3f(0.0f, 1.0f, 1.0f);

 glVertex3f(0.5f, –0.5f, 0.0f);

 glColor3f(0.0f, 0.0f, 1.0f);

 glVertex3f(-0.5f, –0.5f, 0.0f);

 glEnd();

 glFinish();

 SwapBuffers(wglGetCurrentDC());

 angle += 0.5f;

}

По моему проще уже некуда. Я надеюсь, что все ясно.

Ну вот казалось бы и все. Единственное, что остается сделать – убраться за собой. Т.е. надо при выходе удалить контекст рендеринга и убить таймер.

Эти вещи надо сделать в 2-х обработчиках OnClose и OnDestroy. Посмотрим на них:

void CBitScrollDlg::OnClose() {

 // TODO: Add your message handler code here and/or call default

 HGLRC hrc;

 KillTimer(1);

 hrc = ::wglGetCurrentContext();

 ::wglMakeCurrent(NULL, NULL);

 if (hrc)