Glew initialization error

@jonasschneider @glennpow @welinder @alfa07 @colah Dear all, I have this issue:

@jonasschneider @glennpow @welinder @alfa07 @colah
Dear all, I have this issue:

My source package: https://github.com/RussellM2020/GMPS.git

System
mjpro150
mujoco-py<1.50.2,>=1.50.1
tensorflow-gpu 1.5
cuda 9.0 cudnn 7.1

I already have export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libGLEW.so:/usr/lib/nvidia-410/libGL.so under ~/.bashrc

Output:

2019-04-27 10:20:52.345748: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1195] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: GeForce GTX 1050 Ti, pci bus id: 0000:01:00.0, compute capability: 6.1)
2019-04-27 10:21:20.170881 CST | itr #0 | Obtaining samples...
2019-04-27 10:21:20.171025 CST | itr #0 | Obtaining samples for iteration 0...
Found 1 GPUs for rendering. Using device 0.
Traceback (most recent call last):
  File "local_train.py", line 256, in <module>
    experiment(variant)
  File "local_train.py", line 236, in experiment
    algo.train()
  File "/home/jim/gmps/sandbox/rocky/tf/algos/batch_maml_polopt.py", line 396, in train
    logger.dump_tabular(with_prefix=False)
  File "/home/jim/anaconda2/envs/meta/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 1530, in __exit__
    exec_type, exec_value, exec_tb)
  File "/home/jim/anaconda2/envs/meta/lib/python3.5/contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/jim/anaconda2/envs/meta/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 4639, in get_controller
    yield default
  File "/home/jim/gmps/sandbox/rocky/tf/algos/batch_maml_polopt.py", line 396, in train
    logger.dump_tabular(with_prefix=False)
  File "/home/jim/anaconda2/envs/meta/lib/python3.5/contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/jim/gmps/rllab/misc/logger.py", line 156, in prefix
    yield
  File "/home/jim/gmps/sandbox/rocky/tf/algos/batch_maml_polopt.py", line 328, in train
    log_prefix=str(step),testitr=itr in self.testing_itrs,preupdate=True)
  File "/home/jim/gmps/sandbox/rocky/tf/algos/batch_maml_polopt.py", line 242, in obtain_samples
    paths = self.sampler.obtain_samples(itr=itr, reset_args=reset_args, return_dict=True, log_prefix=log_prefix, extra_input=self.extra_input, extra_input_dim=(self.extra_input_dim if self.extra_input is not None else 0), preupdate=preupdate)
  File "/home/jim/gmps/sandbox/rocky/tf/samplers/vectorized_sampler.py", line 110, in obtain_samples
    obses = self.vec_env.reset(reset_args)
  File "/home/jim/gmps/sandbox/rocky/tf/envs/vec_env_executor.py", line 32, in reset
    results = [env.reset(reset_args=arg) for env, arg in zip(self.envs, reset_args)]
  File "/home/jim/gmps/sandbox/rocky/tf/envs/vec_env_executor.py", line 32, in <listcomp>
    results = [env.reset(reset_args=arg) for env, arg in zip(self.envs, reset_args)]
  File "/home/jim/gmps/rllab/envs/proxy_env.py", line 13, in reset
    return self._wrapped_env.reset(*args, **kwargs)
  File "/home/jim/gmps/multiworld/core/finn_maml_env.py", line 54, in reset
    return self.get_flat_obs()
  File "/home/jim/gmps/multiworld/core/flat_goal_env.py", line 73, in get_flat_obs
    obs = self.wrapped_env._get_obs()
  File "/home/jim/gmps/multiworld/envs/mujoco/sawyer_xyz/push/sawyer_push.py", line 142, in _get_obs
    image = self.render(mode = 'nn')
  File "/home/jim/gmps/multiworld/envs/mujoco/sawyer_xyz/push/sawyer_push.py", line 167, in render
    image = self.get_image(width= im_size , height = im_size , camera_name = 'robotview_zoomed').transpose()/norm
  File "/home/jim/gmps/multiworld/envs/mujoco/mujoco_env.py", line 150, in get_image
    camera_name=camera_name,
  File "mjsim.pyx", line 149, in mujoco_py.cymj.MjSim.render
  File "mjsim.pyx", line 151, in mujoco_py.cymj.MjSim.render
  File "mjrendercontext.pyx", line 43, in mujoco_py.cymj.MjRenderContext.__init__
  File "mjrendercontext.pyx", line 108, in mujoco_py.cymj.MjRenderContext._setup_opengl_context
  File "opengl_context.pyx", line 128, in mujoco_py.cymj.OffscreenOpenGLContext.__init__
