2010-04-13 9 views
5

Tôi nhận thấy rằng các trình đổ bóng GLSL của tôi không thể nén khi phiên bản GLSL thấp hơn 130.OpenGL Shading Ngôn ngữ tương thích ngược

Các yếu tố quan trọng nhất để có nguồn đổ bóng tương thích ngược? Tôi không muốn có khả năng tương thích hoàn toàn, nhưng tôi muốn hiểu các nguyên tắc chính để có các trình đổ bóng đơn giản (tương thích) chạy trên GPU với GLSL thấp hơn 130.

Tất nhiên vấn đề có thể được giải quyết với bộ tiền xử lý

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

Nhưng có thể có nhiều vấn đề mà tôi bỏ qua.

Trả lời

2

Các hoạt động gần đây đã đẩy lên câu hỏi cũ này và tôi nhận ra rằng tôi đã giải quyết được vấn đề. Nó không phải là dễ dàng, nhưng nó là một giải pháp thành công, được chứng minh bởi nhiều shaders dựa trên nó và số lượng các trình điều khiển biên dịch nguồn shader.

Về cơ bản, tôi đã sử dụng phần mở rộng GL_ARB_shading_language_include (và tôi cũng đã thực hiện tiền xử lý nguồn cho những hệ thống mà không thực hiện nó), và tôi đã kết thúc để xác định đổ bóng sau bao gồm nguồn:

// 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 

Thật vậy, bao gồm cả shader bao gồm trước nguồn shader framework có thể biên dịch trên một loạt các trình biên dịch. Tất nhiên, khung công tác phải phát hiện các khả năng hệ thống thực tế và xác định các tham số của trình biên dịch để có được những điều được thực hiện đúng (suy nghĩ về một trình đổ bóng dòng vì độ rộng dòng> 1.0 không dùng nữa).

Tất nhiên, cơ sở hạ tầng của trình đổ bóng có thể xác định yêu cầu tối thiểu. Khi trình đổ bóng yêu cầu cấu hình lõi GLSL 1.50 trở lên, không còn cần đến trình đổ bóng bao gồm ở trên.

1
  • đặt #version 110 hoặC#version 120 là dòng đầu tiên của shaders bạn
  • kiểm tra chúng vào ShaderAnalyst từ ATI
  • kiểm tra mã của bạn trên một LOT của card đồ họa thực tế từ các nhà cung cấp khác nhau
0

Đọc "OpenGL Shading Language, Bill Licea-Kane, AMD, SIGGRAPH 2009". Bạn có lẽ cần thêm đoạn mã sau vào ứng dụng của bạn để hỗ trợ GLSL-140, 130 và 120 phiên bản:

#version 150 compatibility 
+0

Cảm ơn bạn, nhưng những gì tôi đã cố gắng là tránh cờ tương thích, bằng cách làm cho mã nguồn của trình đổ bóng có thể biên dịch được cho các phiên bản khác nhau chỉ sử dụng bộ tiền xử lý. – Luca

0

đưa ra dòng #version từ shaders của bạn và kiểm tra mã của bạn trên nhiều máy tính khác nhau với khả năng GPU khác nhau. Bạn sẽ thấy rằng khả năng tương thích của trình đổ bóng sẽ tăng lên. Chỉ thị #version đôi khi sẽ khiến trình đổ bóng thất bại mặc dù GPU trong máy đó có thể thực thi tất cả các mã đổ bóng khi không có số phiên bản.

+0

Đúng, chỉ thị #version được chèn vào lúc chạy tùy thuộc vào khả năng của hệ thống ngay từ đầu. Nó là điều cần thiết để có một động cơ có thể mở rộng; tuy nhiên, hầu hết hệ thống đều hỗ trợ các tính năng GLSL nâng cao. – Luca

+0

Bỏ qua #phiên bản mặc định thành GLSL 1.1 – Luca