2012-02-06 32 views
18

Khi đọc thông số kỹ thuật OpenGL, tôi đã nhận thấy rằng nó có thể bao gồm nhiều trình tạo bóng cùng loại trong một chương trình (nghĩa là nhiều hơn một GL_VERTEX_SHADER đính kèm với glAttachShader). Cụ thể trong OpenGL 4.2, §2.11.3, Program Objects: "Nhiều đối tượng shader cùng loại có thể được gắn vào một đối tượng chương trình duy nhất ...".Đính kèm nhiều trình tạo bóng cùng loại trong một chương trình OpenGL duy nhất?

Chương trình đường ống OpenGL và chương trình con có thể áp dụng ở đây, nhưng điều này đã được xác định trước khi những tồn tại (trên thực tế nó quay trở lại 2.1 spec, §2.15.2) vì vậy tôi đang tìm một ví dụ trước GL4 của ý tưởng này. Khi tôi thực hiện một số thử nghiệm đơn giản, tôi thấy rằng bao gồm nhiều hơn một void main() gây ra lỗi liên kết. Có ai biết về một ví dụ thực tế là thực tế trong trường hợp này được sử dụng không?

+0

Tôi không chắc chắn nếu nó hoạt động, nhưng tôi đoán bạn có thể có các shader với các chức năng chung (nhưng không có chức năng chính) để bạn có thể đính kèm chúng vào porgram và có thể truy cập các chức năng này từ trình đổ bóng chính. Bằng cách này, bạn chỉ cần biên dịch các chức năng đó một lần. –

Trả lời

26

Bạn có thể đặt các chức năng phổ biến ở shader riêng biệt. Sau đó biên dịch nó chỉ một lần và liên kết trong nhiều chương trình.

Cũng tương tự như cách bạn biên dịch tệp cpp của mình chỉ một lần để nhận thư viện tĩnh hoặc chia sẻ. Sau đó, bạn liên kết thư viện này thành nhiều chương trình thực thi, do đó tiết kiệm thời gian biên dịch.

Hãy nói rằng bạn có phức tạp chức năng chiếu sáng:

vec3 ComputeLighting(vec3 position, vec3 eyeDir) 
{ 
    // ... 
    return vec3(...); 
} 

Sau đó cho mỗi người trong số đổ bóng, nơi bạn muốn sử dụng chức năng này làm điều này:

vec3 ComputeLighting(vec3 position, vec3 eyeDir); 

void main() 
{ 
    vec3 light = ComputeLighting(arg1, arg2); 
    gl_FragColor = ...; 
} 

Sau đó, bạn biên dịch riêng rẽ shader chung và chính bạn đổ bóng. Nhưng làm việc biên dịch của shader phổ biến chỉ một lần.

+0

Tất nhiên, điều đó có ý nghĩa hoàn toàn. Cảm ơn! –

7

tôi thấy rằng trong đó có hơn một void main() gây ra lỗi kết nối

Đối với mỗi giai đoạn đổ bóng thì phải có chỉ là một chức năng nhập chính.

ví dụ thực tế khi sử dụng này (trước GL4)?

Bạn có thể khai báo hàm trong nguồn đổ bóng và không xác định hàm và tại thời gian liên kết bạn có thể cung cấp định nghĩa từ nguồn trình đổ bóng khác (rất giống với liên kết c/C++).

Ví dụ:

generate_txcoord.glsl:

#version 330 
precision highp float; 

const vec2 madd = vec2(0.5, 0.5); 

vec2 generate_txcoord(vec2 v) 
{ 
    return v * madd + madd; 
} 

vertex.glsl:

#version 330 
precision highp float; 

in vec2 vxpos; 

out vec2 out_txcoord; 

vec2 generate_txcoord(vec2 vxpos); // << declared, but not defined 

void main() 
{ 
    // generate 0..+1 domain txcoords and interpolate them 
    out_txcoord = generate_txcoord(vxpos); 

    // interpolate -1..+1 domain vxpos 
    gl_Position = vec4(vxpos, 0.0, 1.0); 
} 
Các vấn đề liên quan