Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

OpenGL Setup for GLSL

9
15 августа 2009 года
Lerkin
3.0K / / 25.03.2003
По просьбам трудящихся, интересующихся, сомневающихся и просто не желающих копаться в спецификациях и реестре расширений.

Господа, и как выясняется, дамы. Эта тема прилично описана в Lighthouse 3D, да и много где еще. Теперь вот и здесь будет, благо тема небольшая и отдельной статьи не требует. Настроек проекта не будет, равно как и иллюстраций, поясняющих работу конвейера OpenGL. Работаем при помощи удобной библиотечки GLEW. Обращаю внимание, что пропущены всяческие обязательные подготовительные действия - такие, как создание окна приложения, установка формата отображения и прочих буферов, получение контекста рисования и установка, если необходимо, контекста версии (для OpenGL 3.0 и выше).

Вначале, немного о подключении GLEW.
 
Код:
#include <glew/glew.h>
#ifdef _WIN32
  #include <glew/wglew.h>
  #pragma comment(lib, "glew/glew32.lib")
#endif


Выполнять инициализацию библиотеки, нужно после описанных выше манипуляций с окном, контекстом рендеринга и т.д. Телодвижений, призванных корректно завершить работу с библиотекой, выполнять не требуется.
 
Код:
GLenum glew_result = glewInit();
if (glew_result != GLEW_OK)
{
    std::cerr << glewGetErrorString( glew_result ) << std::endl;
    exit( 1 );
}


Работу с шейдерами, целесообразно начать с получения поддерживаемой картой\драйверами версии GLSL.
Выглядеть это будет примерно так:
Код:
std::string GLSL_version;

if (GLEW_VERSION_2_0 || (GLEW_ARB_shading_language_100 &&
             GLEW_ARB_shader_objects &&
             GLEW_ARB_fragment_shader &&
             GLEW_ARB_vertex_shader))
{
    if (GLEW_VERSION_2_0)
    GLSL_version = reinterpret_cast<const char*>
    (glGetString( GLEW_VERSION_2_0
        ? GL_SHADING_LANGUAGE_VERSION : GL_SHADING_LANGUAGE_VERSION_ARB ));

    if (GLSL_version == NULL)
    if (glGetError() == GL_INVALID_ENUM)
        // Предположительно, поддерживается первоначальная
        // версия GLSL 1.00 (в ревизии 51 спецификации - "1.051")
        GLSL_version = "1.051";
    else
        // Другая ошибка, но обрабатывать её мы здесь не будем
        exit( -1 );
}
else
    // Собственно, ни версия OpenGL 2.0, ни необходимые расширения
    // не поддерживаются. Стало быть, никакой GLSL нам не светит.
    exit( -1 );

Согласно спецификации, результирующая строка [FONT="Courier New"]GLSL_version[/FONT] будет иметь единый для всех вендоров формат "major.minor[.release] [vendor info]" - откуда легко выяснить поддерживаемую версию.
9
15 августа 2009 года
Lerkin
3.0K / / 25.03.2003
Подготовка к работе с шейдерами на GLSL весьма проста:
Код:
// Количество строк в шейдере
int num_shad_str;
// Исходный код шейдера
const char** shad_str;
// Массив длин строк в тексте кода шейдера
int* lens_shad_str;

// тут загружаем исходный код шейдера.
// Надо определить количество и длины строк исходника,
// но можно и обойтись. Как - смотрите спецификации.
...

// в нашем примере будет вершинный (GL_VERTEX_SHADER) шейдер
if (GLEW_VERSION_2_0)
// Работаем с функциями OpenGL версии 2.0
{
    // создаем шейдер
    GLuint shader = glCreateShader( GL_VERTEX_SHADER );
    // устанавливаем источник исходного кода шейдера
    glShaderSource( shader, num_shad_str, shad_str, lens_shad_str );
    // компилируем шейдер
    glCompileShader( shader );

    // создаём программный модуль шейдера
    GLuint program = glCreateProgram();
    // присоединяем шейдер к модулю
    glAttachShader( program, shader );
    // прилинковываем модуль
    glLinkProgram( program );
       
    // используем полученную шейдерную программку
    glUseProgram( program );
}
else if (GLEW_ARB_shading_language_100 &&
     GLEW_ARB_shader_objects &&
     GLEW_ARB_fragment_shader &&
     GLEW_ARB_vertex_shader)
