§ Основной файл main.cpp
Необходимо, чтобы был установлен DevC++#include <windows.h> #include <gl/gl.h> #include "window.cpp" // Главное окно AppWindow* app; // Стартовое окно int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { app = new AppWindow(); return app->start(hInstance, "Example Window", 640, 640); } // Обработчик LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { app->EventProc(hWnd, message, wParam, lParam); }
§ Файл для сборки (makefile.bat)
@echo off echo Build... REM Пути к файлам set MINGW=C:/Program Files/Dev-Cpp/MinGW64 set PLATFORM=x86_64-w64-mingw32 set VERSION=4.9.2 REM Пути к библиотекам set INC1=%MINGW%/include set INC2=%MINGW%/%PLATFORM%/include set INC3=%MINGW%/lib/gcc/%PLATFORM%/%VERSION%/include set INC4=%MINGW%/lib/gcc/%PLATFORM%/%VERSION%/include/c++ set INCLIB=-I"%INC1%" -I"%INC2%" -I"%INC3%" -I"%INC4%" -std=gnu++11 -m32 REM Компиляция файлов rm -f main.exe g++ -c main.cpp -o main.o %INCLIB% g++ -c app.cpp -o app.o %INCLIB% g++ -c window.cpp -o window.o %INCLIB% REM Сборка и очистка g++ main.o app.o window.o -o main.exe -L"%MINGW%/%PLATFORM%/lib32" -static-libgcc -mwindows -lopengl32 -lglu32 -lm -m32 rm -f *.o REM Запуск main.exe pause
§ Основной класс (app.cpp)
#include <windows.h> // Индентификатор таймера #define IDT_TIMER1 1001 // Объявление процедур для окна LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM); // Основные функции для работы class Application { protected: WNDCLASS wc; HWND hWnd; HDC hDC; HGLRC hRC; MSG msg; BOOL bQuit = FALSE; int width, height; public: virtual void InitHook() { } // Запуск кода int start(HINSTANCE hInstance, LPCSTR title, int _width, int _height) { // Регистрация класса wc.style = CS_OWNDC; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "APPClass"; RegisterClass (&wc); // Установка размера width = _width; height = _height; // Создать основное окно hWnd = CreateWindow ( "APPClass", title, WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE, 0, 0, width, height, NULL, NULL, hInstance, NULL); // Подрубка OpenGL EnableOpenGL (hWnd, &hDC, &hRC); // Вызвать функцию потомка InitHook(); // Создать таймер SetTimer(hWnd, IDT_TIMER1, 20, NULL); // Основной программный цикл while (!bQuit) { // Проверить новые сообщения if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { // Выход if (msg.message == WM_QUIT) { bQuit = TRUE; } else { TranslateMessage (&msg); DispatchMessage (&msg); } } } // Удалить таймер KillTimer(hWnd, IDT_TIMER1); // Остановка OpenGL DisableOpenGL (hWnd, hDC, hRC); // Выключить окно DestroyWindow (hWnd); return msg.wParam; } // Обработчик события окна LRESULT CALLBACK EventWnd(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { // Создание окна case WM_CREATE: return 0; // Закрытие окна case WM_CLOSE: PostQuitMessage (0); return 0; // Удаление окна из памяти case WM_DESTROY: return 0; // Нажатие на клавишу case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: PostQuitMessage(0); return 0; } return 0; // Таймер case WM_TIMER: return 0; default: return DefWindowProc (hWnd, message, wParam, lParam); } } // Включение OpenGL void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC) { PIXELFORMATDESCRIPTOR pfd; int iFormat; /* get the device context (DC) */ *hDC = GetDC (hWnd); /* set the pixel format for the DC */ ZeroMemory (&pfd, sizeof (pfd)); pfd.nSize = sizeof (pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE; iFormat = ChoosePixelFormat (*hDC, &pfd); SetPixelFormat (*hDC, iFormat, &pfd); /* create and enable the render context (RC) */ *hRC = wglCreateContext( *hDC ); wglMakeCurrent( *hDC, *hRC ); } // Отключение OpenGL void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC) { wglMakeCurrent (NULL, NULL); wglDeleteContext (hRC); ReleaseDC (hWnd, hDC); } };
§ Класс с реализацией OpenGL (window.cpp)
#include <math.h> #include <gl/gl.h> #include <gl/GLU.h> #include "app.cpp" // Главное окно-обработчик class AppWindow : public Application { protected: float theta; GLuint texture_id; public: // Наследованная виртуальная функция void InitHook() { // Включение возможностей glEnable(GL_DEPTH_TEST); // Включить Z-буфер glEnable(GL_TEXTURE_2D); // Включить текстурирование int w = 512, h = 512; GLuint bgra[w*h]; // Создать тестовую текстуру for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { bgra[i*h + j] = i ^ j; } } // Текстура создается в памяти, назначается GLuint glGenTextures(1, (GLuint *) & texture_id); // Выбираем эту текстуру, работаем с 2D: x, y. glBindTexture(GL_TEXTURE_2D, texture_id); // Интерполяция для приближенных и удаленных объектов glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Повторять текстуры glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra); } // Отслеживаемое событие LRESULT CALLBACK EventProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { // Обработка таймера switch (message) { case WM_TIMER: switch (wParam) { case IDT_TIMER1: // Построение перспективной проекции glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(50, 1, 1, 1000); // Сформировать угол обзора glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 2.0, // Глаз 0.0, 0.0, 0.0, // Куда смотрим 0.0, 1.0, 0.0); // Направление верха // Анимация начинается тут glClearColor (0.0f, 0.0f, 0.0f, 0.0f); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Нарисовать треугольник glRotatef (theta, 0.0f, 0.0f, 1.0f); glBegin (GL_TRIANGLES); glBindTexture(GL_TEXTURE_2D, texture_id); glTexCoord2f(0.0f, 0.0f); glVertex3f (-1.0f, 1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f ( 1.0f, 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f ( 1.0f, -1.0f, -1.0f); glEnd (); // Обмен буферами SwapBuffers (hDC); theta += 1.0f; return 0; } } return EventWnd(hWnd, message, wParam, lParam); } };Загрузка шаблона template_gl.zip
8 мая, 2020
© 2007-2023 Галимая фигня болела