-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add standalone test and 'getting started section' to docs
- Loading branch information
Showing
7 changed files
with
234 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
Getting started | ||
=============== | ||
|
||
|
||
Understanding Thallium contexts and renderers | ||
--------------------------------------------- | ||
|
||
Each Thallium application must have **one** context object. This object stores state data for APIs that need it, such as the Vulkan instance, and is | ||
created using the :c:func:`TL_ContextCreate()` function. | ||
|
||
The context data is initialised as necessary when any renderers are created - in other words, if there are no Vulkan renderers created, then no | ||
Vulkan instance will be created, for example. One or more renderers can be created in batch with the :c:func:`TL_RendererCreate()` function - this can | ||
only be done **once** per context! | ||
|
||
|
||
Debugging functions | ||
------------------- | ||
|
||
While the context is usually the first object to be created in production builds, you might opt for creating a debugger first instead. This is | ||
necessary to recieve any debug output, and can be done with the :c:func:`TL_DebuggerCreate()` function. You'll need to specify the severities and | ||
sources of messages you want to stream to the debugger - this configuration is available in the descriptor, as well as an optional callback function. | ||
|
||
Some functions might explicitly take an optional debugger argument to send output to. However, it's recommended to use a **debugger attachment** to | ||
get much better output from the context. This is a virtual structure that is defined with the :c:struct:`TL_DebuggerAttachmentDescriptor_t` | ||
descriptor, and is specified at context creation. With a debugger attachment, you can recieve output directly from the graphics API(s) your | ||
application uses! | ||
|
||
|
||
Object systems | ||
-------------- | ||
|
||
API-specific versions of objects are abstracted in the form of **object systems**. For example, a renderer created with the | ||
:c:enum:`TL_RendererAPIFlags_t` flag of ``TL_RENDERER_API_VULKAN_BIT`` will itself contain a Vulkan renderer system; swapchains will contain an | ||
API-specific swapchain system, etc. | ||
|
||
Object systems are, by default, not provided in the public API. However, you can still access them by including the appropriate graphics API header, | ||
such as ``thallium_vulkan.h`` for Vulkan applications. These headers provide, among other things, their respective object systems. | ||
|
||
|
||
Interacting with windows | ||
------------------------ | ||
|
||
Windows are passed to Thallium through the :c:struct:`TL_WindowSurface_t` abstraction. This allows for compatibility with various window systems; for | ||
example, on Apple systems, this struct can be created with the :c:func:`TL_WindowSurfaceCreateCocoa()` function. X11 and XCB equivalents exist for | ||
Linux systems - the functions that are compiled depend on which CMake flags are enabled at config-time (e.g. ``THALLIUM_WSI_COCOA`` is ON by default | ||
when building on macOS). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* Copyright (c) 2023 Jack Bennett. | ||
* All Rights Reserved. | ||
* | ||
* See the LICENCE file for more information. | ||
*/ | ||
|
||
#include "thallium.h" | ||
|
||
#if defined(__linux__) | ||
# include <xcb/xcb.h> | ||
# include <X11/Xlib-xcb.h> | ||
|
||
# define GLFW_EXPOSE_NATIVE_X11 | ||
#elif defined(__APPLE__) | ||
# if defined(__OBJC__) | ||
# import <Cocoa/Cocoa.h> | ||
# else | ||
# include <ApplicationServices/ApplicationServices.h> | ||
# include <objc/objc.h> | ||
# endif | ||
|
||
# define GLFW_EXPOSE_NATIVE_COCOA | ||
#elif defined(_WIN32) | ||
# error Useless operating systems are not yet supported by Thallium's WSI abstraction set | ||
#endif | ||
|
||
#include "glfw/include/GLFW/glfw3.h" | ||
#include "glfw/include/GLFW/glfw3native.h" | ||
|
||
#include <iostream> | ||
|
||
#if defined(_THALLIUM_VULKAN_INCL) | ||
# include "thallium_vulkan.h" | ||
#endif | ||
|
||
TL_Debugger_t *debugger; | ||
TL_Context_t *context; | ||
TL_Renderer_t *renderer; | ||
TL_Swapchain_t *swapchain; | ||
|
||
GLFWwindow *window; | ||
TL_WindowSurface_t *window_surface; | ||
|
||
int main() { | ||
// Create the debugger | ||
|
||
TL_DebuggerDescriptor_t debuggerdesc = {}; | ||
(int &) debuggerdesc.severities = TL_DEBUG_SEVERITY_WARNING_BIT | TL_DEBUG_SEVERITY_ERROR_BIT | TL_DEBUG_SEVERITY_FATAL_BIT; | ||
(int &) debuggerdesc.sources = TL_DEBUG_SOURCE_ALL_BIT; | ||
|
||
debugger = TL_DebuggerCreate(debuggerdesc); | ||
|
||
if (!debugger) { | ||
std::cerr << "Failed to create debugger" << std::endl; | ||
return 1; | ||
} | ||
|
||
// debugger attachment will be used to attach debugger to context | ||
TL_DebuggerAttachmentDescriptor_t debugger_attachment = {}; | ||
debugger_attachment.debugger = debugger; | ||
|
||
|
||
// Create the context | ||
|
||
TL_ContextDescriptor_t contextdesc = {}; | ||
contextdesc.debug_attachment_descriptor = &debugger_attachment; | ||
|
||
context = TL_ContextCreate(contextdesc, debugger); | ||
|
||
if (!context) { | ||
std::cerr << "Failed to create context" << std::endl; | ||
return 1; | ||
} | ||
|
||
|
||
// Create the renderer | ||
|
||
TL_RendererFeatures_t rendererfeats = {}; | ||
rendererfeats.presentation = true; | ||
|
||
TL_RendererDescriptor_t rendererdesc = {}; | ||
rendererdesc.api = TL_RENDERER_API_VULKAN_BIT; | ||
rendererdesc.api_version = { 1, 3, 0 }; | ||
rendererdesc.requirements = rendererfeats; | ||
|
||
uint32_t renderersucc = TL_RendererCreate( | ||
context, 1, | ||
(TL_RendererDescriptor_t[]) { rendererdesc }, | ||
(TL_Renderer_t **[]) { &renderer }, | ||
debugger); | ||
|
||
if (renderersucc < 1) { | ||
std::cerr << "Failed to create renderer" << std::endl; | ||
return 1; | ||
} | ||
|
||
|
||
// Create the window | ||
|
||
if (!glfwInit()) { | ||
std::cerr << "Failed to init GLFW" << std::endl; | ||
return 1; | ||
} | ||
|
||
window = glfwCreateWindow(640, 480, "Standalone test", nullptr, nullptr); | ||
|
||
if (!window) { | ||
std::cerr << "Failed to create window" << std::endl; | ||
return 1; | ||
} | ||
|
||
// window surface for interfacing with Thallium swapchains | ||
window_surface = TL_WindowSurfaceCreateXlib(glfwGetX11Display(), glfwGetX11Window(window), debugger); | ||
|
||
if (!window_surface) { | ||
std::cerr << "Failed to create window" << std::endl; | ||
return 1; | ||
} | ||
|
||
// Initially create the swapchain | ||
|
||
TL_SwapchainDescriptor_t swapchaindesc = {}; | ||
swapchaindesc.resolution = { 640, 480 }; | ||
swapchaindesc.window_surface = window_surface; | ||
|
||
swapchain = TL_SwapchainCreate(renderer, swapchaindesc); | ||
|
||
if (!swapchain) { | ||
std::cerr << "Failed to create swapchain" << std::endl; | ||
return 1; | ||
} | ||
|
||
|
||
// Main loop | ||
|
||
for (; !glfwWindowShouldClose(window);) { | ||
glfwPollEvents(); | ||
} | ||
|
||
|
||
// Cleanup | ||
|
||
TL_DebuggerDestroy(debugger); | ||
TL_RendererDestroy(renderer); | ||
TL_ContextDestroy(context); | ||
|
||
glfwTerminate(); | ||
} |