§ Основной файл main.cpp

Необходимо, чтобы был установлен DevC++
1#include <windows.h>
2#include <gl/gl.h>
3#include "window.cpp"
4
5// Главное окно
6AppWindow* app;
7
8// Стартовое окно
9int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) {
10
11    app = new AppWindow();
12    return app->start(hInstance, "Example Window", 640, 640);
13}
14
15// Обработчик
16LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
17    app->EventProc(hWnd, message, wParam, lParam);
18}

§ Файл для сборки (makefile.bat)

1@echo off
2echo Build...
3
4REM Пути к файлам
5set MINGW=C:/Program Files/Dev-Cpp/MinGW64
6set PLATFORM=x86_64-w64-mingw32
7set VERSION=4.9.2
8
9REM Пути к библиотекам
10set INC1=%MINGW%/include
11set INC2=%MINGW%/%PLATFORM%/include
12set INC3=%MINGW%/lib/gcc/%PLATFORM%/%VERSION%/include
13set INC4=%MINGW%/lib/gcc/%PLATFORM%/%VERSION%/include/c++
14set INCLIB=-I"%INC1%" -I"%INC2%" -I"%INC3%" -I"%INC4%" -std=gnu++11 -m32
15
16REM Компиляция файлов
17rm -f main.exe
18g++ -c main.cpp -o main.o %INCLIB%
19g++ -c app.cpp -o app.o %INCLIB%
20g++ -c window.cpp -o window.o %INCLIB%
21
22REM Сборка и очистка
23g++ main.o app.o window.o -o main.exe -L"%MINGW%/%PLATFORM%/lib32" -static-libgcc -mwindows -lopengl32 -lglu32 -lm -m32
24rm -f *.o
25
26REM Запуск
27main.exe
28pause

§ Основной класс (app.cpp)

1#include <windows.h>
2
3// Индентификатор таймера
4#define IDT_TIMER1 1001
5
6// Объявление процедур для окна
7LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM);
8
9// Основные функции для работы
10class Application {
11
12protected:
13
14    WNDCLASS wc;
15    HWND     hWnd;
16    HDC      hDC;
17    HGLRC    hRC;
18    MSG      msg;
19    BOOL     bQuit = FALSE;
20    int      width, height;
21
22public:
23
24    virtual void InitHook() { }
25
26    // Запуск кода
27    int start(HINSTANCE hInstance, LPCSTR title, int _width, int _height) {
28
29        // Регистрация класса
30        wc.style           = CS_OWNDC;
31        wc.lpfnWndProc     = WndProc;
32        wc.cbClsExtra      = 0;
33        wc.cbWndExtra      = 0;
34        wc.hInstance       = hInstance;
35        wc.hIcon           = LoadIcon (NULL, IDI_APPLICATION);
36        wc.hCursor         = LoadCursor (NULL, IDC_ARROW);
37        wc.hbrBackground   = (HBRUSH) GetStockObject (BLACK_BRUSH);
38        wc.lpszMenuName    = NULL;
39        wc.lpszClassName   = "APPClass";
40        RegisterClass (&wc);
41
42        // Установка размера
43        width  = _width;
44        height = _height;
45
46        // Создать основное окно
47        hWnd = CreateWindow (
48            "APPClass",
49            title, WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
50            0, 0, width, height, NULL, NULL, hInstance, NULL);
51
52        // Подрубка OpenGL
53        EnableOpenGL (hWnd, &hDC, &hRC);
54
55        // Вызвать функцию потомка
56        InitHook();
57
58        // Создать таймер
59        SetTimer(hWnd, IDT_TIMER1, 20, NULL);
60
61        // Основной программный цикл
62        while (!bQuit)
63        {
64            // Проверить новые сообщения
65            if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
66
67                // Выход
68                if (msg.message == WM_QUIT) {
69                    bQuit = TRUE;
70                } else {
71                    TranslateMessage (&msg);
72                    DispatchMessage (&msg);
73                }
74            }
75        }
76
77        // Удалить таймер
78        KillTimer(hWnd, IDT_TIMER1);
79
80        // Остановка OpenGL
81        DisableOpenGL (hWnd, hDC, hRC);
82
83        // Выключить окно
84        DestroyWindow (hWnd);
85
86        return msg.wParam;
87    }
88
89    // Обработчик события окна
90    LRESULT CALLBACK EventWnd(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
91
92        switch (message)
93        {
94            // Создание окна
95            case WM_CREATE:
96                return 0;
97
98            // Закрытие окна
99            case WM_CLOSE:
100
101                PostQuitMessage (0);
102                return 0;
103
104            // Удаление окна из памяти
105            case WM_DESTROY:
106                return 0;
107
108            // Нажатие на клавишу
109            case WM_KEYDOWN:
110
111                switch (wParam)
112                {
113                    case VK_ESCAPE:
114
115                        PostQuitMessage(0);
116                        return 0;
117                }
118                return 0;
119
120            // Таймер
121            case WM_TIMER:
122                return 0;
123
124            default:
125                return DefWindowProc (hWnd, message, wParam, lParam);
126        }
127    }
128
129    // Включение OpenGL
130    void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC) {
131
132        PIXELFORMATDESCRIPTOR pfd;
133        int iFormat;
134
135        /* get the device context (DC) */
136        *hDC = GetDC (hWnd);
137
138        /* set the pixel format for the DC */
139        ZeroMemory (&pfd, sizeof (pfd));
140        pfd.nSize = sizeof (pfd);
141        pfd.nVersion = 1;
142        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
143        pfd.iPixelType = PFD_TYPE_RGBA;
144        pfd.cColorBits = 24;
145        pfd.cDepthBits = 16;
146        pfd.iLayerType = PFD_MAIN_PLANE;
147        iFormat = ChoosePixelFormat (*hDC, &pfd);
148        SetPixelFormat (*hDC, iFormat, &pfd);
149
150        /* create and enable the render context (RC) */
151        *hRC = wglCreateContext( *hDC );
152        wglMakeCurrent( *hDC, *hRC );
153    }
154
155    // Отключение OpenGL
156    void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC) {
157
158        wglMakeCurrent (NULL, NULL);
159        wglDeleteContext (hRC);
160        ReleaseDC (hWnd, hDC);
161    }
162};

