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