Code Monkey home page Code Monkey logo

walnut's Introduction

Walnut

Walnut is a simple application framework built with Dear ImGui and designed to be used with Vulkan - basically this means you can seemlessly blend real-time Vulkan rendering with a great UI library to build desktop applications. The plan is to expand Walnut to include common utilities to make immediate-mode desktop apps and simple Vulkan applications.

Currently supports Windows - with macOS and Linux support planned. Setup scripts support Visual Studio 2022 by default.

WalnutExample

Forest Launcher - an application made with Walnut

Requirements

Getting Started

Once you've cloned, run scripts/Setup.bat to generate Visual Studio 2022 solution/project files. Once you've opened the solution, you can run the WalnutApp project to see a basic example (code in WalnutApp.cpp). I recommend modifying that WalnutApp project to create your own application, as everything should be setup and ready to go.

3rd party libaries

Additional

walnut's People

Contributors

jamesthomasgriffin avatar jeffreylindsey avatar julianjany avatar thecherno avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

walnut's Issues

Danish Characters are not supported

If I put any danish characters in the title or in text somewhere is does not work. I will show either "?" or some weird characters.

Characters testes are: "æøå"

Crashes when using ImageFormat::RGBA32F

void ImageViewport::RenderImageData()
{
	Walnut::Timer timer;
	
	// set Image and ImageData if image is null or if ImageResolution changed
	if(!Image || Image->GetHeight() != ImageResolution.y || Image->GetWidth() != ImageResolution.x)
	{
		Image = std::make_shared<Walnut::Image>(ImageResolution.x, ImageResolution.y, Walnut::ImageFormat::RGBA32F);

		ImageData = new float[ImageResolution.x * ImageResolution.y * 4];
	}

	for(uint32_t i = 0; i < ImageResolution.x * ImageResolution.y * 4; i++)
	{
		ImageData[i] = Walnut::Random::Float();
	}
	
	Image->SetData(ImageData);

	LastRenderTime = timer.ElapsedMillis();
}

The app compiles and runs, but when I click on the Render button that triggers this RenderImageData() function it crashes.
When instead using RGBA everything runs as expected.

Feature Request: Syntax Highlighting Widget

It would be great if we could add a syntax highlighting widget to Walnut. From my research, it doesn't appear that there is an out-of-the-box solution for this in ImGui. Perhaps we could create such a widget here and then attempt to have it added to ImGui once it is feature-complete and stable.

As far as implementation goes, I think we have a couple of options:

  1. Create the widget from scratch including lexing for popular languages
  2. Create a Scintilla port for ImGui + Vulkan

There is one repo I found that implements syntax highlighting for ImGui. However, it seems to be out of active development and only supports a few languages.

Anyways, I thought I would just kick off a conversation to see if there is interest in adding something like this into Walnut and to gather suggestions for the best approach.

No such file or directory

When runnning the Setup.bat or Setup-ExampleProject.bat I get this error. I tried changing the path to the directory path but it doesn't work.
image

Custom GLFW changes cause crash in Linux

It prints out Aborted (Core Dumped) I ran it through GDB and found it crashed on this line: https://github.com/TheCherno/Walnut/blob/20f940b9d23946d4836b8549ff3e2c0750c5d985/Walnut/src/Walnut/Application.cpp#L421 (backtrace goes through GLFW code before ultimately throwing a SIGABRT in libvulkan.so).

This merge commit of your GLFW fork is where it broke: d710a034f0667f97aa6cdfe78bf274b3b4f7aa63

Both parents of that merge commit work (one being your fork before you updated from GLFW master and one being stock GLFW without any changes you made).

I also reproduced this with a minimal C program that just calls GLFWInit + glfwVulkanSupported to confirm that it was the GLFW fork at fault rather than anything else in Walnut code.

Repetitive glm dependency

In Visual Studio 2022, I notice that there is a repetitive glm dependency to the path "Walnut/vendor/glm" and VulkanSDK. This causes a duplicated occurance of "glm" and sub-headers in the prompt for code auto-completion.

This is avoidable by not adding any dependency of "Walnut/vendor/glm" to premake files, since Vulkan is bound to be included in the project.

Crash when updating image data

I am trying to render video.
I create one Image and call setData to update image data.

When I change screen size there is a crash.
the crash is related to this 1f18ebb

the code adds freeing of command buffer

// Free command buffers allocated by Application::GetCommandBuffer
auto& allocatedCommandBuffers = s_AllocatedCommandBuffers[wd->FrameIndex];
if (allocatedCommandBuffers.size() > 0)
{
	vkFreeCommandBuffers(g_Device, fd->CommandPool, (uint32_t)allocatedCommandBuffers.size(), allocatedCommandBuffers.data());
	allocatedCommandBuffers.clear();
}

This works. However When changing the main glfw window size with mouse, there is a crash at vulkan, In these lines
this happend if I change the image using SetData() in the Layers OnUIRender()

[vulkan] Debug report from ObjectType: 6
Message: Validation Error: [ VUID-vkFreeCommandBuffers-pCommandBuffers-00048 ] Object 0: handle = 0x18ef04b5820, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x1eb50db9 | Invalid VkCommandBuffer 0x18ef04b5820[]. The Vulkan spec states: pCommandBuffers must be a valid pointer to an array of commandBufferCount VkCommandBuffer handles, each element of which must either be a valid handle or NULL (https://vulkan.lunarg.com/doc/view/1.2.154.1/windows/1.2-extensions/vkspec.html#VUID-vkFreeCommandBuffers-pCommandBuffers-00048)

[vulkan] Debug report from ObjectType: 6
Message: Validation Error: [ UNASSIGNED-Threading-Info ] Object 0: handle = 0x18ef04b5820, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x5d6b67e2 | Couldn't find VkCommandBuffer Object 0x18ef04b5820. This should not happen and may indicate a bug in the application.

[vulkan] Debug report from ObjectType: 6
Message: Validation Error: [ UNASSIGNED-Threading-Info ] Object 0: handle = 0x18ef04b5820, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x5d6b67e2 | Couldn't find VkCommandBuffer Object 0x18ef04b5820. This should not happen and may indicate a bug in the application.

I am not an expert with vulkan, but if I understand each time we setData() to the image, askes for the CommandBuffer and directions are written to copy the data.

What I don't understand is since everything is executed line after line in Run() loop , so we first run over layers and call

for (auto& layer : m_LayerStack)
	layer->OnUIRender();

and then there is a call to
FrameRender(wd, main_draw_data);
which renders and access command buffer and clears it. (by the code above) but it crashes here.

so there is some event on window change, that happens concurrently

this code reproduces the problem

#include "..\..\vendor\stb_image\stb_image.h"
class ExampleLayer : public Walnut::Layer
{
public:
	std::string m_file_name = "C:\\Users\\meir\\Pictures\\vlcsnap-2022-03-16-10h43m50s464.png";
	std::shared_ptr<Walnut::Image> m_ImageOrig;
	virtual void OnAttach() override
	{
		m_ImageOrig = std::make_shared<Walnut::Image>(m_file_name);
	}
	virtual void OnUIRender() override
	{
		ImGui::Begin("Hello");
		ImGui::Button("Button");
               //change the image here for example we load and pass the data buffer to m_ImageOrig
		int width, height, channels;
		uint8_t* data = nullptr;
		uint64_t size = 0;

		if (stbi_is_hdr(m_file_name.c_str()))
		{
			data = (uint8_t*)stbi_loadf(m_file_name.c_str(), &width, &height, &channels, 4);
			size = width * height * 4 * sizeof(float);
			
		}
		else
		{
			data = stbi_load(m_file_name.c_str(), &width, &height, &channels, 4);
			size = width * height * 4;
			
		}
		m_ImageOrig->SetData(data);
		ImGui::Image(m_ImageOrig->GetDescriptorSet(), { (float)m_ImageOrig->GetWidth(),(float)m_ImageOrig->GetHeight() });
		ImGui::End();

		ImGui::ShowDemoWindow();
	}
};

Maybe there is a need to some Vulkan command barrier or fence? I am not an expert.

[vulkan] Error: VkResult = -6

Dear Cherno
How are you, Cherno.

I am learning your course which teaches us building a ray tracer used Walnut as ui module.
But when i run walnut,there are some trouble that I cant solve.
when i push F5, it occurs that image
image
and the cmd shows “[vulkan] Error: VkResult = -6”,as we can see from the below image
image

My English is poor,I'm sorry it may confused you.And i am looking forward to your help. I would also appriacite it if anyone else who will do me a favour.
Yours,
Armin

Linux support

I would love to add a linux support is there's anything I should look for or a guideline to contribute ?

Is the create and delete of the app intentional in EntryPoint.h?

In EntryPoint.h,

int Main(int argc, char** argv)
{
while (g_ApplicationRunning)
{
Walnut::Application* app = Walnut::CreateApplication(argc, argv);
app->Run();
delete app;
}
return 0;
}

This code appears to have a logical error, as it creates and deletes a new Walnut::Application object in each iteration of the while loop. This means that the application is constantly being restarted and terminated, which is probably not the intended behavior. A more reasonable approach would be to create the application object once before the loop, and delete it once after the loop, like this:

namespace Walnut {

    int Main(int argc, char** argv)
    {
        Walnut::Application* app = Walnut::CreateApplication(argc, argv);

        while (g_ApplicationRunning)
        {
            app->Run();
        }

            delete app;

            return 0;
    }

}

Please correct me if I'm mistaken here, Or maybe there's a good reason for it, I'm very new to this project.

Cloning Problem

I'm having an issue with cloning walnut.
When i type git clone --recursive https://github.com/TheCherno/Walnut

I'm getting this message:
Cloning into 'Walnut'... fatal: unable to access 'https://github.com/TheCherno/Walnut/': Failed to connect to 127.0.0.1 port 1080 after 2057 ms: Connection refused

I'm kinda new about these topics so I tried to solve this problem but i could not find any solution can someone help me with that?

Also I tried to clone it with SSH key but I also get the same message while it is downloading the submodules.

Drawing nearest pixel

By default Walnut::Image is set to use linear filter and not nearest filter. I changed the magFilter, minFilter and mipmapMode in the VkSamplerCreateInfo to nearest, but i still get interpolation between pixels. Does anyone know if there is something else i must change?

`

void Image::AllocateMemory(uint64_t size)
{
	VkDevice device = Walnut::Application::GetDevice();

	VkResult err;

	VkFormat vulkanFormat = Utils::WalnutFormatToVulkanFormat(m_Format);

	// Create the Image
	{
		uint32_t queueFamilyIndices[2] = { Walnut::Application::GetGraphicsQueueFamily(), Walnut::Application::GetComputeQueueFamily() };
		VkImageCreateInfo info = {};
		info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
		info.imageType = VK_IMAGE_TYPE_2D;
		info.format = vulkanFormat;
		info.extent.width = m_Width;
		info.extent.height = m_Height;
		info.extent.depth = 1;
		info.mipLevels = 1;
		info.arrayLayers = 1;
		info.samples = VK_SAMPLE_COUNT_1_BIT;
		info.tiling = VK_IMAGE_TILING_OPTIMAL;
		info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		info.sharingMode = VK_SHARING_MODE_CONCURRENT;
		info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
		info.pQueueFamilyIndices = queueFamilyIndices;
		info.queueFamilyIndexCount = 2;
		err = vkCreateImage(device, &info, nullptr, &m_Image);
		check_vk_result(err);
		VkMemoryRequirements req;
		vkGetImageMemoryRequirements(device, m_Image, &req);
		VkMemoryAllocateInfo alloc_info = {};
		alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
		alloc_info.allocationSize = req.size;
		alloc_info.memoryTypeIndex = Utils::GetVulkanMemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits);
		err = vkAllocateMemory(device, &alloc_info, nullptr, &m_Memory);
		check_vk_result(err);
		err = vkBindImageMemory(device, m_Image, m_Memory, 0);
		check_vk_result(err);
	}

	// Create the Image View:
	{
		VkImageViewCreateInfo info = {};
		info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
		info.image = m_Image;
		info.viewType = VK_IMAGE_VIEW_TYPE_2D;
		info.format = vulkanFormat;
		info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		info.subresourceRange.levelCount = 1;
		info.subresourceRange.layerCount = 1;
		err = vkCreateImageView(device, &info, nullptr, &m_ImageView);
		check_vk_result(err);
	}

	// Create sampler:
	{
		VkSamplerCreateInfo info = {};
		info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
		info.magFilter = VK_FILTER_NEAREST;
		info.minFilter = VK_FILTER_NEAREST;
		info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
		info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
		info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
		info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
		info.mipLodBias = 0.f;
		info.minLod = 0.f;
		info.maxLod = 0.f;
		info.anisotropyEnable = VK_FALSE;
		info.maxAnisotropy = 0.f;
		info.unnormalizedCoordinates = VK_FALSE;
		VkResult err = vkCreateSampler(device, &info, nullptr, &m_Sampler);
		check_vk_result(err);
	}

	// Create the Descriptor Set:
	m_DescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(m_Sampler, m_ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}

`

premake5 error

Dear Cherno
How are you, Cherno

I am learning Vulkan with your sources
However, when I tried to build it
by running setup.bat
the error message says (premake5.exe)
Error: cannot open K:/a/wdev/vendor/imgui: No such file or directory

imgui folder was empty so, I copied github source of imgui there
but it still is not working

So, could you please help me with this issue?
Thank you and have a nice day, Cherno

DPI Scale Factor

Hi,

Thanks for sharing this, it is very nice.

I have 4k screen, and the app do not manage dpi scaling.

I am beginner in c++ and it is my first try with glfw.
I try to add some code to get the monitor scale and then apply this value in the window creation, the style and the font.
Do it is a correct way to do ?
Have you a advice on this topic ?

In the Application.h

uint32_t Width = 1280;
uint32_t Height = 720;
float xscale = 1.0f;
float yscale = 1.0f;

In the Application.cpp

glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &m_Specification.xscale, &m_Specification.yscale);
m_WindowHandle = glfwCreateWindow(m_Specification.Width * m_Specification.xscale, m_Specification.Height * m_Specification.yscale, m_Specification.Name.c_str(), NULL, NULL);
ImGuiStyle& style = ImGui::GetStyle();
style.ScaleAllSizes(m_Specification.xscale);
ImFont* robotoFont = io.Fonts->AddFontFromMemoryTTF((void*)g_RobotoRegular, sizeof(g_RobotoRegular), 20.0f * m_Specification.xscale, &fontConfig);

Filter in a Table

Hi, I would like to be able to filter in a table but I can't understand how to connect the 2 things.
This is my table and I would not like to change it if possible:

Thanks to any help.

int selectedRow = -1;
static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable;
if (ImGui::BeginTable("table1", 3, flags)) {
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("MARCA", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("DESCRIZIONE", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableHeadersRow();
for (int i = 0; i < pompeDisponibili.size(); i++) {
string testo = std::to_string(pompeDisponibili.at(i)->getId());
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Selectable(testo.c_str(), selectedRow == i, ImGuiSelectableFlags_SpanAllColumns)) {
selectedRow = i;
}
testo = pompeDisponibili.at(i)->getMarca();
ImGui::TableNextColumn();
ImGui::Text(testo.c_str());
ImGui::TableNextColumn();
testo = pompeDisponibili.at(i)->getDescription();
ImGui::Text(testo.c_str());
}
}
ImGui::EndTable();

Windows 11

Hi, it compiles and works with windows 10, but not when compiling with vs 2022 and windows 11, as it complains that imguid.lib functions are already in ImGui.lib.

RGBA is RBGA

Hey, I have the following issue where:
image
image
the color is switched
so RGBA(255, 0, 255, 255) (Pink, 100% Alpha)
turns into yellow and
RGBA(255, 255, 0, 255) (Yellow, 100% Alpha)
turns into pink

my app code is pretty simple:

#include "Walnut/Application.h"
#include "Walnut/EntryPoint.h"

#include "Walnut/Image.h"
#include "Walnut/Random.h"
#include "Walnut/Timer.h"
#include "Walnut/Color.h"
// std bad, Walnut good.
using namespace Walnut;

class Viewport {
public:
	std::shared_ptr<Image> m_ViewportImage;
	uint32_t* m_ViewportImageBuffer = nullptr;
	uint32_t m_ViewportWidth = 0, m_ViewportHeight = 0;

	Viewport() { }
};

class ExampleLayer : public Walnut::Layer
{
public:
	virtual void OnUIRender() override
	{
		embraceTheDarkness();
		ImGui::Begin("Settings");
		ImGui::Text("%.3fms elapsed since last render (%.3f seconds)", m_TimerElapsedMs, m_TimerElapsedMs / 100.0f);
		if (ImGui::Button("Render")) {
			Render();
		}
		ImGui::End();
		ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
		ImGui::Begin("Viewport");


		if (!m_Viewport)
			m_Viewport = std::make_shared<Viewport>();

		m_Viewport->m_ViewportWidth = ImGui::GetContentRegionAvail().x;
		m_Viewport->m_ViewportHeight = ImGui::GetContentRegionAvail().y;


		if (m_Viewport->m_ViewportImage)
			ImGui::Image(m_Viewport->m_ViewportImage->GetDescriptorSet(), { (float)m_Viewport->m_ViewportImage->GetWidth(), (float)m_Viewport->m_ViewportImage->GetHeight() });

		ImGui::End();
		ImGui::PopStyleVar();

		Render();
	}

	void Render() {
		Timer timer;

		// If the image is not avaliable or the viewport got resized we flush the ImageData and reinitilize it
		if (!m_Viewport->m_ViewportImage || m_Viewport->m_ViewportWidth != m_Viewport->m_ViewportImage->GetWidth() || m_Viewport->m_ViewportHeight != m_Viewport->m_ViewportImage->GetHeight()) {
			m_Viewport->m_ViewportImage = std::make_shared<Image>(m_Viewport->m_ViewportWidth, m_Viewport->m_ViewportHeight, ImageFormat::RGBA);
			delete[] m_Viewport->m_ViewportImageBuffer;
			m_Viewport->m_ViewportImageBuffer = new uint32_t[m_Viewport->m_ViewportWidth * m_Viewport->m_ViewportHeight];
		}

		for (uint32_t x = 0; x < m_Viewport->m_ViewportWidth; x++)
			for (uint32_t y = 0; y < m_Viewport->m_ViewportHeight; y++)
				m_Viewport->m_ViewportImageBuffer[(y * m_Viewport->m_ViewportWidth) + x] = Color{ 255, 255, 0 } | 0xff000000;
		
		m_Viewport->m_ViewportImage->SetData(m_Viewport->m_ViewportImageBuffer);
		m_TimerElapsedMs = timer.ElapsedMillis();
	}

	void embraceTheDarkness()
	{
		ImVec4* colors = ImGui::GetStyle().Colors;
		colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
		colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
		colors[ImGuiCol_WindowBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f);
		colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
		colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
		colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
		colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
		colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
		colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
		colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
		colors[ImGuiCol_TitleBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_TitleBgActive] = ImVec4(0.06f, 0.06f, 0.06f, 1.00f);
		colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
		colors[ImGuiCol_ScrollbarBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
		colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
		colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
		colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
		colors[ImGuiCol_CheckMark] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
		colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
		colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
		colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
		colors[ImGuiCol_ButtonHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
		colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
		colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
		colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
		colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
		colors[ImGuiCol_Separator] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
		colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
		colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
		colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
		colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
		colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
		colors[ImGuiCol_Tab] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
		colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
		colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.20f, 0.20f, 0.36f);
		colors[ImGuiCol_TabUnfocused] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
		colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
		colors[ImGuiCol_DockingPreview] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
		colors[ImGuiCol_DockingEmptyBg] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
		colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
		colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
		colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
		colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
		colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
		colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
		colors[ImGuiCol_NavHighlight] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
		colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 0.00f, 0.00f, 0.70f);
		colors[ImGuiCol_NavWindowingDimBg] = ImVec4(1.00f, 0.00f, 0.00f, 0.20f);
		colors[ImGuiCol_ModalWindowDimBg] = ImVec4(1.00f, 0.00f, 0.00f, 0.35f);

		ImGuiStyle& style = ImGui::GetStyle();
		style.WindowPadding = ImVec2(8.00f, 8.00f);
		style.FramePadding = ImVec2(5.00f, 2.00f);
		style.CellPadding = ImVec2(6.00f, 6.00f);
		style.ItemSpacing = ImVec2(6.00f, 6.00f);
		style.ItemInnerSpacing = ImVec2(6.00f, 6.00f);
		style.TouchExtraPadding = ImVec2(0.00f, 0.00f);
		style.IndentSpacing = 25;
		style.ScrollbarSize = 15;
		style.GrabMinSize = 10;
		style.WindowBorderSize = 1;
		style.ChildBorderSize = 1;
		style.PopupBorderSize = 1;
		style.FrameBorderSize = 1;
		style.TabBorderSize = 1;
		style.WindowRounding = 7;
		style.ChildRounding = 4;
		style.FrameRounding = 3;
		style.PopupRounding = 4;
		style.ScrollbarRounding = 9;
		style.GrabRounding = 3;
		style.LogSliderDeadzone = 4;
		style.TabRounding = 4;
	}

private:
	std::shared_ptr<Viewport> m_Viewport;
	float m_TimerElapsedMs;	
};

Walnut::Application* Walnut::CreateApplication(int argc, char** argv)
{
	Walnut::ApplicationSpecification spec;
	spec.Name = "Project Illustro";

	Walnut::Application* app = new Walnut::Application(spec);
	app->PushLayer<ExampleLayer>();
	app->SetMenubarCallback([app]()
	{
		if (ImGui::BeginMenu("File"))
		{
			if (ImGui::MenuItem("Exit"))
			{
				app->Close();
			}
			ImGui::EndMenu();
		}
	});
	return app;
}

Walnut::Image::SetData() seems to leak memory

Peremptory thanks, for putting this together. My experience so far has been vastly more enjoyable than previous forays into complex GUI apps.

The only snag I've hit so far is that using the Walnut::Image class for dynamically generated image data by calling SetData() (e.g. in OnUIRender()) seems to leak memory and eventually the app crashes. This can be observed even while passing data that does not actually change (i.e. using the same pointer for every SetData() call).

I looked at the code, but I have no Vulkan experience and only pretty rusty C++ experience so nothing stood out to me.

Adding New and Additional Fonts

Hi there, I'm currenly working on an application in Walnut, and I wanted to make use of an icon font to include basic icons on my ImGui buttons and windows, this seems to be a fairly common practice and is even suggested in the ImGui documentation. Following the same documentation, I made several attempts to create, push, and pop a new font within the scope of my Walnut::Layer child class. With no success, I went looking for some insight, and a very helpful person pointed out that the fonts needed to be created after the ImGui context is created, but before it's initialized and the fonts are shipped off to Vulkan. They then pointed out to me where that's done internally in Application.cpp, and I managed to make just a few minor adjustments and am now able to use the icons from the font that I'd like, though from a user standpoint it would be nice if there was an easier way to include additional fonts in Walnut out of the box.

Following is a screenshot of the aforementioned Application.cpp including the changes I made to load the additional font characters. Aside from an additional #include, my changes begin around line 480:
image

Obviously this solution isn't scalable, but I thought I'd include it for future reference for anyone else who's trying to achieve the same effect in the meantime.

Otherwise, as someone with only experience making games in C++, Walnut feels like a great starting point for making apps so far, it's incredible how quickly you can rapid prototype UI, and link any sort of functionality you want to it without having to write any boiler plate rendering code. Thanks so much for making this, and I'd love to see it grow.

Can the Image.cpp load models ?

Walnut is awesome. The Image.h and Image.cpp simplify a lot rendering images.
Is the any sample code about how to use walnut to load models and textures?
Thanks!

VkCommandBuffer error, and member reference type 'void' is not a pointer

I copied the files into my Project, and linked it with my CMake build system. But I get this error:

initial value of reference to non-const must be an lvalue
non-const lvalue reference to type 'VkCommandBuffer' (aka 'VkCommandBuffer_T *') cannot bind to a temporary of type 'void'

at line:

VkCommandBuffer& command_buffer = s_AllocatedCommandBuffers[wd->FrameIndex].emplace_back();

and:

m_LayerStack.emplace_back(std::make_shared<T>())->OnAttach();

with error:

member reference type 'void' is not a pointer

In file: Application.cpp
and in file: Application.h

Any ideas?

Custom logo on the custom titlebar

Hi, i want to put a custom logo of mine on the custom titlebar, if you didnt understand :
i want to change the Walnut logo on the custom titlebar for my logo :

image

i also have a few questions :
how do i need to format my image?
do i need to make custom images for each size?
what do i need to change in my code?
what else do i need?

Window not updating during resizing

While the window is being resized, it is not updating.
This leads to artifacts on the right and bottom of the screen.

Is there interest in a PR fixing this?

Vulkan validation error

When I run the walnut example repo I get these errors, but the window still seems to work normally.

[vulkan] Debug report from ObjectType: 19
Message: Validation Error: [ VUID-vkCmdDrawIndexed-blendEnable-04727 ] Object 0: handle = 0x27d60e0000000019, type = VK_OBJECT_TYPE_PIPELINE; | MessageID = 0x8a06751e | vkCmdDrawIndexed: Image view's format features of the color attachment (0) of the active subpass do not contain VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT bit, but active pipeline's pAttachments[0].blendEnable is not VK_FALSE. The Vulkan spec states: If rasterization is not disabled in the bound graphics pipeline, then for each color attachment in the subpass, if the corresponding image view's format features do not contain VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, then the blendEnable member of the corresponding element of the pAttachments member of pColorBlendState must be VK_FALSE (https://vulkan.lunarg.com/doc/view/1.3.236.0/windows/1.3-extensions/vkspec.html#VUID-vkCmdDrawIndexed-blendEnable-04727)

[vulkan] Debug report from ObjectType: 23
Message: Validation Error: [ VUID-vkCmdDrawIndexed-magFilter-04553 ] Object 0: handle = 0x908683000000001d, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; Object 1: handle = 0x9fde6b0000000014, type = VK_OBJECT_TYPE_SAMPLER; Object 2: handle = 0x2cfba2000000001c, type = VK_OBJECT_TYPE_IMAGE_VIEW; | MessageID = 0x9c7248ee | vkCmdDrawIndexed: Descriptor set VkDescriptorSet 0x908683000000001d[] Sampler (VkSampler 0x9fde6b0000000014[]) is set to use VK_FILTER_LINEAR with compareEnable is set to VK_FALSE, but image view's (VkImageView 0x2cfba2000000001c[]) format (VK_FORMAT_R8G8B8A8_UNORM) does not contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT in its format features. The Vulkan spec states: If a VkSampler created with magFilter or minFilter equal to VK_FILTER_LINEAR and compareEnable equal to VK_FALSE is used to sample a VkImageView as a result of this command, then the image view's format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT (https://vulkan.lunarg.com/doc/view/1.3.236.0/windows/1.3-extensions/vkspec.html#VUID-vkCmdDrawIndexed-magFilter-04553)

I've tried reinstalling Vulkan and I've updated my graphics drivers.

It seems like the only problem is with validation, since the program seems to work properly. Should I change the Vulkan validation layer?

Remove Docking ?

Hi i would like to make an same thing like you did with Forest launcher. But how can i disable docking and make only main window and turn off docking please?

Regards

when I press F5 then window show and in console always show this info and is unlimit print(like while(true) print(info)) and window is black.

[vulkan] Debug report from ObjectType: 5
Message: Validation Error: [ VUID-vkAcquireNextImageKHR-semaphore-01779 ] Object 0: handle = 0xdcc8fd0000000012, type = VK_OBJECT_TYPE_SEMAPHORE; | MessageID = 0x5717e75b | vkAcquireNextImageKHR(): Semaphore must not have any pending operations. The Vulkan spec states: If semaphore is not VK_NULL_HANDLE it must not have any uncompleted signal or wait operations pending (https://vulkan.lunarg.com/doc/view/1.3.283.0/windows/1.3-extensions/vkspec.html#VUID-vkAcquireNextImageKHR-semaphore-01779)
62534edd9859eab9ed25facc9c51e93
f1e6db51a3d4c9b363fb3eeaf446af6

Walnut::Image::SetData causes unresolved memory allocation

After using the Diagnostic Tool of Microsoft Visual Studio it seems the memory allocation happen everytime when
m_FinalImage->SetData(m_Renderer.GetImageDataBuffer()->Get<uint8_t*>());
get called and the size of the allocation keep increasing everytime, I don't know if the issue is in my code side or the Walnut::Image library itself. I hope the issue get fixed.

UPDATE:
I noticed that it happens when the window resized or minimized.

Source code
Screenshot (1)
Screenshot (2)
Screenshot (3)

How can I add fullscreen to Walnut

No way of adding fullscreen appears to work for me with walnut, is there a way to do so when the app starts? If so how would I add this so my app will start fullscreened.

Changing Menubar height cuts off the menubar & menus only clickable for 50% of half the y-size

tricky title buuut:
an issue without modifying the code is that all menubar entries like "File" and "Help" dont react on left clicking when you are at the lower half of the field.

I also tried shifting hte menubar entries on the Y axis down to be actually below the window title, cause I want mine to be beneath the title. You can test that in this line: https://github.com/StudioCherno/Walnut/blob/7e478a3828059eafabc31cb0559a31d1d83dad12/Walnut/Platform/GUI/Walnut/ApplicationGUI.cpp#L734C45-L734C45

just change it to:

ImGui::SetCursorPos(ImVec2(logoHorizontalOffset, 20.0f + titlebarVerticalOffset));

Reandme image link broken

https://camo.githubusercontent.com/c6ed7ddba4b9397529876d6d11dd3a6d8d0904cd8bd5edab4612ca6c3418e32d/68747470733a2f2f68617a656c656e67696e652e636f6d2f696d616765732f466f726573744c61756e6368657253637265656e73686f742e6a7067
leads to not found

Stop the false claims

This post is in response to the pathetic & disrespectful lies which use falsely use the word "Engineering", which makes absolutely no sense (and is disrespectful to real Engineering).
Software devs are stupid wannabe kiddos who keep making huge fake claims.
Engineering has nothing to do with sitting behind a keyboard and writing code.

@TheCherno Yann, Engineering is a real subject. Engineering means designing and building real mechanical systems, like vehicular engines and turbojets.
Software devs are claiming the most ridiculous of false claims these days. Software & game dev is easy and for kids, and has absolutely nothing to do with a real and serious complex subject like engineering. Stop being disrespectful to Engineering. And stop these stupid lies.

Mechanical Engineering is the only Engineering. Period.

Cannot open input file '\Lib\vulkan-1.lib'

Hi!

When trying to build the default example app I get the following errors
cannot open input file '\Lib\vulkan-1.lib'\ And cannot open file 'C:\Users\...\Documents\GitHub\...\Walnut\Walnut\bin\Debug-windows-x86_64\Walnut\Walnut.lib'

I'm hoping someone can help me out with this.
Thank you very much!

No license

It would be nice if you could include a LICENSE.

Walnut::Input to support key callbacks

Existing Input.cpp class only supports checking of if key is pressed down.

This is a proposal to add support for callbacks via:
https://www.glfw.org/docs/3.3/input_guide.html#input_key

Additions to the Input class:

// this method will set a private KeysCallback() function by glfwSetKeyCallback(window, KeysCallback);
static void InitKeysCallBack();

// this method adds func to a unordered_map using KeyCode as the key
static void SetKeyCallback(KeyCode keycode, std::function<void()> func);

// this function gets called by GLFW when a key is pressed, and on keyboard's repeat timing
// we will lookup the unordered_map to see if a std::function is set in the map, if it is, invoke it.
void KeysCallback(GLFWwindow* window, int key, int scancode, int action, int mods);

// this is the undorderd_map that stored custom key callbacks.
static std::unordered_map<int, std::function<void()>> KEY_CALLBACK_MAP;

Dock Window Screen Markers move around with the window being dragged

Reproducible Steps:

  1. Run WalnutApp Example
  2. Click and drag on a floating window
  3. Drag that window over one of the dockspace markers
  4. The marker that's drawn on top of the dragged window will now lag and move in the direction that the window is being dragged while continuously snapping back to their normal place

From a user perspective, I don't necessarily think it should be drawn on top although I understand the choice to do that. I believe they should maybe be half transparent as it is a bit jarring.

Here's a demonstration of the glitch:

https://youtu.be/ZHxc23C_cNU

Image Resize makes images invisible

I am loving Walnut - create application framework.

I've run into an issue where when i try to resize an image, using the built-in method, my images are invisible - but rendered.I know that are rendered as my screen scales relative to the image as if it were there - but i see no image. Very odd.

This is the error:

[vulkan] Debug report from ObjectType: 6
Message: Validation Error: [ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] Object 0: handle = 0x2138b368f40, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x4dae5635 | vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x2138b368f40[] expects VkImage 0x3fbcd60000000028[] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_UNDEFINED.

I am using the resize method like so in the OnAttach() method.

m_Image->Resize(64, 64);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.