kale, magnifying glass
This commit is contained in:
parent
6302d79dec
commit
4cb25b7757
@ -7,6 +7,6 @@ Pos=92,127
|
||||
Size=195,279
|
||||
|
||||
[Window][Kale Renderer]
|
||||
Pos=60,60
|
||||
Pos=62,56
|
||||
Size=181,242
|
||||
|
||||
|
||||
@ -5,15 +5,12 @@ layout(location = 0) out vec4 out_color;
|
||||
layout(set = 2, binding = 0) uniform sampler2D screen;
|
||||
|
||||
layout(std140, set = 3, binding = 0) uniform UniformBlock {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 inv_view;
|
||||
mat4 inv_proj;
|
||||
vec4 cam_pos;
|
||||
vec2 cam_pos;
|
||||
float time;
|
||||
float aspect;
|
||||
int post_mode;
|
||||
vec2 atlas_adjust;
|
||||
float zoom;
|
||||
float radius;
|
||||
};
|
||||
|
||||
float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); }
|
||||
@ -83,7 +80,6 @@ void main() {
|
||||
out_color = vec4(dither());
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
out_color = out_color * 0.9 +
|
||||
0.1*((t(uv.x, uv.y) > 0.01)?
|
||||
|
||||
109
shaders/ray.frag
109
shaders/ray.frag
@ -1,105 +1,30 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 uv;
|
||||
layout(location = 0) in vec2 v_uv;
|
||||
layout(location = 0) out vec4 out_color;
|
||||
layout(set = 2, binding = 0) uniform sampler2D screen;
|
||||
layout(set = 2, binding = 1) uniform sampler2D depth_tex;
|
||||
layout(set = 2, binding = 0) uniform sampler2D sprites;
|
||||
|
||||
layout(std140, set = 3, binding = 0) uniform UniformBlock {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 inv_view;
|
||||
mat4 inv_proj;
|
||||
vec4 cam_pos;
|
||||
vec2 cam_pos;
|
||||
float time;
|
||||
float aspect;
|
||||
int post_mode;
|
||||
vec2 atlas_adjust;
|
||||
float zoom;
|
||||
float radius;
|
||||
};
|
||||
|
||||
const int MAX_MARCH_STEPS = 64;
|
||||
const float EPS_DIST = 1e-6;
|
||||
|
||||
|
||||
float sdf(vec3 point) {
|
||||
vec3 p = point - cam_pos.xyz;
|
||||
const float speed = 1.0 + exp(sin(time));
|
||||
float t = speed * time;
|
||||
const int N = 5;
|
||||
float d = 1.0/EPS_DIST;
|
||||
float orbit_radius = 0.4;
|
||||
float radius = 0.03;
|
||||
for(int i = 0; i < N; i++) {
|
||||
float phase = ((3.14159 * 2.0) / float(N)) * float(i);
|
||||
d = min(d, length(p - orbit_radius*vec3(sin(t + phase), 0.0, cos(t + phase))) - radius);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
vec3 getnormal(vec3 p) {
|
||||
float e = EPS_DIST;
|
||||
return normalize(vec3(
|
||||
sdf(p + vec3(e, 0.0, 0.0)) - sdf(p - vec3(e, 0.0, 0.0)),
|
||||
sdf(p + vec3(0.0, e, 0.0)) - sdf(p - vec3(0.0, e, 0.0)),
|
||||
sdf(p + vec3(0.0, 0.0, e)) - sdf(p - vec3(0.0, 0.0, e))
|
||||
));
|
||||
}
|
||||
|
||||
vec4 march(vec3 point, vec3 ray, float max_depth) {
|
||||
float totaldist = 0.0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < MAX_MARCH_STEPS && totaldist < max_depth; i += 1) {
|
||||
float h = sdf(point);
|
||||
|
||||
if (h < EPS_DIST) {
|
||||
totaldist += h;
|
||||
return vec4(point, totaldist);
|
||||
}
|
||||
|
||||
totaldist += h;
|
||||
if (totaldist > max_depth)
|
||||
break;
|
||||
|
||||
point += h * ray;
|
||||
}
|
||||
|
||||
return vec4(-1.0);
|
||||
}
|
||||
|
||||
vec3 camray() {
|
||||
vec2 ndc = uv * 2.0 - 1.0;
|
||||
ndc.y = -ndc.y;
|
||||
vec4 view_pos = inv_proj * vec4(ndc, 1.0, 1.0);
|
||||
view_pos /= view_pos.w;
|
||||
return normalize((inv_view * vec4(normalize(view_pos.xyz), 0.0)).xyz);
|
||||
}
|
||||
|
||||
vec4 kernel(float max_depth) {
|
||||
max_depth = (max_depth > 0.0)? max_depth : 1000.0;
|
||||
vec3 cam_ray = camray();
|
||||
|
||||
return march(cam_pos.xyz, cam_ray, max_depth);
|
||||
}
|
||||
|
||||
float linearize_depth(vec2 uv) {
|
||||
float d = texture(depth_tex, uv).r;
|
||||
vec4 ndc = vec4(uv * 2.0 - 1.0, d * 2.0 - 1.0, 1.0);
|
||||
vec4 view_pos = inv_proj * ndc;
|
||||
view_pos /= view_pos.w;
|
||||
return -view_pos.z; // view space, positive distance
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
float max_depth = linearize_depth(uv);
|
||||
vec4 hit = kernel(max_depth);
|
||||
|
||||
if (hit.w > 0.0) {
|
||||
out_color = vec4(1.0);//out_color = vec4(getnormal(hit.xyz), 1.0);
|
||||
} else {
|
||||
out_color = texture(screen, uv);
|
||||
vec2 uv = 2.0 * v_uv - vec2(1.0);
|
||||
uv.y *= -1.0;
|
||||
uv.x *= aspect;
|
||||
float l = length(uv);
|
||||
if(l < radius) {
|
||||
uv /= zoom;
|
||||
}
|
||||
|
||||
vec4 bg = texture(sprites, uv + cam_pos * 0.01);
|
||||
out_color = bg;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
#version 460
|
||||
layout(location = 0) in vec4 v_color;
|
||||
layout(location = 1) in vec2 v_uv;
|
||||
layout(location = 2) in vec3 v_normal_vs;
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
layout(set = 2, binding = 0) uniform sampler2D atlas;
|
||||
|
||||
void main() {
|
||||
vec3 light_dir = normalize(vec3(0.5, 1.0, 0.8));
|
||||
|
||||
float ambient = 0.2;
|
||||
float diffuse = max(dot(v_normal_vs, light_dir), 0.0);
|
||||
float lighting = ambient + (1.0 - ambient) * diffuse;
|
||||
|
||||
vec2 uv = vec2(v_uv.x, 1.0-v_uv.y);
|
||||
out_color = texture(atlas, uv);// + v_color;
|
||||
//out_color = v_color * vec4(v_normal_vs,1.0);
|
||||
//out_color = vec4(v_color.rgb * lighting, v_color.a);
|
||||
//out_color = vec4(1.0);
|
||||
//out_color = vec4(viz(v_normal_vs), 1.0);
|
||||
//out_color = vec4(lighting);
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
#version 460
|
||||
layout(location = 0) in vec3 a_pos;
|
||||
layout(location = 1) in vec2 a_uv;
|
||||
layout(location = 2) in vec3 a_normal;
|
||||
|
||||
layout(location = 0) out vec4 v_color;
|
||||
layout(location = 1) out vec2 v_uv;
|
||||
layout(location = 2) out vec3 v_normal_vs; // view-space normal
|
||||
|
||||
layout(std140, set = 1, binding = 0) uniform UniformBlock {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 inv_view;
|
||||
mat4 inv_proj;
|
||||
vec4 cam_pos;
|
||||
float time;
|
||||
int post_mode;
|
||||
vec2 atlas_adjust;
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec4 view_pos = view * model * vec4(a_pos, 1.0);
|
||||
gl_Position = proj * view_pos;
|
||||
v_color = vec4(a_uv, abs(sin(a_uv.x*a_uv.y)), 1.0);
|
||||
v_uv = a_uv*atlas_adjust;
|
||||
|
||||
v_normal_vs = normalize(a_normal);
|
||||
}
|
||||
142
src/camera.cpp
142
src/camera.cpp
@ -2,7 +2,6 @@
|
||||
#include <SDL3/SDL_gamepad.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
/*
|
||||
I bought a very cheap ps4 knockoff controller and for some reason
|
||||
AXIS_RIGHTX and AXIS_RIGHTY are swapped with the triggers?
|
||||
@ -10,75 +9,62 @@
|
||||
*/
|
||||
#define WEIRD_JOYSTICK_BEHAVIOR 1
|
||||
|
||||
vec3 Camera::dir() const {
|
||||
return normalize(vec3(
|
||||
cos(radians(yaw)) * cos(radians(pitch)),
|
||||
sin(radians(pitch)),
|
||||
sin(radians(yaw)) * cos(radians(pitch))
|
||||
));
|
||||
}
|
||||
|
||||
void Camera::update() {
|
||||
if (look_up) pitch += look_speed;
|
||||
if (look_down) pitch -= look_speed;
|
||||
if (look_left) yaw -= look_speed;
|
||||
if (look_right) yaw += look_speed;
|
||||
pitch = clamp(pitch, -89.0f, 89.0f);
|
||||
|
||||
vec3 d = dir();
|
||||
vec3 right = normalize(cross(d, up));
|
||||
target = pos + d;
|
||||
|
||||
float shift_speed = shifted? 10.0 : 1.0;
|
||||
float speed = move_speed * shift_speed;
|
||||
|
||||
if (move_forward) { pos += d * speed; target += d * speed; }
|
||||
if (move_backward) { pos -= d * speed; target -= d * speed; }
|
||||
if (move_left) { pos -= right * speed; target -= right * speed; }
|
||||
if (move_right) { pos += right * speed; target += right * speed; }
|
||||
if (move_up) { pos += up * speed; target += up * speed; }
|
||||
if (move_down) { pos -= up * speed; target -= up * speed; }
|
||||
float speed = move_speed * (shifted ? 2.0f : 1.0f);
|
||||
if(zoom >= 1.0f) {
|
||||
speed /= zoom;
|
||||
}
|
||||
|
||||
if (move_left) pos.x -= speed;
|
||||
if (move_right) pos.x += speed;
|
||||
if (move_up) pos.y += speed;
|
||||
if (move_down) pos.y -= speed;
|
||||
}
|
||||
|
||||
void Camera::on_key(SDL_Scancode scancode, bool pressed) {
|
||||
switch (scancode) {
|
||||
case SDL_SCANCODE_W: move_forward = pressed; break;
|
||||
case SDL_SCANCODE_S: move_backward = pressed; break;
|
||||
case SDL_SCANCODE_A: move_left = pressed; break;
|
||||
case SDL_SCANCODE_D: move_right = pressed; break;
|
||||
case SDL_SCANCODE_SPACE: move_up = pressed; break;
|
||||
case SDL_SCANCODE_LCTRL: move_down = pressed; break;
|
||||
case SDL_SCANCODE_UP: look_up = pressed; break;
|
||||
case SDL_SCANCODE_DOWN: look_down = pressed; break;
|
||||
case SDL_SCANCODE_LEFT: look_left = pressed; break;
|
||||
case SDL_SCANCODE_RIGHT: look_right = pressed; break;
|
||||
case SDL_SCANCODE_W:
|
||||
case SDL_SCANCODE_UP:
|
||||
move_up = pressed;
|
||||
break;
|
||||
case SDL_SCANCODE_S:
|
||||
case SDL_SCANCODE_DOWN:
|
||||
move_down = pressed;
|
||||
break;
|
||||
case SDL_SCANCODE_A:
|
||||
case SDL_SCANCODE_LEFT:
|
||||
move_left = pressed;
|
||||
break;
|
||||
case SDL_SCANCODE_D:
|
||||
case SDL_SCANCODE_RIGHT:
|
||||
move_right = pressed;
|
||||
break;
|
||||
case SDL_SCANCODE_LSHIFT:
|
||||
case SDL_SCANCODE_RSHIFT:
|
||||
case SDL_SCANCODE_RSHIFT:
|
||||
shifted = pressed;
|
||||
break;
|
||||
default: break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef WEIRD_JOYSTICK_BEHAVIOR
|
||||
#define WEIRD_JOYSTICK_BEHAVIOR 0
|
||||
#endif
|
||||
static float normalize_stick(SDL_Gamepad* gamepad, SDL_GamepadAxis axis) {
|
||||
if(axis == SDL_GAMEPAD_AXIS_COUNT || axis == SDL_GAMEPAD_AXIS_INVALID)
|
||||
if (axis == SDL_GAMEPAD_AXIS_COUNT || axis == SDL_GAMEPAD_AXIS_INVALID)
|
||||
return 0.0f;
|
||||
|
||||
|
||||
float d = static_cast<float>(SDL_GetGamepadAxis(gamepad, axis));
|
||||
|
||||
bool reported_trigger = (axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER || axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
|
||||
bool really_trigger = (WEIRD_JOYSTICK_BEHAVIOR)? (axis == SDL_GAMEPAD_AXIS_RIGHTX || axis == SDL_GAMEPAD_AXIS_RIGHTY) : reported_trigger;
|
||||
bool really_trigger = (WEIRD_JOYSTICK_BEHAVIOR) ? (axis == SDL_GAMEPAD_AXIS_RIGHTX || axis == SDL_GAMEPAD_AXIS_RIGHTY) : reported_trigger;
|
||||
|
||||
float min = (reported_trigger)? 0 : SDL_JOYSTICK_AXIS_MIN;
|
||||
float min = (reported_trigger) ? 0 : SDL_JOYSTICK_AXIS_MIN;
|
||||
float max = SDL_JOYSTICK_AXIS_MAX;
|
||||
float n = (d - min) / (max - min);
|
||||
|
||||
return really_trigger? n : ((n - 0.5) * 2.0);
|
||||
return really_trigger ? n : ((n - 0.5) * 2.0);
|
||||
}
|
||||
|
||||
void Camera::on_gamepad(SDL_Gamepad* gamepad) {
|
||||
@ -86,63 +72,43 @@ void Camera::on_gamepad(SDL_Gamepad* gamepad) {
|
||||
|
||||
float lx = normalize_stick(gamepad, SDL_GAMEPAD_AXIS_LEFTX);
|
||||
float ly = normalize_stick(gamepad, SDL_GAMEPAD_AXIS_LEFTY);
|
||||
float ry = normalize_stick(gamepad, (WEIRD_JOYSTICK_BEHAVIOR)? SDL_GAMEPAD_AXIS_RIGHT_TRIGGER : SDL_GAMEPAD_AXIS_RIGHTY);
|
||||
float rx = normalize_stick(gamepad, (WEIRD_JOYSTICK_BEHAVIOR)? SDL_GAMEPAD_AXIS_LEFT_TRIGGER : SDL_GAMEPAD_AXIS_RIGHTX);
|
||||
static uint8_t frame = 0;
|
||||
if(frame++ == 64) {
|
||||
std::cout << "lx: " << lx << " ly: " << ly << " rx: " << rx << " ry: " << ry << std::endl;
|
||||
}
|
||||
float rx = normalize_stick(gamepad, (WEIRD_JOYSTICK_BEHAVIOR) ? SDL_GAMEPAD_AXIS_LEFT_TRIGGER : SDL_GAMEPAD_AXIS_RIGHTX);
|
||||
|
||||
//float lt = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) / 32767.0f;
|
||||
//float rt = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) / 32767.0f;
|
||||
static uint8_t frame = 0;
|
||||
if (frame++ == 64) {
|
||||
std::cout << "lx: " << lx << " ly: " << ly << " rx: " << rx << std::endl;
|
||||
}
|
||||
|
||||
const float dead = 0.1f;
|
||||
if (abs(lx) < dead) lx = 0.0f;
|
||||
if (abs(ly) < dead) ly = 0.0f;
|
||||
if (abs(rx) < dead) rx = 0.0f;
|
||||
if (abs(ry) < dead) ry = 0.0f;
|
||||
// if (lt < dead) lt = 0.0f;
|
||||
// if (rt < dead) rt = 0.0f;
|
||||
|
||||
|
||||
// look — right stick only
|
||||
yaw += rx * look_speed;
|
||||
pitch -= ry * look_speed;
|
||||
pitch = clamp(pitch, -89.0f, 89.0f);
|
||||
|
||||
float speed = move_speed * (shifted ? 2.0f : 1.0f);
|
||||
if(zoom >= 1.0f) {
|
||||
speed /= zoom;
|
||||
}
|
||||
|
||||
vec3 d = dir();
|
||||
vec3 right = normalize(cross(d, up));
|
||||
float speed = move_speed * (shifted ? 4.0f : 1.0f);
|
||||
// Move with left stick
|
||||
pos.x += lx * speed;
|
||||
pos.y += ly * speed;
|
||||
|
||||
// move — left stick
|
||||
pos += d * (-ly * speed);
|
||||
pos += right * ( lx * speed);
|
||||
|
||||
// up/down — triggers
|
||||
//pos += up * (rt - lt) * speed;
|
||||
|
||||
target = pos + d;
|
||||
// Rotation with right stick x-axis
|
||||
rotation += rx * 2.0f;
|
||||
|
||||
shifted = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER);
|
||||
}
|
||||
|
||||
void Camera::on_mouse_motion(float dx, float dy) {
|
||||
yaw += dx * look_speed * 0.1f;
|
||||
pitch -= dy * look_speed * 0.1f;
|
||||
pitch = clamp(pitch, -89.0f, 89.0f);
|
||||
// Not used in 2D mode
|
||||
(void)dx;
|
||||
(void)dy;
|
||||
}
|
||||
|
||||
CameraUBO Camera::ubo(float aspect) const {
|
||||
mat4 v = lookAt(pos, target, up);
|
||||
mat4 p = perspective(radians(fov), aspect, 0.01f, 1000.0f);
|
||||
return CameraUBO {
|
||||
.model = mat4(1.0f),
|
||||
.view = v,
|
||||
.proj = p,
|
||||
.inv_view = inverse(v),
|
||||
.inv_proj = inverse(p),
|
||||
.cam_pos = vec4(pos, 1.0),
|
||||
.time = (float)SDL_GetTicks() / 1000.0f,
|
||||
return CameraUBO{
|
||||
.cam_pos = vec4(pos.x, pos.y, 5.0f, 1.0f),
|
||||
.time = (float)SDL_GetTicks() / 1000.0f,
|
||||
.aspect = aspect
|
||||
};
|
||||
}
|
||||
|
||||
31
src/camera.h
31
src/camera.h
@ -4,33 +4,20 @@
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
struct Camera {
|
||||
vec3 pos = vec3(0.0f, 0.0f, 2.0f);
|
||||
vec3 target = vec3(0.0f, 0.0f, 0.0f);
|
||||
vec3 up = vec3(0.0f, 1.0f, 0.0f);
|
||||
float fov = 60.0f;
|
||||
float move_speed = 0.5f;
|
||||
float look_speed = 1.0f;
|
||||
float pitch = 0.0f;
|
||||
float yaw = -90.0f;
|
||||
vec2 pos = vec2(0.0f, 0.0f);
|
||||
float zoom = 1.0f;
|
||||
float move_speed = 5.0f;
|
||||
float rotation = 0.0f;
|
||||
|
||||
bool move_forward = false;
|
||||
bool move_backward = false;
|
||||
bool move_left = false;
|
||||
bool move_right = false;
|
||||
bool move_up = false;
|
||||
bool move_down = false;
|
||||
bool look_up = false;
|
||||
bool look_down = false;
|
||||
bool look_left = false;
|
||||
bool look_right = false;
|
||||
bool shifted = false;
|
||||
bool move_left = false;
|
||||
bool move_right = false;
|
||||
bool move_up = false;
|
||||
bool move_down = false;
|
||||
bool shifted = false;
|
||||
|
||||
void update();
|
||||
void on_key(SDL_Scancode scancode, bool pressed);
|
||||
void on_mouse_motion(float dx, float dy);
|
||||
void on_gamepad(SDL_Gamepad* gamepad);
|
||||
CameraUBO ubo(float aspect) const;
|
||||
|
||||
private:
|
||||
vec3 dir() const;
|
||||
};
|
||||
|
||||
@ -62,6 +62,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv) {
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void* appstate) {
|
||||
(void)appstate;
|
||||
camera.zoom = renderer.zoom;
|
||||
camera.on_gamepad(renderer.gamepad);
|
||||
camera.update();
|
||||
|
||||
|
||||
@ -3,78 +3,10 @@
|
||||
#include "types.h"
|
||||
#include <iostream>
|
||||
|
||||
void ScenePipeline::create(SDL_GPUDevice* dev, SDL_Window* win) {
|
||||
vert = load_shader(dev, "shaders/scene.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 1);
|
||||
frag = load_shader(dev, "shaders/scene.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 0);
|
||||
|
||||
SDL_GPUVertexBufferDescription vert_buf {
|
||||
.slot = 0,
|
||||
.pitch = sizeof(Vertex),
|
||||
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
|
||||
.instance_step_rate = 0,
|
||||
};
|
||||
|
||||
SDL_GPUVertexAttribute attrs[3] = {
|
||||
{ .location = 0, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = 0 },
|
||||
{ .location = 1, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, .offset = (uint32_t)offsetof(Vertex, uv) },
|
||||
{ .location = 2, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = (uint32_t)offsetof(Vertex, norm) },
|
||||
};
|
||||
|
||||
SDL_GPUColorTargetDescription color_tgt {
|
||||
.format = SDL_GetGPUSwapchainTextureFormat(dev, win),
|
||||
.blend_state = {
|
||||
.src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
|
||||
.dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.color_blend_op = SDL_GPU_BLENDOP_ADD,
|
||||
.src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
|
||||
.dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.alpha_blend_op = SDL_GPU_BLENDOP_ADD,
|
||||
.enable_blend = false,
|
||||
}
|
||||
};
|
||||
|
||||
SDL_GPUGraphicsPipelineCreateInfo info {
|
||||
.vertex_shader = vert,
|
||||
.fragment_shader = frag,
|
||||
.vertex_input_state = {
|
||||
.vertex_buffer_descriptions = &vert_buf,
|
||||
.num_vertex_buffers = 1,
|
||||
.vertex_attributes = attrs,
|
||||
.num_vertex_attributes = sizeof(attrs)/sizeof(attrs[0]),
|
||||
},
|
||||
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
|
||||
.rasterizer_state = {
|
||||
.fill_mode = SDL_GPU_FILLMODE_FILL,
|
||||
.cull_mode = SDL_GPU_CULLMODE_NONE,
|
||||
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
|
||||
},
|
||||
.depth_stencil_state = {
|
||||
.compare_op = SDL_GPU_COMPAREOP_LESS,
|
||||
.enable_depth_test = true,
|
||||
.enable_depth_write = true,
|
||||
},
|
||||
.target_info = {
|
||||
.color_target_descriptions = &color_tgt,
|
||||
.num_color_targets = 1,
|
||||
.depth_stencil_format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
|
||||
.has_depth_stencil_target = true,
|
||||
},
|
||||
};
|
||||
|
||||
pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info);
|
||||
if (!pipeline)
|
||||
std::cerr << "Scene pipeline failed: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
|
||||
void ScenePipeline::destroy(SDL_GPUDevice* dev) {
|
||||
if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline);
|
||||
if (vert) SDL_ReleaseGPUShader(dev, vert);
|
||||
if (frag) SDL_ReleaseGPUShader(dev, frag);
|
||||
}
|
||||
|
||||
void RayPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) {
|
||||
vert = load_shader(dev, "shaders/ray.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0);
|
||||
frag = load_shader(dev, "shaders/ray.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 2, 1);
|
||||
frag = load_shader(dev, "shaders/ray.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1);
|
||||
|
||||
SDL_GPUColorTargetDescription color_tgt {
|
||||
.format = SDL_GetGPUSwapchainTextureFormat(dev, win),
|
||||
|
||||
@ -1,15 +1,6 @@
|
||||
#pragma once
|
||||
#include <SDL3/SDL_gpu.h>
|
||||
|
||||
struct ScenePipeline {
|
||||
SDL_GPUGraphicsPipeline* pipeline = nullptr;
|
||||
SDL_GPUShader* vert = nullptr;
|
||||
SDL_GPUShader* frag = nullptr;
|
||||
|
||||
void create(SDL_GPUDevice* dev, SDL_Window* win);
|
||||
void destroy(SDL_GPUDevice* dev);
|
||||
};
|
||||
|
||||
struct RayPipeline {
|
||||
SDL_GPUGraphicsPipeline* pipeline = nullptr;
|
||||
SDL_GPUShader* vert = nullptr;
|
||||
|
||||
131
src/renderer.cpp
131
src/renderer.cpp
@ -17,6 +17,17 @@
|
||||
#include "imgui_impl_sdlgpu3.h"
|
||||
|
||||
|
||||
static uint64_t visit_grid[64];
|
||||
|
||||
uint64_t simple_rand(uint64_t *s){
|
||||
static uint64_t state = 0xDEADBEEF;
|
||||
const uint64_t taps = 0x1BULL;
|
||||
uint8_t out = state & 1;
|
||||
state >>= 1;
|
||||
if(out) state ^= taps << 60;
|
||||
return state;
|
||||
}
|
||||
|
||||
extern int post_mode;
|
||||
extern vec2 atlas_adjust;
|
||||
|
||||
@ -27,12 +38,9 @@ bool Renderer::init(SDL_Window* w) {
|
||||
|
||||
SDL_ClaimWindowForGPUDevice(dev, win);
|
||||
|
||||
printf("LOAD BIN?\n");
|
||||
load_bin();
|
||||
printf("BIN LOADED\n");
|
||||
load_sprites();
|
||||
|
||||
render_sampler = create_linear_sampler(dev);
|
||||
SDL_GPUSamplerCreateInfo depth_sampler_info {
|
||||
SDL_GPUSamplerCreateInfo sprite_sampler_info {
|
||||
.min_filter = SDL_GPU_FILTER_NEAREST,
|
||||
.mag_filter = SDL_GPU_FILTER_NEAREST,
|
||||
.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST,
|
||||
@ -41,69 +49,50 @@ bool Renderer::init(SDL_Window* w) {
|
||||
.compare_op = SDL_GPU_COMPAREOP_INVALID,
|
||||
.enable_compare = false,
|
||||
};
|
||||
|
||||
depth_sampler = SDL_CreateGPUSampler(dev, &depth_sampler_info);
|
||||
atlas_sampler = SDL_CreateGPUSampler(dev, &depth_sampler_info);
|
||||
|
||||
atlas_sampler = SDL_CreateGPUSampler(dev, &sprite_sampler_info);
|
||||
render_sampler = create_linear_sampler(dev);
|
||||
|
||||
resize_render_texture(960, 540);
|
||||
|
||||
setup_imgui();
|
||||
|
||||
fprintf(stderr, "Pipeline creation....");
|
||||
scene.create(dev, win);
|
||||
ray.create(dev, win);
|
||||
post.create(dev, win);
|
||||
fprintf(stderr, "finished\n");
|
||||
|
||||
return scene.pipeline && ray.pipeline;
|
||||
return post.pipeline && ray.pipeline;
|
||||
}
|
||||
|
||||
void Renderer::destroy() {
|
||||
if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex);
|
||||
if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex);
|
||||
if (render_sampler) SDL_ReleaseGPUSampler(dev, render_sampler);
|
||||
if (vert_buff) SDL_ReleaseGPUBuffer(dev, vert_buff);
|
||||
if (depth_tex) SDL_ReleaseGPUTexture(dev, depth_tex);
|
||||
if (atlas_tex) SDL_ReleaseGPUTexture(dev, atlas_tex);
|
||||
if (gamepad) SDL_CloseGamepad(gamepad);
|
||||
scene.destroy(dev);
|
||||
ray.destroy(dev);
|
||||
post.destroy(dev);
|
||||
SDL_DestroyGPUDevice(dev);
|
||||
}
|
||||
|
||||
bool Renderer::load_bin() {
|
||||
const char* path = "assets/bin/hl1.bin";
|
||||
bool Renderer::load_sprites() {
|
||||
const char* tex_path = "assets/bin/hl1.bin.png";
|
||||
/*if(!std::filesystem::exists(path) || !std::filesystem::exists(tex_path)) {
|
||||
SDL_Log("Failed to find %s (or maybe %s)", path, tex_path);
|
||||
return false;
|
||||
}*/
|
||||
|
||||
size_t bin_size;
|
||||
const uint8_t* bin_data = (uint8_t*)SDL_LoadFile(path, &bin_size);
|
||||
if(!bin_data) {
|
||||
SDL_Log("Failed to read %s %s", path, tex_path);
|
||||
return false;
|
||||
}
|
||||
vertices.resize(bin_size/sizeof(Vertex));
|
||||
memcpy(vertices.data(), bin_data, bin_size);
|
||||
SDL_Log("File size: %zu, %zu vertices", bin_size, bin_size/3);
|
||||
|
||||
|
||||
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(dev);
|
||||
SDL_GPUCopyPass *copy_pass = SDL_BeginGPUCopyPass(cmd);
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd);
|
||||
int w,h;
|
||||
atlas_tex = IMG_LoadGPUTexture(dev, copy_pass, tex_path, &w, &h);
|
||||
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_SubmitGPUCommandBuffer(cmd);
|
||||
SDL_GPUBufferCreateInfo info {
|
||||
.usage = SDL_GPU_BUFFERUSAGE_VERTEX,
|
||||
.size = static_cast<uint32_t>(vertices.size() * sizeof(Vertex)),
|
||||
};
|
||||
vert_buff = SDL_CreateGPUBuffer(dev, &info);
|
||||
upload_buffer(dev, vert_buff, vertices.data(), info.size);
|
||||
return true;
|
||||
|
||||
if(atlas_tex) {
|
||||
SDL_Log("Loaded sprite atlas: %s, size: %dx%d", tex_path, w, h);
|
||||
} else {
|
||||
SDL_Log("Failed to load sprite atlas: %s, error: %s", tex_path, SDL_GetError());
|
||||
}
|
||||
|
||||
return !!atlas_tex;
|
||||
}
|
||||
|
||||
void Renderer::setup_imgui() {
|
||||
@ -144,60 +133,14 @@ bool Renderer::load_bsp() {
|
||||
|
||||
void Renderer::resize_render_texture(uint32_t w, uint32_t h) {
|
||||
SDL_WaitForGPUIdle(dev);
|
||||
if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex);
|
||||
if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex);
|
||||
if (depth_tex) SDL_ReleaseGPUTexture(dev, depth_tex);
|
||||
|
||||
SDL_GPUTextureCreateInfo depth_info {
|
||||
.type = SDL_GPU_TEXTURETYPE_2D,
|
||||
.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
|
||||
.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER,
|
||||
.width = w,
|
||||
.height = h,
|
||||
.layer_count_or_depth = 1,
|
||||
.num_levels = 1,
|
||||
};
|
||||
|
||||
depth_tex = SDL_CreateGPUTexture(dev, &depth_info);
|
||||
render_tex = create_render_texture(dev, win, w, h);
|
||||
post_tex = create_render_texture(dev, win, w, h);
|
||||
render_w = w;
|
||||
render_h = h;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) {
|
||||
SDL_PushGPUVertexUniformData(cmd, 0, &ubo, sizeof(ubo));
|
||||
|
||||
SDL_GPUColorTargetInfo tgt {
|
||||
.texture = render_tex,
|
||||
.clear_color = { 0.0, 0.0, 0.0, 1.0},
|
||||
.load_op = SDL_GPU_LOADOP_CLEAR,
|
||||
.store_op = SDL_GPU_STOREOP_STORE,
|
||||
};
|
||||
|
||||
SDL_GPUDepthStencilTargetInfo depth_tgt {
|
||||
.texture = depth_tex,
|
||||
.clear_depth = 1.0f,
|
||||
.load_op = SDL_GPU_LOADOP_CLEAR,
|
||||
.store_op = SDL_GPU_STOREOP_STORE,
|
||||
.stencil_load_op = SDL_GPU_LOADOP_DONT_CARE,
|
||||
.stencil_store_op = SDL_GPU_STOREOP_STORE,
|
||||
};
|
||||
|
||||
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, &depth_tgt);
|
||||
SDL_BindGPUGraphicsPipeline(pass, scene.pipeline);
|
||||
SDL_GPUBufferBinding binding { .buffer = vert_buff, .offset = 0 };
|
||||
SDL_BindGPUVertexBuffers(pass, 0, &binding, 1);
|
||||
|
||||
SDL_GPUTextureSamplerBinding tex[1] = {
|
||||
{ .texture = atlas_tex, .sampler = atlas_sampler },
|
||||
};
|
||||
SDL_BindGPUFragmentSamplers(pass, 0, tex, 1);
|
||||
SDL_DrawGPUPrimitives(pass, vertices.size(), 1, 0, 0);
|
||||
SDL_EndGPURenderPass(pass);
|
||||
}
|
||||
|
||||
void Renderer::pass_ray(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) {
|
||||
SDL_PushGPUFragmentUniformData(cmd, 0, &ubo, sizeof(ubo));
|
||||
|
||||
@ -209,11 +152,11 @@ void Renderer::pass_ray(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) {
|
||||
|
||||
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL);
|
||||
SDL_BindGPUGraphicsPipeline(pass, ray.pipeline);
|
||||
SDL_GPUTextureSamplerBinding texs[2] = {
|
||||
{ .texture = render_tex, .sampler = render_sampler },
|
||||
{ .texture = depth_tex, .sampler = depth_sampler },
|
||||
SDL_GPUTextureSamplerBinding texs[1] = {
|
||||
{ .texture = atlas_tex, .sampler = atlas_sampler },
|
||||
};
|
||||
SDL_BindGPUFragmentSamplers(pass, 0, texs, 2);
|
||||
|
||||
SDL_BindGPUFragmentSamplers(pass, 0, texs, 1);
|
||||
SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0);
|
||||
SDL_EndGPURenderPass(pass);
|
||||
}
|
||||
@ -251,8 +194,10 @@ void Renderer::draw_imgui(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* tex) {
|
||||
post_mode = 2;
|
||||
|
||||
|
||||
ImGui::SliderFloat("Atlas du", &atlas_adjust.x, 0.1f, 100.0f);
|
||||
ImGui::SliderFloat("Atlas dv", &atlas_adjust.y, 0.1f, 100.0f);
|
||||
if(ImGui::CollapsingHeader("Magnification")) {
|
||||
ImGui::SliderFloat("Zoom", &zoom, 0.1f, 100.0f);
|
||||
ImGui::SliderFloat("Radius", &radius, 0.1f, 1.0f);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
@ -282,7 +227,8 @@ void Renderer::draw_imgui(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* tex) {
|
||||
|
||||
void Renderer::draw(CameraUBO& ubo) {
|
||||
ubo.post_mode = post_mode;
|
||||
ubo.atlas_adjust = atlas_adjust;
|
||||
ubo.zoom = zoom;
|
||||
ubo.radius = radius;
|
||||
static std::array<float, 25> frame_times;
|
||||
|
||||
static float last_time = (float)SDL_GetPerformanceCounter()/(float)SDL_GetPerformanceFrequency();
|
||||
@ -312,7 +258,6 @@ void Renderer::draw(CameraUBO& ubo) {
|
||||
if (sw_w != render_w || sw_h != render_h)
|
||||
resize_render_texture(sw_w, sw_h);
|
||||
|
||||
pass_scene(cmd, ubo);
|
||||
pass_ray(cmd, ubo);
|
||||
pass_post(cmd, swapchain, ubo);
|
||||
draw_imgui(cmd, swapchain);
|
||||
|
||||
@ -10,26 +10,26 @@ struct Renderer {
|
||||
SDL_Window* win = nullptr;
|
||||
SDL_Gamepad* gamepad = nullptr;
|
||||
|
||||
ScenePipeline scene;
|
||||
RayPipeline ray;
|
||||
PostPipeline post;
|
||||
|
||||
SDL_GPUBuffer* vert_buff = nullptr;
|
||||
SDL_GPUTexture* render_tex = nullptr;
|
||||
SDL_GPUTexture* post_tex = nullptr;
|
||||
SDL_GPUTexture* depth_tex = nullptr;
|
||||
SDL_GPUTexture* sprite_tex = nullptr;
|
||||
SDL_GPUTexture* atlas_tex = nullptr;
|
||||
SDL_GPUSampler* render_sampler = nullptr;
|
||||
SDL_GPUSampler* depth_sampler = nullptr;
|
||||
SDL_GPUSampler* sprite_sampler = nullptr;
|
||||
SDL_GPUSampler* atlas_sampler = nullptr;
|
||||
uint32_t render_w = 0, render_h = 0;
|
||||
uint64_t frame = 0;
|
||||
|
||||
bool in_menu = 0;
|
||||
float fps = 0.0;
|
||||
|
||||
/* imgui controlled */
|
||||
int post_mode = 0;
|
||||
vec2 atlas_adjust = vec2(0);
|
||||
float zoom = 1.0f;
|
||||
float radius = 0.1f;
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
|
||||
@ -39,13 +39,12 @@ struct Renderer {
|
||||
void draw(CameraUBO& ubo);
|
||||
|
||||
private:
|
||||
bool load_bin();
|
||||
bool load_sprites();
|
||||
bool load_bsp();
|
||||
void setup_imgui();
|
||||
void draw_imgui(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* tex);
|
||||
void add_gol_layer();
|
||||
void resize_render_texture(uint32_t w, uint32_t h);
|
||||
void pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo);
|
||||
void pass_ray(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo);
|
||||
void pass_post(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* swapchain, const CameraUBO& ubo);
|
||||
};
|
||||
|
||||
11
src/types.h
11
src/types.h
@ -10,13 +10,10 @@ struct Vertex {
|
||||
};
|
||||
|
||||
struct CameraUBO {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 inv_view;
|
||||
mat4 inv_proj;
|
||||
vec4 cam_pos;
|
||||
vec2 cam_pos;
|
||||
float time;
|
||||
float aspect;
|
||||
int post_mode;
|
||||
vec2 atlas_adjust;
|
||||
float zoom;
|
||||
float radius;
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user