Add matrices

This commit is contained in:
abdelrahman committed 2026-10-25 18:58:16 +00:00
1 parent f7dfdd9666
commit 06059e197c
5 files changed
+162 -8

No files matched your search

+2 -2
View File
@@ -12,7 +12,7 @@ C_UNITY_SRCS = src/wapp/wapp.c \
src/window/window_src.c \ src/window/window_src.c \
src/gpu/gpu_c_src.c src/gpu/gpu_c_src.c
CXX_UNITY_SRCS = src/gpu/gpu_cc_src.cpp CXX_UNITY_SRCS = src/gpu/gpu_cc_src.cpp
CFLAGS = -g -c -DWP_DEBUG_ASSERT CFLAGS = -g -c -DWP_DEBUG_ASSERT -DCGLM_DEFINE_PRINTS
CXXFLAGS = -g -c -Wno-nullability-completeness -DWP_DEBUG_ASSERT CXXFLAGS = -g -c -Wno-nullability-completeness -DWP_DEBUG_ASSERT
LDFLAGS = -g -DWP_DEBUG_ASSERT LDFLAGS = -g -DWP_DEBUG_ASSERT
LDLIBS = -lm LDLIBS = -lm
@@ -36,7 +36,7 @@ ifeq ($(GPU_BKND), Vulkan)
C_SRCS += vendor/vulkan/include/volk/volk.c C_SRCS += vendor/vulkan/include/volk/volk.c
CFLAGS += -DUSE_VULKAN_RENDER_BACKEND -DVK_NO_PROTOTYPES -Ivendor/vulkan/include CFLAGS += -DUSE_VULKAN_RENDER_BACKEND -DVK_NO_PROTOTYPES -Ivendor/vulkan/include
CXXFLAGS += -DUSE_VULKAN_RENDER_BACKEND -DVK_NO_PROTOTYPES -Ivendor/vulkan/include CXXFLAGS += -DUSE_VULKAN_RENDER_BACKEND -DVK_NO_PROTOTYPES -Ivendor/vulkan/include
LDFLAGS += -Lvendor/vulkan/lib -Wl,-rpath,vendor/vulkan/lib LDFLAGS += -Lvendor/vulkan/lib -Wl,-rpath,$(shell realpath vendor/vulkan/lib)
endif endif
COBJS = $(patsubst %.c, $(COBJDIR)/%.o, $(C_SRCS)) COBJS = $(patsubst %.c, $(COBJDIR)/%.o, $(C_SRCS))
+129 -4
View File
@@ -5,6 +5,7 @@
#include "window/window_inc.h" #include "window/window_inc.h"
#include "gpu/gpu_inc.h" #include "gpu/gpu_inc.h"
#include "wapp/wapp.h" #include "wapp/wapp.h"
#define CGLM_FORCE_DEPTH_ZERO_TO_ONE
#include "cglm/struct.h" #include "cglm/struct.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -22,22 +23,53 @@ typedef struct Vertex {
} Vertex; } Vertex;
typedef Vertex *VertexArray; typedef Vertex *VertexArray;
typedef struct ShaderData {
mat4s mvp;
} ShaderData;
typedef struct Camera {
vec3s position;
vec3s target;
vec3s up;
} Camera;
typedef struct Projection {
f32 fov_deg;
f32 aspect;
f32 near;
f32 far;
} Projection;
wp_intern const VertexArray vertices = wpArray( wp_intern const VertexArray vertices = wpArray(
Vertex, Vertex,
(Vertex){ (Vertex){
.position = (vec3s){ .x = 0.0f, .y = -0.5f, .z = 0.0f }, .position = (vec3s){ .x = 0.0f, .y = 0.5f, .z = 0.0f },
.color = (vec3s){ .r = 1.0f, .g = 0.0f, .b = 0.0f }, .color = (vec3s){ .r = 1.0f, .g = 0.0f, .b = 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 = 0.0f, .g = 1.0f, .b = 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 = 0.0f, .b = 1.0f }, .color = (vec3s){ .r = 0.0f, .g = 0.0f, .b = 1.0f },
},
(Vertex){
.position = (vec3s){ .x = 0.25f, .y = 0.5f, .z = -1.0f },
.color = (vec3s){ .r = 1.00f, .g = 0.5f, .b = 0.0f },
},
(Vertex){
.position = (vec3s){ .x = -0.25f, .y = -0.5f, .z = -1.0f },
.color = (vec3s){ .r = 1.00f, .g = 0.5f, .b = 0.0f },
},
(Vertex){
.position = (vec3s){ .x = 0.75f, .y = -0.5f, .z = -1.0f },
.color = (vec3s){ .r = 1.00f, .g = 0.5f, .b = 0.0f },
} }
); );
wp_intern mat4s modelViewProjection(mat4s model, mat4s view, mat4s proj);
i32 main(void) { i32 main(void) {
wpLogConfigure(NULL, NULL, WP_LOG_LEVEL_INFO); wpLogConfigure(NULL, NULL, WP_LOG_LEVEL_INFO);
@@ -138,7 +170,40 @@ i32 main(void) {
wpFileClose(spirv); wpFileClose(spirv);
GpuPipelineLayoutCreateRequest graphics_pipeline_layout_request = { .device = device }; GpuBufferCreateRequest shader_data_req = { .device = device,
.size = sizeof(ShaderData),
.usage = GPU_BUFFER_USAGE_STORAGE_BUFFER |
GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS };
GpuBuffer shader_data = gpuCreateBuffer(&arena, shader_data_req);
Camera camera = {
.position = { .x = 0.0f, .y = 0.0f, .z = 2.0f },
.target = { 0 },
.up = { 0.0f, 1.0f, 0.0f },
};
Projection projection = {
.fov_deg = 45.0f,
.aspect = (f32)window.size.x / (f32)window.size.y,
.near = 0.1f,
.far = 100.0f,
};
ShaderData data = {
.mvp = modelViewProjection(
glms_mat4_identity(),
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, sizeof(ShaderData));
GpuPushConstantRange push_constants = {
.stages = GPU_SHADER_STAGE_VERTEX,
.size = sizeof(shader_data.gpu_device_address),
};
GpuPipelineLayoutCreateRequest graphics_pipeline_layout_request = {
.device = device,
.push_constants = wpArray(GpuPushConstantRange, push_constants),
};
GpuPipelineLayout *layout = gpuCreatePipelineLayout(&arena, &temp_arena, graphics_pipeline_layout_request); GpuPipelineLayout *layout = gpuCreatePipelineLayout(&arena, &temp_arena, graphics_pipeline_layout_request);
GpuVertexInputBinding vert_binding = { GpuVertexInputBinding vert_binding = {
@@ -316,6 +381,15 @@ i32 main(void) {
}; };
gpuCmdBeginRendering(&temp_arena, render_request); gpuCmdBeginRendering(&temp_arena, render_request);
GpuCmdPushConstantsRequest push_const_req = {
.command_buffer = buffers[0],
.layout = layout,
.stage_flags = GPU_SHADER_STAGE_VERTEX,
.values = &shader_data.gpu_device_address,
.total_size_in_bytes = sizeof(shader_data.gpu_device_address),
};
gpuCmdPushConstants(push_const_req);
GpuViewportArray viewports = wpArray( GpuViewportArray viewports = wpArray(
GpuViewport, GpuViewport,
(GpuViewport){ .x = 0, .y = 0, (GpuViewport){ .x = 0, .y = 0,
@@ -390,6 +464,45 @@ i32 main(void) {
.swapchain_infos = wpArray(GpuSwpachainPresentInfo, present_info), .swapchain_infos = wpArray(GpuSwpachainPresentInfo, present_info),
}; };
gpuPresentSwapchains(&temp_arena, present_request); gpuPresentSwapchains(&temp_arena, present_request);
if (windowIsKeyPressed(KEYBOARD_KEY_UP)) {
camera.position.z -= 0.01f;
data.mvp = modelViewProjection(
glms_mat4_identity(),
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, sizeof(ShaderData));
}
if (windowIsKeyPressed(KEYBOARD_KEY_DOWN)) {
camera.position.z += 0.01f;
data.mvp = modelViewProjection(
glms_mat4_identity(),
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, sizeof(ShaderData));
}
if (windowIsKeyPressed(KEYBOARD_KEY_RIGHT)) {
camera.position.x += 0.01f;
camera.target.x += 0.01f;
data.mvp = modelViewProjection(
glms_mat4_identity(),
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, sizeof(ShaderData));
}
if (windowIsKeyPressed(KEYBOARD_KEY_LEFT)) {
camera.position.x -= 0.01f;
camera.target.x -= 0.01f;
data.mvp = modelViewProjection(
glms_mat4_identity(),
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, sizeof(ShaderData));
}
} }
gpuDeviceWaitIdle(device); gpuDeviceWaitIdle(device);
@@ -402,6 +515,7 @@ i32 main(void) {
gpuDestroyPipeline(pipelines[i]); gpuDestroyPipeline(pipelines[i]);
} }
gpuDestroyPipelineLayout(layout); gpuDestroyPipelineLayout(layout);
gpuDestroyBuffer(&shader_data);
gpuDestroyShader(shader); gpuDestroyShader(shader);
gpuDestroyCommandPool(pool); gpuDestroyCommandPool(pool);
gpuDestroyBuffer(&vertex_buffer); gpuDestroyBuffer(&vertex_buffer);
@@ -420,3 +534,14 @@ i32 main(void) {
return ERROR_NONE; return ERROR_NONE;
} }
wp_intern mat4s modelViewProjection(mat4s model, mat4s view, mat4s proj) {
// Matrix to flip the Y-axis since in Vulkan Y points down
mat4s clip = {
.raw = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f }
};
return glms_mat4_mul(clip, glms_mat4_mul(proj, glms_mat4_mul(view, model)));
}
+6 -2
View File
@@ -3,16 +3,20 @@ struct VSInput {
float3 Color; float3 Color;
}; };
struct ShaderData {
float4x4 mvp;
};
struct VertexOutput { struct VertexOutput {
float3 Color; float3 Color;
float4 sv_position : SV_Position; float4 sv_position : SV_Position;
}; };
[shader("vertex")] [shader("vertex")]
VertexOutput vertMain(VSInput input, uint vid : SV_VertexID) { VertexOutput vertMain(VSInput input, uniform ShaderData *data, uint vid : SV_VertexID) {
VertexOutput output; VertexOutput output;
output.Color = input.Color; output.Color = input.Color;
output.sv_position = float4(input.Pos, 1.0); output.sv_position = mul(data->mvp, float4(input.Pos, 1.0));
return output; return output;
} }
+17
View File
@@ -8,15 +8,18 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_error.h> #include <SDL3/SDL_error.h>
#include <SDL3/SDL_init.h> #include <SDL3/SDL_init.h>
#include <SDL3/SDL_keyboard.h>
#include <SDL3/SDL_keycode.h> #include <SDL3/SDL_keycode.h>
#include <SDL3/SDL_video.h> #include <SDL3/SDL_video.h>
#include <SDL3/SDL_vulkan.h> #include <SDL3/SDL_vulkan.h>
#include <stdbool.h>
wp_intern WpLogger logger = wpLogMakeLogger(wpStr8LitRo("SDL Window")); wp_intern WpLogger logger = wpLogMakeLogger(wpStr8LitRo("SDL Window"));
wp_intern b8 loadGpuLibrary(void); wp_intern b8 loadGpuLibrary(void);
wp_intern void unloadGpuLibrary(void); wp_intern void unloadGpuLibrary(void);
wp_intern SDL_WindowFlags getGpuWindowFlags(void); wp_intern SDL_WindowFlags getGpuWindowFlags(void);
wp_intern SDL_Scancode sdlScancodeFromKeyboardKey(KeyboardKey key);
b8 windowBackendInit(void) { b8 windowBackendInit(void) {
return SDL_Init(SDL_INIT_VIDEO) && loadGpuLibrary(); return SDL_Init(SDL_INIT_VIDEO) && loadGpuLibrary();
@@ -73,6 +76,11 @@ void windowBackendQuit(void) {
SDL_Quit(); SDL_Quit();
} }
b8 windowIsKeyPressed(KeyboardKey key) {
const bool *state = SDL_GetKeyboardState(NULL);
return state[sdlScancodeFromKeyboardKey(key)];
}
wp_intern b8 loadGpuLibrary(void) { wp_intern b8 loadGpuLibrary(void) {
Config config = configGet(); Config config = configGet();
@@ -109,3 +117,12 @@ wp_intern SDL_WindowFlags getGpuWindowFlags(void) {
} }
} }
} }
wp_intern SDL_Keycode sdlScancodeFromKeyboardKey(KeyboardKey key) {
switch (key) {
case KEYBOARD_KEY_UP: return SDL_SCANCODE_UP;
case KEYBOARD_KEY_DOWN: return SDL_SCANCODE_DOWN;
case KEYBOARD_KEY_RIGHT: return SDL_SCANCODE_RIGHT;
case KEYBOARD_KEY_LEFT: return SDL_SCANCODE_LEFT;
}
}
+8
View File
@@ -24,11 +24,19 @@ typedef struct Window {
f32 display_scale; f32 display_scale;
} Window; } Window;
typedef enum KeyboardKey {
KEYBOARD_KEY_UP,
KEYBOARD_KEY_DOWN,
KEYBOARD_KEY_RIGHT,
KEYBOARD_KEY_LEFT,
} KeyboardKey;
wp_extern b8 windowBackendInit(void); wp_extern b8 windowBackendInit(void);
wp_extern Window windowCreate(WpStr8 title, ivec2s size); wp_extern Window windowCreate(WpStr8 title, ivec2s size);
wp_extern b8 windowShouldClose(const Window *window); wp_extern b8 windowShouldClose(const Window *window);
wp_extern void windowDestroy(Window *window); wp_extern void windowDestroy(Window *window);
wp_extern void windowBackendQuit(void); wp_extern void windowBackendQuit(void);
wp_extern b8 windowIsKeyPressed(KeyboardKey key);
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE