Remove multiple shaders, fuse in one

This commit is contained in:
Dendy 2023-01-03 09:31:12 +01:00
parent 7dec3d9386
commit eccc24811f
3 changed files with 61 additions and 61 deletions

View File

@ -12,20 +12,14 @@ buffer: gl.Buffer,
color: [4]f32 = .{ 0, 0, 0, 0 },
// There's a vbo for each shader program
vbo: [nPrograms][max_objects]f32 = .{.{0.0} ** max_objects} ** nPrograms,
vbo_index: [nPrograms]usize = .{0} ** nPrograms,
vbo: [max_objects]f32 = .{0.0} ** max_objects,
vbo_index: usize = 0,
// The index of the program is the enum converted to int
programs: [nPrograms]gl.Program = .{undefined} ** nPrograms,
textures: [max_objects]Texture = .{undefined} ** max_objects,
const max_objects: usize = 16384;
const shaderProgram = enum {
color,
texture,
};
const nPrograms = std.meta.fields(shaderProgram).len;
const quadSize: usize = 9 * 6;
fn glGetProcAddress(p: []const u8, proc: [:0]const u8) ?*const anyopaque {
_ = p;
@ -58,6 +52,7 @@ pub fn init() !Self {
std.debug.print("WARNING: Unable to configure the swap interval.\n", .{});
};
// Activate blending and configure it
gl.enable(.blend);
gl.blendFunc(.src_alpha, .one_minus_src_alpha);
@ -67,22 +62,23 @@ pub fn init() !Self {
var renderer = Self{ .window = window, .context = ctx, .buffer = buf };
// Load the shader programs according to the names in the enum
inline for (std.meta.fields(shaderProgram)) |programEnum| {
renderer.programs[programEnum.value] = renderer.loadProgram(programEnum.name);
}
_ = renderer.loadProgram("texture").use();
var vertex_array = gl.VertexArray.gen();
vertex_array.bind();
gl.vertexAttribPointer(0, 2, .float, false, @sizeOf(f32) * 8, @sizeOf(f32) * 0);
gl.vertexAttribPointer(0, 2, .float, false, @sizeOf(f32) * 9, @sizeOf(f32) * 0);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(1, 4, .float, false, @sizeOf(f32) * 8, @sizeOf(f32) * 2);
gl.vertexAttribPointer(1, 4, .float, false, @sizeOf(f32) * 9, @sizeOf(f32) * 2);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(2, 2, .float, false, @sizeOf(f32) * 8, @sizeOf(f32) * 6);
gl.vertexAttribPointer(2, 2, .float, false, @sizeOf(f32) * 9, @sizeOf(f32) * 6);
gl.enableVertexAttribArray(2);
gl.vertexAttribPointer(3, 1, .float, false, @sizeOf(f32) * 9, @sizeOf(f32) * 8);
gl.enableVertexAttribArray(3);
gl.clearColor(0.91, 0.85, 0.65, 1.00);
return renderer;
@ -125,32 +121,20 @@ fn loadProgram(self: Self, comptime name: []const u8) gl.Program {
}
pub fn render(self: *Self) void {
// Render with each of the defined shader programs
for (self.programs) |_, program_i| {
self.programs[program_i].use();
// TODO: Submit with SubData instead to not pass the whole buffer
self.buffer.data(f32, &self.vbo, .static_draw);
self.buffer.data(f32, &(self.vbo[program_i]), .static_draw);
switch (@intToEnum(shaderProgram, program_i)) {
.color => {
gl.drawArrays(.triangles, 0, self.vbo_index[program_i]);
},
.texture => {
var i: usize = 0;
const amount = self.vbo_index[program_i] / 48;
while (i < amount) : (i += 1) {
gl.bindTexture(self.textures[i].texture, .@"2d");
gl.drawArrays(.triangles, i * 6, 6);
}
},
}
self.vbo_index[program_i] = 0;
// Clear the vbo, this really shouldn't be necessary as the index is set to zero,
// but otherwise it leads to bugs
self.vbo[program_i] = .{0.0} ** max_objects;
var i: usize = 0;
const amount = self.vbo_index / quadSize;
while (i < amount) : (i += 1) {
gl.bindTexture(self.textures[i].texture, .@"2d");
gl.drawArrays(.triangles, i * 6, 6);
}
self.vbo_index = 0;
// Clear the vbo, this really shouldn't be necessary as the index is set to zero,
// but otherwise it leads to bugs
self.vbo = .{0.0} ** max_objects;
sdl.gl.swapWindow(self.window);
gl.clear(.{ .color = true });
@ -158,6 +142,9 @@ pub fn render(self: *Self) void {
pub fn deinit(self: *Self) void {
gl.disableVertexAttribArray(0);
gl.disableVertexAttribArray(1);
gl.disableVertexAttribArray(2);
gl.disableVertexAttribArray(3);
sdl.quit();
sdl.ttf.quit();
self.window.destroy();
@ -192,19 +179,15 @@ pub fn fillRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32) void {
}
pub fn fillRectangleEx(self: *Self, x: i32, y: i32, w: i32, h: i32, skew_x: i32) void {
renderRectangle(self, x, y, w, h, skew_x, shaderProgram.color);
renderRectangle(self, x, y, w, h, skew_x, 0);
}
pub fn renderTexture(self: *Self, texture: Texture, x: i32, y: i32) void {
const programEnum = shaderProgram.texture;
self.textures[self.vbo_index[@enumToInt(programEnum)] / 48] = texture;
renderRectangle(self, x, y, @intCast(i32, texture.width), @intCast(i32, texture.height), 0, programEnum);
self.textures[self.vbo_index / quadSize] = texture;
renderRectangle(self, x, y, @intCast(i32, texture.width), @intCast(i32, texture.height), 0, 1);
}
fn renderRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32, skew_x: i32, program: shaderProgram) void {
const program_i = @enumToInt(program);
fn renderRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32, skew_x: i32, unit: f32) void {
var xf = @intToFloat(f32, x);
var yf = @intToFloat(f32, y);
var wf = @intToFloat(f32, w);
@ -212,35 +195,41 @@ fn renderRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32, skew_x: i32, pro
const skew_x_offset = @intToFloat(f32, skew_x) * hf / 100;
const i = self.vbo_index[program_i];
const i = self.vbo_index;
const vertex_data = [_]f32{
xf + skew_x_offset, yf, // up-left
self.color[0], self.color[1],
self.color[2], self.color[3],
0.0, 0.0,
0, 0,
unit,
xf + wf + skew_x_offset, yf, // up-right
self.color[0], self.color[1],
self.color[2], self.color[3],
1.0, 0.0,
1, 0,
unit,
xf - skew_x_offset, yf + hf, // down-left
self.color[0], self.color[1],
self.color[2], self.color[3],
0.0, 1.0,
0, 1,
unit,
xf + wf - skew_x_offset, yf + hf, // down-right
self.color[0], self.color[1],
self.color[2], self.color[3],
1.0, 1.0,
1, 1,
unit,
xf + wf + skew_x_offset, yf, // up-right
self.color[0], self.color[1],
self.color[2], self.color[3],
1.0, 0.0,
1, 0,
unit,
xf - skew_x_offset, yf + hf, // down-left
self.color[0], self.color[1],
self.color[2], self.color[3],
0.0, 1.0,
0, 1,
unit,
};
std.mem.copy(f32, self.vbo[program_i][i..], &vertex_data);
self.vbo_index[program_i] += vertex_data.len;
std.mem.copy(f32, self.vbo[i..], &vertex_data);
self.vbo_index += vertex_data.len;
}
pub const OutputSize = struct { width: c_int, height: c_int };

View File

@ -1,9 +1,17 @@
#version 330 core
in vec2 texcoord;
in vec4 color;
in vec2 texCoord;
in float texId;
uniform sampler2D tex;
void main(){
gl_FragColor = texture(tex, texcoord) * color;
vec4 finalColor = color;
if (int(texId) == 1) {
finalColor *= texture(tex, texCoord);
}
gl_FragColor = finalColor;
}

View File

@ -2,14 +2,17 @@
layout (location = 0) in vec2 pos;
layout (location = 1) in vec4 vColor;
layout (location = 2) in vec2 vTexCoord;
layout (location = 3) in float vTexId;
out vec4 color;
layout (location = 2) in vec2 vTexcoord;
out vec2 texcoord;
out vec2 texCoord;
out float texId;
uniform mat4 mvp;
void main() {
texcoord = vTexcoord;
texCoord = vTexCoord;
color = vColor;
texId = vTexId;
gl_Position = mvp * vec4((pos + vec2(0.5, 0.5)), 0, 1);
}