Remove multiple shaders, fuse in one
This commit is contained in:
		
							parent
							
								
									7dec3d9386
								
							
						
					
					
						commit
						eccc24811f
					
				
							
								
								
									
										101
									
								
								src/Renderer.zig
								
								
								
								
							
							
						
						
									
										101
									
								
								src/Renderer.zig
								
								
								
								
							| 
						 | 
				
			
			@ -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 };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue