Skip to content

Commit

Permalink
vulkanize: Enable split screen viewing
Browse files Browse the repository at this point in the history
The first part of this is to implement setting the viewport, which was
deferred before. This means that the viewport must be dynamic for every
pipeline. Okay. not every one, but it's easier to make them the same.

Much of this involves adding uniforms for the portions of the scene that
are rendered in the split screen. Since it is derived from a different
player, the values are entirely independent and need their own uniforms,
but the pipelines can be reused.

The text buffer is considerably lesser on the split screen, but it's
simpler and not terribly inefficient to use the same mechanism.

Like so many others, player vertex buffers were getting created and
deleted on a per-frame basis. This converts them to dynamic buffers and
updates them instead of recreating them. A side effect of this is that
the CPU finally caught up with the v-synch and revealed that I left out
a fence wait at start_frame.
  • Loading branch information
pow2clk committed Jun 19, 2019
1 parent 33224b1 commit 8f085b4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 36 deletions.
49 changes: 30 additions & 19 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,17 @@ Buffer gen_plant_buffer(float x, float y, float z, float n, int w) {
return gen_faces(10, 4, data);
} // gen_plant_buffer()

// Generate a vertex buffer representing a player at location <x>, <y>, and <z>
// and rotation <rx> and <ry> and return its handle
// Update the vertex buffer <buffer> representing a player at location <x>, <y>, and <z>
// and rotation <rx> and <ry>
// A player is represented as a single floating cube with a face and clothes texture
// 3D position coords, 3D normals, and a 4-component texcoord is included.
// The first 2 components of the texcoord are standard tex coordinates,
// The last two are theoretically used for ambient occlusion, but not for plants.
Buffer gen_player_buffer(float x, float y, float z, float rx, float ry) {
void update_player_buffer(Buffer buffer, float x, float y, float z, float rx, float ry) {
float *data = malloc_faces(10, 6);
make_player(data, x, y, z, rx, ry);
return gen_faces(10, 6, data);
} // gen_player_buffer()
update_faces(buffer, 10, 6, data);
} // update_player_buffer()

// Make a sequence of vertices representing UI text at location <x>,<y> on the screen
// and scaled by a factor of <n> representing <text> and copy them into <data>
Expand Down Expand Up @@ -365,8 +365,7 @@ void update_player(Player *player,
else {
State *s = &player->state;
s->x = x; s->y = y; s->z = z; s->rx = rx; s->ry = ry;
del_buffer(player->buffer);
player->buffer = gen_player_buffer(s->x, s->y, s->z, s->rx, s->ry);
update_player_buffer(player->buffer, s->x, s->y, s->z, s->rx, s->ry);
}
}

Expand Down Expand Up @@ -2454,7 +2453,7 @@ void parse_buffer(char *buffer) {
player = g->players + g->player_count;
g->player_count++;
player->id = pid;
player->buffer = 0;
player->buffer = gen_dynamic_buffer(sizeof(float) * 6 * 10 * 6, NULL);
snprintf(player->name, MAX_NAME_LENGTH, "player%d", pid);
update_player(player, px, py, pz, prx, pry, 1); // twice
}
Expand Down Expand Up @@ -2570,6 +2569,12 @@ int main(int argc, char **argv) {
Uniform sign_uniform = gen_uniform(sizeof(MatUbo), STAGE_VERT_BIT, sign, NULL);
Uniform sky_uniform = gen_uniform(sizeof(SkyUbo), STAGE_VERT_BIT|STAGE_FRAG_BIT, sky, NULL);

// Additional uniforms for picture in picture
Uniform block2_uniform = gen_uniform(sizeof(BlockUbo), STAGE_VERT_BIT|STAGE_FRAG_BIT, texture, sky);
Uniform text2_uniform = gen_uniform(sizeof(MatUbo), STAGE_VERT_BIT, font, NULL);
Uniform sign2_uniform = gen_uniform(sizeof(MatUbo), STAGE_VERT_BIT, sign, NULL);
Uniform sky2_uniform = gen_uniform(sizeof(SkyUbo), STAGE_VERT_BIT|STAGE_FRAG_BIT, sky, NULL);

// LOAD SHADERS //
uint32_t attrib_components[3] = {3, 3, 4};
Pipeline block_pipeline = gen_pipeline("shaders/block_vertex.spv", "shaders/block_fragment.spv",
Expand Down Expand Up @@ -2653,6 +2658,7 @@ int main(int argc, char **argv) {
Buffer wireframe_buffer = gen_wireframe_buffer(0.53);
Buffer type_buffer = gen_text_buffer(5, MAX_TEXT_LENGTH);
Buffer text_buffer = gen_text_buffer(4, MAX_TEXT_LENGTH * (MAX_MESSAGES + 1) + MAX_INFO_LENGTH + 2 * MAX_NAME_LENGTH);
Buffer text2_buffer = gen_text_buffer(4, MAX_NAME_LENGTH);
Buffer *item_buffers = malloc(sizeof(Buffer) * item_count);
for(int i = 0; i < item_count; i++) {
int w = items[i];
Expand All @@ -2665,7 +2671,7 @@ int main(int argc, char **argv) {
State *s = &g->players->state;
me->id = 0;
me->name[0] = '\0';
me->buffer = 0;
me->buffer = gen_dynamic_buffer(sizeof(float) * 6 * 10 * 6, NULL);
g->player_count = 1;

// LOAD STATE FROM DATABASE //
Expand All @@ -2681,7 +2687,6 @@ int main(int argc, char **argv) {
// WINDOW SIZE AND SCALE //
g->scale = get_scale_factor();
glfwGetFramebufferSize(g->window, &g->width, &g->height);
set_viewport(0, 0, g->width, g->height);

// FRAME RATE //
if (g->time_changed) {
Expand Down Expand Up @@ -2726,15 +2731,15 @@ int main(int argc, char **argv) {
g->observe1 = g->observe1 % g->player_count;
g->observe2 = g->observe2 % g->player_count;
delete_chunks();
del_buffer(me->buffer);
me->buffer = gen_player_buffer(s->x, s->y, s->z, s->rx, s->ry);
update_player_buffer(me->buffer, s->x, s->y, s->z, s->rx, s->ry);
for (int i = 1; i < g->player_count; i++) {
interpolate_player(g->players + i);
}
Player *player = g->players + g->observe1;

// RENDER 3-D SCENE //
start_frame();
set_viewport(0, 0, g->width, g->height);
clear_frame(CLEAR_COLOR_BIT | CLEAR_DEPTH_BIT);
render_sky(sky_pipeline, sky_uniform, player, sky_buffer);
clear_frame(CLEAR_DEPTH_BIT);
Expand Down Expand Up @@ -2840,20 +2845,19 @@ int main(int argc, char **argv) {
g->ortho = 0;
g->fov = 65;

render_sky(sky_pipeline, sky_uniform, player, sky_buffer);
render_sky(sky_pipeline, sky2_uniform, player, sky_buffer);
clear_frame(CLEAR_DEPTH_BIT);
render_chunks(block_pipeline, block_uniform, player);
render_signs(sign_pipeline, sign_uniform, player);
render_players(block_pipeline, block_uniform, player);
render_chunks(block_pipeline, block2_uniform, player);
render_signs(sign_pipeline, sign2_uniform, player);
render_players(block_pipeline, block2_uniform, player);
clear_frame(CLEAR_DEPTH_BIT);
if (SHOW_PLAYER_NAMES) {
int length = strlen(player->name);
float x = pw / 2 - ts * ALIGN_CENTER * (length - 1)/2;
float *data = malloc_faces(4, length);
make_text(data, x, ts, ts, player->name);
Buffer name_buffer = gen_faces(4, length, data);
render_text(text_pipeline, text_uniform, length, name_buffer);
del_buffer(name_buffer);
update_faces(text2_buffer, 4, length, data);
render_text(text_pipeline, text2_uniform, length, text2_buffer);
}
}

Expand Down Expand Up @@ -2887,6 +2891,8 @@ int main(int argc, char **argv) {
del_buffer(crosshair_buffer);
del_buffer(sky_buffer);

del_buffer(text2_buffer);

del_uniform(block_uniform);
del_uniform(item_uniform);
del_uniform(line_uniform);
Expand All @@ -2895,6 +2901,11 @@ int main(int argc, char **argv) {
del_uniform(sign_uniform);
del_uniform(sky_uniform);

del_uniform(block2_uniform);
del_uniform(text2_uniform);
del_uniform(sign2_uniform);
del_uniform(sky2_uniform);

del_pipeline(block_pipeline);
del_pipeline(line_pipeline);
del_pipeline(text_pipeline);
Expand Down
37 changes: 20 additions & 17 deletions src/vkrenderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ int init_renderer(GLFWwindow *window) {
if (create_frames(vk->swapchain))
return -1;

vk->descriptor_pool = create_descriptor_pool(vk->frame_ct*5, vk->frame_ct*5);
vk->descriptor_pool = create_descriptor_pool(vk->frame_ct*11, vk->frame_ct*12);
if (vk->descriptor_pool == VK_NULL_HANDLE)
return -1;

Expand Down Expand Up @@ -778,7 +778,17 @@ void clear_frame(uint32_t bitfield) {

// set viewport for the framebuffer limited to <x,y,width,height>
void set_viewport(int32_t x, int32_t y, int32_t width, int32_t height) {
// UNIMPLIMENTED
VkViewport viewport = {
.x = x,
.y = vk->depth_buf->extent.height - y,
.width = width,
.height = -height,
.minDepth = -1.0f,
.maxDepth = 1.0f,
};

vkCmdSetViewport(vk->cmd_bufs[vk->cur_frame], 0, 1, &viewport);

} // set_viewport()

// Create a bufer object of <size> bytes able to be used for <usage> allocated with memory
Expand Down Expand Up @@ -1395,15 +1405,6 @@ Pipeline gen_pipeline(const char *path1, const char *path2, Uniform uniform,
.primitiveRestartEnable = VK_FALSE,
};

// Viewport and scissor dimensions are taken from the currently bound images
VkViewport viewport = {
.x = 0.0f,
.y = (float)vk->depth_buf->extent.height,
.width = (float) vk->depth_buf->extent.width,
.height = -((float)vk->depth_buf->extent.height),
.minDepth = -1.0f,
.maxDepth = 1.0f,
};
VkRect2D scissor = {
.offset = {0, 0},
.extent = vk->depth_buf->extent,
Expand All @@ -1412,7 +1413,7 @@ Pipeline gen_pipeline(const char *path1, const char *path2, Uniform uniform,
VkPipelineViewportStateCreateInfo viewport_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.viewportCount = 1,
.pViewports = &viewport,
.pViewports = NULL,
.scissorCount = 1,
.pScissors = &scissor,
};
Expand Down Expand Up @@ -1479,13 +1480,15 @@ Pipeline gen_pipeline(const char *path1, const char *path2, Uniform uniform,
return NULL;
}

// The only required dynamic state is line width if line rendering is enabled
VkDynamicState dynamic_state = VK_DYNAMIC_STATE_LINE_WIDTH;
// The only definitely required dynamic state is viewport
// line width too if line rendering is enabled
VkDynamicState dynamic_states[2] = {VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_LINE_WIDTH};

VkPipelineDynamicStateCreateInfo dynamic_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = 1,
.pDynamicStates = &dynamic_state,
.dynamicStateCount = 1 + line,
.pDynamicStates = dynamic_states,
};
// This is where it all gets packaged up and submitted to the Vulkan bureaucracy
VkGraphicsPipelineCreateInfo pipeline_info = {
Expand All @@ -1499,7 +1502,7 @@ Pipeline gen_pipeline(const char *path1, const char *path2, Uniform uniform,
.pMultisampleState = &msaa_info,
.pDepthStencilState = &depth_info,
.pColorBlendState = &blend_info,
.pDynamicState = (line?&dynamic_info:NULL),
.pDynamicState = &dynamic_info,
.layout = layout,
.renderPass = vk->render_pass,
.subpass = 0,
Expand Down

0 comments on commit 8f085b4

Please sign in to comment.