Problems setting font color

I am new using Vulkan, and i am trying to learn it looking tutorials and looking the vulkan examples that you upload.

One of them is the Overlaytext project. In this project they teach you how to implement an overlay text in Vulkan.

Using this code, i wanted to change it to add an additional uniform to be able to change the color of the fonts. The problem is that the uniform is not getting set to the color, is always an 0 vec4(0,0,0,0) and i am not getting any warning or error.

If you can please tell me what i am missing i will be really appreciated, i dont know anymore what to do, i am out of ideas.

The code that i added or changed of this project to add this uniform is the following:

Variables in class:

        glm::vec4	_color = glm::vec4(1.0f,1.0f,1.0f,1.0f);
	struct {
		VkBuffer buffer;
		VkDeviceMemory memory;
	} _colorBuffer;

Input binding and attributes of the pipeline(preparePipeline method):

	std::array<VkVertexInputBindingDescription, 3> vertexBindings = {};
	vertexBindings[0] = vertexInputBindingDescription(0, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
	vertexBindings[1] = vertexInputBindingDescription(1, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
	vertexBindings[2] = vertexInputBindingDescription(2, sizeof(glm::vec4), VK_VERTEX_INPUT_RATE_VERTEX);
	std::array<VkVertexInputAttributeDescription, 3> vertexAttribs = {};
	// Position
	vertexAttribs[0] = vertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32_SFLOAT, 0);
	// UV
	vertexAttribs[1] = vertexInputAttributeDescription(1, 1, VK_FORMAT_R32G32_SFLOAT, sizeof(glm::vec2));
	// Color
	vertexAttribs[2] = vertexInputAttributeDescription(2, 2, VK_FORMAT_R32G32B32A32_SFLOAT, 0);

Added starging buffer to copy the content of the color vec4 to a local device buffer(prepareResources method):

	struct {
		VkBuffer buffer;
		VkDeviceMemory memory;
	} colorStaging;

	ErrorCheck(renderer->CreateBuffer(
		VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
		sizeof(glm::vec4),
		&colorStaging.buffer,
		&colorStaging.memory,
		&_color));

	ErrorCheck(renderer->CreateBuffer(
		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
		sizeof(glm::vec4),
		&_colorBuffer.buffer,
		&_colorBuffer.memory));

Copy the staging buffer to the colorBuffer uniform(prepareResources, just after the setImageLayout method and before the end command buffer):

	VkBufferCopy copyRegion = {};

	copyRegion.size = sizeof(glm::vec4);
	vkCmdCopyBuffer(
		copyCmd,
		colorStaging.buffer,
		_colorBuffer.buffer,
		1,
		&copyRegion);

Clean up staging buffer(between stagingBuffer.destroy() and vkFreeCommandBuffers(_device, _command_pool, 1, &copyCmd); in the prepareResources method):

	vkDestroyBuffer(renderer->GetVulkanDevice(), colorStaging.buffer, nullptr);
	vkFreeMemory(renderer->GetVulkanDevice(), colorStaging.memory, nullptr);

Added the new binding vertex to the update command buffers(update command buffers method, just next to the other bindings):

		vkCmdBindVertexBuffers(_commandBuffers[i], 2, 1, &_colorBuffer.buffer, &offsets);

Vertex shader:

#version 450 core

layout (location = 0) in vec2 inPos;
layout (location = 1) in vec2 inUV;
layout (location = 2) in vec4 color;


layout (location = 0) out vec2 outUV;
layout (location = 1) out vec4 outColor;

out gl_PerVertex 
{
    vec4 gl_Position;   
};

void main(void)
{
	gl_Position = vec4(inPos, 0.0, 1.0);
	outUV = inUV;
	outColor = color;
}

Fragment shader:

#version 450 core

layout (location = 0) in vec2 inUV;
layout (location = 1) in vec4 inColor;

layout (binding = 0) uniform sampler2D samplerFont;

layout (location = 0) out vec4 outFragColor;

void main(void)
{
	float color = texture(samplerFont, inUV).r;
	
	outFragColor = inColor*color;
}

I recompiled both shaders.

If i didnt add something will mean that i didnt change it.

Thank you for attention.

i wanted to change it to add an additional uniform to be able to change the color of the fonts.

And yet, you did not add a uniform. You added a vertex shader input. It’s not a uniform, as shown by the fact that you declared the variable with in and not uniform.

You then allocate a buffer that is only one vec4 in size. But you told OpenGL that it would contain an array of vec4s, since that’s how vertex shader inputs work.

Uniforms of this nature are passed through uniform blocks, either those backed by buffers (through descriptor sets) or backed by push constant memory. I’d suggest push constants.

[QUOTE=Alfonse Reinheart;42203]And yet, you did not add a uniform. You added a vertex shader input. It’s not a uniform, as shown by the fact that you declared the variable with in and not uniform.

You then allocate a buffer that is only one vec4 in size. But you told OpenGL that it would contain an array of vec4s, since that’s how vertex shader inputs work.

Uniforms of this nature are passed through uniform blocks, either those backed by buffers (through descriptor sets) or backed by push constant memory. I’d suggest push constants.[/QUOTE]

Oh god, you are right. I dont know what i was thinking D:. Ill change it for a uniform, thank you for your reply.

[QUOTE=Alfonse Reinheart;42203]And yet, you did not add a uniform. You added a vertex shader input. It’s not a uniform, as shown by the fact that you declared the variable with in and not uniform.

You then allocate a buffer that is only one vec4 in size. But you told OpenGL that it would contain an array of vec4s, since that’s how vertex shader inputs work.

Uniforms of this nature are passed through uniform blocks, either those backed by buffers (through descriptor sets) or backed by push constant memory. I’d suggest push constants.[/QUOTE]

I solved my problem implementing a uniform buffer (i have to investigate how to push constant memory). But i have a question, why i cant do this:

layout (binding = 1) uniform vec4 color;

I have to do this:

layout (binding = 1) uniform vector4
{
vec4 color;
}inColor;

Because, aside of opaque types, Vulkan doesn’t allow you to specify uniforms outside of uniform blocks. That’s an OpenGL-only thing which exists for the sake of convenience. Vulkan isn’t about being convenient; it’s about being low-level.

So you have to do manually what OpenGL would have done internally.

Also, you don’t have to give interface blocks instance names. If you remove the inColor part of that, you can just use color to access it.