#define GN_USE_SURFACE_XLIB #include #include "stdlib.h" #include "iostream" #define GLFW_EXPOSE_NATIVE_X11 #include "glfw/include/GLFW/glfw3.h" #include "glfw/include/GLFW/glfw3native.h" #define CONCAT_IMPL(a, b) a##b #define CONCAT(a, b) CONCAT_IMPL(a, b) #define CHECK(func) \ gnReturnCode CONCAT(res, __LINE__) = (func); \ if (CONCAT(res, __LINE__) != GN_SUCCESS) { \ std::cout << "Gryphn Error at line " << __LINE__ \ << ": " << CONCAT(res, __LINE__) << "\n"; \ } GLFWwindow* window; gnVersion version = gnCreateVersion(1, 0, 0); gnInstance instance; gnPhysicalDevice pysicalDevice; gnDevice device; gnSurface surface; gnSwapchain swapchain; uint32_t min(uint32_t a, uint32_t b) { if (a < b) return a; return b; } void createInstance() { uint32_t backendCount = 0; CHECK(gnGetAvaliableBackends(version, &backendCount, nullptr)); if (backendCount == 0) { throw std::runtime_error("Gryphn returned 0 avaliable backends"); } gnBackend* backends = (gnBackend*)malloc(sizeof(gnBackend) * backendCount); CHECK(gnGetAvaliableBackends(version, &backendCount, backends)); const char* extensions[2] = { "GN_EXT_surface", "GN_EXT_surface_xlib" }; gnInstanceCreateInfo createInfo = { .backend = backends[0], .info = { .applicationName = "Chemistry Rendering App", .applicationVersion = gnCreateVersion(0, 0, 1), .engineName = "Chemistry Rendering Engine", .engineVersion = gnCreateVersion(0, 0, 1) }, .enabledValidationLayerCount = 0, .enabledValidationLayers = nullptr, .enabledExtensionCount = 2, .enabledExtensions = extensions }; CHECK(gnCreateInstance(&instance, &createInfo)); free(backends); } void createDevice() { uint32_t physicalDeviceCount; CHECK(gnEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr)); gnPhysicalDevice* devices = (gnPhysicalDevice*)malloc(sizeof(gnPhysicalDevice) * physicalDeviceCount); CHECK(gnEnumeratePhysicalDevices(instance, &physicalDeviceCount, devices)); std::cout << "Found " << physicalDeviceCount << " physical devices:\n"; for (int i = 0; i < physicalDeviceCount; i++) { gnPhysicalDeviceProperties properties; gnGetPhysicalDeviceProperties(devices[i], &properties); std::cout << "Name: " << properties.deviceName << "\n"; } pysicalDevice = devices[0]; const char* extensions[1] = { "GN_EXT_swapchain" }; gnDeviceCreateInfo createInfo = { .physicalDevice = pysicalDevice, .enabledExtensionCount = 1, .enabledExtensions = extensions }; CHECK(gnCreateDevice(instance, &createInfo, &device)); } void createSurface() { gnXlibSurfaceCreateInfo createInfo = { .dpy = glfwGetX11Display(), .window = glfwGetX11Window(window) }; CHECK(gnCreateXlibSurface(instance, &createInfo, &surface)); } gnSurfaceFormat getSurfaceFormat() { uint32_t surfaceFormatCount = 0; CHECK(gnGetSurfaceFormats(pysicalDevice, surface, &surfaceFormatCount, NULL)); if (surfaceFormatCount == 0) throw std::runtime_error("Gryphn returned 0 avaliable surface formats"); gnSurfaceFormat* formats = (gnSurfaceFormat*)malloc(sizeof(gnSurfaceFormat) * surfaceFormatCount); CHECK(gnGetSurfaceFormats(pysicalDevice, surface, &surfaceFormatCount, formats)); for (int i = 0; i < surfaceFormatCount; i++) if (formats[i].format == GN_FORMAT_BGRA8_SRGB && formats[i].colorSpace == GN_COLOR_SPACE_SRGB_NONLINEAR) return formats[i]; return formats[0]; return (gnSurfaceFormat){ .format = GN_FORMAT_UNDEFINED, .colorSpace = GN_COLOR_SPACE_UNKNOWN }; } gnPresentMode getPresentMode() { uint32_t presentModeCount = 0; CHECK(gnGetSurfacePresentModes(pysicalDevice, surface, &presentModeCount, NULL)); if (presentModeCount == 0) throw std::runtime_error("Gryphn returned 0 avaliable presentMode"); gnPresentMode* presentModes = (gnPresentMode*)malloc(sizeof(gnPresentMode) * presentModeCount); CHECK(gnGetSurfacePresentModes(pysicalDevice, surface, &presentModeCount, presentModes)); for (int i = 0; i < presentModeCount; i++) if (presentModes[i] == GN_PRESENT_MODE_MAILBOX) return presentModes[i]; return presentModes[0]; } void createSwapchain() { gnSurfaceCapabilities capabilites; gnGetSurfaceCapabilities(pysicalDevice, surface, &capabilites); gnSurfaceFormat chosenFormat = getSurfaceFormat(); gnPresentMode chosenMode = getPresentMode(); int width, height; glfwGetWindowSize(window, &width, &height); gnSwapchainCreateInfo createInfo = { .surface = surface, .minImageCount = min(capabilites.minImageCount + 1, capabilites.maxImageCount), .imageFormat = chosenFormat.format, .imageColorSpace = chosenFormat.colorSpace, .imageExtent = { (uint32_t)width, (uint32_t)height }, .imageArrayLayers = 1, .presentMode = chosenMode, }; CHECK(gnCreateSwapchain(device, &createInfo, &swapchain)); } int main() { if (!glfwInit()) { std::cout << "Failed to init GLFW\n"; return -1; } glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); window = glfwCreateWindow(640, 360, "Chemistry Rendering App", nullptr, nullptr); if (!window) { std::cerr << "Failed to create window\n"; return -1; } try { createInstance(); createDevice(); createSurface(); createSwapchain(); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); } } catch (const std::exception& e) { std::cerr << "Caught Exception: " << e.what() << "\n"; return 0; } glfwDestroyWindow(window); gnDestroySurface(instance, &surface); gnDestroyDevice(&device); gnDestroyInstance(&instance); }