diff --git a/demo.mp4 b/demo.mp4 new file mode 100644 index 0000000..9a6ee10 Binary files /dev/null and b/demo.mp4 differ diff --git a/shaders/post.frag b/shaders/post.frag index e994cff..7e2cb94 100644 --- a/shaders/post.frag +++ b/shaders/post.frag @@ -70,7 +70,7 @@ void main() { const mat3 sobely = mat3(-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0); - int time = int(fract(time_padded.x/25.0) * 30.0)/10; + int time = int(fract(time_padded.x/1000.0) * 3.0); switch(time) { case 0: out_color = texture(screen, uv); diff --git a/shaders/ray.frag b/shaders/ray.frag index 1860762..234af9e 100644 --- a/shaders/ray.frag +++ b/shaders/ray.frag @@ -21,8 +21,8 @@ const float EPS_DIST = 1e-6; float sdf(vec3 point){ float t = 1.0 + 5.0*abs(sin(time_padded.x)); - vec3 s1_local = mod(point, vec3(t)) - vec3(t/2.0); - float s1 = length(s1_local) - 0.3; + vec3 s1_local = point; //mod(point, vec3(t)) - vec3(t/2.0); + float s1 = length(s1_local) - t; return s1; } diff --git a/src/camera.cpp b/src/camera.cpp index 69d671c..3992932 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,4 +1,14 @@ #include "camera.h" +#include +#include + + +/* + I bought a very cheap ps4 knockoff controller and for some reason + AXIS_RIGHTX and AXIS_RIGHTY are swapped with the triggers? + this should be defined as 0 for a working one + */ +#define WEIRD_JOYSTICK_BEHAVIOR 1 vec3 Camera::dir() const { return normalize(vec3( @@ -50,6 +60,73 @@ void Camera::on_key(SDL_Scancode scancode, bool pressed) { } } + +#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) + return 0.0f; + + + float d = static_cast(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; + + 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); +} + +void Camera::on_gamepad(SDL_Gamepad* gamepad) { + if (!gamepad) return; + + 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 lt = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) / 32767.0f; + //float rt = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) / 32767.0f; + + 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); + + + vec3 d = dir(); + vec3 right = normalize(cross(d, up)); + float speed = move_speed * (shifted ? 4.0f : 1.0f); + + // move — left stick + pos += d * (-ly * speed); + pos += right * ( lx * speed); + + // up/down — triggers + //pos += up * (rt - lt) * speed; + + target = pos + d; + + 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; @@ -68,4 +145,4 @@ CameraUBO Camera::ubo(float aspect) const { .time = vec4((float)SDL_GetTicks() / 1000.0f, 0.0, 0.0, 0.0), .cam_pos = vec4(pos, 1.0), }; -} \ No newline at end of file +} diff --git a/src/camera.h b/src/camera.h index 2371ae0..96edbb8 100644 --- a/src/camera.h +++ b/src/camera.h @@ -28,6 +28,7 @@ struct Camera { 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: diff --git a/src/main.cpp b/src/main.cpp index 8666ce7..9bf3b47 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,42 @@ +#include +#include #include #include #define SDL_MAIN_USE_CALLBACKS #include #include +#include + #include "camera.h" #include "renderer.h" static Camera camera; static Renderer renderer; +static SDL_Gamepad* GetGamepad() { + int count = 0; + SDL_JoystickID* jids = SDL_GetGamepads(&count); + + SDL_Gamepad* gamepad = nullptr; + for(int i = 0; i < count; i++) { + SDL_Gamepad* candidate_gamepad = SDL_OpenGamepad(jids[i]); + + if(!gamepad) { + gamepad = candidate_gamepad; + } + } + + if(!gamepad) { + std::cerr << "No Gamepad :(" << std::endl; + } else { + std::cerr << "Selected: " << SDL_GetGamepadName(gamepad) << std::endl; + } + + SDL_free(jids); + return gamepad; +} + SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv) { (void)appstate; (void)argc; @@ -17,14 +44,21 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv) { SDL_Window* win = SDL_CreateWindow("Kale", 960, 540, SDL_WINDOW_RESIZABLE); SDL_SetWindowRelativeMouseMode(win, true); + SDL_InitSubSystem(SDL_INIT_GAMEPAD); + + SDL_SetGamepadEventsEnabled(true); + if (!renderer.init(win)) return SDL_APP_FAILURE; + renderer.gamepad = GetGamepad(); + return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppIterate(void* appstate) { (void)appstate; + camera.on_gamepad(renderer.gamepad); camera.update(); uint32_t sw_w = renderer.render_w; @@ -42,7 +76,16 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { case SDL_EVENT_WINDOW_CLOSE_REQUESTED: case SDL_EVENT_QUIT: return SDL_APP_SUCCESS; - + case SDL_EVENT_GAMEPAD_ADDED: + if(!renderer.gamepad) + renderer.gamepad = SDL_OpenGamepad(event->gdevice.which); + break; + case SDL_EVENT_GAMEPAD_REMOVED: + if (renderer.gamepad && SDL_GetGamepadID(renderer.gamepad) == event->gdevice.which) { + SDL_CloseGamepad(renderer.gamepad); + renderer.gamepad = nullptr; + } + break; case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: if(event->key.scancode == SDL_SCANCODE_ESCAPE) diff --git a/src/renderer.cpp b/src/renderer.cpp index f15909e..686a15f 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1,5 +1,6 @@ #include "renderer.h" #include "gpu.h" +#include #include #define TINYOBJLOADER_IMPLEMENTATION #include "tiny_obj_loader.h" @@ -42,6 +43,7 @@ void Renderer::destroy() { 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 (gamepad) SDL_CloseGamepad(gamepad); scene.destroy(dev); ray.destroy(dev); post.destroy(dev); diff --git a/src/renderer.h b/src/renderer.h index 4272249..34d7b4a 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -3,10 +3,12 @@ #include "pipelines.h" #include #include +#include struct Renderer { SDL_GPUDevice* dev = nullptr; SDL_Window* win = nullptr; + SDL_Gamepad* gamepad = nullptr; ScenePipeline scene; RayPipeline ray;