summaryrefslogtreecommitdiff
path: root/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/test_3d.cc9
-rw-r--r--src/tests/test_3d_render.cc193
-rw-r--r--src/tests/test_texture_manager.cc26
3 files changed, 121 insertions, 107 deletions
diff --git a/src/tests/test_3d.cc b/src/tests/test_3d.cc
index 33e6a04..88b8db9 100644
--- a/src/tests/test_3d.cc
+++ b/src/tests/test_3d.cc
@@ -33,10 +33,10 @@ void test_object_transform() {
std::cout << "Testing Object Transform..." << std::endl;
Object3D obj;
obj.position = vec3(10, 0, 0);
-
+
// Model matrix should translate by (10,0,0)
mat4 m = obj.get_model_matrix();
- assert(near(m.m[12], 10.0f)); // Col 3, Row 0 is x translation in Col-Major?
+ assert(near(m.m[12], 10.0f)); // Col 3, Row 0 is x translation in Col-Major?
// Wait, my mat4 struct:
// r.m[12] = t.x; // Index 12 is translation X
assert(near(m.m[12], 10.0f));
@@ -44,11 +44,12 @@ void test_object_transform() {
// Rotate 90 deg Y
obj.rotation = quat::from_axis(vec3(0, 1, 0), 1.570796f);
m = obj.get_model_matrix();
-
+
// Transform point (1,0,0) -> Rot(0,0,-1) -> Trans(10,0,-1)
vec4 p(1, 0, 0, 1);
vec4 res = m * p;
- assert(near(res.x, 10.0f)); // Rotated vector is (0,0,-1). + (10,0,0) translation -> (10,0,-1)
+ assert(near(res.x, 10.0f)); // Rotated vector is (0,0,-1). + (10,0,0)
+ // translation -> (10,0,-1)
assert(near(res.z, -1.0f));
}
diff --git a/src/tests/test_3d_render.cc b/src/tests/test_3d_render.cc
index 4be7153..e4477a0 100644
--- a/src/tests/test_3d_render.cc
+++ b/src/tests/test_3d_render.cc
@@ -5,11 +5,13 @@
#include "3d/object.h"
#include "3d/renderer.h"
#include "3d/scene.h"
+#include "gpu/texture_manager.h"
#include "platform.h"
-#include <iostream>
-#include <vector>
+#include "procedural/generator.h"
#include <cmath>
#include <cstring>
+#include <iostream>
+#include <vector>
#if defined(DEMO_CROSS_COMPILE_WIN32)
#include <webgpu/webgpu.h>
@@ -19,6 +21,7 @@
// Global State
static Renderer3D g_renderer;
+static TextureManager g_textures;
static Scene g_scene;
static Camera g_camera;
static WGPUDevice g_device = nullptr;
@@ -29,18 +32,18 @@ static WGPUTextureFormat g_format = WGPUTextureFormat_Undefined;
static int g_width = 1280;
static int g_height = 720;
-// Reimplementing basic WebGPU init here
+// ... (init_wgpu implementation same as before)
void init_wgpu() {
WGPUInstance instance = wgpuCreateInstance(nullptr);
if (!instance) {
- std::cerr << "Failed to create WGPU instance." << std::endl;
- exit(1);
+ std::cerr << "Failed to create WGPU instance." << std::endl;
+ exit(1);
}
-
+
g_surface = platform_create_wgpu_surface(instance);
if (!g_surface) {
- std::cerr << "Failed to create WGPU surface." << std::endl;
- exit(1);
+ std::cerr << "Failed to create WGPU surface." << std::endl;
+ exit(1);
}
WGPURequestAdapterOptions adapter_opts = {};
@@ -50,21 +53,17 @@ void init_wgpu() {
#if defined(DEMO_CROSS_COMPILE_WIN32)
auto on_adapter = [](WGPURequestAdapterStatus status, WGPUAdapter adapter,
const char* message, void* userdata) {
- if (status == WGPURequestAdapterStatus_Success) {
- *(WGPUAdapter*)userdata = adapter;
- } else {
- std::cerr << "Adapter Error: " << (message ? message : "null") << std::endl;
- }
+ if (status == WGPURequestAdapterStatus_Success) {
+ *(WGPUAdapter*)userdata = adapter;
+ }
};
wgpuInstanceRequestAdapter(instance, &adapter_opts, on_adapter, &g_adapter);
#else
auto on_adapter = [](WGPURequestAdapterStatus status, WGPUAdapter adapter,
WGPUStringView message, void* userdata, void* user2) {
- if (status == WGPURequestAdapterStatus_Success) {
- *(WGPUAdapter*)userdata = adapter;
- } else {
- std::cerr << "Adapter Error: " << (message.data ? message.data : "null") << std::endl;
- }
+ if (status == WGPURequestAdapterStatus_Success) {
+ *(WGPUAdapter*)userdata = adapter;
+ }
};
WGPURequestAdapterCallbackInfo adapter_cb = {};
adapter_cb.mode = WGPUCallbackMode_WaitAnyOnly;
@@ -73,34 +72,33 @@ void init_wgpu() {
wgpuInstanceRequestAdapter(instance, &adapter_opts, adapter_cb);
#endif
- // Spin wait for adapter
#if !defined(DEMO_CROSS_COMPILE_WIN32)
while (!g_adapter) {
- wgpuInstanceProcessEvents(instance);
+ wgpuInstanceProcessEvents(instance);
}
#endif
-
+
if (!g_adapter) {
- std::cerr << "Failed to get adapter." << std::endl;
- exit(1);
+ std::cerr << "Failed to get adapter." << std::endl;
+ exit(1);
}
WGPUDeviceDescriptor device_desc = {};
-
+
#if defined(DEMO_CROSS_COMPILE_WIN32)
auto on_device = [](WGPURequestDeviceStatus status, WGPUDevice device,
const char* message, void* userdata) {
- if (status == WGPURequestDeviceStatus_Success) {
- *(WGPUDevice*)userdata = device;
- }
+ if (status == WGPURequestDeviceStatus_Success) {
+ *(WGPUDevice*)userdata = device;
+ }
};
wgpuAdapterRequestDevice(g_adapter, &device_desc, on_device, &g_device);
#else
auto on_device = [](WGPURequestDeviceStatus status, WGPUDevice device,
WGPUStringView message, void* userdata, void* user2) {
- if (status == WGPURequestDeviceStatus_Success) {
- *(WGPUDevice*)userdata = device;
- }
+ if (status == WGPURequestDeviceStatus_Success) {
+ *(WGPUDevice*)userdata = device;
+ }
};
WGPURequestDeviceCallbackInfo device_cb = {};
device_cb.mode = WGPUCallbackMode_WaitAnyOnly;
@@ -108,19 +106,18 @@ void init_wgpu() {
device_cb.userdata1 = &g_device;
wgpuAdapterRequestDevice(g_adapter, &device_desc, device_cb);
#endif
-
+
#if !defined(DEMO_CROSS_COMPILE_WIN32)
- // Poll until device is ready (WaitAny is unimplemented in current wgpu-native build)
while (!g_device) {
- wgpuInstanceProcessEvents(instance);
+ wgpuInstanceProcessEvents(instance);
}
#endif
if (!g_device) {
- std::cerr << "Failed to get device." << std::endl;
- exit(1);
+ std::cerr << "Failed to get device." << std::endl;
+ exit(1);
}
-
+
g_queue = wgpuDeviceGetQueue(g_device);
WGPUSurfaceCapabilities caps = {};
@@ -140,95 +137,105 @@ void init_wgpu() {
void setup_scene() {
g_scene.clear();
- // Center Red Cube (Wireframe Proxy)
- Object3D center(ObjectType::CUBE);
+ Object3D center(ObjectType::BOX);
center.position = vec3(0, 0, 0);
center.color = vec4(1, 0, 0, 1);
g_scene.add_object(center);
- // Orbiting Objects
for (int i = 0; i < 8; ++i) {
ObjectType type = ObjectType::SPHERE;
- if (i % 3 == 1) type = ObjectType::TORUS;
- if (i % 3 == 2) type = ObjectType::BOX;
-
+ if (i % 3 == 1)
+ type = ObjectType::TORUS;
+ if (i % 3 == 2)
+ type = ObjectType::BOX;
+
Object3D obj(type);
float angle = (i / 8.0f) * 6.28318f;
obj.position = vec3(std::cos(angle) * 4.0f, 0, std::sin(angle) * 4.0f);
obj.scale = vec3(0.5f, 0.5f, 0.5f);
-
- if (type == ObjectType::SPHERE) obj.color = vec4(0, 1, 0, 1);
- else if (type == ObjectType::TORUS) obj.color = vec4(0, 0.5, 1, 1);
- else obj.color = vec4(1, 1, 0, 1);
-
+
+ if (type == ObjectType::SPHERE)
+ obj.color = vec4(0, 1, 0, 1);
+ else if (type == ObjectType::TORUS)
+ obj.color = vec4(0, 0.5, 1, 1);
+ else
+ obj.color = vec4(1, 1, 0, 1);
+
g_scene.add_object(obj);
}
}
+// Wrapper to generate periodic noise
+void gen_periodic_noise(uint8_t* buffer, int w, int h, const float* params,
+ int num_params) {
+ procedural::gen_noise(buffer, w, h, params, num_params);
+ float p_params[] = {0.1f}; // 10% overlap
+ procedural::make_periodic(buffer, w, h, p_params, 1);
+}
+
int main() {
platform_init_window(false);
-
init_wgpu();
-
+
g_renderer.init(g_device, g_queue, g_format);
g_renderer.resize(g_width, g_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)
+ g_textures.create_procedural_texture("noise", noise_def);
+
+ g_renderer.set_noise_texture(g_textures.get_texture_view("noise"));
+
setup_scene();
-
+
g_camera.position = vec3(0, 5, 10);
g_camera.target = vec3(0, 0, 0);
-
+
float time = 0.0f;
while (!platform_should_close()) {
platform_poll();
-
- time += 0.016f; // Approx 60fps
-
- // Animate Objects
- for (size_t i = 1; i < g_scene.objects.size(); ++i) {
- g_scene.objects[i].rotation = quat::from_axis(vec3(0, 1, 0), time * 2.0f + i);
- g_scene.objects[i].position.y = std::sin(time * 3.0f + i) * 1.5f;
- }
-
- // Animate Camera Height and Radius
+ time += 0.016f;
+
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)
- );
-
- // Render Frame
+ 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));
+
+ for (size_t i = 1; i < g_scene.objects.size(); ++i) {
+ g_scene.objects[i].rotation =
+ quat::from_axis(vec3(0, 1, 0), time * 2.0f + i);
+ g_scene.objects[i].position.y = std::sin(time * 3.0f + i) * 1.5f;
+ }
+
WGPUSurfaceTexture surface_tex;
wgpuSurfaceGetCurrentTexture(g_surface, &surface_tex);
-
- if (surface_tex.status == WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal) {
- 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);
-
- wgpuTextureViewRelease(view);
- wgpuSurfacePresent(g_surface);
- wgpuTextureRelease(surface_tex.texture);
+ if (surface_tex.status ==
+ WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal) {
+ 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);
+ wgpuTextureViewRelease(view);
+ wgpuSurfacePresent(g_surface);
+ wgpuTextureRelease(surface_tex.texture);
}
-
-#if !defined(DEMO_CROSS_COMPILE_WIN32)
- // Poll events for wgpu-native to ensure callbacks fire and frame presents?
- // We don't have easy access to instance here unless we store it globally.
- // Let's just assume Present handles enough synchronization for this demo.
-#endif
}
-
+
g_renderer.shutdown();
+ g_textures.shutdown();
platform_shutdown();
return 0;
}
diff --git a/src/tests/test_texture_manager.cc b/src/tests/test_texture_manager.cc
index 7f40447..5741d8c 100644
--- a/src/tests/test_texture_manager.cc
+++ b/src/tests/test_texture_manager.cc
@@ -1,5 +1,6 @@
// This file is part of the 64k demo project.
-// It tests the TextureManager (mocking the GPU parts where possible or running with valid device).
+// It tests the TextureManager (mocking the GPU parts where possible or running
+// with valid device).
#include "gpu/texture_manager.h"
#include "procedural/generator.h"
@@ -15,28 +16,33 @@
// Forward decls from platform.h or similar (simplifying for test)
// Note: This test requires a valid WebGPU device, which is hard in CI/headless.
// We will structure it to compile, but runtime might skip if no device.
-// For now, we just test the C++ side logic if possible, but TextureManager depends heavily on WGPU calls.
+// For now, we just test the C++ side logic if possible, but TextureManager
+// depends heavily on WGPU calls.
// We will use a "Headless" approach if possible, or just skip if Init fails.
-// Actually, let's just make it a compilation test + basic logic check if we can mock or stub.
-// Since we don't have a mocking framework, we'll try to init wgpu-native.
+// Actually, let's just make it a compilation test + basic logic check if we can
+// mock or stub. Since we don't have a mocking framework, we'll try to init
+// wgpu-native.
int main() {
- // Need to init GLFW for surface creation usually, even for headless in some impls?
+ // Need to init GLFW for surface creation usually, even for headless in some
+ // impls?
if (!glfwInit()) {
std::cerr << "Failed to init GLFW" << std::endl;
return 1;
}
-
+
// NOTE: In a real CI environment without GPU, this will likely fail or hang.
- // For this "demo" context, we assume the user has a GPU or we just verify it compiles.
- // We'll skip actual GPU init for this simple test to avoid hanging the agent if no GPU.
+ // For this "demo" context, we assume the user has a GPU or we just verify it
+ // compiles. We'll skip actual GPU init for this simple test to avoid hanging
+ // the agent if no GPU.
std::cout << "TextureManager Compilation Test Passed." << std::endl;
-
+
/*
TextureManager tm;
// tm.init(device, queue); // execution would happen here
- // tm.create_procedural_texture("noise", {256, 256, procedural::gen_noise, {1234, 1.0f}});
+ // tm.create_procedural_texture("noise", {256, 256, procedural::gen_noise,
+ {1234, 1.0f}});
*/
return 0;