RuntimeError: Failed to initialize OpenGL

It seems that have the same question with @donamin issue

LightGameStudio

8 / 8 / 1

Регистрация: 03.11.2015

Сообщений: 143

1

24.01.2016, 18:18. Показов 2435. Ответов 14

Метки нет (Все метки)


Вот код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<iostream>
#include<conio.h>
#include<Windows.h>
 
#include<glew.h>
#include<glfw3.h>
#include<glmglm.hpp>
#pragma comment(lib, "glfw3.lib")
#pragma comment(lib,"glew32.lib")
 
using namespace std;
using namespace glm;
 
void display()
{}
int main()
{
    setlocale(LC_ALL, "RUS");
    glfwInit();
    glewInit();
    glfwWindowHint(GLFW_SAMPLES, 4); // 4x Сглаживание
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Мы хотим использовать OpenGL 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Мы не хотим старый OpenGL
    
         // Открыть окно и создать в нем контекст OpenGL
         GLFWwindow* window; // (В сопроводительном исходном коде эта переменная является глобальной)
     window = glfwCreateWindow(640, 480, "FIRST", NULL, NULL);
     if (window == NULL)
     {
            cout<<"Невозможно открыть окно GLFW.";
            glfwTerminate();    
    }
     glfwMakeContextCurrent(window);
 
         glewExperimental = true; // Флаг необходим в Core-режиме OpenGL
         glewInit();
         if (glewInit() != GL_TRUE) 
         {
             fprintf(stderr, "Невозможно инициализировать GLEW");
        
        }
        
         glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
         do{
             display();
 
                      glfwSwapBuffers(window);
                      glfwPollEvents();
             
            
         } 
          while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
         glfwWindowShouldClose(window) == 0);
 
    return 0;
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Эксперт С++

4978 / 3085 / 456

Регистрация: 10.11.2010

Сообщений: 11,164

Записей в блоге: 10

28.01.2016, 18:50

2

Вы где такую инициализацию видели? У вас вызов glewInit() происходит

три

раза!



0



1 / 1 / 0

Регистрация: 17.06.2013

Сообщений: 62

07.02.2016, 01:47

3

Проверьте совпадают ли Ваши инклюды с версией glew, которую используете.

В новых версиях glew функции glewInit в dll вовсе нет, например.



0



Эксперт С++

4978 / 3085 / 456

Регистрация: 10.11.2010

Сообщений: 11,164

Записей в блоге: 10

07.02.2016, 01:54

4

Цитата
Сообщение от Korybut
Посмотреть сообщение

В новых версиях glew функции glewInit в dll вовсе нет, например.

А что там есть? Как происходит инициализация библиотеки?



0



1 / 1 / 0

Регистрация: 17.06.2013

Сообщений: 62

07.02.2016, 02:16

5

Как конкретно в новых версиях идет инициализация не в курсе.

Си-шный текст инициализации остался прежним, но вот если захотите вызвать glewInit используя GetProcAddress, то вылетит ошибка, что такой функции там нет, хотя в версиях, когда glew входила в nvidia sdk она есть. Прогал на асме, наступил на эти грабли



0



Эксперт С++

4978 / 3085 / 456

Регистрация: 10.11.2010

Сообщений: 11,164

Записей в блоге: 10

07.02.2016, 02:28

6

Цитата
Сообщение от Korybut
Посмотреть сообщение

Как конкретно в новых версиях идет инициализация не в курсе.
Си-шный текст инициализации остался прежним, но вот если захотите вызвать glewInit используя GetProcAddress, то вылетит ошибка, что такой функции там нет, хотя в версиях, когда glew входила в nvidia sdk она есть. Прогал на асме, наступил на эти грабли

Вы откровенно несёте чушь.

glewInit как была так и есть.

Добавлено через 1 минуту

Цитата
Сообщение от Korybut
Посмотреть сообщение

В новых версиях glew функции glewInit в dll вовсе нет, например.

Цитата
Сообщение от Korybut
Посмотреть сообщение

Как конкретно в новых версиях идет инициализация не в курсе.

Тогда просто стоит промолчать.



0



1 / 1 / 0

Регистрация: 17.06.2013

