pull/10994/merge
NateSmyth 2026-06-03 15:28:40 -04:00 committed by GitHub
commit 5ebcac4b0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 77 additions and 26 deletions

View File

@ -226,7 +226,6 @@ pub const Target = enum(c_uint) {
array = c.GL_ARRAY_BUFFER,
element_array = c.GL_ELEMENT_ARRAY_BUFFER,
uniform = c.GL_UNIFORM_BUFFER,
storage = c.GL_SHADER_STORAGE_BUFFER,
_,
};

View File

@ -70,6 +70,7 @@ pub const InternalFormat = enum(c_int) {
red = c.GL_RED,
rgb = c.GL_RGB8,
rgba = c.GL_RGBA8,
r32ui = c.GL_R32UI,
srgb = c.GL_SRGB8,
srgba = c.GL_SRGB8_ALPHA8,
@ -147,6 +148,19 @@ pub const Binding = struct {
try errors.getError();
}
pub fn buffer(
b: Binding,
internal_format: InternalFormat,
id: c.GLuint,
) errors.Error!void {
glad.context.TexBuffer.?(
@intFromEnum(b.target),
@intCast(@intFromEnum(internal_format)),
id,
);
try errors.getError();
}
pub fn image2D(
b: Binding,
level: c.GLint,

View File

@ -275,7 +275,6 @@ pub inline fn bufferOptions(self: Metal) bufferpkg.Options {
};
}
pub const instanceBufferOptions = bufferOptions;
pub const uniformBufferOptions = bufferOptions;
pub const fgBufferOptions = bufferOptions;
pub const bgBufferOptions = bufferOptions;

View File

@ -344,7 +344,6 @@ pub inline fn bufferOptions(self: OpenGL) bufferpkg.Options {
};
}
pub const instanceBufferOptions = bufferOptions;
pub const uniformBufferOptions = bufferOptions;
pub const fgBufferOptions = bufferOptions;
pub const bgBufferOptions = bufferOptions;

View File

@ -1622,7 +1622,6 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
pass.step(.{
.pipeline = self.shaders.pipelines.bg_color,
.uniforms = frame.uniforms.buffer,
.buffers = &.{ null, frame.cells_bg.buffer },
.draw = .{ .type = .triangle, .vertex_count = 3 },
});
}

View File