§ Класс с реализацией OpenGL (window.cpp)

1#include <math.h>
2#include <gl/gl.h>
3#include <gl/GLU.h>
4
5#include "app.cpp"
6
7// Главное окно-обработчик
8class AppWindow : public Application {
9protected:
10
11    float   theta;
12    GLuint  texture_id;
13
14public:
15
16    // Наследованная виртуальная функция
17    void InitHook() {
18
19        // Включение возможностей
20        glEnable(GL_DEPTH_TEST);                // Включить Z-буфер
21        glEnable(GL_TEXTURE_2D);                // Включить текстурирование
22
23        int w = 512, h = 512;
24        GLuint bgra[w*h];
25
26        // Создать тестовую текстуру
27        for (int i = 0; i < h; i++) {
28        for (int j = 0; j < w; j++) {
29            bgra[i*h + j] = i ^ j;
30        } }
31
32        // Текстура создается в памяти, назначается GLuint
33        glGenTextures(1, (GLuint *) & texture_id);
34
35        // Выбираем эту текстуру, работаем с 2D: x, y.
36        glBindTexture(GL_TEXTURE_2D, texture_id);
37
38        // Интерполяция для приближенных и удаленных объектов
39        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
40        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
41
42        // Повторять текстуры
43        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
44        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
45
46        // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml
47        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
48    }
49
50    // Отслеживаемое событие
51    LRESULT CALLBACK EventProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
52
53        // Обработка таймера
54        switch (message) {
55
56            case WM_TIMER:
57
58                switch (wParam)
59                {
60                    case IDT_TIMER1:
61
62                        // Построение перспективной проекции
63                        glMatrixMode(GL_PROJECTION);
64                        glLoadIdentity();
65                        gluPerspective(50, 1, 1, 1000);
66
67                        // Сформировать угол обзора
68                        glMatrixMode(GL_MODELVIEW);
69                        glLoadIdentity();
70                        gluLookAt(0.0, 0.0, 2.0, // Глаз
71                                  0.0, 0.0, 0.0, // Куда смотрим
72                                  0.0, 1.0, 0.0); // Направление верха
73
74                        // Анимация начинается тут
75                        glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
76                        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
77
78                        // Нарисовать треугольник
79                        glRotatef (theta, 0.0f, 0.0f, 1.0f);
80                        glBegin (GL_TRIANGLES);
81                        glBindTexture(GL_TEXTURE_2D, texture_id);
82                        glTexCoord2f(0.0f, 0.0f); glVertex3f (-1.0f,  1.0f, -1.0f);
83                        glTexCoord2f(1.0f, 0.0f); glVertex3f ( 1.0f,  1.0f, -1.0f);
84                        glTexCoord2f(1.0f, 1.0f); glVertex3f ( 1.0f, -1.0f, -1.0f);
85                        glEnd ();
86
87                        // Обмен буферами
88                        SwapBuffers (hDC);
89
90                        theta += 1.0f;
91                        return 0;
92                }
93        }
94
95        return EventWnd(hWnd, message, wParam, lParam);
96    }
97};
Загрузка шаблона template_gl.zip