Render texture and fix camera target

This commit is contained in:
abdelrahman committed 2026-11-01 17:38:22 +00:00
1 parent 9536dbc550
commit 136853328a
4 files changed
+87 -71

No files matched your search

+1 -1
View File
@@ -355,8 +355,8 @@ typedef struct GpuBufferCreateRequest {
} GpuBufferCreateRequest; } GpuBufferCreateRequest;
typedef struct GpuBufferFlushRequest { typedef struct GpuBufferFlushRequest {
GpuDevice *device;
GpuBuffer buffer; GpuBuffer buffer;
GpuDevice *device;
u64 offset; u64 offset;
u64 size; u64 size;
} GpuBufferFlushRequest; } GpuBufferFlushRequest;
+4
View File
@@ -321,6 +321,8 @@ wp_intern u32 calcMaxMipLevelsForSize(ivec3s size);
GpuInstance *gpuInit(const WpAllocator *allocator, GpuInitRequest request) { GpuInstance *gpuInit(const WpAllocator *allocator, GpuInitRequest request) {
assertWithLogger(volkInitialize() == VK_SUCCESS, &logger, "Failed to initialise volk"); assertWithLogger(volkInitialize() == VK_SUCCESS, &logger, "Failed to initialise volk");
stbi_set_flip_vertically_on_load(true);
VpProfileProperties profile = { VpProfileProperties profile = {
.profileName = VP_TEST_WINDOW_RENDERER_NAME, .profileName = VP_TEST_WINDOW_RENDERER_NAME,
.specVersion = VP_TEST_WINDOW_RENDERER_SPEC_VERSION, .specVersion = VP_TEST_WINDOW_RENDERER_SPEC_VERSION,
@@ -859,6 +861,8 @@ GpuSampler *gpuCreateSampler(const WpAllocator *allocator, GpuSamplerCreateReque
wpLogDebug(&logger, wpStr8Lit("Created Vulkan sampler")); wpLogDebug(&logger, wpStr8Lit("Created Vulkan sampler"));
output->device = request.device;
return output; return output;
} }
+73 -66
View File
@@ -20,7 +20,7 @@ enum Errors {
typedef struct Vertex { typedef struct Vertex {
vec3s position; vec3s position;
vec3s color; vec3s color;
// vec2s uv; vec2s uv;
} Vertex; } Vertex;
typedef Vertex *VertexArray; typedef Vertex *VertexArray;
@@ -33,7 +33,6 @@ typedef ShaderData *ShaderDataArray;
typedef struct Camera { typedef struct Camera {
vec3s position; vec3s position;
vec3s target;
vec3s up; vec3s up;
} Camera; } Camera;
@@ -48,19 +47,23 @@ wp_intern const VertexArray vertices = wpArray(
Vertex, Vertex,
(Vertex){ (Vertex){
.position = (vec3s){ .x = -0.5f, .y = -0.5f, .z = 0.0f }, .position = (vec3s){ .x = -0.5f, .y = -0.5f, .z = 0.0f },
.color = (vec3s){ .r = 1.0f, .g = 0.0f, .b = 0.0f }, .color = (vec3s){ .r = 1.0f, .g = 1.0f, .b = 1.0f },
.uv = (vec2s){ .x = 0.0f, .y = 0.0f },
}, },
(Vertex){ (Vertex){
.position = (vec3s){ .x = -0.5f, .y = 0.5f, .z = 0.0f }, .position = (vec3s){ .x = -0.5f, .y = 0.5f, .z = 0.0f },
.color = (vec3s){ .r = 0.0f, .g = 1.0f, .b = 0.0f }, .color = (vec3s){ .r = 1.0f, .g = 1.0f, .b = 1.0f },
.uv = (vec2s){ .x = 0.0f, .y = 1.0f },
}, },
(Vertex){ (Vertex){
.position = (vec3s){ .x = 0.5f, .y = -0.5f, .z = 0.0f }, .position = (vec3s){ .x = 0.5f, .y = -0.5f, .z = 0.0f },
.color = (vec3s){ .r = 0.0f, .g = 0.0f, .b = 1.0f }, .color = (vec3s){ .r = 1.0f, .g = 1.0f, .b = 1.0f },
.uv = (vec2s){ .x = 1.0f, .y = 0.0f },
}, },
(Vertex){ (Vertex){
.position = (vec3s){ .x = 0.5f, .y = 0.5f, .z = 0.0f }, .position = (vec3s){ .x = 0.5f, .y = 0.5f, .z = 0.0f },
.color = (vec3s){ .r = 1.0f, .g = 1.0f, .b = 1.0f }, .color = (vec3s){ .r = 1.0f, .g = 1.0f, .b = 1.0f },
.uv = (vec2s){ .x = 1.0f, .y = 1.0f },
}, },
); );
wp_intern const WpU16Array indices = wpArray( wp_intern const WpU16Array indices = wpArray(
@@ -69,6 +72,7 @@ wp_intern const WpU16Array indices = wpArray(
1, 3, 2, 1, 3, 2,
); );
wp_intern mat4s calculateModelViewProjection(vec3s translation, Camera camera, Projection projection);
wp_intern mat4s modelViewProjection(mat4s model, mat4s view, mat4s proj); wp_intern mat4s modelViewProjection(mat4s model, mat4s view, mat4s proj);
i32 main(void) { i32 main(void) {
@@ -171,6 +175,17 @@ i32 main(void) {
}; };
GpuImage *texture = gpuLoadImageFromFile(&arena, &temp_arena, load_img_req); GpuImage *texture = gpuLoadImageFromFile(&arena, &temp_arena, load_img_req);
GpuSamplerCreateRequest sampler_req = {
.device = device,
.min_filter = GPU_FILTER_LINEAR,
.mag_filter = GPU_FILTER_LINEAR,
.address_mode_u = GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.address_mode_v = GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.address_mode_w = GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.mipmap_mode = GPU_SAMPLER_MIPMAP_MODE_LINEAR,
};
GpuSampler *sampler = gpuCreateSampler(&arena, sampler_req);
GpuShaderCreateRequest shader_request = { GpuShaderCreateRequest shader_request = {
.device = device, .device = device,
.code = (void *)code, .code = (void *)code,
@@ -194,7 +209,6 @@ i32 main(void) {
Camera camera = { Camera camera = {
.position = { .x = 0.0f, .y = 0.0f, .z = 2.0f }, .position = { .x = 0.0f, .y = 0.0f, .z = 2.0f },
.target = { 0 },
.up = { 0.0f, 1.0f, 0.0f }, .up = { 0.0f, 1.0f, 0.0f },
}; };
Projection projection = { Projection projection = {
@@ -207,18 +221,10 @@ i32 main(void) {
ShaderDataArray data = wpArray( ShaderDataArray data = wpArray(
ShaderData, ShaderData,
(ShaderData){ (ShaderData){
.mvp = modelViewProjection( .mvp = calculateModelViewProjection(translations[0], camera, projection),
glms_translate(glms_mat4_identity(), translations[0]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
),
}, },
(ShaderData){ (ShaderData){
.mvp = modelViewProjection( .mvp = calculateModelViewProjection(translations[1], camera, projection),
glms_translate(glms_mat4_identity(), translations[1]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
),
}, },
); );
memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data)); memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data));
@@ -226,7 +232,8 @@ i32 main(void) {
GpuDescriptorPoolSizeArray pool_sizes = wpArray( GpuDescriptorPoolSizeArray pool_sizes = wpArray(
GpuDescriptorPoolSize, GpuDescriptorPoolSize,
(GpuDescriptorPoolSize){ .type = GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER, .count = 1 } (GpuDescriptorPoolSize){ .type = GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER, .count = 1 },
(GpuDescriptorPoolSize){ .type = GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .count = 1 }
); );
GpuDescriptorPoolCreateRequest desc_pool_req = { GpuDescriptorPoolCreateRequest desc_pool_req = {
.descriptor_pool_sizes = pool_sizes, .descriptor_pool_sizes = pool_sizes,
@@ -242,6 +249,12 @@ i32 main(void) {
.type = GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER, .type = GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptor_count = 1, .descriptor_count = 1,
.stages = GPU_SHADER_STAGE_VERTEX, .stages = GPU_SHADER_STAGE_VERTEX,
},
(GpuDescriptorSetBinding){
.binding = 1,
.type = GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptor_count = 1,
.stages = GPU_SHADER_STAGE_FRAGMENT,
} }
); );
GpuDescriptorSetLayoutCreateRequest desc_set_layout_req = { GpuDescriptorSetLayoutCreateRequest desc_set_layout_req = {
@@ -259,14 +272,28 @@ i32 main(void) {
GpuDescriptorSetWriteInfo shader_data_write_info = { GpuDescriptorSetWriteInfo shader_data_write_info = {
.set = descriptor_sets[0], .set = descriptor_sets[0],
.descriptor_type = GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptor_type = GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.dst_binding = 0,
.buffer_infos = wpArray( .buffer_infos = wpArray(
GpuDescriptorBufferInfo, GpuDescriptorBufferInfo,
(GpuDescriptorBufferInfo){ .buffer = &shader_data }, (GpuDescriptorBufferInfo){ .buffer = &shader_data },
), ),
}; };
GpuDescriptorSetWriteInfo texture_write_info = {
.set = descriptor_sets[0],
.descriptor_type = GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.dst_binding = 1,
.image_infos = wpArray(
GpuDescriptorImageInfo,
(GpuDescriptorImageInfo){
.image = texture,
.image_layout = GPU_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
.sampler = sampler,
}
),
};
GpuDescriptorSetWriteRequest desc_set_req = { GpuDescriptorSetWriteRequest desc_set_req = {
.device = device, .device = device,
.write_infos = wpArray(GpuDescriptorSetWriteInfo, shader_data_write_info), .write_infos = wpArray(GpuDescriptorSetWriteInfo, shader_data_write_info, texture_write_info),
}; };
gpuWriteDescriptorSets(&temp_arena, desc_set_req); gpuWriteDescriptorSets(&temp_arena, desc_set_req);
@@ -295,12 +322,12 @@ i32 main(void) {
.offset = offsetof(Vertex, color), .offset = offsetof(Vertex, color),
.format = GPU_FORMAT_R32G32B32_SFLOAT, .format = GPU_FORMAT_R32G32B32_SFLOAT,
}, },
// (GpuVertexInputAttribute){ (GpuVertexInputAttribute){
// .location = 2, .location = 2,
// .binding = 0, .binding = 0,
// .offset = offsetof(Vertex, uv), .offset = offsetof(Vertex, uv),
// .format = GPU_FORMAT_R32G32_SFLOAT, .format = GPU_FORMAT_R32G32_SFLOAT,
// }, },
); );
GpuPipelineVertexInputStateInfo vert_info = { GpuPipelineVertexInputStateInfo vert_info = {
.bindings = wpArray(GpuVertexInputBinding, vert_binding), .bindings = wpArray(GpuVertexInputBinding, vert_binding),
@@ -376,63 +403,29 @@ i32 main(void) {
if (windowIsKeyPressed(KEYBOARD_KEY_UP)) { if (windowIsKeyPressed(KEYBOARD_KEY_UP)) {
camera.position.z -= 0.01f; camera.position.z -= 0.01f;
data[0].mvp = modelViewProjection( data[0].mvp = calculateModelViewProjection(translations[0], camera, projection);
glms_translate(glms_mat4_identity(), translations[0]), data[1].mvp = calculateModelViewProjection(translations[1], camera, projection);
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
data[1].mvp = modelViewProjection(
glms_translate(glms_mat4_identity(), translations[1]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data)); memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data));
gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data }); gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data });
} }
if (windowIsKeyPressed(KEYBOARD_KEY_DOWN)) { if (windowIsKeyPressed(KEYBOARD_KEY_DOWN)) {
camera.position.z += 0.01f; camera.position.z += 0.01f;
data[0].mvp = modelViewProjection( data[0].mvp = calculateModelViewProjection(translations[0], camera, projection);
glms_translate(glms_mat4_identity(), translations[0]), data[1].mvp = calculateModelViewProjection(translations[1], camera, projection);
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
data[1].mvp = modelViewProjection(
glms_translate(glms_mat4_identity(), translations[1]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data)); memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data));
gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data }); gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data });
} }
if (windowIsKeyPressed(KEYBOARD_KEY_RIGHT)) { if (windowIsKeyPressed(KEYBOARD_KEY_RIGHT)) {
camera.position.x += 0.01f; camera.position.x += 0.01f;
camera.target.x += 0.01f; data[0].mvp = calculateModelViewProjection(translations[0], camera, projection);
data[0].mvp = modelViewProjection( data[1].mvp = calculateModelViewProjection(translations[1], camera, projection);
glms_translate(glms_mat4_identity(), translations[0]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
data[1].mvp = modelViewProjection(
glms_translate(glms_mat4_identity(), translations[1]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data)); memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data));
gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data }); gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data });
} }
if (windowIsKeyPressed(KEYBOARD_KEY_LEFT)) { if (windowIsKeyPressed(KEYBOARD_KEY_LEFT)) {
camera.position.x -= 0.01f; camera.position.x -= 0.01f;
camera.target.x -= 0.01f; data[0].mvp = calculateModelViewProjection(translations[0], camera, projection);
data[0].mvp = modelViewProjection( data[1].mvp = calculateModelViewProjection(translations[1], camera, projection);
glms_translate(glms_mat4_identity(), translations[0]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
data[1].mvp = modelViewProjection(
glms_translate(glms_mat4_identity(), translations[1]),
glms_lookat(camera.position, camera.target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data)); memcpy(shader_data.cpu_mapping, data, wpArrayItemSize(data) * wpArrayCount(data));
gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data }); gpuFlushBuffer((GpuBufferFlushRequest){ .device = device, .buffer = shader_data });
} }
@@ -626,6 +619,7 @@ i32 main(void) {
gpuDestroyDescriptorPool(desc_pool); gpuDestroyDescriptorPool(desc_pool);
gpuDestroyBuffer(&shader_data); gpuDestroyBuffer(&shader_data);
gpuDestroyShader(shader); gpuDestroyShader(shader);
gpuDestroySampler(sampler);
gpuDestroyImage(texture); gpuDestroyImage(texture);
gpuDestroyCommandPool(pool); gpuDestroyCommandPool(pool);
gpuDestroyBuffer(&vert_idx_buffer); gpuDestroyBuffer(&vert_idx_buffer);
@@ -645,6 +639,19 @@ i32 main(void) {
return ERROR_NONE; return ERROR_NONE;
} }
wp_intern mat4s calculateModelViewProjection(vec3s translation, Camera camera, Projection projection) {
vec3s target = {
.x = camera.position.x,
.y = camera.position.y,
.z = camera.position.z - 2.0f
};
return modelViewProjection(
glms_translate(glms_mat4_identity(), translation),
glms_lookat(camera.position, target, camera.up),
glms_perspective(glm_rad(projection.fov_deg), projection.aspect, projection.near, projection.far)
);
}
wp_intern mat4s modelViewProjection(mat4s model, mat4s view, mat4s proj) { wp_intern mat4s modelViewProjection(mat4s model, mat4s view, mat4s proj) {
// Matrix to flip the Y-axis since in Vulkan Y points down // Matrix to flip the Y-axis since in Vulkan Y points down
mat4s clip = { mat4s clip = {
+9 -4
View File
@@ -1,7 +1,7 @@
struct VSInput { struct VSInput {
float3 Pos; float3 Pos;
float3 Color; float3 Color;
// float2 Uv; float2 Uv;
}; };
struct ShaderData { struct ShaderData {
@@ -9,20 +9,25 @@ struct ShaderData {
}; };
StructuredBuffer<ShaderData> data; StructuredBuffer<ShaderData> data;
Sampler2D texture;
struct VertexOutput { struct VertexOutput {
float3 Color;
float4 sv_position : SV_Position; float4 sv_position : SV_Position;
float3 Color;
float2 Uv;
}; };
[shader("vertex")] [shader("vertex")]
VertexOutput vertMain(VSInput input, uint idx: SV_InstanceID) { VertexOutput vertMain(VSInput input, uint idx: SV_InstanceID) {
VertexOutput output; VertexOutput output;
output.Color = input.Color;
output.sv_position = mul(data[idx].mvp, float4(input.Pos, 1.0)); output.sv_position = mul(data[idx].mvp, float4(input.Pos, 1.0));
output.Color = input.Color;
output.Uv = input.Uv;
return output; return output;
} }
[shader("fragment")] [shader("fragment")]
float4 fragMain(VertexOutput inVert) : SV_Target { float4 fragMain(VertexOutput inVert) : SV_Target {
return float4(inVert.Color, 1.0); float4 color = texture.Sample(inVert.Uv) * float4(inVert.Color, 1.0f);
return color;
} }