summaryrefslogtreecommitdiff
path: root/cpp-timeplot/src/main.cpp
diff options
context:
space:
mode:
authorgrothedev <grothedev@gmail.com>2025-10-02 01:27:50 -0400
committergrothedev <grothedev@gmail.com>2025-10-02 01:27:50 -0400
commita162c98ce54159e3e7dbe867d908ce3276b7f633 (patch)
treeef49d87f7c5345e8ed08884da99a35af7b3c2b5b /cpp-timeplot/src/main.cpp
parent685ab63782daeb868a999ec65ef0ceb0883acb3e (diff)
trying c++ impl
Diffstat (limited to 'cpp-timeplot/src/main.cpp')
-rw-r--r--cpp-timeplot/src/main.cpp143
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;
+}