Basic post processing (spooky)
This commit is contained in:
parent
1504c9c2e6
commit
0b6d8c392a
14
assets/quad.obj
Normal file
14
assets/quad.obj
Normal file
@ -0,0 +1,14 @@
|
||||
# Blender 4.0.2
|
||||
# www.blender.org
|
||||
o Plane
|
||||
v 1.000000 -1.000000 0.000000
|
||||
v -1.000000 -1.000000 0.000000
|
||||
v 1.000000 1.000000 0.000000
|
||||
v -1.000000 1.000000 0.000000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 1.000000 0.000000
|
||||
s 0
|
||||
f 1/1/1 3/2/1 4/3/1 2/4/1
|
27
assets/shaders/post_process.glsl
Normal file
27
assets/shaders/post_process.glsl
Normal file
@ -0,0 +1,27 @@
|
||||
// Input, output blocks
|
||||
VERTEX_EXPORT VertexData {
|
||||
vec2 uv;
|
||||
} VertexOut;
|
||||
|
||||
#if VERTEX_SHADER
|
||||
|
||||
layout(location = 0) in vec3 aPos;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aPos, 1);
|
||||
VertexOut.uv = aPos.xy * 0.5 + 0.5;
|
||||
}
|
||||
#endif // VERTEX_SHADER
|
||||
|
||||
#if FRAGMENT_SHADER
|
||||
|
||||
layout(binding = 0) uniform sampler2D screen_sampler;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(1) - texture(screen_sampler, VertexOut.uv);
|
||||
}
|
||||
|
||||
|
||||
#endif // FRAGMNET_SHADER
|
6
assets/shaders/post_process.prog
Normal file
6
assets/shaders/post_process.prog
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
{
|
||||
"shader": "post_process.glsl",
|
||||
"vertex": true,
|
||||
"fragment": true
|
||||
}
|
@ -13,6 +13,7 @@ const Vec3 = za.Vec3;
|
||||
const Vec4 = za.Vec4;
|
||||
const Mat4 = za.Mat4;
|
||||
const Quat = za.Quat;
|
||||
const Vec2_i32 = za.Vec2_i32;
|
||||
|
||||
pub const MAX_FRAMES_QUEUED = 3;
|
||||
pub const MAX_POINT_LIGHTS = 8;
|
||||
@ -46,6 +47,15 @@ cube_shadow_texture_array: gl.GLuint = 0,
|
||||
cube_shadow_texture_handle: gl.GLuint64 = 0,
|
||||
cube_shadow_framebuffer: gl.GLuint = 0,
|
||||
|
||||
// Destination for all 3d rendering
|
||||
screen_color_texture: gl.GLuint = 0,
|
||||
screen_depth_texture: gl.GLuint = 0,
|
||||
screen_fbo: gl.GLuint = 0,
|
||||
screen_tex_size: Vec2_i32 = Vec2_i32.zero(),
|
||||
|
||||
// VAO for post processing shaders
|
||||
post_process_vao: gl.GLuint = 0,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetman: *AssetManager) Render {
|
||||
var render = Render{
|
||||
.allocator = allocator,
|
||||
@ -237,9 +247,65 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.Position.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||
}
|
||||
|
||||
// Screen HDR FBO
|
||||
{
|
||||
gl.createFramebuffers(1, &render.screen_fbo);
|
||||
std.debug.assert(render.screen_fbo != 0);
|
||||
|
||||
var width: c_int = 0;
|
||||
var height: c_int = 0;
|
||||
c.SDL_GL_GetDrawableSize(globals.g_init.window, &width, &height);
|
||||
|
||||
var textures = [2]gl.GLuint{ 0, 0 };
|
||||
gl.createTextures(gl.TEXTURE_2D, textures.len, &textures);
|
||||
render.screen_color_texture = textures[0];
|
||||
render.screen_depth_texture = textures[1];
|
||||
|
||||
std.debug.assert(render.screen_color_texture != 0);
|
||||
std.debug.assert(render.screen_depth_texture != 0);
|
||||
|
||||
// These will always match output framebuffer size, so no interpolation required
|
||||
gl.textureParameteri(render.screen_color_texture, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.textureParameteri(render.screen_color_texture, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
|
||||
render.updateScreenBufferSize(width, height);
|
||||
}
|
||||
|
||||
// Post process VAO
|
||||
{
|
||||
gl.createVertexArrays(1, &render.post_process_vao);
|
||||
std.debug.assert(render.post_process_vao != 0);
|
||||
const vao = render.post_process_vao;
|
||||
|
||||
// positions
|
||||
gl.enableVertexArrayAttrib(vao, Attrib.Position.value());
|
||||
gl.vertexArrayAttribBinding(vao, Attrib.Position.value(), 0);
|
||||
gl.vertexArrayAttribFormat(vao, Attrib.Position.value(), 3, gl.FLOAT, gl.FALSE, 0);
|
||||
}
|
||||
|
||||
return render;
|
||||
}
|
||||
|
||||
fn updateScreenBufferSize(self: *Render, width: c_int, height: c_int) void {
|
||||
gl.bindTexture(gl.TEXTURE_2D, self.screen_color_texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, width, height, 0, gl.RGB, gl.HALF_FLOAT, null);
|
||||
checkGLError();
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, self.screen_depth_texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F, width, height, 0, gl.DEPTH_COMPONENT, gl.FLOAT, null);
|
||||
checkGLError();
|
||||
|
||||
gl.namedFramebufferTexture(self.screen_fbo, gl.COLOR_ATTACHMENT0, self.screen_color_texture, 0);
|
||||
gl.namedFramebufferTexture(self.screen_fbo, gl.DEPTH_ATTACHMENT, self.screen_depth_texture, 0);
|
||||
|
||||
if (gl.checkNamedFramebufferStatus(self.screen_fbo, gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
||||
checkGLError();
|
||||
@panic("Framebuffer incomplete");
|
||||
}
|
||||
|
||||
self.screen_tex_size = Vec2_i32.new(width, height);
|
||||
}
|
||||
|
||||
pub fn begin(self: *Render) void {
|
||||
self.command_count = 0;
|
||||
self.tripple_buffer_index = (self.tripple_buffer_index + 1) % MAX_FRAMES_QUEUED;
|
||||
@ -392,7 +458,12 @@ pub fn finish(self: *Render) void {
|
||||
var height: c_int = 0;
|
||||
c.SDL_GL_GetDrawableSize(globals.g_init.window, &width, &height);
|
||||
|
||||
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, 0);
|
||||
if (width != self.screen_tex_size.x() or height != self.screen_tex_size.y()) {
|
||||
self.updateScreenBufferSize(width, height);
|
||||
}
|
||||
|
||||
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, self.screen_fbo);
|
||||
|
||||
gl.viewport(0, 0, width, height);
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
@ -502,6 +573,29 @@ pub fn finish(self: *Render) void {
|
||||
|
||||
//std.log.debug("Total draws {}, frustum culled draws {}\n", .{ self.command_count, rendered_count });
|
||||
|
||||
// Post processing pass
|
||||
{
|
||||
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, 0);
|
||||
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.post_process).program);
|
||||
gl.bindVertexArray(self.post_process_vao);
|
||||
|
||||
gl.bindTextureUnit(0, self.screen_color_texture);
|
||||
|
||||
const mesh = self.assetman.resolveMesh(a.Meshes.quad.Plane);
|
||||
|
||||
mesh.positions.bind(Render.Attrib.Position.value());
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer);
|
||||
gl.drawElements(
|
||||
gl.TRIANGLES,
|
||||
mesh.indices.count,
|
||||
mesh.indices.type,
|
||||
@ptrFromInt(mesh.indices.offset),
|
||||
);
|
||||
}
|
||||
|
||||
self.gl_fences[self.tripple_buffer_index] = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
c.SDL_GL_SwapWindow(ginit.window);
|
||||
c.SDL_Delay(1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user