summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gpu/gpu.cc10
-rw-r--r--src/gpu/gpu.h4
-rw-r--r--src/main.cc13
-rw-r--r--src/platform.cc123
-rw-r--r--src/platform.h53
-rw-r--r--src/tests/test_3d_render.cc37
-rw-r--r--tools/spectool.cc9
7 files changed, 120 insertions, 129 deletions
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc
index 17d32ee..cecf018 100644
--- a/src/gpu/gpu.cc
+++ b/src/gpu/gpu.cc
@@ -310,9 +310,9 @@ static void handle_request_device(WGPURequestDeviceStatus status,
#endif /* defined(DEMO_CROSS_COMPILE_WIN32) */
#endif /* !defined(STRIP_ALL) */
-void gpu_init(GLFWwindow* window, int width, int height) {
+void gpu_init(PlatformState* platform_state) {
g_instance = wgpuCreateInstance(nullptr);
- g_surface = platform_create_wgpu_surface(g_instance);
+ g_surface = platform_create_wgpu_surface(g_instance, platform_state);
WGPURequestAdapterOptions adapter_opts = {};
adapter_opts.compatibleSurface = g_surface;
@@ -364,13 +364,13 @@ void gpu_init(GLFWwindow* window, int width, int height) {
g_config.device = g_device;
g_config.format = swap_chain_format;
g_config.usage = WGPUTextureUsage_RenderAttachment;
- g_config.width = width;
- g_config.height = height;
+ g_config.width = platform_state->width;
+ g_config.height = platform_state->height;
g_config.presentMode = WGPUPresentMode_Fifo;
g_config.alphaMode = WGPUCompositeAlphaMode_Opaque;
wgpuSurfaceConfigure(g_surface, &g_config);
- g_main_sequence.init(g_device, g_queue, g_config.format, width, height);
+ g_main_sequence.init(g_device, g_queue, g_config.format, platform_state->width, platform_state->height);
LoadTimeline(g_main_sequence, g_device, g_queue, g_config.format);
}
diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h
index 9ed1913..a0ab6ba 100644
--- a/src/gpu/gpu.h
+++ b/src/gpu/gpu.h
@@ -71,7 +71,7 @@ static inline WGPUStringView label_view(const char* str) {
#endif /* defined(DEMO_CROSS_COMPILE_WIN32) */
-struct GLFWwindow;
+struct PlatformState; // Forward declaration
// Basic wrapper for WebGPU buffers
struct GpuBuffer {
@@ -96,7 +96,7 @@ struct RenderPass {
uint32_t instance_count;
};
-void gpu_init(GLFWwindow* window, int width, int height);
+void gpu_init(PlatformState* platform_state);
void gpu_draw(float audio_peak, float aspect_ratio, float time, float beat);
#if !defined(STRIP_ALL)
void gpu_simulate_until(float time);
diff --git a/src/main.cc b/src/main.cc
index f7136ef..2ece549 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -129,6 +129,7 @@ float* generate_tone(float* buffer, float freq) {
}
int main(int argc, char** argv) {
+ PlatformState platform_state = {};
bool fullscreen_enabled = false;
float seek_time = 0.0f;
int* width_ptr = nullptr;
@@ -156,8 +157,8 @@ int main(int argc, char** argv) {
fullscreen_enabled = true;
#endif /* STRIP_ALL */
- platform_init_window(fullscreen_enabled, width_ptr, height_ptr);
- gpu_init(platform_get_window(), platform_get_width(), platform_get_height());
+ platform_init(&platform_state, fullscreen_enabled, width_ptr, height_ptr);
+ gpu_init(&platform_state);
audio_init();
// Register drum assets
@@ -234,14 +235,14 @@ int main(int argc, char** argv) {
// Start real audio
audio_start();
- while (!platform_should_close()) {
- platform_poll();
+ while (!platform_should_close(&platform_state)) {
+ platform_poll(&platform_state);
double current_time = platform_get_time() + seek_time; // Offset logic time
update_game_logic(current_time);
- float aspect_ratio = platform_get_aspect_ratio();
+ float aspect_ratio = platform_get_aspect_ratio(&platform_state);
// Adjusted multiplier for visuals (preventing constant 1.0 saturation)
float raw_peak = synth_get_output_peak();
@@ -254,6 +255,6 @@ int main(int argc, char** argv) {
audio_shutdown();
gpu_shutdown();
- platform_shutdown();
+ platform_shutdown(&platform_state);
return 0;
}
diff --git a/src/platform.cc b/src/platform.cc
index 464003f..8df9992 100644
--- a/src/platform.cc
+++ b/src/platform.cc
@@ -4,120 +4,93 @@
#include "platform.h"
#include "glfw3webgpu.h"
-
#include <GLFW/glfw3.h>
-static GLFWwindow* window = nullptr;
-static int windowed_x, windowed_y, windowed_w, windowed_h;
-static bool g_is_fullscreen = false;
-
-// --- New state for framebuffer size ---
-static int g_width = 1280;
-static int g_height = 720;
-
-// Forward declaration for callback
-void platform_toggle_fullscreen();
-
// --- Callbacks ---
-static void framebuffer_size_callback(GLFWwindow* cb_window, int width, int height) {
- (void)cb_window; // Unused
- g_width = width;
- g_height = height;
- // Note: We would trigger a swap chain resize here, but our demo handles it implicitly.
+static void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
+ PlatformState* state = (PlatformState*)glfwGetWindowUserPointer(window);
+ if (state) {
+ state->width = width;
+ state->height = height;
+ }
}
-static void glfw_key_callback(GLFWwindow* cb_window, int key, int scancode,
- int action, int mods) {
- if (action == GLFW_PRESS) {
- if (key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) {
- glfwSetWindowShouldClose(cb_window, GLFW_TRUE);
- } else if (key == GLFW_KEY_F) {
- platform_toggle_fullscreen();
+static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
+ PlatformState* state = (PlatformState*)glfwGetWindowUserPointer(window);
+ if (action == GLFW_PRESS) {
+ if (key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) {
+ glfwSetWindowShouldClose(window, GLFW_TRUE);
+ } else if (key == GLFW_KEY_F) {
+ if (state) platform_toggle_fullscreen(state);
+ }
}
- }
}
-void platform_init_window(bool fullscreen, int* width_ptr, int* height_ptr) {
+// --- Public API Implementation ---
+
+void platform_init(PlatformState* state, bool fullscreen, int* width_ptr, int* height_ptr) {
if (width_ptr && height_ptr) {
- g_width = *width_ptr;
- g_height = *height_ptr;
+ state->width = *width_ptr;
+ state->height = *height_ptr;
}
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- window = glfwCreateWindow(g_width, g_height, "demo64k", nullptr, nullptr);
+ state->window = glfwCreateWindow(state->width, state->height, "demo64k", nullptr, nullptr);
+
+ // Store our state pointer in the window for callbacks
+ glfwSetWindowUserPointer(state->window, state);
// Immediately query the actual framebuffer size for high-DPI displays
- glfwGetFramebufferSize(window, &g_width, &g_height);
+ glfwGetFramebufferSize(state->window, &state->width, &state->height);
- glfwSetKeyCallback(window, glfw_key_callback);
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
+ glfwSetKeyCallback(state->window, glfw_key_callback);
+ glfwSetFramebufferSizeCallback(state->window, framebuffer_size_callback);
- g_is_fullscreen = fullscreen;
+ state->is_fullscreen = fullscreen;
if (fullscreen) {
- // Save current windowed mode dimensions before going fullscreen
- glfwGetWindowPos(window, &windowed_x, &windowed_y);
- glfwGetWindowSize(window, &windowed_w, &windowed_h);
+ glfwGetWindowPos(state->window, &state->windowed_x, &state->windowed_y);
+ glfwGetWindowSize(state->window, &state->windowed_w, &state->windowed_h);
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
- glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height,
- mode->refreshRate);
+ glfwSetWindowMonitor(state->window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
}
}
-void platform_shutdown() {
- glfwDestroyWindow(window);
+void platform_shutdown(PlatformState* state) {
+ if (state->window) {
+ glfwDestroyWindow(state->window);
+ }
glfwTerminate();
}
-void platform_poll() {
+void platform_poll(PlatformState* state) {
glfwPollEvents();
}
-bool platform_should_close() {
- return glfwWindowShouldClose(window);
+bool platform_should_close(PlatformState* state) {
+ return glfwWindowShouldClose(state->window);
}
-void platform_toggle_fullscreen() {
- g_is_fullscreen = !g_is_fullscreen;
- if (g_is_fullscreen) {
- glfwGetWindowPos(window, &windowed_x, &windowed_y);
- glfwGetWindowSize(window, &windowed_w, &windowed_h);
+void platform_toggle_fullscreen(PlatformState* state) {
+ state->is_fullscreen = !state->is_fullscreen;
+ if (state->is_fullscreen) {
+ glfwGetWindowPos(state->window, &state->windowed_x, &state->windowed_y);
+ glfwGetWindowSize(state->window, &state->windowed_w, &state->windowed_h);
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
- glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height,
- mode->refreshRate);
+ glfwSetWindowMonitor(state->window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
} else {
- glfwSetWindowMonitor(window, nullptr, windowed_x, windowed_y, windowed_w,
- windowed_h, 0);
+ glfwSetWindowMonitor(state->window, nullptr, state->windowed_x, state->windowed_y, state->windowed_w, state->windowed_h, 0);
}
}
-GLFWwindow* platform_get_window() {
- return window;
+WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, PlatformState* state) {
+ return glfwCreateWindowWGPUSurface(instance, state->window);
}
-double platform_get_time() {
- return glfwGetTime();
-}
-
-// --- New dimension getters ---
-int platform_get_width() {
- return g_width;
-}
-
-int platform_get_height() {
- return g_height;
-}
-
-float platform_get_aspect_ratio() {
- if (g_height == 0) return 1.0f;
- return (float)g_width / (float)g_height;
-}
-
-WGPUSurface platform_create_wgpu_surface(WGPUInstance instance) {
- return glfwCreateWindowWGPUSurface(instance, window);
-}
+// Note: platform_get_* functions are now inline in the header.
+// platform_get_time() remains global.
diff --git a/src/platform.h b/src/platform.h
index 38a0568..2d2fc9e 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -1,25 +1,46 @@
-// This file is part of the 64k demo project.
-// It defines the platform abstraction layer for windowing and input.
-// Provides a consistent interface for GLFW-based operations.
+// Handles windowing, input, and native surface creation.
#pragma once
-#include <webgpu.h>
-
// Forward declare GLFWwindow to avoid including the full header here.
struct GLFWwindow;
-void platform_init_window(bool fullscreen, int* width_ptr, int* height_ptr);
-void platform_shutdown();
-void platform_poll();
-bool platform_should_close();
+struct PlatformState {
+ GLFWwindow* window = nullptr;
+ int width = 1280;
+ int height = 720;
+ bool is_fullscreen = false;
+ // Store windowed geometry for fullscreen toggle
+ int windowed_x = 0, windowed_y = 0, windowed_w = 0, windowed_h = 0;
+};
+
+void platform_init(PlatformState* state, bool fullscreen, int* width_ptr, int* height_ptr);
+void platform_shutdown(PlatformState* state);
+void platform_poll(PlatformState* state);
+bool platform_should_close(PlatformState* state);
+void platform_toggle_fullscreen(PlatformState* state);
+
+// Inline getters for direct access
+inline GLFWwindow* platform_get_window(PlatformState* state) { return state->window; }
+inline int platform_get_width(PlatformState* state) { return state->width; }
+inline int platform_get_height(PlatformState* state) { return state->height; }
+inline float platform_get_aspect_ratio(PlatformState* state) {
+ if (state->height == 0) return 1.0f;
+ return (float)state->width / (float)state->height;
+}
-GLFWwindow* platform_get_window();
-double platform_get_time();
+// glfwGetTime is a simple global query, so it doesn't need the state struct.
+// Include the header directly to get the proper linkage.
+#include <GLFW/glfw3.h>
+inline double platform_get_time() {
+ return glfwGetTime();
+}
-// Add dimension getters
-int platform_get_width();
-int platform_get_height();
-float platform_get_aspect_ratio();
-WGPUSurface platform_create_wgpu_surface(WGPUInstance instance);
+// WebGPU specific surface creation
+#if defined(DEMO_CROSS_COMPILE_WIN32)
+#include <webgpu/webgpu.h>
+#else
+#include <wgpu.h>
+#endif
+WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, PlatformState* state);
diff --git a/src/tests/test_3d_render.cc b/src/tests/test_3d_render.cc
index 0a809c4..e14ed93 100644
--- a/src/tests/test_3d_render.cc
+++ b/src/tests/test_3d_render.cc
@@ -29,18 +29,16 @@ static WGPUQueue g_queue = nullptr;
static WGPUSurface g_surface = nullptr;
static WGPUAdapter g_adapter = nullptr;
static WGPUTextureFormat g_format = WGPUTextureFormat_Undefined;
-static int g_width = 1280;
-static int g_height = 720;
// ... (init_wgpu implementation same as before)
-void init_wgpu() {
+void init_wgpu(PlatformState* platform_state) {
WGPUInstance instance = wgpuCreateInstance(nullptr);
if (!instance) {
std::cerr << "Failed to create WGPU instance." << std::endl;
exit(1);
}
- g_surface = platform_create_wgpu_surface(instance);
+ g_surface = platform_create_wgpu_surface(instance, platform_state);
if (!g_surface) {
std::cerr << "Failed to create WGPU surface." << std::endl;
exit(1);
@@ -128,8 +126,8 @@ void init_wgpu() {
config.device = g_device;
config.format = g_format;
config.usage = WGPUTextureUsage_RenderAttachment;
- config.width = g_width;
- config.height = g_height;
+ config.width = platform_state->width;
+ config.height = platform_state->height;
config.presentMode = WGPUPresentMode_Fifo;
config.alphaMode = WGPUCompositeAlphaMode_Opaque;
wgpuSurfaceConfigure(g_surface, &config);
@@ -176,22 +174,21 @@ void gen_periodic_noise(uint8_t* buffer, int w, int h, const float* params,
int main() {
printf("Running 3D Renderer Test...\n");
- platform_init_window(false, nullptr, nullptr);
- gpu_init(platform_get_window(), platform_get_width(), platform_get_height());
-
- // Create Renderer and Scene
- Renderer3D renderer;
+ PlatformState platform_state = {};
+ platform_init(&platform_state, false, nullptr, nullptr);
+
+ // The test's own WGPU init sequence
+ init_wgpu(&platform_state);
g_renderer.init(g_device, g_queue, g_format);
- g_renderer.resize(g_width, g_height);
+ g_renderer.resize(platform_state.width, platform_state.height);
g_textures.init(g_device, g_queue);
ProceduralTextureDef noise_def;
noise_def.width = 256;
noise_def.height = 256;
noise_def.gen_func = gen_periodic_noise;
- noise_def.params = {1234.0f,
- 16.0f}; // Seed, Frequency (Increased for more detail)
+ noise_def.params = {1234.0f, 16.0f};
g_textures.create_procedural_texture("noise", noise_def);
g_renderer.set_noise_texture(g_textures.get_texture_view("noise"));
@@ -202,15 +199,16 @@ int main() {
g_camera.target = vec3(0, 0, 0);
float time = 0.0f;
- while (!platform_should_close()) {
- platform_poll();
- time += 0.016f;
+ while (!platform_should_close(&platform_state)) {
+ platform_poll(&platform_state);
+ time = (float)platform_get_time();
float cam_radius = 10.0f + std::sin(time * 0.3f) * 4.0f;
float cam_height = 5.0f + std::cos(time * 0.4f) * 3.0f;
g_camera.set_look_at(vec3(std::sin(time * 0.5f) * cam_radius, cam_height,
std::cos(time * 0.5f) * cam_radius),
vec3(0, 0, 0), vec3(0, 1, 0));
+ g_camera.aspect_ratio = platform_get_aspect_ratio(&platform_state);
for (size_t i = 1; i < g_scene.objects.size(); ++i) {
g_scene.objects[i].rotation =
@@ -225,11 +223,8 @@ int main() {
WGPUTextureViewDescriptor view_desc = {};
view_desc.format = g_format;
view_desc.dimension = WGPUTextureViewDimension_2D;
- view_desc.baseMipLevel = 0;
view_desc.mipLevelCount = 1;
- view_desc.baseArrayLayer = 0;
view_desc.arrayLayerCount = 1;
- view_desc.aspect = WGPUTextureAspect_All;
WGPUTextureView view =
wgpuTextureCreateView(surface_tex.texture, &view_desc);
g_renderer.render(g_scene, g_camera, time, view);
@@ -241,6 +236,6 @@ int main() {
g_renderer.shutdown();
g_textures.shutdown();
- platform_shutdown();
+ platform_shutdown(&platform_state);
return 0;
}
diff --git a/tools/spectool.cc b/tools/spectool.cc
index dfb00de..19f3a2f 100644
--- a/tools/spectool.cc
+++ b/tools/spectool.cc
@@ -131,7 +131,8 @@ int play_spec(const char* in_path) {
fread(spec_data.data(), sizeof(float), spec_data.size(), f_in);
fclose(f_in);
- platform_init_window(false, nullptr, nullptr);
+ PlatformState platform_state = {};
+ platform_init(&platform_state, false, nullptr, nullptr);
audio_init();
audio_start();
Spectrogram spec;
@@ -144,12 +145,12 @@ int play_spec(const char* in_path) {
synth_trigger_voice(spec_id, 0.7f, 0.0f);
printf("Playing... Press Ctrl+C to exit.\n");
- while (synth_get_active_voice_count() > 0 && !platform_should_close()) {
- platform_poll();
+ while (synth_get_active_voice_count() > 0 && !platform_should_close(&platform_state)) {
+ platform_poll(&platform_state);
}
audio_shutdown();
- platform_shutdown();
+ platform_shutdown(&platform_state);
return 0;
}