// Работаем через ARB расширения
{
    // создаем шейдер
    GLhandleARB shader = glCreateShaderObjectARB( GL_VERTEX_SHADER );
    // устанавливаем источник исходного кода шейдера
    glShaderSourceARB( shader, num_shad_str, shad_str, lens_shad_str );
    // компилируем шейдер
    glCompileShaderARB( shader );

    // создаём программный модуль шейдера
    GLhandleARB program = glCreateProgramObjectARB();
    // присоединяем шейдер к модулю
    glAttachObjectARB( program, shader );
    // прилинковываем модуль
    glLinkProgramARB( program );
       
    // используем полученную шейдерную программку
    glUseProgramObjectARB( program );
}


Написанное следует воспринимать как некий псевдокод, поскольку общие переменные [FONT="Courier New"]shader[/FONT] и [FONT="Courier New"]program [/FONT]объявляются здесь внутри неких локальных областей видимости.
9
15 августа 2009 года
Lerkin
3.0K / / 25.03.2003
Избавиться от шейдерной программки, надлежит в следующем виде:
Код:
...

if (GLEW_VERSION_2_0)
{
    // отсоединяем шейдер от программного модуля.
    // к модулю может быть присоединено несколько
    // шейдеров, поэтому и нужна эта функция
    glDetachShader( program, shader );

    // удаляем шейдер
    glDeleteShader( shader );

    // если больше шейдеров нет,
    // то можно удалить и программный модуль
    glDeleteProgram( program );
}
else if (GLEW_ARB_shading_language_100 &&
     GLEW_ARB_shader_objects &&
     GLEW_ARB_fragment_shader &&
     GLEW_ARB_vertex_shader)
{
    // отсоединяем шейдер от программного модуля.
    // к модулю может быть присоединено несколько
    // шейдеров, поэтому и нужна эта функция
    glDetachObjectARB( program, shader );

    // удаляем шейдер
    glDeleteObjectARB( shader );

    // если больше шейдеров нет,
    // то можно удалить и программный модуль
    glDeleteObjectARB( program );
}
9
16 августа 2009 года
Lerkin
3.0K / / 25.03.2003
Дополнительно, могу предложить вариант получения версии драйвера OpenGL для nVidia и ATI в Windows.
Если знаете названия файлов драйверов других вендоров - напишите.
Код:
// для линковки
// GetFileVersionInfo, GetFileVersionInfoSize, VerQueryValue
#pragma comment(lib, "version.lib")

...

std::string icd_version;

try
{
    LPSTR _tmp = (LPSTR)malloc( sizeof(CHAR) * MAX_PATH );
    GetSystemDirectory( _tmp, MAX_PATH );

    std::string icd_path( _tmp );
    free( _tmp );

    WIN32_FIND_DATA file_data;

    std::string icd_file = icd_path + "\\nvoglnt.dll";
    HANDLE hFind = FindFirstFile( icd_file.c_str(), &file_data );
    if (hFind == INVALID_HANDLE_VALUE)
    {
    icd_file = icd_path + "\\atioglxx.dll";
    hFind = FindFirstFile( icd_file.c_str(), &file_data );
    if (hFind == INVALID_HANDLE_VALUE)
        icd_file.clear();
    }

    if (!icd_file.empty())
    {
    FindClose( hFind );

    DWORD dummy;
    DWORD size = GetFileVersionInfoSize( icd_file.c_str(), &dummy );
    if (size)
    {
        void* buff = malloc( size );
        GetFileVersionInfo( icd_file.c_str(), 0, size, buff );

        DWORD len;
        VS_FIXEDFILEINFO* ffi;
        if (VerQueryValue( buff, TEXT("\\"), (LPVOID*)(&ffi), (PUINT)(&len)) )
        {
        std::stringstream ss;
        ss << HIWORD(ffi->dwProductVersionMS) << "."
           << LOWORD(ffi->dwProductVersionMS) << "."
           << HIWORD(ffi->dwProductVersionLS) << "."
           << LOWORD(ffi->dwProductVersionLS);

        icd_version = ss.str();
        }

        free( buff );
    }
    }
    else
    {
    // файл драйвера неизвестен. доработать по вкусу
    }
}
catch(...)
{
    // Critical error during getting information about OpenGL ICD Driver.
    // Action cancelled.
}

Код не комментирую, идея и так понятна. На выходе в [FONT="Courier New"]icd_version[/FONT] - версия драйвера OpenGL.
Здесь можно посмотреть альтернативный вариант.
Для чего вообще это нужно? Ну, иногда бывает нужно. Кто знает, чего вы там пишете ;)


Продолжение, может быть последует...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог