2010-04-13 8 views
5

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

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

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

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

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

ответ

2

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

По существу, я использовал расширение 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
  • положить #version 110 или #version 120 в качестве первой строки ваших шейдеров
  • испытания их в ShaderAnalyst от ATI
  • тест код на много реальных графических карт от разных производителей
0

Прочитано "OpenGL Shading Language, Bill Licea-Kane, AMD, SIGGRAPH 2009". Вы, вероятно, нужно добавить следующий код в приложение для того, чтобы поддержать GLSL-140, 130 и 120 версий:

#version 150 compatibility 
+0

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

0

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

+0

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

+0

Опускание #версии по умолчанию для GLSL 1.1 – Luca