diff options
Diffstat (limited to 'cpp-timeplot/src/main.cpp')
| -rw-r--r-- | cpp-timeplot/src/main.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/cpp-timeplot/src/main.cpp b/cpp-timeplot/src/main.cpp new file mode 100644 index 0000000..7afd3e8 --- /dev/null +++ b/cpp-timeplot/src/main.cpp @@ -0,0 +1,143 @@ +#include <GLFW/glfw3.h> +#include <webgpu/webgpu.hpp> +#include <glfw3webgpu.h> +#include <iostream> +#include <memory> +#include <cstdlib> + +#include "renderer.h" + +constexpr int WINDOW_WIDTH = 1280; +constexpr int WINDOW_HEIGHT = 720; + +class Application { +public: + Application() : window_(nullptr) {} + + ~Application() { + cleanup(); + } + + bool initialize() { + if (!glfwInit()) { + std::cerr << "Failed to initialize GLFW" << std::endl; + return false; + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); + + window_ = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, + "TimePlot - C++ WebGPU", nullptr, nullptr); + if (!window_) { + std::cerr << "Failed to create window" << std::endl; + return false; + } + + glfwSetWindowUserPointer(window_, this); + glfwSetKeyCallback(window_, keyCallback); + glfwSetFramebufferSizeCallback(window_, resizeCallback); + + if (!initWebGPU()) { + return false; + } + + renderer_ = std::make_unique<Renderer>(device_, surface_, WINDOW_WIDTH, WINDOW_HEIGHT); + if (!renderer_->initialize()) { + std::cerr << "Failed to initialize renderer" << std::endl; + return false; + } + + return true; + } + + void run() { + while (!glfwWindowShouldClose(window_)) { + glfwPollEvents(); + + renderer_->update(); + renderer_->render(); + } + } + +private: + bool initWebGPU() { + // Create instance + instance_ = wgpu::createInstance(wgpu::InstanceDescriptor{}); + if (!instance_) { + std::cerr << "Failed to create WebGPU instance" << std::endl; + return false; + } + + // Create surface from GLFW window + surface_ = glfwCreateWindowWGPUSurface(instance_, window_); + if (!surface_) { + std::cerr << "Failed to create surface" << std::endl; + return false; + } + + // Request adapter (synchronous version) + wgpu::RequestAdapterOptions adapterOpts{}; + adapterOpts.compatibleSurface = surface_; + + wgpu::Adapter adapter = instance_.requestAdapter(adapterOpts); + if (!adapter) { + std::cerr << "Failed to get adapter" << std::endl; + return false; + } + + // Request device (synchronous version) + wgpu::DeviceDescriptor deviceDesc{}; + device_ = adapter.requestDevice(deviceDesc); + + if (!device_) { + std::cerr << "Failed to get device" << std::endl; + return false; + } + + return true; + } + + void cleanup() { + renderer_.reset(); + + if (window_) { + glfwDestroyWindow(window_); + window_ = nullptr; + } + glfwTerminate(); + } + + static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { + auto* app = static_cast<Application*>(glfwGetWindowUserPointer(window)); + if (action == GLFW_PRESS) { + if (key == GLFW_KEY_ESCAPE) { + glfwSetWindowShouldClose(window, GLFW_TRUE); + } else if (key == GLFW_KEY_G) { + app->renderer_->toggleGrid(); + } + } + } + + static void resizeCallback(GLFWwindow* window, int width, int height) { + auto* app = static_cast<Application*>(glfwGetWindowUserPointer(window)); + app->renderer_->resize(width, height); + } + + GLFWwindow* window_; + wgpu::Instance instance_; + wgpu::Device device_; + wgpu::Surface surface_; + std::unique_ptr<Renderer> renderer_; +}; + +int main() { + Application app; + + if (!app.initialize()) { + return EXIT_FAILURE; + } + + app.run(); + return EXIT_SUCCESS; +} |
