Может ли GLAD загрузить функции OpenGL из dll файла?
. И почему-то OpenGL функции не загружаются при таком способе. Однако, если я перенесу функцию «gladLoadGLLoader» в «main» функцию (откуда я и использую этот dll), то все ок. Если честно, то у меня есть только одно предположение почему так происходит. Вроде функция «gladLoadGLLoader» загружает указатели на OpenGL функции в память, а так как загрузка происходила в dll, то об этих загруженных функциях знает только эта dll. Это так? Если нет, то хотелось бы знать, какой правильный ответ
Отслеживать
задан 30 авг 2023 в 17:14
51 8 8 бронзовых знаков
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
так как загрузка происходила в dll, то об этих загруженных функциях знает только эта dll. Это так?
Да. Может быть можно что-то нашаманить, чтобы они грузились сразу на все DLL (собрать GLAD как динамическую библиотеку?), но мы решили вот так: (писать в хедере)
inline void LoadGL() < [[maybe_unused]] static const std::nullptr_t once = []< gladLoadGLLoader(. ); return nullptr; >(); >
И вызывать эту функцию перед манипуляциями с OpenGL. Первый вызов в каждой отдельной DLL вызовет лямбду, а следующие не будут ничего делать.
Отслеживать
ответ дан 31 авг 2023 в 3:34
HolyBlackCat HolyBlackCat
26.9k 3 3 золотых знака 27 27 серебряных знаков 40 40 бронзовых знаков
Хорошо, спасибо за ответ
31 авг 2023 в 13:41
так как загрузка происходила в dll, то об этих загруженных функциях знает только эта dll. Это так?
Нет. Все отресовленные GLAD функции становятся доступны для всего процесса. Другое дело, что если использовать GLAD, линкуя его в виде статической библиотеки, либо, еще хуже, как то часто советуют, прямо собирать glad.c вместе с файлами своего проекта, то в программе окажется два набора глобальных переменных, которые GLAD заполняет указателями на соотв. функции — один набор виден в единицах трансляции, составляющих .exe, а другой — в единицах трансляции, составляющих .dll. Ну и вызов gladLoadGLLoader будет инициализировать только тот набор, который виден в месте вызова.
¿Что делать? По-хорошему, отказываться от GLAD и прочих динамических загрузчиков и линковать нужные библиотеки, как обычно. На самом деле это не всегда возможно, но стоит использовать более адекватный загрузчик, не плодящий глобальные переменные, и не прячущий их потом за макросами.
GLFW + GLAD = OpenGL графика с шейдерами
Здравствуйте, как давно меня здесь не было. Наверное не было ещё такой темы ради которой стоило бы Вас, дорогие читатели моих опусов, беспокоить.
Решил я познакомится поближе с OpenGL. Единственный доступный инструмент для написания программ и их компиляции, оказался NetBeans IDE 8.2, установочный файл netbeans-8.2-windows.exe размером 225 472 кб. и jdk-8u144-windows-x64 установочный файл jdk-8u144-windows-x64.exe размером 202 523 кб.
Размеры файлов и названия пишу точно, поскольку их размер зависит от их комплектации, а комплектация, насколько могу быть точным от конечной функциональности. После установки получаем вот такой инструмент разработки:


Использую компилятор CLang. Все инструменты скачаны при помощи утилиты MSYS которую можно скачать по ссылке https://www.msys2.org. Упор был сделан на инструменты UCRT64. MinGW не пользуюсь совсем.
Об инструментах поговорили и перейдём к OpenGL.
Проблема состояла в том, как тот код, который из интернета, запихать в конструкцию из GLFW + GLAD и получить OpenGL графику с шейдерами.
Первая проблема была с тем, как инициализировать GLAD? С glad.h проблем не было, а вот с glad.c возникли. Поиски решения оказались успешными и её реализацию вы увидите в коде, который я приведу ниже.
Вторая проблема в том, что часто можно увидеть конструкцию GLFW+GLEW, но я от неё отказался поскольку хотел реализовать конструкцию GLFW+GLAD.
Третья проблема, что везде в «туториалах» даётся множество примеров, которые отвязаны от цельного кода, куда писать, как встраивать код в программу, где искать дополнительные файлы, не понятно.
Я новичок в программировании, поэтому пишу с позиции именно новичка, так что не нападайте 🙂
//#define GLAD_GL_IMPLEMENTATION #include #include #define GLFW_INCLUDE_NONE #include #include #include #include #include using namespace std; //GLFWwindow *window; static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) < if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE); switch (key) < case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(window, GLFW_TRUE); break; /* case GLFW_KEY_SPACE: cur_icon_color = (cur_icon_color + 1) % 5; set_icon(window, cur_icon_color); break; case GLFW_KEY_X: glfwSetWindowIcon(window, 0, NULL); break;*/ >> void triang() < GLuint vbo = 0; GLuint vao = 0; float points[] = < 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f >; const char* vertex_shader = "#version 400\n" "in vec3 vp;" "void main() "; const char* fragment_shader = "#version 400\n" "out vec4 frag_colour;" "void main() "; GLuint vs = glCreateShader(GL_VERTEX_SHADER); GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); GLuint shader_programme = glCreateProgram(); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glShaderSource(vs, 1, &vertex_shader, NULL); glCompileShader(vs); glShaderSource(fs, 1, &fragment_shader, NULL); glCompileShader(fs); glAttachShader(shader_programme, fs); glAttachShader(shader_programme, vs); glLinkProgram(shader_programme); glUseProgram(shader_programme); glBindVertexArray(vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays(GL_TRIANGLES, 0, 3); // update other events like input handling > // Когда пользователь меняет размер окна, окно просмотра также должно быть скорректировано, требуя функцию обратного вызова void framebuffer_size_callback(GLFWwindow* window,int width,int height) < // Первые два параметра функции glViewport управляют положением нижнего левого угла окна, а третий и четвертый параметры контролируют ширину и высоту окна рендеринга glfwSetKeyCallback(window, key_callback); glfwGetFramebufferSize(window, &width, &height); glViewport(0,0,width,height); >// Объявляем функцию, чтобы определить, нажата ли конкретная клавиша void processInput(GLFWwindow * window) < // Проверка, нажимает ли пользователь клавишу возврата (Esc) (если не нажата, glfwGetKey вернет GLFW_RELEASE, если нажата, GLFW_PRESS) if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) < glfwSetWindowShouldClose(window, true); >> int main(int argc, char** argv) < // Инициализация GLFW glfwInit(); // Установить номер основной версии OpenGL (Major) и номер вспомогательной версии (Minor) в 3 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Использование режима ядра (Core-profile) glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Если это система MacOS, вам понадобится следующая строка кода для работы конфигурации //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Создать объект окна GLFWwindow * window = glfwCreateWindow(800, 600, "GLFW + GLAD", NULL, NULL); if (window == NULL)< cout // Уведомить GLFW, чтобы установить контекст нашего окна в качестве основного контекста текущего потока glfwMakeContextCurrent(window); // GLAD используется для управления указателем функции OpenGL, нам нужно инициализировать GLAD перед вызовом любой функции OpenGL if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) < cout // Зарегистрируем определенную функцию обратного вызова и сообщаем GLFW вызывать эту функцию при каждом изменении размера окна glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // Визуализация цикла while (!glfwWindowShouldClose(window)) < // Проверить, нажата ли конкретная клавиша, и обрабатывать ее каждый кадр processInput(window); // функция glClearColor - это функция установки состояния, используемая для установки цвета, используемого для очистки экрана glClearColor(0.2f,0.3f,0.3f,1.0f); // Функция glClear - это функция использования состояния, которая использует текущее состояние для очистки экрана с указанным цветом glClear(GL_COLOR_BUFFER_BIT); //triang(); - запускаем отрисовку треугольника. Работает именно в этом месте! triang(); // Функция glfwSwapBuffers будет обмениваться цветовыми буферами glfwSwapBuffers(window); // Функция glfwPollEvents проверяет, запущены ли какие-либо события glfwPollEvents(); >// Освободить все ресурсы, выделенные ранее glfwTerminate(); return 0; >
результат работы программы:
В этом коде я собрал много разных идей, здесь нет ни чего моего, кроме компоновки кода.

Да. Программа не ахти какая, но как видно из примера, работать в этой конструкции можно и вполне себе успешно. Можно выдернуть код, удалив всего одну функцию не разрушив целость структуры и так же вставить другой код. Какие перспективы у данной реализации? Наверно ограничиваются только фантазией.
Всем творческих успехов.
OpenGL. Что выбрать? GLEW, GLAD, glLoadGen, GLXW, libepoxy
Я пишу небольшой игровой движок для саморазвития: хочу чтобы он был кросплатформенный (win, linux, mac os). Использую glfw.
#1
15:10, 3 мар 2017
Я за PhantomGL :DDD
Можно загрузиться с почти любого!
Правда официально известно только о GLEW/GLAD/glbinding, epoxy не тестил, а GLXW и glLoadGen пока не внедрял.
#2
17:01, 3 мар 2017
Может сначала просто лучше почитать, какая либа что делает? Glew вполне достаточно для загрузки расширений. Но можно и вообще руками описать необходимые для приложения расширения и не тащить с собой еще одну либу.
- coremission
- Постоялец
#3
17:54, 3 мар 2017
bool
так ведь все они делают одно и то же. Руками писать расширения совсем не хочется..
#4
19:37, 3 мар 2017
coremission
бери любую. Как только наткнешься на реальные проблемы — вот тогда и будешь решать «что лучше» 🙂
Я лично GLEW использую, он меня всем устраивает. Правда вот советую почитать что делает glewExperimental, один раз он меня подвёл
#5
21:19, 3 мар 2017
Лучше ничего из этого не выбирать.
#6
21:25, 3 мар 2017
ArchiDevil
а чем оно плохо?)) Думаю, если автор еще не знает толком, какие екстеншены ему нужны, glew вполне подходит. А когда будет знать, скопирует их к себе в хидерочек и все будет ок.
- coremission
- Постоялец
#7
11:39, 5 мар 2017
А я правильно понимаю, что помимо загрузки адресов функций в файлах еще и константы, typedef’ы на типы, всякие макросы необходимые?
GLfloat, GL_TRIANGLES, и тп. не хочется ведь все это самому лепить.
Я действительно не знаю какие экстеншны мне нужны, у меня маловато опыта да и проектик как раз для обучения — попробовать что есть.
Я пробовал GLEW, но у меня не получилось сделать кросслплатформенный проект из репозитория, на макоси пытался генерировать экстеншны для релиза 2.0.0 и не получилось, долго ковырялся и решил попробовать GLAD.
#8
15:32, 5 мар 2017
coremission
Для некоторых расширений есть константы, да. Бери на самом деле любую универсальную либу, которую тебе удобно. Они не делают ничего, кроме того, что дают тебе хедер с описанием всего и получают указатели на расширения.
#9
15:47, 5 мар 2017
coremission
> , но у меня не получилось сделать кросслплатформенный проект из репозитория,
Если хочешь — могу помочь. В ЛС контакты черкани 🙂
#10
16:06, 5 мар 2017
coremission
Вот openglExt, наслаждайся.
Подключаем, все как обычно:
#ifndef OPENGL_H #define OPENGL_H #define WIN32_LEAN_AND_MEAN 1 #include windows.h> #include GL/gl.h> #include "GL/glext.h" #include "GL/wglext.h" #endif /* OPENGL_H */
#11
17:05, 5 мар 2017
Кстати, не забывай о том что их нужно сначала инициализировать!
Пополняй список, по мере надобности. И все будет ОК.
#define OPENGL_GET_PROC( p,n) \ n = ( p)wglGetProcAddress( #n); \ if ( NULL == n) \ < \ return false; \ > bool OpenGLInitExtensions( ); /* Global extension */ // Texture extern PFNGLACTIVETEXTUREPROC glActiveTexture; // VAO extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; // VBO extern PFNGLGENBUFFERSPROC glGenBuffers; extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; extern PFNGLBINDBUFFERPROC glBindBuffer; extern PFNGLBUFFERDATAPROC glBufferData; extern PFNGLBUFFERSUBDATAPROC glBufferSubData; extern PFNGLMAPBUFFERPROC glMapBuffer; extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; // Shaders extern PFNGLCREATEPROGRAMPROC glCreateProgram; extern PFNGLDELETEPROGRAMPROC glDeleteProgram; extern PFNGLLINKPROGRAMPROC glLinkProgram; extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; extern PFNGLUSEPROGRAMPROC glUseProgram; extern PFNGLGETPROGRAMIVPROC glGetProgramiv; extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; extern PFNGLCREATESHADERPROC glCreateShader; extern PFNGLDELETESHADERPROC glDeleteShader; extern PFNGLSHADERSOURCEPROC glShaderSource; extern PFNGLCOMPILESHADERPROC glCompileShader; extern PFNGLATTACHSHADERPROC glAttachShader; extern PFNGLDETACHSHADERPROC glDetachShader; extern PFNGLGETSHADERIVPROC glGetShaderiv; extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; // Attributes extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; // Uniforms extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; extern PFNGLUNIFORM1IPROC glUniform1i; extern PFNGLUNIFORM1FVPROC glUniform1fv; extern PFNGLUNIFORM3FVPROC glUniform3fv; extern PFNGLUNIFORM4FVPROC glUniform4fv;
bool OpenGLInitExtensions( ) < // Texture OPENGL_GET_PROC( PFNGLACTIVETEXTUREPROC, glActiveTexture); // VAO OPENGL_GET_PROC( PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); OPENGL_GET_PROC( PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays); OPENGL_GET_PROC( PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); // VBO OPENGL_GET_PROC( PFNGLGENBUFFERSPROC, glGenBuffers); OPENGL_GET_PROC( PFNGLDELETEBUFFERSPROC, glDeleteBuffers); OPENGL_GET_PROC( PFNGLBINDBUFFERPROC, glBindBuffer); OPENGL_GET_PROC( PFNGLBUFFERDATAPROC, glBufferData); OPENGL_GET_PROC( PFNGLBUFFERSUBDATAPROC, glBufferSubData); OPENGL_GET_PROC( PFNGLMAPBUFFERPROC, glMapBuffer); OPENGL_GET_PROC( PFNGLUNMAPBUFFERPROC, glUnmapBuffer); // Shaders OPENGL_GET_PROC( PFNGLCREATEPROGRAMPROC, glCreateProgram); OPENGL_GET_PROC( PFNGLDELETEPROGRAMPROC, glDeleteProgram); OPENGL_GET_PROC( PFNGLLINKPROGRAMPROC, glLinkProgram); OPENGL_GET_PROC( PFNGLVALIDATEPROGRAMPROC, glValidateProgram); OPENGL_GET_PROC( PFNGLUSEPROGRAMPROC, glUseProgram); OPENGL_GET_PROC( PFNGLGETPROGRAMIVPROC, glGetProgramiv); OPENGL_GET_PROC( PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog); OPENGL_GET_PROC( PFNGLCREATESHADERPROC, glCreateShader); OPENGL_GET_PROC( PFNGLDELETESHADERPROC, glDeleteShader); OPENGL_GET_PROC( PFNGLSHADERSOURCEPROC, glShaderSource); OPENGL_GET_PROC( PFNGLCOMPILESHADERPROC, glCompileShader); OPENGL_GET_PROC( PFNGLATTACHSHADERPROC, glAttachShader); OPENGL_GET_PROC( PFNGLDETACHSHADERPROC, glDetachShader); OPENGL_GET_PROC( PFNGLGETSHADERIVPROC, glGetShaderiv); OPENGL_GET_PROC( PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); // Attributes OPENGL_GET_PROC( PFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation); OPENGL_GET_PROC( PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); OPENGL_GET_PROC( PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); OPENGL_GET_PROC( PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); // Uniforms OPENGL_GET_PROC( PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation); OPENGL_GET_PROC( PFNGLUNIFORMMATRIX3FVPROC, glUniformMatrix3fv); OPENGL_GET_PROC( PFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv); OPENGL_GET_PROC( PFNGLUNIFORM1IPROC, glUniform1i); OPENGL_GET_PROC( PFNGLUNIFORM1FVPROC, glUniform1fv); OPENGL_GET_PROC( PFNGLUNIFORM3FVPROC, glUniform3fv); OPENGL_GET_PROC( PFNGLUNIFORM4FVPROC, glUniform4fv); OPENGL_CHECK_FOR_ERRORS( ); return true; > /* Global extension */ // Texture PFNGLACTIVETEXTUREPROC glActiveTexture = NULL; // VAO PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL; PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL; // VBO PFNGLGENBUFFERSPROC glGenBuffers = NULL; PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL; PFNGLBINDBUFFERPROC glBindBuffer = NULL; PFNGLBUFFERDATAPROC glBufferData = NULL; PFNGLBUFFERSUBDATAPROC glBufferSubData = NULL; PFNGLMAPBUFFERPROC glMapBuffer = NULL; PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL; // Shaders PFNGLCREATEPROGRAMPROC glCreateProgram = NULL; PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL; PFNGLLINKPROGRAMPROC glLinkProgram = NULL; PFNGLVALIDATEPROGRAMPROC glValidateProgram = NULL; PFNGLUSEPROGRAMPROC glUseProgram = NULL; PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL; PFNGLCREATESHADERPROC glCreateShader = NULL; PFNGLDELETESHADERPROC glDeleteShader = NULL; PFNGLSHADERSOURCEPROC glShaderSource = NULL; PFNGLCOMPILESHADERPROC glCompileShader = NULL; PFNGLATTACHSHADERPROC glAttachShader = NULL; PFNGLDETACHSHADERPROC glDetachShader = NULL; PFNGLGETSHADERIVPROC glGetShaderiv = NULL; PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL; // Attributes PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = NULL; // Uniforms PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL; PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv = NULL; PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL; PFNGLUNIFORM1IPROC glUniform1i = NULL; PFNGLUNIFORM1FVPROC glUniform1fv = NULL; PFNGLUNIFORM3FVPROC glUniform3fv = NULL; PFNGLUNIFORM4FVPROC glUniform4fv = NULL;
#12
11:15, 6 мар 2017
bool
> Думаю, если автор еще не знает толком, какие екстеншены ему нужны, glew вполне
> подходит
Вот. А нужно чтобы знал, и чтобы знал какие экстеншоны можно в случае наличия/отсутствия заменять друг на друга, что учитываю чехарду функционала в дровах — полезно. Так что онли glXGetProcAddress и wglGetProcAddress, с пониманием каждого для чего оно нужно и как какое кор/арб можно заменять.
- coremission
- Постоялец
#13
11:21, 6 мар 2017
Laynos, спасибо большое) я решил попробовать GLAD с ним проблем нет пока.
IgorBgz, еще где-то typedefs для PFNGLACTIVETEXTUREPROC нужны где-то. Теперь понятно как это работает примерно)
А можно еще глупый вопрос, для чего объявления глобальных с extern? Для читаемости? Глобальные объявления по умолчанию с внешним связыванием ведь, или я ошибаюсь?
#14
11:40, 6 мар 2017
coremission
> еще где-то typedefs для PFNGLACTIVETEXTUREPROC нужны где-то
Все они описаны в файле glext.h, файл я прикрепил к своему первому посту.
//glext.h typedef void ( APIENTRYP PFNGLACTIVETEXTUREPROC) ( GLenum texture);
> А можно еще глупый вопрос, для чего объявления глобальных с extern? Для читаемости? Глобальные объявления по умолчанию с внешним связыванием ведь, или я ошибаюсь?
Ключевое слово extern объявляет переменную или функцию и указывает, что она имеет внешние компоновки (ее имя будет видимым не только в пределах файла, в котором она определена, но и в других файлах)
Как начать программировать на OpenGL
Вообщем, задумал начать программировать 3д-графику и взгляд пал на OpenGL. Не долго думая, вбил в поиск: «Download OpenGL SDK». Перейдя по первой ссылке (https://www.opengl.org/sdk/), понял, что не всё так просто. Скачивал GLEW, так там библиотеки в разрешение «.lib». Скачал GLFW, решил скомпилировать пример, так у меня нету GLAD. Долго искал GLAD, но безуспешно. Так и не понял, что такое OpenGL и как начать его использовать.
Отслеживать
13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков
задан 17 июн 2021 в 22:09
Супрематический Крестьянин Супрематический Крестьянин
101 6 6 бронзовых знаков
Начните лучше с DirectX, для которого действительно существует SDK, а поплясать с бубном opengl можно будет и потом, по необходимости.
18 июн 2021 в 6:09
Начните вот тут, например: learnopengl.com отличный ресурс по обучению OpenGL
18 июн 2021 в 13:35
«Скачивал GLEW, так там библиотеки в разрешение «.lib».» — а что не так?
18 июн 2021 в 13:42
@insolor Дело в том, что я долгое время использовал gcc и старался избегать возможности перехода в vs, однако, похоже, что иного выхода нет 😀
18 июн 2021 в 19:55
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Поскольку сам OpenGL — всего лишь спецификация — описание интерфейсов, сигнатур и функциональности (и ни слова о том, как это должно быть реализовано), то для каждой ОС OpenGL — свой (общим будет лишь код, который написан с использованием OpenGL).
Базово, для работы с OpenGL нужны 2 вещи: контекст (каковым, обычно, является окно) и библиотека для работы с ним.
И самый быстрый вариант получить вожделенный OpenGL на Windows — Visual Studio + vcpkg: скачиваем и устанавливаем и то, и другое (также, vcpkg позволяет устанавливать и кучу других библиотек). Думаю, установка студии не представляет сложности, поэтому остановлюсь на пакетном менеджере, который стоит установить после Visual Studio: можно варварски (без гита) скачать с гитхаба, кнопкой «code» / «download zip» — архивчик и вытряхнуть его куда-нибудь (в любую папку), после чего нужно найти и запомнить папку с файликом bootstrap-vcpkg.bat. Нужно будет запустить bootstrap-vcpkg.bat (можно просто кликнуть, а можно запустить из командной строки cmd.exe — последний вариант каноничнее):
cd bootstrap-vcpkg.bat
Дальше, соберётся vcpkg — в папке с bootstrap-vcpkg.bat появится vcpkg.exe. Вот он-то нам и потребуется: снова открываем командную строку, переходим в папку с bootstrap-vcpkg.bat и (теперь) vcpkg.exe:
Дальше, не закрывая командную строку, вводим следующие заклинания (если ОС 32 битная, то пишем x86, иначе x64; ниже пишу для 64х разрядной винды):
vcpkg inststall glfw3:x64-windows-static vcpkg inststall glfw3:x64-windows vcpkg inststall glbinding:x64-windows-static vcpkg inststall glbinding:x64-windows vcpkg integrate install
После чего будут установлены: GLFW3 для создания окна (подойдёт и для Windows, и для Linux, и для MacOS) и glbinding, который позволяет использовать OpenGL (разница между тем, что в примерах и glbinding — лишь в том, что всё, что в glbinding надо доставать из пространства имён gl и иногда отключать через #undef некоторые константы, т.к. они уже есть в glbinding).
Короче, в итоге получится что-то такое (подразумеваю C++17):
#include #include #include int main(int argc, char* argv[]) < glfwInit(); // Самая простая инициализация GLFW3 auto window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); // Самый простой вариант создания окна с помощью GLFW# glfwMakeContextCurrent(window);// Указываем OpenGL работать с данным окном glbinding::initialize(glfwGetProcAddress); // Инициализируем glbinding, с помощью glfwGetProcAddress из GLFW3 (чтобы glbinding "знал" где какие функции OpenGL) // С этого момента, можно вызывать функции OpenGL, // при необходимости вызывая #undef для констант OpenGL, // которые могут высыпаться из GLFW3, но которые не // понимает glbinding; // весь OpenGL находится в пространстве имён gl в glbinding, // поэтому перед всем, что относится к OpenGL может быть нужно писать gl:: (или можно написать using namespace gl; или можно написать using gl:: glfwTerminate(); // Очищаем всякое барахло >