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 menu_display_d3d11_blend_end(video_frame_info_t *video_info)
{
   d3d11_video_t* d3d11 = (d3d11_video_t*)video_info->userdata;
   D3D11SetBlendState(d3d11->context,
         d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
}
Beispiel #4
0
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;
}