Сообщений: 62

07.02.2016, 02:49

7

Если Вы загрузите библиотеку череду LoadLibrary, а затем захотите узнать адрес функции GetProcAddress, то в новых версиях в eax получите ноль. В самой glew32.dll такой функции нет, хотя раньше была. Это все, что я хотел сказать.



0



Эксперт С++

4978 / 3085 / 456

Регистрация: 10.11.2010

Сообщений: 11,164

Записей в блоге: 10

07.02.2016, 12:26

8

Цитата
Сообщение от Korybut
Посмотреть сообщение

Если Вы загрузите библиотеку череду LoadLibrary, а затем захотите узнать адрес функции GetProcAddress, то в новых версиях в eax получите ноль. В самой glew32.dll такой функции нет, хотя раньше была. Это все, что я хотел сказать.

Специально скачал динамическую библиотеку отсюда. Проверил файл glew32.dll. Функция glewInit там есть. Декорированная, но есть.



0



1 / 1 / 0

Регистрация: 17.06.2013

Сообщений: 62

07.02.2016, 13:37

9

ХЗ, что там надекорировано (может ей там имя поменяли), но при попытке прямо ее вызвать получаю вот это

Миниатюры

Ошибка инициализации GLEW
 



0



Эксперт С++

4978 / 3085 / 456

Регистрация: 10.11.2010

Сообщений: 11,164

Записей в блоге: 10

07.02.2016, 13:49

10

Цитата
Сообщение от Korybut
Посмотреть сообщение

ХЗ, что там надекорировано (может ей там имя поменяли), но при попытке прямо ее вызвать получаю вот это

Это всё потому, что вы используете её не так как положено. В архиве вместе с DLL есть библиотека импорта, которая предназначена для того чтобы использовали её, а не GetProcAddress.
Если уж вы по каким-то причинам решили использовать GetProcAddress, то надо уметь это делать и знать что такое декорация имён (Name Mangling).



0



Korybut

1 / 1 / 0

Регистрация: 17.06.2013

Сообщений: 62

07.02.2016, 13:58

11

Это я в курсе, что реальные имена функций расширений в ней не совпадают с теми, которые можно увидеть в Сишном коде

они там все идут с префиксами __glewFunction, а в коде можно увидеть, только glFunction. И то, что они вызываются они там иначе, чем в системной dll, тоже в курсе.

Assembler
1
2
mov eax, Procedure
call dword [eax]

Хотя сама glewInit в примерах, что дербанил вызывается канонично



0



Эксперт С++

4978 / 3085 / 456

Регистрация: 10.11.2010

Сообщений: 11,164

Записей в блоге: 10

07.02.2016, 14:06

12

Цитата
Сообщение от Korybut
Посмотреть сообщение

ХЗ, что там надекорировано

Цитата
Сообщение от Korybut
Посмотреть сообщение

Это я в курсе

Так вы в курсе или ХЗ?
Есть там по-вашему glewInit или нет?



0



1 / 1 / 0

Регистрация: 17.06.2013

Сообщений: 62

07.02.2016, 14:58

13

Цитата
Сообщение от castaway
Посмотреть сообщение

Так Вы в курсе или ХЗ?

Давайте уважать друг друга.

Открыл таблицу экспорта и нашел, что там есть ‘_glewInit@0’, в библиотеке другой версии(1.3.5) была просто ‘glewInit’. Потому и сверяйте версии инклюдов



0



Эксперт С++

4978 / 3085 / 456

Регистрация: 10.11.2010

Сообщений: 11,164

Записей в блоге: 10

07.02.2016, 15:04

14

Не по теме:

Цитата
Сообщение от Korybut
Посмотреть сообщение

Давайте уважать друг друга.

Всегда считал что маленькая буква ‘в’ — не показатель неуважения.

Цитата
Сообщение от Korybut
Посмотреть сообщение

Потому и сверяйте версии инклюдов

Зачем мне это делать?



0



1 / 1 / 0

Регистрация: 17.06.2013

Сообщений: 62

07.02.2016, 15:05

15

Это уже было автору темы)



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

07.02.2016, 15:05

15

В статье глубже описана структура API OpenGL, обработка ошибок, работа с расширениями и получение информации о возможностях драйвера.


Содержание

Структура API OpenGL

API OpenGL описан на языке C без применения C++ ради простоты и платформонезависимости. Он состоит только из функций, констант и примитивных типов, объявленных через typedef, таких как "typedef int GLenum;".

Функции делятся на две группы:

  • команды (англ. commands) для изменения состояния драйвера
  • запросы (англ. queries) состояния драйвера

Вот несколько примеров:

  • функция-команда void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) устанавливает цвет очистки; RGBA компоненты цвета передаются как число с плавающей точкой на отрезке [0..1].
  • функция-команда void glClear() очищает буфер кадра путём заливки пикселей цветом очистки.
  • функция-запрос const GLubyte *glGetString(GLenum name) возвращает строковое значение некоторой константы или величины в видеодрайвере, выбор величины зависит от параметра name; при этом const GLubyte* можно преобразовать в const char* с помощью reinterpret_cast.
  • тип данных GLclampf означает “число с плавающей точкой на отрезке [0..1]”; при этом никаких проверок принадлежности диапазону компилятор делать не будет, потому что тип объявлен просто как typedef float GLclampf.

Функции-команды ничего не возвращают, даже статуса своего выполнения. Это даёт возможность выполнить команду асинхронно, не заставляя приложение ждать, пока видеодрайвер отправит данные на видеокарту и получит от неё ответ.

Обработка ошибок

OpenGL старательно обрабатывает ошибки, такие как “недопустимый аргумент”, “неправильная константа enum”, “несвоевременный вызов команды”. Узнать о наличии общей ошибки в одной из предыдущих функций-команд можно функцией-запросом GLenum glGetError().

  • Если функция возвращает GL_NO_ERROR, ошибок не было
  • В противном случае код ошибки обозначает категорию ошибки без конкретных указаний
  • Функция не только возвращает код ошибки, но и очищает флаг ошибки в драйвере

Условно, код может выглядеть так:

void ValidateGLErrors()
{
    GLenum error = glGetError();
    if (error != GL_NO_ERROR)
    {
        std::string message;
        // с помощью switch превращаем GLenum в строковое описание
        // печатаем строку или делаем ещё что-то в целях отладки
    }
}

Функцию можно улучшить, если учесть следующее:

  • Распечатать строку ошибки можно в поток ошибок std::cerr
  • Любую ошибку можно считать фатальной, вызывая std::abort для аварийного завершения программы после вывода текста ошибки
  • Функцию можно сделать статическим методом класса CUtils

Представим улучшенную версию:

void CUtils::ValidateOpenGLErrors()
{
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
	{
		std::string message;
		switch (error)
		{
		case GL_INVALID_ENUM:
			message = "invalid enum passed to GL function (GL_INVALID_ENUM)";
			break;
		case GL_INVALID_VALUE:
			message = "invalid parameter passed to GL function (GL_INVALID_VALUE)";
			break;
		case GL_INVALID_OPERATION:
			message = "cannot execute some of GL functions in current state (GL_INVALID_OPERATION)";
			break;
		case GL_STACK_OVERFLOW:
			message = "matrix stack overflow occured inside GL (GL_STACK_OVERFLOW)";
			break;
		case GL_STACK_UNDERFLOW:
			message = "matrix stack underflow occured inside GL (GL_STACK_UNDERFLOW)";
			break;
		case GL_OUT_OF_MEMORY:
			message = "no enough memory to execute GL function (GL_OUT_OF_MEMORY)";
			break;
		default:
			message = "error in some GL extension (framebuffers, shaders, etc)";
			break;
		}
		std::cerr << "OpenGL error: " << message << std::endl;
		std::abort();
	}
}

После добавления этого метода можно улучшить основной цикл приложения:

// Очистка буфера кадра, обновление и рисование сцены, вывод буфера кадра.
if (running)
{
	m_pImpl->Clear();
	const float deltaSeconds = chronometer.GrabDeltaTime();
	OnUpdateWindow(deltaSeconds);
	OnDrawWindow(m_pImpl->GetWindowSize());
	CUtils::ValidateOpenGLErrors();
	m_pImpl->SwapBuffers();
}

Расширения OpenGL

