demo/backend: add vulkan SDL backend and demo
Based on other SDL demos and GLFW Vulkan demo.
This commit is contained in:
parent
03198a016b
commit
b2ffce5131
3
demo/sdl_vulkan/.gitignore
vendored
Normal file
3
demo/sdl_vulkan/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
src/nuklearshaders/*.spv
|
||||||
|
src/nuklear_sdl_vulkan.h
|
||||||
|
shaders/*.spv
|
29
demo/sdl_vulkan/Makefile
Normal file
29
demo/sdl_vulkan/Makefile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Install
|
||||||
|
BIN = demo
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
CFLAGS += -std=c89 -Wall -Wextra -pedantic -fsanitize=address -O2
|
||||||
|
|
||||||
|
SRC = main.c
|
||||||
|
OBJ = $(SRC:.c=.o)
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
BIN := $(BIN).exe
|
||||||
|
LIBS = -lsdl2 -lvulkan -lm
|
||||||
|
else
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
SDL2 := $(shell pkg-config --libs sdl2)
|
||||||
|
LIBS = $(SDL2) -lvulkan -lm
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
$(BIN): shaders/demo.vert.spv shaders/demo.frag.spv
|
||||||
|
@mkdir -p bin
|
||||||
|
rm -f bin/$(BIN) $(OBJS)
|
||||||
|
$(CC) $(SRC) $(CFLAGS) -o bin/$(BIN) $(LIBS)
|
||||||
|
|
||||||
|
shaders/demo.vert.spv: shaders/demo.vert
|
||||||
|
glslc --target-env=vulkan shaders/demo.vert -o shaders/demo.vert.spv
|
||||||
|
|
||||||
|
shaders/demo.frag.spv: shaders/demo.frag
|
||||||
|
glslc --target-env=vulkan shaders/demo.frag -o shaders/demo.frag.spv
|
52
demo/sdl_vulkan/README.md
Normal file
52
demo/sdl_vulkan/README.md
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# nuklear sdl vulkan
|
||||||
|
|
||||||
|
## Theory of operation
|
||||||
|
|
||||||
|
The nuklear SDL vulkan integration creates an independent graphics pipeline that will render the nuklear UI to separate render targets.
|
||||||
|
The application is responsible to fully manage these render targets. So it must ensure they are properly sized (and resized when requested).
|
||||||
|
|
||||||
|
Furthermore it is assumed that you will have a swap chain in place and the number of nuklear overlay images and number of swap chain images match.
|
||||||
|
|
||||||
|
This is how you can integrate it in your application:
|
||||||
|
|
||||||
|
```
|
||||||
|
/*
|
||||||
|
Setup: overlay_images have been created and their number match with the number
|
||||||
|
of the swap_chain_images of your application. The overlay_images in this
|
||||||
|
example have the same format as your swap_chain images (optional)
|
||||||
|
*/
|
||||||
|
struct nk_context *ctx = nk_sdl_init(
|
||||||
|
demo.win, demo.device, demo.physical_device, demo.indices.graphics,
|
||||||
|
demo.overlay_image_views, demo.swap_chain_images_len,
|
||||||
|
demo.swap_chain_image_format, 0,
|
||||||
|
MAX_VERTEX_BUFFER, MAX_ELEMENT_BUFFER);
|
||||||
|
[...]
|
||||||
|
/*
|
||||||
|
in your draw loop draw you can then render to the overlay image at
|
||||||
|
`image_index`
|
||||||
|
your own application can then wait for the semaphore and produce
|
||||||
|
the swap_chain_image at `image_index`
|
||||||
|
this should simply sample from the overlay_image (see example)
|
||||||
|
*/
|
||||||
|
nk_semaphore semaphore =
|
||||||
|
nk_sdl_render(demo.graphics_queue, image_index,
|
||||||
|
demo.image_available, NK_ANTI_ALIASING_ON);
|
||||||
|
if (!render(&demo, &bg, nk_semaphore, image_index)) {
|
||||||
|
fprintf(stderr, "render failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You must call `nk_sdl_resize` whenever the size of the overlay_images resize.
|
||||||
|
|
||||||
|
## Using images
|
||||||
|
|
||||||
|
Images can be used by providing a VkImageView as an nk_image_ptr to nuklear:
|
||||||
|
|
||||||
|
```
|
||||||
|
img = nk_image_ptr(demo.demo_texture_image_view);
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that they must have SHADER_READ_OPTIMAL layout
|
||||||
|
|
||||||
|
It is currently not possible to specify how they are being sampled. The nuklear SDL vulkan integration uses a fixed sampler that does linear filtering.
|
2251
demo/sdl_vulkan/main.c
Normal file
2251
demo/sdl_vulkan/main.c
Normal file
File diff suppressed because it is too large
Load Diff
1648
demo/sdl_vulkan/nuklear_sdl_vulkan.h
Normal file
1648
demo/sdl_vulkan/nuklear_sdl_vulkan.h
Normal file
File diff suppressed because it is too large
Load Diff
12
demo/sdl_vulkan/shaders/demo.frag
Normal file
12
demo/sdl_vulkan/shaders/demo.frag
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout(binding = 0) uniform sampler2D overlay;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 inUV;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outColor = texture(overlay, inUV);
|
||||||
|
}
|
10
demo/sdl_vulkan/shaders/demo.vert
Normal file
10
demo/sdl_vulkan/shaders/demo.vert
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout (location = 0) out vec2 outUV;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
|
gl_Position = vec4(outUV * 2.0f + -1.0f, 0.0f, 1.0f);
|
||||||
|
}
|
11
demo/sdl_vulkan/src/Makefile
Normal file
11
demo/sdl_vulkan/src/Makefile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
create_shader_inlined_header: nuklearshaders/nuklear.vert.spv nuklearshaders/nuklear.frag.spv
|
||||||
|
awk -v st='// NUKLEAR_SHADERS_START' -v et='// NUKLEAR_SHADERS_END' -v repl="$$(xxd -i nuklearshaders/nuklear.vert.spv && xxd -i nuklearshaders/nuklear.frag.spv)" '$$0 == st{del=1} $$0 == et{$$0 = repl; del=0} !del' nuklear_sdl_vulkan.in.h > nuklear_sdl_vulkan.h
|
||||||
|
|
||||||
|
nuklearshaders/nuklear.vert.spv: nuklearshaders/nuklear.vert
|
||||||
|
glslc --target-env=vulkan nuklearshaders/nuklear.vert -o nuklearshaders/nuklear.vert.spv
|
||||||
|
|
||||||
|
nuklearshaders/nuklear.frag.spv: nuklearshaders/nuklear.frag
|
||||||
|
glslc --target-env=vulkan nuklearshaders/nuklear.frag -o nuklearshaders/nuklear.frag.spv
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm nuklearshaders/nuklear.vert.spv nuklearshaders/nuklear.frag.spv nuklear_sdl_vulkan.h
|
5
demo/sdl_vulkan/src/README.md
Normal file
5
demo/sdl_vulkan/src/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Contrary to OpenGL Vulkan needs precompiled shaders in the SPIR-V format which makes it a bit more difficult to inline the shadercode.
|
||||||
|
|
||||||
|
After executing `make` the result should be a self contained `nuklear_sdl_vulkan.h`. Copy the result file to the parent directory and the "release" should be done.
|
||||||
|
|
||||||
|
You will need to have `xxd`, `glslc` and `awk` installed for this.
|
1425
demo/sdl_vulkan/src/nuklear_sdl_vulkan.in.h
Normal file
1425
demo/sdl_vulkan/src/nuklear_sdl_vulkan.in.h
Normal file
File diff suppressed because it is too large
Load Diff
13
demo/sdl_vulkan/src/nuklearshaders/nuklear.frag
Normal file
13
demo/sdl_vulkan/src/nuklearshaders/nuklear.frag
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout(binding = 0, set = 1) uniform sampler2D currentTexture;
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 fragColor;
|
||||||
|
layout(location = 1) in vec2 fragUv;
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texColor = texture(currentTexture, fragUv);
|
||||||
|
outColor = fragColor * texColor;
|
||||||
|
}
|
23
demo/sdl_vulkan/src/nuklearshaders/nuklear.vert
Normal file
23
demo/sdl_vulkan/src/nuklearshaders/nuklear.vert
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
out gl_PerVertex {
|
||||||
|
vec4 gl_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(binding = 0) uniform UniformBufferObject {
|
||||||
|
mat4 projection;
|
||||||
|
} ubo;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 position;
|
||||||
|
layout(location = 1) in vec2 uv;
|
||||||
|
layout(location = 2) in uvec4 color;
|
||||||
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
layout(location = 1) out vec2 fragUv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ubo.projection * vec4(position, 0.0, 1.0);
|
||||||
|
gl_Position.y = -gl_Position.y;
|
||||||
|
fragColor = vec4(color[0]/255.0, color[1]/255.0, color[2]/255.0, color[3]/255.0);
|
||||||
|
fragUv = uv;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user