Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

OpenGL 4 со стандартного Windows SDK

#cpp #windows #opengl #cmake


хотел подключить OpenGL 4 стандартными средствами Windows SDK ко своему проекту на
С++, не используя сторонние библиотеки на подобии glut, glfw и т.д.. Opengl 1 подключался
прекрасно, когда я использовал следующее:

// В файлах проекта:
#include 
#include 
#include 

// в CMake
target_link_libraries (ProjectName opengl32.lib glu32.lib)


Но а вот когда я решил использовать функции шейдеров, VAO, VBO, то их просто не оказалось,
но думаю старая версия OpenGL стоит на винде... Скачал OpenGL Extension Viewer и как
оказалось, была у меня установлена OpenGL 1.1. После чего я обновил OpenGL до версии
4.4, но у меня так и не получается использовать функции шейдеров, VAO, VBO. Хотел спросить
может каких хедеров не хватает или стоит еще дополнительные библиотеки прилинковать
или что-то я не дообновил?
    


Ответы

Ответ 1



Дело в том, что системная библиотека opengl32.dll предоставляет только базовые функции, существовавшие во время OpenGL 1.1. Доступ к более новым возможностям можно получить с помощью функции wglGetProcAddress(). В качестве параметра ей необходимо передать имя требуемой функции, а возвращаемый указатель — преобразовать в тип PFNИМЯФУНКЦИИPROC (типы объявлены в ). Пример: const PFNGLCOMPILESHADERPROC _glCompileShader = reinterpret_cast(wglGetProcAddress("glCompileShader")); Примечание: для работы с OpenGL таким способом требуется наличие трёх заголовочных файлов, отсутствующих в стандартной поставке Windows SDK. Эти файлы необходимо скачать с сайта компании-создателя OpenGL и разместить в папке проекта следующим рекомендуемым образом: https://www.khronos.org/registry/OpenGL/api/GL/glext.h → папка_проекта/include/GL/glext.h https://www.khronos.org/registry/OpenGL/api/GL/wglext.h → папка_проекта/include/GL/wglext.h https://www.khronos.org/registry/EGL/api/KHR/khrplatform.h → папка_проекта/include/KHR/khrplatform.h При этом необходимо указать CMake на наличие этих файлов: target_include_directories (ProjectName include) Также необходимо вручную создать контекст, поддерживающий OpenGL 4. Создание OpenGL-контекста происходит в два этапа: Сначала создаём контекст версии 1.1 для корректной работы wglGetProcAddress(). Затем получаем указатель на функцию wglCreateContextAttribsARB() и используем её для создания уже нужного нам контекста. Ниже приведены функции создания и уничтожения контекста: #include #include #define WGL_WGLEXT_PROTOTYPES #include // Параметры начального контекста static const PIXELFORMATDESCRIPTOR pfd = { /* nSize */ sizeof(PIXELFORMATDESCRIPTOR), /* nVersion */ 1, /* dwFlags */ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, /* iPixelType */ PFD_TYPE_RGBA, /* cColorBits */ 32, /* c...Bits|Shift */ 0, 0, 0, 0, 0, 0, 0, 0, /* cAccum...Bits */ 0, 0, 0, 0, 0, /* cDepthBits */ 16, /* cStencilBits */ 0, /* cAuxBuffers */ 0, /* iLayerType */ PFD_MAIN_PLANE, /* bReserved */ 0, /* dw...Mask */ 0, 0, 0 }; // Параметры конечного контекста (OpenGL 4.0 Core) static const int context_attributes[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0 }; // Функция для создания контекста OpenGL 4. Принимает HWND окна вывода, возвращает // дескриптор GL-контекста. HGLRC gl_init(HWND default_output) { const HDC canvas = GetDC(default_output); // Этап 1 HGLRC gl = NULL; const int format = ChoosePixelFormat(canvas, &pfd); if (format != 0) { SetPixelFormat(canvas, format, &pfd); const HGLRC gl_boostrap = wglCreateContext(canvas); wglMakeCurrent(canvas, gl_boostrap); // Этап 2 gl = reinterpret_cast (wglGetProcAddress("wglCreateContextAttribsARB")) (canvas, NULL, context_attributes); wglMakeCurrent(canvas, gl); wglDeleteContext(gl_boostrap); } // Удаляем более не требуемый начальный контекст и возвращаем конечный ReleaseDC(default_output, canvas); return gl; } // Функция для уничтожения GL контекста. Принимает HWND окна вывода и дескриптор // GL-контекста. Можно было бы ограничиться и HWND, но у некоторых драйверов для // интегрированной графики Intel функция wglMakeCurrent() не работает при нулевом // значении параметра с GL-дескриптором. void gl_release(HWND default_output, HGLRC gl) { const HDC hdc = GetDC(default_output); wglMakeCurrent(hdc, NULL); ReleaseDC(default_output, hdc); wglDeleteContext(gl); }

Комментариев нет:

Отправить комментарий