@ -20,6 +20,14 @@ pub const Options = struct {
/// Whether to enable blending.
blending_enabled: bool = true,
/// Texture buffer binding for `buffers[1]`.
buffer_texture: ?BufferTexture = null,
pub const BufferTexture = struct {
unit: gl.c.GLuint,
internal_format: gl.Texture.InternalFormat,
};
pub const StepFunction = enum {
constant,
per_vertex,
@ -27,6 +35,12 @@ pub const Options = struct {
};
};
const BufferTextureBinding = struct {
texture: gl.Texture,
unit: gl.c.GLuint,
internal_format: gl.Texture.InternalFormat,
};
program: gl.Program,
fbo: gl.Framebuffer,
@ -37,6 +51,8 @@ stride: usize,
blending_enabled: bool,
buffer_texture: ?BufferTextureBinding = null,
pub fn init(comptime VertexAttributes: ?type, opts: Options) !Self {
// Load and compile our shaders.
const program = try gl.Program.createVF(
@ -60,16 +76,32 @@ pub fn init(comptime VertexAttributes: ?type, opts: Options) !Self {
if (VertexAttributes) |VA| try autoAttribute(VA, vaobind, opts.step_fn);
const buffer_texture: ?BufferTextureBinding = if (opts.buffer_texture) |cfg| texture: {
const texture = try gl.Texture.create();
errdefer texture.destroy();
break :texture .{
.texture = texture,
.unit = cfg.unit,
.internal_format = cfg.internal_format,
};
} else null;
return .{
.program = program,
.fbo = fbo,
.vao = vao,
.stride = if (VertexAttributes) |VA| @sizeOf(VA) else 0,
.blending_enabled = opts.blending_enabled,
.buffer_texture = buffer_texture,
};
}
pub fn deinit(self: *const Self) void {
if (self.buffer_texture) |tbo| {
tbo.texture.destroy();
}
self.program.destroy();
}

View File

@ -9,7 +9,6 @@ const Sampler = @import("Sampler.zig");
const Target = @import("Target.zig");
const Texture = @import("Texture.zig");
const Pipeline = @import("Pipeline.zig");
const Buffer = @import("buffer.zig").Buffer;
/// Options for beginning a render pass.
pub const Options = struct {
@ -101,13 +100,19 @@ pub fn step(self: *Self, s: Step) void {
_ = tex.texture.bind(tex.target) catch return;
};
// Bind `buffers[1]` as a texture buffer if this pipeline uses one.
if (s.pipeline.buffer_texture) |tbo| {
gl.Texture.active(tbo.unit) catch return;
const tbind = tbo.texture.bind(.Buffer) catch return;
tbind.buffer(tbo.internal_format, s.buffers[1].?.id) catch return;
}
// Bind relevant samplers.
for (s.samplers, 0..) |s_, i| if (s_) |sampler| {
_ = sampler.sampler.bind(@intCast(i)) catch return;
};
// Bind 0th buffer as the vertex buffer,
// and bind the rest as storage buffers.
// Bind the 0th buffer as the vertex buffer.
if (s.buffers.len > 0) {
if (s.buffers[0]) |vbo| vaobind.bindVertexBuffer(
0,
@ -115,10 +120,6 @@ pub fn step(self: *Self, s: Step) void {
0,
@intCast(s.pipeline.stride),
) catch return;
for (s.buffers[1..], 1..) |b, i| if (b) |buf| {
_ = buf.bindBase(.storage, @intCast(i)) catch return;
};
}
if (s.pipeline.blending_enabled) {

View File

@ -18,6 +18,10 @@ const pipeline_descs: []const struct { [:0]const u8, PipelineDescription } =
.vertex_fn = loadShaderCode("../shaders/glsl/full_screen.v.glsl"),
.fragment_fn = loadShaderCode("../shaders/glsl/cell_bg.f.glsl"),
.blending_enabled = true,
.buffer_texture = .{
.unit = 2,
.internal_format = .r32ui,
},
} },
.{ "cell_text", .{
.vertex_attributes = CellText,
@ -25,6 +29,10 @@ const pipeline_descs: []const struct { [:0]const u8, PipelineDescription } =
.fragment_fn = loadShaderCode("../shaders/glsl/cell_text.f.glsl"),
.step_fn = .per_instance,
.blending_enabled = true,
.buffer_texture = .{
.unit = 2,
.internal_format = .r32ui,
},
} },
.{ "image", .{
.vertex_attributes = Image,
@ -50,6 +58,7 @@ const PipelineDescription = struct {
fragment_fn: [:0]const u8,
step_fn: Pipeline.Options.StepFunction = .per_vertex,
blending_enabled: bool = true,
buffer_texture: ?Pipeline.Options.BufferTexture = null,
fn initPipeline(self: PipelineDescription) !Pipeline {
return try .init(self.vertex_attributes, .{
@ -57,6 +66,7 @@ const PipelineDescription = struct {
.fragment_fn = self.fragment_fn,
.step_fn = self.step_fn,
.blending_enabled = self.blending_enabled,
.buffer_texture = self.buffer_texture,
});
}
};
@ -81,7 +91,7 @@ const PipelineCollection = t: {
} });
};
/// This contains the state for the shaders used by the Metal renderer.
/// This contains the state for the shaders used by the OpenGL renderer.
pub const Shaders = struct {
/// Collection of available render pipelines.
pipelines: PipelineCollection,

View File

@ -6,9 +6,7 @@ layout(origin_upper_left) in vec4 gl_FragCoord;
// Must declare this output for some versions of OpenGL.
layout(location = 0) out vec4 out_FragColor;
layout(binding = 1, std430) readonly buffer bg_cells {
uint cells[];
};
layout(binding = 2) uniform usamplerBuffer cells;
vec4 cell_bg() {
uvec2 grid_size = unpack2u16(grid_size_packed_2u16);
@ -48,10 +46,11 @@ vec4 cell_bg() {
}
// Load the color for the cell.
vec4 cell_color = load_color(
unpack4u8(cells[grid_pos.y * grid_size.x + grid_pos.x]),
use_linear_blending
);
uint cell = texelFetch(
cells,
grid_pos.y * int(grid_size.x) + grid_pos.x
).r;
vec4 cell_color = load_color(unpack4u8(cell), use_linear_blending);
return cell_color;
}

View File

@ -36,9 +36,7 @@ out CellTextVertexOut {
vec2 tex_coord;
} out_data;
layout(binding = 1, std430) readonly buffer bg_cells {
uint bg_colors[];
};
layout(binding = 2) uniform usamplerBuffer bg_colors;
void main() {
uvec2 grid_size = unpack2u16(grid_size_packed_2u16);
@ -116,10 +114,11 @@ void main() {
// make it easier to handle minimum contrast calculations.
out_data.color = load_color(color, true);
// Get the BG color
out_data.bg_color = load_color(
unpack4u8(bg_colors[grid_pos.y * grid_size.x + grid_pos.x]),
true
);
uint bg_color = texelFetch(
bg_colors,
int(grid_pos.y * grid_size.x + grid_pos.x)
).r;
out_data.bg_color = load_color(unpack4u8(bg_color), true);
// Blend it with the global bg color
vec4 global_bg = load_color(
unpack4u8(bg_color_packed_4u8),