static void menu_display_d3d11_draw_pipeline(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { d3d11_video_t* d3d11 = video_info ? (d3d11_video_t*)video_info->userdata : NULL; if (!d3d11 || !draw) return; switch (draw->pipeline.id) { case VIDEO_SHADER_MENU: case VIDEO_SHADER_MENU_2: { video_coord_array_t* ca = menu_display_get_coords_array(); if (!d3d11->menu_pipeline_vbo) { D3D11_BUFFER_DESC desc = { 0 }; desc.Usage = D3D11_USAGE_IMMUTABLE; desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float); desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; { D3D11_SUBRESOURCE_DATA vertexData = { ca->coords.vertex }; D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu_pipeline_vbo); } } D3D11SetVertexBuffer(d3d11->context, 0, d3d11->menu_pipeline_vbo, 2 * sizeof(float), 0); draw->coords->vertices = ca->coords.vertices; D3D11SetBlendState(d3d11->context, d3d11->blend_pipeline, NULL, D3D11_DEFAULT_SAMPLE_MASK); break; } case VIDEO_SHADER_MENU_3: case VIDEO_SHADER_MENU_4: case VIDEO_SHADER_MENU_5: case VIDEO_SHADER_MENU_6: D3D11SetVertexBuffer(d3d11->context, 0, d3d11->frame.vbo, sizeof(d3d11_vertex_t), 0); draw->coords->vertices = 4; break; default: return; } D3D11SetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); d3d11->ubo_values.time += 0.01f; { D3D11_MAPPED_SUBRESOURCE mapped_ubo; D3D11MapBuffer(d3d11->context, d3d11->ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo); *(d3d11_uniform_t*)mapped_ubo.pData = d3d11->ubo_values; D3D11UnmapBuffer(d3d11->context, d3d11->ubo, 0); } }
static void menu_display_d3d11_draw(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info) { int vertex_count; d3d11_video_t* d3d11 = video_info ? (d3d11_video_t*)video_info->userdata : NULL; if (!d3d11 || !draw || !draw->texture) return; switch (draw->pipeline.id) { case VIDEO_SHADER_MENU: case VIDEO_SHADER_MENU_2: case VIDEO_SHADER_MENU_3: case VIDEO_SHADER_MENU_4: case VIDEO_SHADER_MENU_5: case VIDEO_SHADER_MENU_6: d3d11_set_shader(d3d11->context, &d3d11->shaders[draw->pipeline.id]); D3D11Draw(d3d11->context, draw->coords->vertices, 0); D3D11SetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK); d3d11_set_shader(d3d11->context, &d3d11->sprites.shader); D3D11SetVertexBuffer(d3d11->context, 0, d3d11->sprites.vbo, sizeof(d3d11_sprite_t), 0); D3D11SetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); return; } if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color) vertex_count = draw->coords->vertices; else vertex_count = 1; if (!d3d11->sprites.enabled || vertex_count > d3d11->sprites.capacity) return; if (d3d11->sprites.offset + vertex_count > d3d11->sprites.capacity) d3d11->sprites.offset = 0; { D3D11_MAPPED_SUBRESOURCE mapped_vbo; d3d11_sprite_t* sprite = NULL; D3D11MapBuffer( d3d11->context, d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo); sprite = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset; if (vertex_count == 1) { sprite->pos.x = draw->x / (float)d3d11->viewport.Width; sprite->pos.y = (d3d11->viewport.Height - draw->y - draw->height) / (float)d3d11->viewport.Height; sprite->pos.w = draw->width / (float)d3d11->viewport.Width; sprite->pos.h = draw->height / (float)d3d11->viewport.Height; sprite->coords.u = 0.0f; sprite->coords.v = 0.0f; sprite->coords.w = 1.0f; sprite->coords.h = 1.0f; if (draw->scale_factor) sprite->params.scaling = draw->scale_factor; else sprite->params.scaling = 1.0f; sprite->params.rotation = draw->rotation; sprite->colors[3] = DXGI_COLOR_RGBA( 0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1], 0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]); sprite->colors[2] = DXGI_COLOR_RGBA( 0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5], 0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]); sprite->colors[1] = DXGI_COLOR_RGBA( 0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9], 0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]); sprite->colors[0] = DXGI_COLOR_RGBA( 0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13], 0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]); } else { int i; const float* vertex = draw->coords->vertex; const float* tex_coord = draw->coords->tex_coord; const float* color = draw->coords->color; for (i = 0; i < vertex_count; i++) { d3d11_vertex_t* v = (d3d11_vertex_t*)sprite; v->position[0] = *vertex++; v->position[1] = *vertex++; v->texcoord[0] = *tex_coord++; v->texcoord[1] = *tex_coord++; v->color[0] = *color++; v->color[1] = *color++; v->color[2] = *color++; v->color[3] = *color++; sprite++; } d3d11_set_shader(d3d11->context, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]); D3D11SetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); } D3D11UnmapBuffer(d3d11->context, d3d11->sprites.vbo, 0); } d3d11_set_texture_and_sampler(d3d11->context, 0, (d3d11_texture_t*)draw->texture); D3D11Draw(d3d11->context, vertex_count, d3d11->sprites.offset); d3d11->sprites.offset += vertex_count; if (vertex_count > 1) { d3d11_set_shader(d3d11->context, &d3d11->sprites.shader); D3D11SetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); } return; }
static void d3d11_font_render_line( video_frame_info_t* video_info, d3d11_font_t* font, const char* msg, unsigned msg_len, float scale, const unsigned int color, float pos_x, float pos_y, unsigned text_align) { unsigned i, count; D3D11_MAPPED_SUBRESOURCE mapped_vbo; d3d11_sprite_t* v; d3d11_video_t* d3d11 = (d3d11_video_t*)video_driver_get_ptr(false); unsigned width = video_info->width; unsigned height = video_info->height; int x = roundf(pos_x * width); int y = roundf((1.0 - pos_y) * height); if (!d3d11->sprites.enabled || msg_len > (unsigned)d3d11->sprites.capacity) return; if (d3d11->sprites.offset + msg_len > (unsigned)d3d11->sprites.capacity) d3d11->sprites.offset = 0; switch (text_align) { case TEXT_ALIGN_RIGHT: x -= d3d11_font_get_message_width(font, msg, msg_len, scale); break; case TEXT_ALIGN_CENTER: x -= d3d11_font_get_message_width(font, msg, msg_len, scale) / 2; break; } D3D11MapBuffer(d3d11->context, d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo); v = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset; for (i = 0; i < msg_len; i++) { const struct font_glyph* glyph; const char* msg_tmp = &msg[i]; unsigned code = utf8_walk(&msg_tmp); unsigned skip = msg_tmp - &msg[i]; if (skip > 1) i += skip - 1; glyph = font->font_driver->get_glyph(font->font_data, code); if (!glyph) /* Do something smarter here ... */ glyph = font->font_driver->get_glyph(font->font_data, '?'); if (!glyph) continue; v->pos.x = (x + glyph->draw_offset_x) * scale / (float)d3d11->viewport.Width; v->pos.y = (y + glyph->draw_offset_y) * scale / (float)d3d11->viewport.Height; v->pos.w = glyph->width * scale / (float)d3d11->viewport.Width; v->pos.h = glyph->height * scale / (float)d3d11->viewport.Height; v->coords.u = glyph->atlas_offset_x / (float)font->texture.desc.Width; v->coords.v = glyph->atlas_offset_y / (float)font->texture.desc.Height; v->coords.w = glyph->width / (float)font->texture.desc.Width; v->coords.h = glyph->height / (float)font->texture.desc.Height; v->params.scaling = 1; v->params.rotation = 0; v->colors[0] = color; v->colors[1] = color; v->colors[2] = color; v->colors[3] = color; v++; x += glyph->advance_x * scale; y += glyph->advance_y * scale; } count = v - ((d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset); D3D11UnmapBuffer(d3d11->context, d3d11->sprites.vbo, 0); if (!count) return; if (font->atlas->dirty) { d3d11_update_texture( d3d11->context, font->atlas->width, font->atlas->height, font->atlas->width, DXGI_FORMAT_A8_UNORM, font->atlas->buffer, &font->texture); font->atlas->dirty = false; } d3d11_set_texture_and_sampler(d3d11->context, 0, &font->texture); D3D11SetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK); D3D11SetPShader(d3d11->context, d3d11->sprites.shader_font.ps, NULL, 0); D3D11Draw(d3d11->context, count, d3d11->sprites.offset); D3D11SetPShader(d3d11->context, d3d11->sprites.shader.ps, NULL, 0); d3d11->sprites.offset += count; }