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 },
|
color: [4]f32 = .{ 0, 0, 0, 0 },
|
||||||
|
|
||||||
// There's a vbo for each shader program
|
// There's a vbo for each shader program
|
||||||
vbo: [nPrograms][max_objects]f32 = .{.{0.0} ** max_objects} ** nPrograms,
|
vbo: [max_objects]f32 = .{0.0} ** max_objects,
|
||||||
vbo_index: [nPrograms]usize = .{0} ** nPrograms,
|
vbo_index: usize = 0,
|
||||||
|
|
||||||
// The index of the program is the enum converted to int
|
// The index of the program is the enum converted to int
|
||||||
programs: [nPrograms]gl.Program = .{undefined} ** nPrograms,
|
|
||||||
textures: [max_objects]Texture = .{undefined} ** max_objects,
|
textures: [max_objects]Texture = .{undefined} ** max_objects,
|
||||||
|
|
||||||
const max_objects: usize = 16384;
|
const max_objects: usize = 16384;
|
||||||
|
const quadSize: usize = 9 * 6;
|
||||||
const shaderProgram = enum {
|
|
||||||
color,
|
|
||||||
texture,
|
|
||||||
};
|
|
||||||
const nPrograms = std.meta.fields(shaderProgram).len;
|
|
||||||
|
|
||||||
fn glGetProcAddress(p: []const u8, proc: [:0]const u8) ?*const anyopaque {
|
fn glGetProcAddress(p: []const u8, proc: [:0]const u8) ?*const anyopaque {
|
||||||
_ = p;
|
_ = p;
|
||||||
|
@ -58,6 +52,7 @@ pub fn init() !Self {
|
||||||
std.debug.print("WARNING: Unable to configure the swap interval.\n", .{});
|
std.debug.print("WARNING: Unable to configure the swap interval.\n", .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Activate blending and configure it
|
||||||
gl.enable(.blend);
|
gl.enable(.blend);
|
||||||
gl.blendFunc(.src_alpha, .one_minus_src_alpha);
|
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 };
|
var renderer = Self{ .window = window, .context = ctx, .buffer = buf };
|
||||||
|
|
||||||
// Load the shader programs according to the names in the enum
|
// Load the shader programs according to the names in the enum
|
||||||
inline for (std.meta.fields(shaderProgram)) |programEnum| {
|
_ = renderer.loadProgram("texture").use();
|
||||||
renderer.programs[programEnum.value] = renderer.loadProgram(programEnum.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
var vertex_array = gl.VertexArray.gen();
|
var vertex_array = gl.VertexArray.gen();
|
||||||
vertex_array.bind();
|
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.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.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.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);
|
gl.clearColor(0.91, 0.85, 0.65, 1.00);
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
|
@ -125,32 +121,20 @@ fn loadProgram(self: Self, comptime name: []const u8) gl.Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(self: *Self) void {
|
pub fn render(self: *Self) void {
|
||||||
// Render with each of the defined shader programs
|
// TODO: Submit with SubData instead to not pass the whole buffer
|
||||||
for (self.programs) |_, program_i| {
|
self.buffer.data(f32, &self.vbo, .static_draw);
|
||||||
self.programs[program_i].use();
|
|
||||||
|
|
||||||
self.buffer.data(f32, &(self.vbo[program_i]), .static_draw);
|
var i: usize = 0;
|
||||||
|
const amount = self.vbo_index / quadSize;
|
||||||
switch (@intToEnum(shaderProgram, program_i)) {
|
while (i < amount) : (i += 1) {
|
||||||
.color => {
|
gl.bindTexture(self.textures[i].texture, .@"2d");
|
||||||
gl.drawArrays(.triangles, 0, self.vbo_index[program_i]);
|
gl.drawArrays(.triangles, i * 6, 6);
|
||||||
},
|
|
||||||
.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;
|
|
||||||
}
|
}
|
||||||
|
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);
|
sdl.gl.swapWindow(self.window);
|
||||||
gl.clear(.{ .color = true });
|
gl.clear(.{ .color = true });
|
||||||
|
@ -158,6 +142,9 @@ pub fn render(self: *Self) void {
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
gl.disableVertexAttribArray(0);
|
gl.disableVertexAttribArray(0);
|
||||||
|
gl.disableVertexAttribArray(1);
|
||||||
|
gl.disableVertexAttribArray(2);
|
||||||
|
gl.disableVertexAttribArray(3);
|
||||||
sdl.quit();
|
sdl.quit();
|
||||||
sdl.ttf.quit();
|
sdl.ttf.quit();
|
||||||
self.window.destroy();
|
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 {
|
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 {
|
pub fn renderTexture(self: *Self, texture: Texture, x: i32, y: i32) void {
|
||||||
const programEnum = shaderProgram.texture;
|
self.textures[self.vbo_index / quadSize] = texture;
|
||||||
|
renderRectangle(self, x, y, @intCast(i32, texture.width), @intCast(i32, texture.height), 0, 1);
|
||||||
self.textures[self.vbo_index[@enumToInt(programEnum)] / 48] = texture;
|
|
||||||
renderRectangle(self, x, y, @intCast(i32, texture.width), @intCast(i32, texture.height), 0, programEnum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32, skew_x: i32, program: shaderProgram) void {
|
fn renderRectangle(self: *Self, x: i32, y: i32, w: i32, h: i32, skew_x: i32, unit: f32) void {
|
||||||
const program_i = @enumToInt(program);
|
|
||||||
|
|
||||||
var xf = @intToFloat(f32, x);
|
var xf = @intToFloat(f32, x);
|
||||||
var yf = @intToFloat(f32, y);
|
var yf = @intToFloat(f32, y);
|
||||||
var wf = @intToFloat(f32, w);
|
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 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{
|
const vertex_data = [_]f32{
|
||||||
xf + skew_x_offset, yf, // up-left
|
xf + skew_x_offset, yf, // up-left
|
||||||
self.color[0], self.color[1],
|
self.color[0], self.color[1],
|
||||||
self.color[2], self.color[3],
|
self.color[2], self.color[3],
|
||||||
0.0, 0.0,
|
0, 0,
|
||||||
|
unit,
|
||||||
xf + wf + skew_x_offset, yf, // up-right
|
xf + wf + skew_x_offset, yf, // up-right
|
||||||
self.color[0], self.color[1],
|
self.color[0], self.color[1],
|
||||||
self.color[2], self.color[3],
|
self.color[2], self.color[3],
|
||||||
1.0, 0.0,
|
1, 0,
|
||||||
|
unit,
|
||||||
xf - skew_x_offset, yf + hf, // down-left
|
xf - skew_x_offset, yf + hf, // down-left
|
||||||
self.color[0], self.color[1],
|
self.color[0], self.color[1],
|
||||||
self.color[2], self.color[3],
|
self.color[2], self.color[3],
|
||||||
0.0, 1.0,
|
0, 1,
|
||||||
|
unit,
|
||||||
xf + wf - skew_x_offset, yf + hf, // down-right
|
xf + wf - skew_x_offset, yf + hf, // down-right
|
||||||
self.color[0], self.color[1],
|
self.color[0], self.color[1],
|
||||||
self.color[2], self.color[3],
|
self.color[2], self.color[3],
|
||||||
1.0, 1.0,
|
1, 1,
|
||||||
|
unit,
|
||||||
xf + wf + skew_x_offset, yf, // up-right
|
xf + wf + skew_x_offset, yf, // up-right
|
||||||
self.color[0], self.color[1],
|
self.color[0], self.color[1],
|
||||||
self.color[2], self.color[3],
|
self.color[2], self.color[3],
|
||||||
1.0, 0.0,
|
1, 0,
|
||||||
|
unit,
|
||||||
xf - skew_x_offset, yf + hf, // down-left
|
xf - skew_x_offset, yf + hf, // down-left
|
||||||
self.color[0], self.color[1],
|
self.color[0], self.color[1],
|
||||||
self.color[2], self.color[3],
|
self.color[2], self.color[3],
|
||||||
0.0, 1.0,
|
0, 1,
|
||||||
|
unit,
|
||||||
};
|
};
|
||||||
std.mem.copy(f32, self.vbo[program_i][i..], &vertex_data);
|
std.mem.copy(f32, self.vbo[i..], &vertex_data);
|
||||||
self.vbo_index[program_i] += vertex_data.len;
|
self.vbo_index += vertex_data.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const OutputSize = struct { width: c_int, height: c_int };
|
pub const OutputSize = struct { width: c_int, height: c_int };
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
in vec2 texcoord;
|
|
||||||
in vec4 color;
|
in vec4 color;
|
||||||
|
in vec2 texCoord;
|
||||||
|
in float texId;
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
|
||||||
void main(){
|
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 = 0) in vec2 pos;
|
||||||
layout (location = 1) in vec4 vColor;
|
layout (location = 1) in vec4 vColor;
|
||||||
|
layout (location = 2) in vec2 vTexCoord;
|
||||||
|
layout (location = 3) in float vTexId;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
layout (location = 2) in vec2 vTexcoord;
|
out vec2 texCoord;
|
||||||
out vec2 texcoord;
|
out float texId;
|
||||||
|
|
||||||
uniform mat4 mvp;
|
uniform mat4 mvp;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
texcoord = vTexcoord;
|
texCoord = vTexCoord;
|
||||||
color = vColor;
|
color = vColor;
|
||||||
|
texId = vTexId;
|
||||||
gl_Position = mvp * vec4((pos + vec2(0.5, 0.5)), 0, 1);
|
gl_Position = mvp * vec4((pos + vec2(0.5, 0.5)), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue