This commit is contained in:
Jorijn van der Graaf 2025-11-16 15:32:03 +01:00
commit c82c8c0887
35 changed files with 245 additions and 10 deletions

View file

@ -0,0 +1,32 @@
# HelloWindow Example
## Description
This example demonstrates how to draw pixels to a window.
## Expected Result
A window with a red colored square.
## Highlighted Code Snippet
```cpp
for(uint32_t x = 0; x < 1280; x++) {
for(uint32_t y = 0; y < 720; y++) {
window.framebuffer[x*720+y].r = 255;
window.framebuffer[x*720+y].g = 0;
window.framebuffer[x*720+y].b = 0;
window.framebuffer[x*720+y].a = 255;
}
}
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[WindowWaylandWayland](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1WindowWaylandWayland.html)

View file

@ -0,0 +1,51 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <cstdint>
#include <iostream>
import Crafter.Graphics;
using namespace Crafter;
int main() {
WindowWaylandWayland window("HelloWindow", 1280, 720);
// for(uint32_t x = 0; x < 1280; x++) {
// for(uint32_t y = 0; y < 720; y++) {
// window.framebuffer[x*720+y].r = 255;
// window.framebuffer[x*720+y].g = 0;
// window.framebuffer[x*720+y].b = 0;
// window.framebuffer[x*720+y].a = 255;
// }
// }
//Semi transparant version:
// for(uint32_t x = 0; x < 1280; x++) {
// for(uint32_t y = 0; y < 720; y++) {
// window.framebuffer[x*720+y].r = 128;//alpha channel must be premultiplied
// window.framebuffer[x*720+y].g = 0;
// window.framebuffer[x*720+y].b = 0;
// window.framebuffer[x*720+y].a = 128;
// }
// }
window.StartSync();
}

View file

@ -0,0 +1,22 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}

View file

@ -0,0 +1,49 @@
# HelloInput Example
## Description
This example demonstrates how to handle basic input events by:
- Create a window using `WindowWaylandWayland`
- Register event listeners using `EventListener<T>` for:
- Mouse click events
- Specific key events
- General keypress events
- Print formatted feedback to the console when events are triggered
## Expected Result
When you interact with the window, you might see console output like:
Clicked on X:450 Y:320!
Pressed specifically the a key!
Pressed the b key!
Make sure that the window has focus.
## Highlighted Code Snippet
```cpp
EventListener<MousePoint> clickListener(&window.onMouseLeftClick, [](MousePoint point){
std::cout << std::format("Clicked on X:{} Y:{}!", point.x, point.y);
});
EventListener<void> keyAListener(&window.onKeyDown['a'], [](){
std::cout << std::format("Pressed specifically the a key!");
});
EventListener<char> anyKeyListener(&window.onAnyKeyDown, [](char key){
std::cout << std::format("Pressed the {} key!", key);
});
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[Window](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1Window.html)

View file

@ -0,0 +1,57 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <iostream>
#include <format>
import Crafter.Graphics;
//Needed for events
import Crafter.Event;
using namespace Crafter;
int main() {
// Create a Wayland window named "HelloWindow" with resolution 1280x720
// (window creation explained in HelloWindow example)
WindowWaylandWayland window("HelloWindow", 1280, 720);
// Listen for left mouse click events on the window
// The callback receives the MousePoint struct containing the click coordinates in float pixels from the top left corner
EventListener<MousePoint> clickListener(&window.onMouseLeftClick, [](MousePoint point){
// Print the coordinates where the user clicked
std::cout << std::format("Clicked on X:{} Y:{}!", point.x, point.y) << std::endl;
});
// Listen specifically for the 'a' key being pressed down
// The callback takes no parameters since the key is fixed
EventListener<void> keyAListener(&window.onKeyDown['a'], [](){
// Print confirmation of 'a' key press
std::cout << std::format("Pressed specifically the a key!") << std::endl;
});
// Listen for any key press on the window
// The callback receives the character of the key pressed
EventListener<char> anyKeyListener(&window.onAnyKeyDown, [](char key){
// Print which key was pressed
std::cout << std::format("Pressed the {} key!", key) << std::endl;
});
// Start the window event loop, unless the window is started events will not trigger.
window.StartSync();
}

View file

@ -0,0 +1,22 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}

View file

@ -0,0 +1,36 @@
# HelloWindow Example
## Description
This example demonstrates how to draw pixels to a window.
## Expected Result
A window with a green and blue colored square, when clicking on the square it logs the coordinates relative to the square.
## Highlighted Code Snippet
```cpp
UiElement& element = window.elements.emplace_back(
0.5,
0.5,
2,
1,
0.5f,
0.5f,
0.5,
0.5,
0,
false
);
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[UiElement](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1UiElement.html)

65
examples/HelloUI/main.cpp Normal file
View file

@ -0,0 +1,65 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <cstdint>
#include <iostream>
import Crafter.Event;
import Crafter.Graphics;
using namespace Crafter;
int main() {
WindowWaylandWayland window("HelloWindow", 1280, 720);
UiElement& element = window.elements.emplace_back(
0.5, //anchorX: relative position where this elements x anchor (top-left) is placed to its parent x anchor
0.5, //anchorY: relative position where this elements y anchor (top-left) is placed to its parent y anchor
2, //bufferWidth: the width of this elements pixel buffer
1, //bufferHeight: the height of this elements pixel buffer
0.5f, //relativeSizeX: the relative x size this element should be scaled to compared to its parent
0.5f, //relativeSizeY: the relative y size this element should be scaled to compared to its parent
0.5, //anchorOffsetX: the amount this element's anchor should be offset from the top left corner (0.5 to in the middle)
0.5, //anchorOffsetY: the amount this element's anchor should be offset from the top left corner (0.5 to place it in the middle)
0, //z: this elements Z position
false //ignoreScaling: wether this element ignores the scaling of the window, if true its size will be scaled according to the window scale
);
// UiElement& element = window.elements.emplace_back(
// 0.5,
// 0.5,
// 2,
// 1,
// uint32_t(100), //absoluteSizeX: the absolute x size in pixels this element should be scaled to
// uint32_t(100), //absoluteSizeY: the absolute x size in pixels this element should be scaled to
// 0.5,
// 0.5,
// 0,
// false
// );
EventListener<MousePoint> clickListener(&element.onMouseLeftClick, [](MousePoint point){
// Print the coordinates where the user clicked relative to the element's top left corner.
std::cout << std::format("Clicked on X:{} Y:{}!", point.x, point.y) << std::endl;
});
element.buffer = {{255, 0, 0 ,255}, {0, 255, 0 ,255}};
window.scale = 1;
window.StartSync();
}

View file

@ -0,0 +1,22 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}

View file

@ -0,0 +1,27 @@
# HelloWindow Example
## Description
This example demonstrates the minimal code needed to create a window and show it on the screen.
## Expected Result
A empty window with the title "HelloWindow" shows onscreen.
## Highlighted Code Snippet
```cpp
WindowWaylandWayland window("HelloWindow", 1280, 720);
window.StartSync();
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[WindowWaylandWayland](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1WindowWaylandWayland.html)

View file

@ -0,0 +1,39 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import Crafter.Graphics;
using namespace Crafter;
int main() {
/*
This creates a window titled "HelloWindow" with a size of 1280x720 pixels.
The WindowWaylandWayland class is a specialized window implementation
that uses the Wayland display server protocol and renderer (hence the name "WaylandWayland").
*/
WindowWaylandWayland window("HelloWindow", 1280, 720);
/*
This starts the windows main event loop, allowing it to respond to user input and system events.
The window will remain open and responsive until it is closed.
You can hook into various events through the event system.
This call blocks the current thread; to run the event loop asynchronously, use StartAsync instead.
*/
window.StartSync();
}

View file

@ -0,0 +1,22 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}

52
examples/README.md Normal file
View file

@ -0,0 +1,52 @@
# Crafter.Graphics Examples
Welcome to the **Crafter.Graphics** examples folder!
Here you'll find a variety of demos to help you learn and experiment with the features of the `Crafter.Graphics` library.
## Getting Started
To run any example, navigate into its folder and use the following command:
```bash
crafter-build -c example -r
```
## Hello Series
This series explains the absolute basics.
1. **HelloWindow**
Basic window creation using Crafter.Graphics.
2. **HelloInput**
Handling keyboard and mouse input events.
3. **HelloDrawing**
Introduction to drawing on a window.
4. **HelloUI**
Creating and rendering user interface components.
## Vulkan Series
This series explains the vulkan integration.
1. **VulkanWindow**
HelloWindow vulkan edition.
2. **VulkanTraingle**
Introduction to drawing on a window.
3. **VulkanCube**
Creating a custom shader.
4. **VulkanShader**
Creating a custom shader.
## Notes
- Each example is self-contained and meant to be run individually.
- Make sure your environment is correctly set up with all dependencies required by `Crafter.Graphics`.
- A comaptible WSL envoirement can be set up by running these commands:
```cmd
wsl --update --pre-release
wsl --install archlinux --name crafter --no-launch
wsl -d crafter pacman -Syu vulkan-devel mesa vulkan-dzn clang git base-devel code libpqxx onetbb boost lld glslang code --noconfirm
wsl -d crafter bash -c "echo export GALLIUM_DRIVER=d3d12 > /etc/profile.d/wslg.sh"
wsl -d crafter ln -s /usr/lib/libedit.so /usr/lib/libedit.so.2
wsl --terminate crafter
```

View file

@ -0,0 +1,27 @@
# HelloWindow Example
## Description
This example showcases how to use the camera to get a rotating 3D cube.
## Expected Result
A blue tinted vulkan window with a white rotating 3D cube.
## Highlighted Code Snippet
```cpp
Camera camera(ToRadian(90), 1280.0f / 720.0f, 0.01, 512);
camera.view = MatrixRowMajor<float, 4, 4, 1>::Translation(0, 0, -5);
camera.Update();
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[Camera](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1Mesh.html)

View file

@ -0,0 +1,108 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <cstring>
#include <vulkan/vulkan.h>
//required for the camera matrix.
import Crafter.Math;
import Crafter.Event;
import Crafter.Graphics;
using namespace Crafter;
typedef VulkanShader<"MeshShaderXYZ.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT, 3, {{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2}}}> MeshShaderSpirv;
typedef VulkanShader<"FragmentShaderSolidWhite.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader;
typedef VulkanPipeline<MeshShaderSpirv, FragmentShader> Pipeline;
int main() {
VulkanDevice::CreateDevice();
MeshShaderSpirv::CreateShader();
FragmentShader::CreateShader();
Pipeline::CreatePipeline();
WindowWaylandVulkan window("HelloWindow", 1280, 720);
/*
Load the verticies and indicies for our cube.
*/
Mesh<Vertex> cube(8, 12);
Vertex verticies[] {
{-0.5f, -0.5f, -0.5f, 1.0f},
{-0.5f, -0.5f, 0.5f, 1.0f},
{-0.5f, 0.5f, -0.5f, 1.0f},
{-0.5f, 0.5f, 0.5f, 1.0f},
{0.5f, -0.5f, -0.5f, 1.0f},
{0.5f, -0.5f, 0.5f, 1.0f},
{0.5f, 0.5f, -0.5f, 1.0f},
{0.5f, 0.5f, 0.5f, 1.0f}
};
std::memcpy(cube.verticies.value, &verticies, sizeof(verticies));
uint32_t indicies[]
{
0, 2, 1,
1, 2, 3,
4, 5, 6,
5, 7, 6,
0, 1, 5,
0, 5, 4,
2, 6, 7,
2, 7, 3,
0, 4, 6,
0, 6, 2,
1, 3, 7,
1, 7, 5
};
std::memcpy(cube.indicies.value, &indicies, sizeof(indicies));
/*
Defines a perspective camera, with an FOV of 90, an aspect ratio of 16/9 a near clip of 0.01 and a far clip of 512.
*/
Camera camera(ToRadian(90), 1280.0f / 720.0f, 0.01, 512);
camera.view = MatrixRowMajor<float, 4, 4, 1>::Translation(0, 0, -5);
/*
Calculates the viewprojection, must be called each time after updating the camera.
*/
camera.Update();
MeshShader<Vertex> meshShader(&cube, &camera);
DescriptorSet<MeshShaderSpirv, FragmentShader> descriptors;
meshShader.WriteDescriptors(descriptors.set[0]);
/*
Calculates the modelviewprojection matrix.
*/
meshShader.Update();
float counter = 0;
EventListener<VkCommandBuffer> listener(&window.onDraw, [&descriptors, &meshShader, &counter](VkCommandBuffer cmd){
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline);
VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1);
meshShader.transform = MatrixRowMajor<float, 4, 4, 1>::Rotation(counter, counter, 0);
/*
We edited the transform so must recalculate the model view projection matrix.
*/
meshShader.Update();
counter+=0.01;
});
window.StartSync();
}

View file

@ -0,0 +1,22 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}

View file

@ -0,0 +1,49 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#version 450
#extension GL_EXT_mesh_shader : require
layout (binding = 0) buffer COLORS
{
vec4 colors[];
} colors;
layout (location = 0) out PerVertexData
{
vec4 color;
} outVert[];
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(triangles, max_vertices = 3, max_primitives = 1) out;
void main()
{
SetMeshOutputsEXT(3, 1);
gl_MeshVerticesEXT[0].gl_Position = vec4(0, -0.3, 0, 1);
gl_MeshVerticesEXT[1].gl_Position = vec4(0.3, 0.3, 0, 1);
gl_MeshVerticesEXT[2].gl_Position = vec4(-0.3, 0.3, 0, 1);
outVert[0].color = colors.colors[0];
outVert[1].color = colors.colors[1];
outVert[2].color = colors.colors[2];
gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);
}

View file

@ -0,0 +1,37 @@
# HelloWindow Example
## Description
This example showcases how to define a custom shader.
## Expected Result
A RGB triangle.
## Highlighted Code Snippet
```cpp
class CustomShader {
public:
Buffer<Vector<float, 4>> colors;
CustomShader(const std::vector<Vector<float, 4>>& colors) : colors(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, colors.size()) {
memcpy(this->colors.value, colors.data(), colors.size()*sizeof(Vector<float, 4>));
}
void WriteDescriptors(VkDescriptorSet set) {
VkWriteDescriptorSet write[1] = {
vks::initializers::writeDescriptorSet(set, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, &colors.descriptor),
};
vkUpdateDescriptorSets(VulkanDevice::device, 1, &write[0], 0, nullptr);
}
};
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[DescriptorSet](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1DescriptorSet.html)
[VulkanShader](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1VulkanShader.html)

View file

@ -0,0 +1,80 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../lib/VulkanInitializers.hpp"
#include <cstring>
#include <vector>
#include <vulkan/vulkan.h>
//required for the camera matrix.
import Crafter.Math;
import Crafter.Event;
import Crafter.Graphics;
using namespace Crafter;
typedef VulkanShader<"CustomShader.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT, 1, {{{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0}}}> CustomShaderSpirv;
typedef VulkanShader<"FragmentShaderVertexColor.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader;
typedef VulkanPipeline<CustomShaderSpirv, FragmentShader> Pipeline;
class CustomShader {
public:
/*
Define a buffer holding our color vectors.
*/
Buffer<Vector<float, 4>> colors;
/*
Initialze our buffer as shader visible storage buffer with the size of the colors vector.
*/
CustomShader(const std::vector<Vector<float, 4>>& colors) : colors(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, colors.size()) {
memcpy(this->colors.value, colors.data(), colors.size()*sizeof(Vector<float, 4>));
}
void WriteDescriptors(VkDescriptorSet set) {
/*
Write the color buffer descriptor to the set.
*/
VkWriteDescriptorSet write[1] = {
vks::initializers::writeDescriptorSet(set, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, &colors.descriptor),
};
vkUpdateDescriptorSets(VulkanDevice::device, 1, &write[0], 0, nullptr);
}
};
int main() {
VulkanDevice::CreateDevice();
CustomShaderSpirv::CreateShader();
FragmentShader::CreateShader();
Pipeline::CreatePipeline();
WindowWaylandVulkan window("HelloWindow", 1280, 720);
DescriptorSet<CustomShaderSpirv, FragmentShader> descriptors;
CustomShader customShader({{1,0,0,1}, {0,1,0,1}, {0,0,1,1}});
customShader.WriteDescriptors(descriptors.set[0]);
EventListener<VkCommandBuffer> listener(&window.onDraw, [&descriptors](VkCommandBuffer cmd){
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline);
VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, 1, 1, 1);
});
window.StartSync();
}

View file

@ -0,0 +1,29 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
],
"shaders": [
{
"path":"CustomShader.glsl",
"type":13,
"entrypoint":"main"
}
]
}
]
}

View file

@ -0,0 +1,34 @@
# HelloWindow Example
## Description
This example demonstrates how to load shaders and render a triangle.
## Expected Result
A blue tinted vulkan window with a white triangle in the center.
## Highlighted Code Snippet
```cpp
EventListener<VkCommandBuffer> listener(&window.onDraw, [&descriptors, &meshShader](VkCommandBuffer cmd){
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline);
VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1);
});
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[DescriptorSet](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1DescriptorSet.html)
[Mesh](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1Mesh.html)
[MeshShader](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1MeshShader.html)
[VulkanShader](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1VulkanShader.html)
[VulkanPipeline](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1VulkanPipeline.html)
[WindowWaylandVulkan](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1WindowWaylandVulkan.html)

View file

@ -0,0 +1,102 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vulkan/vulkan.h>
import Crafter.Event;
import Crafter.Graphics;
using namespace Crafter;
/*
This typedefs a shader configuration we will use, this includes all necessary info to load in the shader from a file.
*/
typedef VulkanShader<
"MeshShaderXYZ.spirv", //the filename of the shader
"main", //the name of the entrypoint symbol of the shader
VK_SHADER_STAGE_MESH_BIT_EXT, //the shader stage
3, //how many descriptors this shader has
{{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2}}}//an array of descriptor types and their binding slot, 1 unfiform for the mvp and 2 for vertex and index.
> MeshShaderSpirv;
typedef VulkanShader<"FragmentShaderSolidWhite.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader;
/*
This typedefs the pipeline we will use, for each combination of mesh and fragment shader a new pipeline must be used, but this pipeline can be shared with each object using this combination.
*/
typedef VulkanPipeline<MeshShaderSpirv, FragmentShader> Pipeline;
int main() {
VulkanDevice::CreateDevice();
WindowWaylandVulkan window("HelloWindow", 1280, 720);
/*
Each shader and pipeline must be created before use.
*/
MeshShaderSpirv::CreateShader();
FragmentShader::CreateShader();
Pipeline::CreatePipeline();
/*
Create a mesh typed on Vertex, which is a vertex type with only a position, it holds 3 vertexes and 3 indexes for our triangle.
*/
Mesh<Vertex> triangle(3, 3);
triangle.verticies.value[0] = {0, -0.3, 0, 1};
triangle.verticies.value[1] = {0.3, 0.3, 0, 1};
triangle.verticies.value[2] = {-0.3, 0.3, 0, 1};
triangle.indicies.value[0] = 0;
triangle.indicies.value[1] = 1;
triangle.indicies.value[2] = 2;
/*
Use the created traingle mesh in a meshShader to render it.
*/
MeshShader<Vertex> meshShader(&triangle);
/*
Create a DescriptorSet to hold the descriptors of our meshShader, since our fragment shader doesn't use any.
We are writing to the 0 index in the set because the mesh shader is the first stage.
For fragment shaders write to the 1 index.
*/
DescriptorSet<MeshShaderSpirv, FragmentShader> descriptors;
meshShader.WriteDescriptors(descriptors.set[0]);
/*
Create a listener on the window onDraw event that gets a command buffer, this event is called for each frame and where drawing happens.
*/
EventListener<VkCommandBuffer> listener(&window.onDraw, [&descriptors, &meshShader](VkCommandBuffer cmd){
/*
Bind the descriptor set we created earlier, CreatePipeline() creates Pipeline::pipelineLayout and Pipeline::pipeline.
*/
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL);
/*
Bind our pipeline, these can use static members because of the templating.
*/
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline);
/*
Launch our mesh shader with the required threads.
*/
VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1);
});
window.StartSync();
}

View file

@ -0,0 +1,22 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}

View file

@ -0,0 +1,31 @@
# HelloWindow Example
## Description
This example demonstrates the minimal code needed to create a vulkan window and show it on the screen.
## Expected Result
A blue tinted vulkan window with the title "HelloWindow" shows onscreen, with debug info in the console.
## Highlighted Code Snippet
```cpp
VulkanDevice::CreateDevice();
WindowWaylandVulkan window("HelloWindow", 1280, 720);
VkCommandBuffer cmd = window.StartInit();
window.FinishInit();
window.StartSync();
```
## How to Run
```bash
crafter-build -c example -r
```
## Relevant documentation
[VulkanDevice](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1VulkanDevice.html)
[WindowWaylandVulkan](https://crafter-graphics.docs.catcrafts.net/classCrafter_1_1WindowWaylandVulkan.html)

View file

@ -0,0 +1,60 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vulkan/vulkan.h>
import Crafter.Graphics;
using namespace Crafter;
int main() {
/*
This sets up all necessary things and creates the vulkan device.
This must be called before any vulkan related things.
Things like VkDevice are static members of the VulkanDevice class.
*/
VulkanDevice::CreateDevice();
/*
This creates a window titled "HelloWindow" with a size of 1280x720 pixels.
The WindowWaylandVulkan class is a specialized window implementation.
that uses the Wayland display server protocol and vulkan renderer (hence the name "WaylandVulkan").
*/
WindowWaylandVulkan window("HelloWindow", 1280, 720);
/*
StartInit gives you a VkCommandBuffer to use before the event loop starts
Use this for inititializing things like textures.
*/
VkCommandBuffer cmd = window.StartInit();
/*
FinishInit executes all commands recorded to StartInit.
This must be called before the the event loops starts if you called StartInit before.
*/
window.FinishInit();
/*
This starts the windows main event loop, allowing it to respond to user input and system events.
The window will remain open and responsive until it is closed.
You can hook into various events through the event system.
This call blocks the current thread; to run the event loop asynchronously, use StartAsync instead.
*/
window.StartSync();
}

View file

@ -0,0 +1,22 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "example",
"standard": "c++26",
"source_files": ["main"],
"module_files": [],
"build_dir": "build",
"output_dir": "bin",
"type":"executable",
"libs": [],
"flags": ["-Wno-uninitialized"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}