183 lines
5.9 KiB
C++
183 lines
5.9 KiB
C++
#define GN_USE_SURFACE_XLIB
|
|
#include <Gryphn/gryphn.h>
|
|
#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);
|
|
}
|