В целях максимальной гибкости, все изменения в OpenGL вносятся в виде расширений. Расширение OpenGL — это задокументированная спецификация, которая описывает новые функции и их поведение, изменения в поведении старых функций и новые константы. Каждое расширение имеет имя, например, "GL_ARB_multitexture". При выпуске новой версии OpenGL часть расширений попадает в новую версию и становится частью ядра OpenGL. Таким образом, в версии OpenGL 3.0 и выше вы автоматически получаете ряд возможностей, которые в OpenGL 1.2 были доступны только как расширения.

  • В UNIX-системах и на мобильных устройствах доступны достаточно свежие версии OpenGL (обычно 3.0 и выше), где многие важные расширения уже стали частью ядра стандарта.
  • В Windows версии старше OpenGL 1.1 напрямую недоступны, но разработчики драйверов дают доступ к ним через механизм расширений. Если видеодрайвер не установлен, будет доступен только OpenGL 1.1, обладающий весьма ограниченными возможностями.

Функция, описанная в расширении, может не существовать в конкретной реализации OpenGL (если она не поддерживает данное расширение). Поэтому программист должен

  • либо запросить адрес функции и использовать её, только если адрес ненулевой
  • либо проверить наличие поддержки расширения по его имени и потом смело запрашивать адреса описанных в расширении функций

В стандарте OpenGL не описан способ получения адреса, и каждая операционная система или мультимедийная библиотека предоставляет свой способ. В SDL2 есть функция void *SDL_GL_GetProcAddress(const char *proc), которая по имени OpenGL-функции возвращает её адрес или nullptr, если функция недоступна.

Получение информации о версии OpenGL

Один и тот же видеодрайвер может создать разные констексты с разными версиями OpenGL и разными наборами расширений. Поэтому получать версионную информацию следует уже после создания контекста.

Для получения информации мы применим функцию-запрос glGetString с тремя различными параметрами. На эту тему есть статья Get Context Info (opengl.org).

  • константа с именем GL_VERSION возвращает строку версии OpenGL, причём в начале строки обязательно стоит "<номер мажорной версии>.<номер минорной версии> ", а остальная часть строки не определена. Например, строка "3.0 Mesa 10.3.2" обозрачает “OpenGL версии 3.0, реализуемый подсистемой графики Mesa версии 10.3.2”.
  • константа с именем GL_VENDOR возвращает имя поставщика реализации OpenGL. Например, строка "Intel Open Source Technology Center" обозначает “Видеодрайвер предоставлен OpenSource-подразделением корпорации Intel”.
  • константа с именем GL_EXTENSIONS содержит полный список расширений, разделённый пробелами. Список обычно насчитывает свыше ста расширений.

Функция печати информации о контексте

void PrintOpenGLInfo()
{
    std::string version = reinterpret_cast<const char *>(glGetString(GL_VERSION));
    std::string vendorInfo = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
    std::string extensionsInfo = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
    std::cerr << "OpenGL version: " << version << std::endl;
    std::cerr << "OpenGL vendor: " << vendorInfo << std::endl;
    std::cerr << "Full OpenGL extensions list: " << extensionsInfo << std::endl;
}

Следуя “правилу трёх ударов”, можно отрефакторить этот код:

void PrintOpenGLInfo()
{
    auto printOpenGLString = [](const char *description, GLenum name) {
        std::string info = reinterpret_cast<const char *>(glGetString(name));
        std::cerr << description << info << std::endl;
    };
    printOpenGLString("OpenGL version: ", GL_VERSION);
    printOpenGLString("OpenGL vendor: ", GL_VENDOR);
    printOpenGLString("Full OpenGL extensions list: ", GL_EXTENSIONS);
}

Библиотека GLEW

  • Сайт проекта: http://glew.sourceforge.net/
  • В Debian/Ubuntu доступна в пакете libglew-dev

Запрашивать функции и проверять расширения вручную не всегда удобно. Для решения этой типовой задачи создана библиотека GLEW (сокращение от “openGL Extensions Wrapper”). С помощью макросов и отложенной загрузки адресов функций эта библиотека позволяет использовать расширения так, как будто бы никаких расширений не существует:

  • вы просто вызываете функции по имени; если функции нет, произойдёт разыменование нулевого указания
  • также вы можете использовать модифицированное имя расширения (с префиксом “GLEW_” вместо “GL_”) как целочисленную переменную со значением 0 или 1; 1 означает, что расширение есть и доступно, 0 означает, что расширения нет или оно недоступно
  • если расширение недоступно, вы не должны вызывать функции расширения, чтобы не получить разыменование нулевого указателя
  • если при создании контекста OpenGL вы потребовали и получили контекст не ниже определённой версии, то можно даже не проверять расширения, вошедшие в эту версию: они есть.

