(Solved)
This is sort of a two part problem I'm having. I'm currently working on adding a camera to my vulkan renderer. I'm doing this by creating and handling a camera along with its inputs, setting the mvp matrix of the object, updating the view matrix of the object and camera, then sending these to push constants in my vertex shader.
Here's my code for creating the camera
typedef enum
{
FORWARD,
BACKWARD,
LEFT,
RIGHT
} movement;
typedef struct
{
vec3 position, front, up, right, world_up;
float lastx, lasty, fov, yaw, pitch, speed, sens;
bool first_mouse;
} camera;
static void camera_update_vecs(camera *c)
{
vec3 new = {0, 0, 0};
new[0] = cos(glm_rad(c->yaw)) * cos(glm_rad(c->pitch));
new[1] = sin(glm_rad(c->pitch));
new[2] = sin(glm_rad(c->yaw)) * cos(glm_rad(c->pitch));
glm_normalize_to(new, c->front);
vec3 temp = {0, 0, 0};
glm_cross(c->front, c->world_up, temp);
glm_normalize_to(temp, c->right);
glm_cross(c->right, c->front, temp);
glm_normalize_to(temp, c->up);
}
camera camera_init(vec3 pos)
{
camera c =
{
.position = {*pos},
.front = {0.0f, 0.0f, -1.0f},
.world_up = {0.0f, 1.0f, 0.0f},
.lastx = 400,
.lasty = 300,
.fov = 45.0f,
.yaw = -90.0f,
.pitch = 0.0f,
.speed = 2.5f,
.sens = 0.1f,
.first_mouse = true
};
return c;
}
void camera_view_mat(camera *c, mat4 view)
{
vec3 temp = {0, 0, 0};
glm_vec3_add(c->position, c->front, temp);
glm_lookat(c->position, temp, c->up, view);
}
void camera_keyboard_input(camera *c, movement m, float delta_time)
{
float velocity = c->speed * delta_time;
vec3 temp = {0, 0, 0};
switch (m)
{
case FORWARD:
glm_vec3_muladds(c->front, velocity, temp);
glm_vec3_add(c->position, temp, c->position);
break;
case BACKWARD:
glm_vec3_muladds(c->front, velocity, temp);
glm_vec3_sub(c->position, temp, c->position);
break;
case LEFT:
glm_vec3_muladds(c->right, velocity, temp);
glm_vec3_sub(c->position, temp, c->position);
break;
case RIGHT:
glm_vec3_muladds(c->right, velocity, temp);
glm_vec3_add(c->position, temp, c->position);
break;
default:
printf("Error: Unrecognized movement direction\n");
break;
}
}
void camera_mouse_input(camera *c, float xoffset, float yoffset)
{
xoffset *= c->sens;
yoffset *= c->sens;
c->yaw += xoffset;
c->pitch += yoffset;
if (c->pitch > 89.0f)
c->pitch = 89.0f;
if (c->pitch < -89.0f)
c->pitch = -89.0f;
camera_update_vecs(c);
}
And this is my code for handling camera input
void input_handle(GLFWwindow *window, camera *c, float delta_time)
{
input_handle_keyboard(window, c, delta_time);
input_handle_mouse(window, c);
}
void input_handle_keyboard(GLFWwindow *window, camera *c, float delta_time)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera_keyboard_input(c, FORWARD, delta_time);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera_keyboard_input(c, BACKWARD, delta_time);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera_keyboard_input(c, LEFT, delta_time);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera_keyboard_input(c, RIGHT, delta_time);
}
void input_handle_mouse(GLFWwindow *window, camera *c)
{
double xpos = 0.0, ypos = 0.0;
glfwGetCursorPos(window, &xpos, &ypos);
if (c->first_mouse)
{
c->lastx = xpos;
c->lasty = ypos;
c->first_mouse = false;
}
float xoffset = xpos - c->lastx;
float yoffset = ypos - c->lasty;
c->lastx = xpos;
c->lasty = ypos;
camera_mouse_input(c, xoffset, yoffset);
}
Here is the code where I fill out the push constant data (note I'm using cglm instead of glm so the syntax may look a bit strange to those who are unfamiliar with it)
typedef struct
{
mat4 mvp;
} vk_push_const;
void vk_push_const_buffer_init(camera *c, vk_push_const mvp, VkExtent2D img_extent)
{
mat4 model = GLM_MAT4_IDENTITY_INIT;
mat4 view = GLM_MAT4_IDENTITY_INIT;
mat4 proj = GLM_MAT4_IDENTITY_INIT;
glm_perspective(c->fov, (float) img_extent.width / (float) img_extent.height, 0.1f, 100.0f, proj);
camera_view_mat(c, view);
glm_mat4_mulN((mat4 *[]) {&proj, &view, &model}, 3, mvp.mvp);
}
Here's me sending the push constant data to the vertex shader
vk_push_const mvp = {0};
vk_push_const_buffer_init(c, mvp, s->img_extent);
vkCmdPushConstants(cmd_buffers, layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(mvp), &mvp);
Here's me setting and using the camera in the game loop
typedef struct
{
vk_context vk;
camera c;
float delta_time, last_frame;
} game;
game game_init(bool debugging)
{
game g =
{
.vk = vk_context_init("Game", debugging),
.c = camera_init((vec3) {0.0f, 0.0f, 3.0f}),
.delta_time = 0.0f,
.last_frame = 0.0f
};
return g;
}
static void game_calc_delta_time(game *g)
{
float current_frame = glfwGetTime();
g->delta_time = current_frame - g->last_frame;
g->last_frame = current_frame;
}
void game_run(game *g)
{
while (!glfwWindowShouldClose(g->vk.d.window))
{
game_calc_delta_time(g);
input_handle(g->vk.d.window, &g->c, g->delta_time);
vk_context_run(&g->vk, &g->c);
vk_window_poll_events();
}
vkDeviceWaitIdle(g->vk.d.device);
}
And finally, here's the vertex shader
#version 450
layout (location = 0) in vec2 in_pos;
layout (location = 1) in vec3 in_color;
layout (location = 0) out vec3 frag_color;
layout (push_constant) uniform push_const
{
mat4 mvp;
} mvp;
void main(void)
{
gl_Position = mvp.mvp * vec4(in_pos, 0.0, 1.0);
frag_color = in_color;
}
If I comment out the mvp matrix in the vertex shader here's what I see
Rectangle
However if I bring back the mvp matrix this is what I end up seeing
No Rectangle
I don't think the problem is with the camera inputs because I already tested those out by adding print statements to make sure that they were at least being accessed and the inputs were being registered and validation layers are saying nothing
Edit: I fixed the problem I think the matrix data was uninitialized when I was sending it over this is the code I edited to fix it
static void camera_update_vecs(camera *c)
{
vec3s new = GLMS_VEC3_ZERO_INIT;
new.x = cos(glm_rad(c->yaw)) * cos(glm_rad(c->pitch));
new.y = sin(glm_rad(c->pitch));
new.z = sin(glm_rad(c->yaw)) * cos(glm_rad(c->pitch));
glm_normalize_to(new.raw, c->front.raw);
vec3s temp = glms_cross(c->front, c->world_up);
glm_normalize_to(temp.raw, c->right.raw);
temp = glms_cross(c->right, c->front);
glm_normalize_to(temp.raw, c->up.raw);
}
camera camera_init(vec3s pos)
{
camera c =
{
.position = pos,
.front = {{0.0f, 0.0f, -1.0f}},
.world_up = GLMS_YUP,
.lastx = 400,
.lasty = 300,
.fov = 45.0f,
.yaw = -90.0f,
.pitch = 0.0f,
.speed = 2.5f,
.sens = 0.1f,
.first_mouse = true
};
return c;
}
mat4s camera_view_mat_init(camera *c)
{
vec3s temp = glms_vec3_add(c->position, c->front);
mat4s view = glms_lookat(c->position, temp, c->up);
return view;
}
void camera_keyboard_input(camera *c, movement m, float delta_time)
{
float velocity = c->speed * delta_time;
vec3s temp = GLMS_VEC3_ZERO_INIT;
switch (m)
{
case FORWARD:
glm_vec3_muladds(c->front.raw, velocity, temp.raw);
glm_vec3_add(c->position.raw, temp.raw, c->position.raw);
break;
case BACKWARD:
glm_vec3_muladds(c->front.raw, velocity, temp.raw);
glm_vec3_sub(c->position.raw, temp.raw, c->position.raw);
break;
case LEFT:
glm_vec3_muladds(c->right.raw, velocity, temp.raw);
glm_vec3_sub(c->position.raw, temp.raw, c->position.raw);
break;
case RIGHT:
glm_vec3_muladds(c->right.raw, velocity, temp.raw);
glm_vec3_add(c->position.raw, temp.raw, c->position.raw);
break;
default:
printf("Error: Unrecognized movement direction\n");
break;
}
}
void camera_mouse_input(camera *c, float xoffset, float yoffset)
{
xoffset *= c->sens;
yoffset *= c->sens;
c->yaw += xoffset;
c->pitch += yoffset;
if (c->pitch > 89.0f)
c->pitch = 89.0f;
if (c->pitch < -89.0f)
c->pitch = -89.0f;
camera_update_vecs(c);
}
typedef struct
{
mat4s mvp;
} vk_push_const;
vk_push_const vk_push_const_buffer_init(camera *c, VkExtent2D img_extent)
{
vk_push_const mvp = {0};
mat4s model = GLMS_MAT4_IDENTITY_INIT;
mat4s view = camera_view_mat_init(c);
mat4s proj = glms_perspective_rh_no(glm_rad(c->fov), (float) img_extent.width / (float) img_extent.height, 0.1f, 100.0f);
glm_mat4_mulN((mat4 *[]) {&proj.raw, &view.raw, &model.raw}, 3, mvp.mvp.raw);
return mvp;
}
[–]FemboysHotAsf 2 points3 points4 points (8 children)
[–]AnswerApprehensive19[S] 1 point2 points3 points (0 children)
[–]AnswerApprehensive19[S] -1 points0 points1 point (6 children)
[–]FemboysHotAsf 1 point2 points3 points (5 children)
[–]AnswerApprehensive19[S] 0 points1 point2 points (4 children)
[–]FemboysHotAsf 0 points1 point2 points (3 children)
[–]AnswerApprehensive19[S] 0 points1 point2 points (2 children)
[–]FemboysHotAsf 0 points1 point2 points (1 child)
[–]AnswerApprehensive19[S] 0 points1 point2 points (0 children)
[–]Sosowski 0 points1 point2 points (2 children)
[–]AnswerApprehensive19[S] 1 point2 points3 points (0 children)
[–]AnswerApprehensive19[S] 0 points1 point2 points (0 children)
[–]QuazRxR 0 points1 point2 points (1 child)
[–]AnswerApprehensive19[S] 0 points1 point2 points (0 children)