Skip to content

Commit

Permalink
render consecutive shaders to the fbo (opengl) (#5037)
Browse files Browse the repository at this point in the history
fixes #4729

allows the shaders to sample each other via the fbo texture.

also, a better example would use the full screen e.g.:
"behind.glsl"
```glsl
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    fragColor = vec4(fragCoord/iResolution.xy, 0.0, 1.0);
}
```

"infront.glsl"
```glsl
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    fragColor = texture(iChannel0, fragCoord/iResolution.xy);
}
```
`ghostty --custom-shader=behind.glsl --custom-shader=infront.glsl`
|before|after|
|-|-|
|
![image](https://github.com/user-attachments/assets/d96cc8f1-7d87-4346-963a-a1fb27b81cba)
|
![image](https://github.com/user-attachments/assets/203c3827-9574-4739-9d54-430dc4a47dcc)|
  • Loading branch information
mitchellh authored Jan 20, 2025
2 parents f8ece63 + 4cc1fa2 commit 977c999
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
22 changes: 17 additions & 5 deletions src/renderer/OpenGL.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2350,11 +2350,9 @@ pub fn drawFrame(self: *OpenGL, surface: *apprt.Surface) !void {
}

/// Draw the custom shaders.
fn drawCustomPrograms(
self: *OpenGL,
custom_state: *custom.State,
) !void {
fn drawCustomPrograms(self: *OpenGL, custom_state: *custom.State) !void {
_ = self;
assert(custom_state.programs.len > 0);

// Bind our state that is global to all custom shaders
const custom_bind = try custom_state.bind();
Expand All @@ -2363,8 +2361,22 @@ fn drawCustomPrograms(
// Setup the new frame
try custom_state.newFrame();

// To allow programs to retrieve each other via a texture
// then we must render the next shaders to the screen fbo.
// However, the first shader must be run while the default fbo
// is attached
{
const bind = try custom_state.programs[0].bind();
defer bind.unbind();
try bind.draw();
if (custom_state.programs.len == 1) return;
}

const fbobind = try custom_state.fbo.bind(.framebuffer);
defer fbobind.unbind();

// Go through each custom shader and draw it.
for (custom_state.programs) |program| {
for (custom_state.programs[1..]) |program| {
// Bind our cell program state, buffers
const bind = try program.bind();
defer bind.unbind();
Expand Down
1 change: 0 additions & 1 deletion src/renderer/opengl/custom.zig
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ pub const Program = struct {
const program = try gl.Program.createVF(
@embedFile("../shaders/custom.v.glsl"),
src,
//@embedFile("../shaders/temp.f.glsl"),
);
errdefer program.destroy();

Expand Down

0 comments on commit 977c999

Please sign in to comment.