Подключать заголовок glew.h следует до первого включения gl.h, иначе вы получите ошибку при компиляции.

// Правильно
#include <GL/glew.h>
#include <GL/gl.h>

// Неправильно!
#include <GL/gl.h>
#include <GL/glew.h>

Библиотека GLEW требует явного вызова функции glewInit для своей инициализации. Сделать вызов следует только один раз. Чтобы не накладывать на класс CAbstractWindow лишних ограничений, нужно гарантировать, что при первом конструировании объекта CAbstractWindow функция будет вызвана, а при последующих — уже нет. Также надо установить глобальную переменную-флаг glewExperimental, чтобы GLEW оборачивала функции из версий OpenGL 3.x и 4.x.

Для этой цели можно использовать два подхода

  • взять из стандартного заголовка <mutex> функцию std::call_once
  • завести в функции статическую переменную типа bool, которая будет устанавливаться в false в инициализаторе (который для статических переменных внутри функции вызывается ровно один раз)

В многопоточной среде было бы правильным использовать call_once, чтобы исключить возможность повторного вызова инициализации во время выполнения “glewInit” в другом потоке. Однако, ни контекст OpenGL, ни GLEW не могут использоваться из нескольких потоков одновременно. Поэтому call_once нам не потребуется, и достаточно статической переменной типа bool:

void CUtils::InitOnceGLEW()
{
	static bool didInit = false;
	if (!didInit)
	{
		glewExperimental = GL_TRUE;
		GLenum status = glewInit();
		if (status != GLEW_OK)
		{
			std::cerr << "GLEW initialization failed: " << glewGetErrorString(status) << std::endl;
			std::abort();
		}
	}
}

Узнаём о расширениях через GLEW

Читать полный список расширений, полученный через glGetString(GL_EXTENSIONS), не очень удобно. Сканировать его программно слишком трудоёмко в плане вычислений.

Для удобного получения расширений у GLEW есть переменные-флаги, которые устанавливаются при вызове glewInit(). Для проверки наличия расширения надо:

  • найти идентификатор расширения в реестре расширений (opengl.org), например, GL_ARB_vertex_shader
  • заменить префикс GL_ на GLEW_
  • написать проверку переменной-флага с таким именем

Теперь можно улучшить функцию PrintOpenGLInfo:

void PrintOpenGLInfo()
{
    auto printOpenGLString = [](const char *description, GLenum name) {
        std::string info = reinterpret_cast<const char *>(glGetString(name));
        std::cerr << description << info << std::endl;
    };
    printOpenGLString("OpenGL version: ", GL_VERSION);
    printOpenGLString("OpenGL vendor: ", GL_VENDOR);

    if (GLEW_ARB_vertex_shader)
    {
        std::cerr << "Has vertex shaders" << std::endl;
    }
    else
    {
        std::cerr << "Has no vertex shaders" << std::endl;
    }
    if (GLEW_ARB_fragment_shader)
    {
        std::cerr << "Has fragment shaders" << std::endl;
    }
    else
    {
        std::cerr << "Has no fragment shaders" << std::endl;
    }
    if (GLEW_ARB_vertex_buffer_object)
    {
        std::cerr << "Has vertex buffers" << std::endl;
    }
    else
    {
        std::cerr << "Has vertex busffers" << std::endl;
    }
    if (GLEW_ARB_framebuffer_object)
    {
        std::cerr << "Has framebuffers" << std::endl;
    }
    else
    {
        std::cerr << "Has framebuffers" << std::endl;
    }
}

Рефакторим код:

void PrintOpenGLInfo()
{
    auto printOpenGLString = [](const char *description, GLenum name) {
        std::string info = reinterpret_cast<const char *>(glGetString(name));
        std::cerr << description << info << std::endl;
    };
    printOpenGLString("OpenGL version: ", GL_VERSION);
    printOpenGLString("OpenGL vendor: ", GL_VENDOR);

    auto testExtension = [](const char *description, GLboolean supportFlag) {
        const char *prefix = supportFlag ? "Has " : "Has no ";
        std::cerr << prefix << description << std::endl;
    };
    testExtension("vertex shaders", GLEW_ARB_vertex_shader);
    testExtension("fragment shaders", GLEW_ARB_fragment_shader);
    testExtension("vertex buffers", GLEW_ARB_vertex_buffer_object);
    testExtension("framebuffers", GLEW_ARB_framebuffer_object);
}

На машине с Ubuntu 14.04 и встроенной видеокартой Intel программа выводит следующее:

OpenGL version: 3.0 Mesa 10.3.2
OpenGL vendor: Intel Open Source Technology Center
Has vertex shaders
Has fragment shaders
Has vertex buffers
Has framebuffers

На машине с Windows 8 и видеокартой Intel вывод отличается:

OpenGL version: 4.4.0 - Build 20.19.15.4377
OpenGL vendor: Intel
Has vertex shaders
Has fragment shaders
Has vertex buffers
Has framebuffers

Создаём работоспособное приложение

Код запроса версии OpenGL разместим в классе CWindow, потому что в дальнейших примерах нам уже не нужно будет печатать что-либо в консоль.

Файл Window.h

#pragma once
#include "AbstractWindow.h"

class CWindow : public CAbstractWindow
{
    // CAbstractWindow interface
protected:
    void OnWindowEvent(const SDL_Event &event) override;
    void OnUpdateWindow(float deltaSeconds) override;
    void OnDrawWindow(const glm::ivec2 &size) override;

private:
    void PrintOpenGLInfo();
};

листинг Window.cpp

#include "stdafx.h"
#include "Window.h"
#include <mutex>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>

namespace
{
std::once_flag g_didPrintOpenGLInfo;
}

void CWindow::OnWindowEvent(const SDL_Event &event)
{
    (void)event;
}

void CWindow::OnUpdateWindow(float deltaSeconds)
{
    (void)deltaSeconds;
}

void CWindow::OnDrawWindow(const glm::ivec2 &size)
{
    (void)size;
    std::call_once(g_didPrintOpenGLInfo, &CWindow::PrintOpenGLInfo, this);
}

void CWindow::PrintOpenGLInfo()
{
    auto printOpenGLString = [](const char *description, GLenum name) {
        std::string info = reinterpret_cast<const char *>(glGetString(name));
        std::cerr << description << info << std::endl;
    };
    printOpenGLString("OpenGL version: ", GL_VERSION);
    printOpenGLString("OpenGL vendor: ", GL_VENDOR);

    auto testExtension = [](const char *description, GLboolean supportFlag) {
        const char *prefix = supportFlag ? "Has " : "Has no ";
        std::cerr << prefix << description << std::endl;
    };
    testExtension("vertex shaders", GLEW_ARB_vertex_shader);
    testExtension("fragment shaders", GLEW_ARB_fragment_shader);
    testExtension("vertex buffers", GLEW_ARB_vertex_buffer_object);
    testExtension("framebuffers", GLEW_ARB_framebuffer_object);
}

Topic: Failed to Initialize GLEW. Missing GL version  (Read 8601 times)

0 Members and 1 Guest are viewing this topic.

In a previous thread I’ve mentioned similar errors and a fresh install for qt creator did the trick at first, but as soon as I imported my source into the IDE everything went bad again, now creating a new project results in the same errors and it appears something is not right here. upon compiling my SFML game this is what I get, and all sprites appear as boxes in-game:

Someone on SO told me I should make sure SFML’s not being released before I initialize GLEW but I don’t know what that means, I thought SFML handles all the OpenGL things for me so I wouldn’t have to worry about it. I’m sure it’s something silly but I really don’t know where to even start with fixing this, as I have 0 knowledge of OpenGL. And also, why is the max texture size 250×250? That is really small, if I were to make a fullscreen this could be a serious issue, unless it’s just my computer


Logged


What graphics card do you have?
Is the driver up-to-date? Because it the error sounds like it’s not. ;)


Logged


What graphics card do you have?
Is the driver up-to-date? Because it the error sounds like it’s not. ;)

It doesn’t really matter because I can use SFML for any IDE possible except qt creator but the answers are: Nvidia Geforce 210 and yes, last update was about 2 months or so ago.


Logged


It doesn’t really matter because I can use SFML for any IDE possible except qt creator

Well you didn’t specify that… ;)
(Might as well link to the SO question.)

Make sure that Qt Creator doesn’t provide some of it’s own glew/opengl versions.

What does happen if you start the application not from within Qt, but directly via the explorer?
Qt Creator is using MinGW underneath and since that works without problem (at least on my system), it must be some strange environment variables setup by Qt.


Logged


It doesn’t really matter because I can use SFML for any IDE possible except qt creator

Well you didn’t specify that… ;)
(Might as well link to the SO question.)

