Обратная совместимость OpenGL Shading Language - PullRequest
6 голосов
/ 13 апреля 2010

Я заметил, что мои шейдеры GLSL не компилируются, когда версия GLSL ниже 130.

Каковы наиболее важные элементы для наличия обратно совместимого источника шейдеров?Я не хочу иметь полную обратную совместимость, но я хотел бы понять основные рекомендации по использованию простых (совместимых с прямым) шейдеров, работающих на графическом процессоре с GLSL ниже 130.

Конечно, проблема может бытьбыть решена с помощью препроцессора

#if __VERSION__ < 130
#define VERTEX_IN attribute
#else
#define VERTER_IN in
#endif

Но, вероятно, есть много проблем, которые я игнорирую.

Ответы [ 4 ]

2 голосов
/ 03 июля 2013

Недавние действия подтолкнули этот старый вопрос, и я понял, что решил проблему. Это было непросто, но это успешное решение, проверенное многими шейдерами на его основе и количеством драйверов, компилирующих источник шейдеров.

По сути, я использовал расширение GL_ARB_shading_language_include (и я также реализовал исходный препроцессор для тех систем, которые его не реализуют), и я решил определить следующий шейдер, включающий источник:

//  Copyright (C) 2011-2013 Luca Piccioni
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

// @BeginInterface

// Shader renderer

// Symbol defined if running on NVIDIA renderer.
#define DS_VENDOR_NVIDIA            1
// Symbol defined if running on ATI/AMD renderer.
#define DS_VENDOR_AMD               2
// Symbol defined if running on INTEL renderer
#define DS_VENDOR_INTEL             3

// Shader inputs and outputs keywords
//
// - ATTRIBUTE: used to mark a vertex shader inputs
// - SHADER_IN: used to mark a non-vertex shader inputs
// - SHADER_OUT: used to mark a non-fragment shader output
// - OUT: used to mark a fragment shader output
#if __VERSION__ >= 130

#define ATTRIBUTE in
#define SHADER_IN in
#define SHADER_OUT out
#define OUT out

#else

#define ATTRIBUTE attribute
#define SHADER_IN varying
#define SHADER_OUT varying
#define OUT

#endif

// Support array attributes
#if __VERSION__ >= 130

#define ARRAY_ATTRIBUTE(name, size) name[size]

#else

#define ARRAY_ATTRIBUTE(name, size) name[size]

#endif

// Uniform blocks
#if __VERSION__ >= 130

#define BEGIN_UNIFORM_BLOCK(name)   uniform name {

#define END_UNIFORM_BLOCK() };

#else

#define BEGIN_UNIFORM_BLOCK(name)

#define END_UNIFORM_BLOCK()

#endif

// Input and output blocks
#if __VERSION__ >= 150

#define BEGIN_INPUT_BLOCK(name) in name {
#define END_INPUT_BLOCK() };

#define BEGIN_OUTPUT_BLOCK(name) out name {
#define END_OUTPUT_BLOCK() };

#else

#define BEGIN_INPUT_BLOCK(name)
#define END_INPUT_BLOCK()

#define BEGIN_OUTPUT_BLOCK(name)
#define END_OUTPUT_BLOCK()

#endif

// Texturing functions
#if __VERSION__ >= 130

#define TEXTURE_2D texture
#define TEXTURE_3D texture
#define TEXTURE_RECT texture
#define TEXTURE_CUBE texture

#if __VERSION__ >= 150
#define TEXTURE_SIZE(sampler) textureSize(sampler)
#else
#define TEXTURE_SIZE(sampler) sampler ## _Size
#endif

#else

#define TEXTURE_2D texture2D
#define TEXTURE_3D texture3D
#define TEXTURE_RECT texture2DRect
#define TEXTURE_CUBE textureCube

#endif

// Invariance
#if __VERSION__ >= 120
#define INVARIANT invariant
#else
#define INVARIANT
#endif

// Attribute location
#if defined(GL_ARB_explicit_attrib_location)
#define LOCATION(loc)       layout(location = loc)
#else
#define LOCATION(loc)
#endif

// Geometry shader layout
#if __VERSION__ >= 150
#define GEOMETRY_LAYOUT_IN(from) layout (from) in
#define GEOMETRY_LAYOUT(to, max) layout (to, max_vertices = max) out
#else
#define GEOMETRY_LAYOUT_IN(from)
#define GEOMETRY_LAYOUT(to, max)
#endif

// @EndInterface

Действительно, включая включение шейдера до источника шейдера, фреймворк может компилироваться на широком спектре компиляторов. Конечно, инфраструктура должна определять реальные возможности системы и определять параметры компилятора, чтобы все было сделано правильно (подумайте о шейдере строки, потому что ширина линии> 1,0 устарела).

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

1 голос
/ 21 апреля 2010
  • поместите #version 110 или #version 120 в качестве первой строки ваших шейдеров
  • протестируйте их в ShaderAnalyst от ATI
  • протестируйте свой код на МНОГО реальных графических карт от разных поставщиков
0 голосов
/ 03 июля 2013

извлеките строку # version из ваших шейдеров и протестируйте свой код на разных компьютерах с различными возможностями графического процессора. Вы увидите, что ваша совместимость с шейдерами возрастет. Директива #version иногда приводит к сбою шейдера, даже если графический процессор на этом компьютере может выполнять весь код шейдера, если ему не присвоен номер версии.

0 голосов
/ 25 января 2011

Читать "Язык затенения OpenGL, Билл Лицеа-Кейн, AMD, SIGGRAPH 2009" . Возможно, вам потребуется добавить следующий код в ваше приложение для поддержки версий GLSL-140, 130 и 120:

#version 150 compatibility
...