Make sure that Qt Creator doesn’t provide some of it’s own glew/opengl versions.

What does happen if you start the application not from within Qt, but directly via the explorer?
Qt Creator is using MinGW underneath and since that works without problem (at least on my system), it must be some strange environment variables setup by Qt.

Sorry I forgot to mention that, I was assuming most of the people saw my other thread. I have no idea if qt creator set up any enviromentals or if it uses it’s own version of openGL (possible)

Running from explorer does nothing, console opens and closes instantly, without any message in it. And yes all the DLLs are there and everything needed.  :-


Logged


Running from explorer does nothing, console opens and closes instantly, without any message in it. And yes all the DLLs are there and everything needed.  :-

Run it from the command line, to see if you get an error there.

On SO you mentioned that a normal Hello World also produces the error, so does the following  code also produce the error AND open and close directly when run from explorer AND not show any output when run from the console?

 

#include <SFML/Graphics.hpp>

  int main()
 {
     // Create the main window
     sf::RenderWindow window(sf::VideoMode(800, 600), «SFML window»);

     // Start the game loop
     while (window.isOpen())
     {
         // Process events
         sf::Event event;
         while (window.pollEvent(event))
         {
             // Close window : exit
             if (event.type == sf::Event::Closed)
                 window.close();
         }

          // Clear screen
         window.clear();

          // Update the window
         window.display();
     }

      return EXIT_SUCCESS;
 }


Logged


The code above runs perfectly fine, the only problems I’m having is with sprites and texture, as soon as I add a sprite it shows the errors I pointed above, I don’t understand what determines if the errors appear when closing the program or when opening, because I have 2 projects, same configurations: On one project I have the whole game, and the errors appear when it opens and sprites appear like boxes, and the 2nd project, where I have just 1 file with similar code as above except it also renders a sprite, but in that project the sprites appear normal and the errors are shown when closing the program.

Overall this behaviour is incredibly weird, I’m sure it’s something really silly, but I can’t think of even 1 thing I’ve done wrong, I just have no clue


Logged


So I suppose nobody has a fix for this so I’ll get back to VS  :-


Logged


What version of MinGW does QtCreator ship with?
Have you ever tried to compile the application directly with GCC instead via the IDE?

I’ve never had problems with MinGW and SFML, so I don’t really see where the problem is. Btw. there’s also Code::Blocks if you don’t want to work with VS. ;)


Logged


What version of MinGW does QtCreator ship with?
Have you ever tried to compile the application directly with GCC instead via the IDE?

I’ve never had problems with MinGW and SFML, so I don’t really see where the problem is. Btw. there’s also Code::Blocks if you don’t want to work with VS. ;)

I suppose I compiled the application with gcc when I was running it on VS or C::B because it worked perfectly fine when I did, it’s the qt creator that’s the problem, and I can’t quite tell what, and I doubt I’ll find out. I like C::B but it’s not really suited for big projects, I used it at first but as the project grew I had to switch the IDE


Logged


I suppose I compiled the application with gcc when I was running it on VS or C::B because it worked perfectly fine when I did

Visual Studio has its own compiler, I’m not even sure if you’d be able to trick it into compiling with GCC.
But that doesn’t answer my question on the version of MinGW and actually what version of QtCreator do you use?

it’s the qt creator that’s the problem, and I can’t quite tell what, and I doubt I’ll find out.

Well nobody else here seems to have run into the same problem and since it works with other IDEs, it seems just a like a setup-problem. We can’t really help you further here, other than suggesting to freshly install the newest version of QtCreator and make sure you don’t setup strange things. :D

I like C::B but it’s not really suited for big projects, I used it at first but as the project grew I had to switch the IDE

I’m not sure why you’d conclude that…
C::B and QtCreator are quite similar and I don’t see how one IDE would be way better at handling larger projects, I don’t even understand what exactly the problem is… ;)


Logged


Most details that you need are found here and on the SO question, but my mingw version is the latest, and qt is also latest, and I’ve tried doing a fresh qt SDK install, and a fresh qt creator install, even a fresh SFML install as well  :-


Logged


Понравилась статья? Поделить с друзьями:

Читайте также:

  • Get contact как изменить номер телефона
  • Gl info error runtimeexception no opengl context found in the current thread minecraft
  • Get async error sigame
  • Gl 6033 kuppersberg ошибка 15
  • Gk61 как изменить подсветку

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии