(direct3D) fix scaling in the menu display driver.

This commit is contained in:
aliaspider 2018-01-15 03:45:37 +01:00
parent 7b09d5399c
commit 25a7c04a27
10 changed files with 156 additions and 125 deletions

View File

@ -1183,6 +1183,14 @@ bool d3d_set_vertex_shader(LPDIRECT3DDEVICE dev, unsigned index,
return true;
}
bool d3d_set_vertex_shader_constantf(LPDIRECT3DDEVICE dev,
UINT start_register,const float* constant_data, unsigned vector4f_count)
{
#if defined(HAVE_D3D9)
return (IDirect3DDevice9_SetVertexShaderConstantF(dev, start_register, constant_data, vector4f_count) == D3D_OK);
#endif
return false;
}
void d3d_texture_blit(unsigned pixel_size,
LPDIRECT3DTEXTURE tex, D3DLOCKED_RECT *lr, const void *frame,

View File

@ -111,6 +111,9 @@ bool d3d_set_pixel_shader(LPDIRECT3DDEVICE dev, void *data);
bool d3d_set_vertex_shader(LPDIRECT3DDEVICE dev, unsigned index,
void *data);
bool d3d_set_vertex_shader_constantf(LPDIRECT3DDEVICE dev,
UINT start_register,const float* constant_data, unsigned vector4f_count);
void d3d_texture_blit(unsigned pixel_size,
LPDIRECT3DTEXTURE tex,
D3DLOCKED_RECT *lr, const void *frame,

View File

@ -339,6 +339,14 @@ static void d3d_viewport_info(void *data, struct video_viewport *vp)
d3d->renderchain_driver->viewport_info(d3d, vp);
}
static void d3d_set_mvp(void *data,
void *shader_data,
const void *mat_data)
{
d3d_video_t *d3d = (d3d_video_t*)data;
d3d->renderchain_driver->set_mvp(d3d, d3d->renderchain_data, shader_data, mat_data);
}
static void d3d_overlay_render(d3d_video_t *d3d,
video_frame_info_t *video_info,
overlay_t *overlay)
@ -347,7 +355,6 @@ static void d3d_overlay_render(d3d_video_t *d3d,
void *verts;
unsigned i;
float vert[4][9];
float overlay_width, overlay_height;
unsigned width = video_info->width;
unsigned height = video_info->height;
@ -374,21 +381,14 @@ static void d3d_overlay_render(d3d_video_t *d3d,
d3d_viewport_info(d3d, &vp);
overlay_width = vp.width;
overlay_height = vp.height;
vert[0][0] = overlay->vert_coords[0] * overlay_width;
vert[1][0] = (overlay->vert_coords[0] + overlay->vert_coords[2])
* overlay_width;
vert[2][0] = overlay->vert_coords[0] * overlay_width;
vert[3][0] = (overlay->vert_coords[0] + overlay->vert_coords[2])
* overlay_width;
vert[0][1] = overlay->vert_coords[1] * overlay_height;
vert[1][1] = overlay->vert_coords[1] * overlay_height;
vert[2][1] = (overlay->vert_coords[1] + overlay->vert_coords[3])
* overlay_height;
vert[3][1] = (overlay->vert_coords[1] + overlay->vert_coords[3])
* overlay_height;
vert[0][0] = overlay->vert_coords[0];
vert[1][0] = overlay->vert_coords[0] + overlay->vert_coords[2];
vert[2][0] = overlay->vert_coords[0];
vert[3][0] = overlay->vert_coords[0] + overlay->vert_coords[2];
vert[0][1] = overlay->vert_coords[1];
vert[1][1] = overlay->vert_coords[1];
vert[2][1] = overlay->vert_coords[1] + overlay->vert_coords[3];
vert[3][1] = overlay->vert_coords[1] + overlay->vert_coords[3];
vert[0][3] = overlay->tex_coords[0];
vert[1][3] = overlay->tex_coords[0] + overlay->tex_coords[2];
@ -399,13 +399,6 @@ static void d3d_overlay_render(d3d_video_t *d3d,
vert[2][4] = overlay->tex_coords[1] + overlay->tex_coords[3];
vert[3][4] = overlay->tex_coords[1] + overlay->tex_coords[3];
/* Align texels and vertices. */
for (i = 0; i < 4; i++)
{
vert[i][0] -= 0.5f;
vert[i][1] += 0.5f;
}
verts = d3d_vertex_buffer_lock(overlay->vert_buf);
memcpy(verts, vert, sizeof(vert));
d3d_vertex_buffer_unlock(overlay->vert_buf);
@ -899,6 +892,11 @@ static bool d3d_initialize(d3d_video_t *d3d, const video_info_t *info)
if (!d3d->menu_display.buffer)
return false;
d3d_matrix_ortho_off_center_lh(&d3d->mvp_transposed, 0, 1, 0, 1, 0, 1);
d3d_matrix_transpose(&d3d->mvp, &d3d->mvp_transposed);
d3d_set_render_state(d3d->dev, D3DRS_CULLMODE, D3DCULL_NONE);
return true;
}
@ -1537,16 +1535,18 @@ static bool d3d_frame(void *data, const void *frame,
return false;
}
d3d->renderchain_driver->set_mvp(d3d->renderchain_data, d3d, screen_vp.Width, screen_vp.Height, 0);
d3d_set_viewports(d3d->dev, &screen_vp);
#ifdef HAVE_MENU
if (d3d->menu && d3d->menu->enabled)
{
d3d_set_mvp(d3d, NULL, &d3d->mvp);
d3d_overlay_render(d3d, video_info, d3d->menu);
d3d->menu_display.offset = 0;
d3d_set_vertex_declaration(d3d->dev, d3d->menu_display.decl);
d3d_set_stream_source(d3d->dev, 0, d3d->menu_display.buffer, 0, 8 * sizeof(float));
d3d_set_viewports(d3d->dev, &screen_vp);
menu_driver_frame(video_info);
}
#endif
@ -1554,13 +1554,17 @@ static bool d3d_frame(void *data, const void *frame,
#ifdef HAVE_OVERLAY
if (d3d->overlays_enabled)
{
d3d_set_mvp(d3d, NULL, &d3d->mvp);
for (i = 0; i < d3d->overlays_size; i++)
d3d_overlay_render(d3d, video_info, &d3d->overlays[i]);
}
#endif
if (msg && *msg)
{
d3d_set_viewports(d3d->dev, &screen_vp);
font_driver_render_msg(video_info, NULL, msg, NULL);
}
video_info->cb_update_window_title(
video_info->context_data, video_info);
@ -1809,18 +1813,6 @@ static void d3d_unload_texture(void *data, uintptr_t id)
d3d_texture_free(texid);
}
static void d3d_set_mvp(void *data,
void *shader_data,
const void *mat_data)
{
d3d_video_t *d3d = (d3d_video_t*)data;
if (d3d && d3d->renderchain_driver->set_mvp)
d3d->renderchain_driver->set_mvp(
d3d->renderchain_data,
data,
640, 480, 0);
}
static const video_poke_interface_t d3d_poke_interface = {
NULL, /* set_coords */
d3d_set_mvp,

View File

@ -17,6 +17,8 @@
#ifndef __D3DVIDEO_INTF_H__
#define __D3DVIDEO_INTF_H__
#include <gfx/math/matrix_4x4.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
@ -83,6 +85,8 @@ typedef struct d3d_video
RECT font_rect;
RECT font_rect_shifted;
math_matrix_4x4 mvp;
math_matrix_4x4 mvp_transposed;
struct video_viewport vp;
struct video_shader shader;

View File

@ -39,8 +39,8 @@ typedef struct
#else
ID3DXFont *font;
#endif
uint32_t color;
uint32_t font_size;
uint32_t ascent;
} d3dfonts_t;
#ifdef __cplusplus
@ -49,9 +49,11 @@ typedef struct
#if !defined(__cplusplus) || defined(CINTERFACE)
#define IDirect3DXFont_DrawTextA(p, a, b, c, d, e, f) (p)->lpVtbl->DrawTextA(p, a, b, c, d, e, f)
#define IDirect3DXFont_GetTextMetricsA(p, a) (p)->lpVtbl->GetTextMetricsA(p, a)
#define IDirect3DXFont_Release(p) (p)->lpVtbl->Release(p)
#else
#define IDirect3DXFont_DrawTextA(p, a, b, c, d, e, f) (p)->DrawTextA(a, b, c, d, e, f)
#define IDirect3DXFont_GetTextMetricsA(p, a) (p)->GetTextMetricsA(a)
#define IDirect3DXFont_Release(p) (p)->Release()
#endif
@ -74,24 +76,20 @@ static void *d3dfonts_w32_init_font(void *video_data,
#endif
};
d3dfonts_t *d3dfonts = (d3dfonts_t*)calloc(1, sizeof(*d3dfonts));
uint32_t r = (settings->floats.video_msg_color_r * 255);
uint32_t g = (settings->floats.video_msg_color_g * 255);
uint32_t b = (settings->floats.video_msg_color_b * 255);
r &= 0xff;
g &= 0xff;
b &= 0xff;
if (!d3dfonts)
return NULL;
d3dfonts->font_size = font_size;
d3dfonts->font_size = font_size * 1.2; /* to match the other font drivers */
d3dfonts->d3d = (d3d_video_t*)video_data;
d3dfonts->color = D3DCOLOR_XRGB(r, g, b);
desc.Height = d3dfonts->font_size;
if (!d3dx_create_font_indirect(d3dfonts->d3d->dev,
&desc, (void**)&d3dfonts->font))
goto error;
IDirect3DXFont_GetTextMetricsA(d3dfonts->font, &metrics);
d3dfonts->ascent = metrics.tmAscent;
return d3dfonts;
error:
@ -131,7 +129,8 @@ static int d3dfonts_w32_get_message_width(void* data, const char* msg,
static void d3dfonts_w32_render_msg(video_frame_info_t *video_info, void *data, const char *msg,
const void *userdata)
{
unsigned color, format;
unsigned format;
unsigned a, r, g, b;
RECT rect, *p_rect;
RECT rect_shifted, *p_rect_shifted;
settings_t *settings = config_get_ptr();
@ -152,22 +151,18 @@ static void d3dfonts_w32_render_msg(video_frame_info_t *video_info, void *data,
if (!d3d_begin_scene(d3dfonts->d3d->dev))
return;
color = d3dfonts->color;
format = DT_LEFT;
p_rect = &d3dfonts->d3d->font_rect;
p_rect_shifted = &d3dfonts->d3d->font_rect_shifted;
if(params)
{
unsigned a, r, g, b;
a = FONT_COLOR_GET_ALPHA(params->color);
r = FONT_COLOR_GET_RED(params->color);
g = FONT_COLOR_GET_GREEN(params->color);
b = FONT_COLOR_GET_BLUE(params->color);
color = D3DCOLOR_ARGB(a, r, g, b);
switch (params->text_align)
{
case TEXT_ALIGN_RIGHT:
@ -188,7 +183,7 @@ static void d3dfonts_w32_render_msg(video_frame_info_t *video_info, void *data,
break;
}
rect.top = (1.0 - params->y) * height - d3dfonts->font_size;
rect.top = (1.0 - params->y) * height - d3dfonts->ascent;
rect.bottom = height;
p_rect = &rect;
@ -207,22 +202,30 @@ static void d3dfonts_w32_render_msg(video_frame_info_t *video_info, void *data,
p_rect_shifted = &rect_shifted;
}
}
else
{
a = 255;
r = video_info->font_msg_color_r * 255;
g = video_info->font_msg_color_g * 255;
b = video_info->font_msg_color_b * 255;
}
if(drop_x || drop_y)
{
unsigned a, r, g, b;
unsigned drop_a, drop_r, drop_g, drop_b;
a = FONT_COLOR_GET_ALPHA(color) * drop_alpha;
r = FONT_COLOR_GET_RED(color) * drop_mod;
g = FONT_COLOR_GET_GREEN(color) * drop_mod;
b = FONT_COLOR_GET_BLUE(color) * drop_mod;
drop_a = a * drop_alpha;
drop_r = r * drop_mod;
drop_g = g * drop_mod;
drop_b = b * drop_mod;
IDirect3DXFont_DrawTextA(d3dfonts->font, NULL, msg, -1,
p_rect_shifted, format, D3DCOLOR_ARGB(a, r, g, b));
IDirect3DXFont_DrawTextA(d3dfonts->font, NULL, msg, -1, p_rect_shifted, format,
D3DCOLOR_ARGB(drop_a , drop_r, drop_g, drop_b));
}
IDirect3DXFont_DrawTextA(d3dfonts->font, NULL, msg, -1,
p_rect, format, color);
p_rect, format, D3DCOLOR_ARGB(a, r, g, b));
d3d_end_scene(d3dfonts->d3d->dev);
}

View File

@ -42,23 +42,19 @@ typedef struct d3d8_renderchain
} d3d8_renderchain_t;
static void d3d8_renderchain_set_mvp(
void *data,
void *chain_data,
void *data, unsigned vp_width,
unsigned vp_height, unsigned rotation)
void *shader_data,
const void *mat_data)
{
D3DMATRIX identity;
d3d_video_t *d3d = (d3d_video_t*)data;
LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev;
D3DMATRIX p_out, p_rotate, mat;
(void)chain_data;
d3d_matrix_identity(&identity);
d3d_matrix_ortho_off_center_lh(&mat, 0, vp_width, vp_height, 0, 0.0f, 1.0f);
d3d_matrix_identity(&p_out);
d3d_matrix_rotation_z(&p_rotate, rotation * (M_PI / 2.0));
d3d_set_transform(d3dr, D3DTS_WORLD, &p_rotate);
d3d_set_transform(d3dr, D3DTS_VIEW, &p_out);
d3d_set_transform(d3dr, D3DTS_PROJECTION, &p_out);
d3d_set_transform(d3d->dev, D3DTS_WORLD, &identity);
d3d_set_transform(d3d->dev, D3DTS_VIEW, &identity);
d3d_set_transform(d3d->dev, D3DTS_PROJECTION, mat_data);
}
static void d3d8_renderchain_clear(void *data)

View File

@ -1182,6 +1182,14 @@ static void d3d9_cg_renderchain_end_render(cg_renderchain_t *chain)
}
static void d3d9_cg_renderchain_set_shader_mvp(
cg_renderchain_t *chain, CGprogram vPrg, D3DMATRIX *matrix)
{
CGparameter cgpModelViewProj = cgGetNamedParameter(vPrg, "modelViewProj");
if (cgpModelViewProj)
cgD3D9SetUniformMatrix(cgpModelViewProj, matrix);
}
static void d3d9_cg_renderchain_calc_and_set_shader_mvp(
cg_renderchain_t *chain, CGprogram vPrg,
unsigned vp_width, unsigned vp_height,
unsigned rotation)
@ -1195,20 +1203,28 @@ static void d3d9_cg_renderchain_set_shader_mvp(
d3d_matrix_multiply(&proj, &ortho, &rot);
d3d_matrix_transpose(&matrix, &proj);
CGparameter cgpModelViewProj = cgGetNamedParameter(vPrg, "modelViewProj");
if (cgpModelViewProj)
cgD3D9SetUniformMatrix(cgpModelViewProj, &matrix);
d3d9_cg_renderchain_set_shader_mvp(chain, vPrg, &matrix);
}
static void d3d9_cg_renderchain_set_mvp(
void *chain_data,
void *data,
unsigned vp_width, unsigned vp_height,
unsigned rotation)
{
void *data,
void *chain_data,
void *shader_data,
const void *mat_data)
{
d3d_video_t *d3d = (d3d_video_t*)data;
#if 0
cg_renderchain_t *chain = (cg_renderchain_t*)chain_data;
d3d9_cg_renderchain_set_shader_mvp(chain, chain->vStock, vp_width, vp_height, rotation);
if(shader_data)
d3d9_cg_renderchain_set_shader_mvp(chain, shader_data, mat_data);
else
d3d9_cg_renderchain_set_shader_mvp(chain, chain->vStock, mat_data);
#else
d3d_set_vertex_shader_constantf(d3d->dev, 0, mat_data, 4);
#endif
}
static void cg_d3d9_renderchain_set_vertices(
@ -1298,7 +1314,7 @@ static void cg_d3d9_renderchain_set_vertices(
if (chain)
{
d3d9_cg_renderchain_set_shader_mvp(
d3d9_cg_renderchain_calc_and_set_shader_mvp(
chain, pass->vPrg, vp_width, vp_height, rotation);
if (pass)
d3d9_cg_renderchain_set_shader_params(chain, pass,
@ -1562,7 +1578,7 @@ static bool d3d9_cg_renderchain_render(
d3d9_cg_renderchain_end_render(chain);
cgD3D9BindProgram(chain->fStock);
cgD3D9BindProgram(chain->vStock);
d3d9_cg_renderchain_set_shader_mvp(
d3d9_cg_renderchain_calc_and_set_shader_mvp(
chain, chain->vStock, chain->final_viewport->Width,
chain->final_viewport->Height, 0);
}

View File

@ -45,28 +45,17 @@ typedef struct hlsl_d3d9_renderchain
void hlsl_set_proj_matrix(void *data, void *matrix_data);
static void hlsl_d3d9_renderchain_set_mvp(
void *data,
void *chain_data,
void *data, unsigned vp_width,
unsigned vp_height, unsigned rotation)
void *shader_data,
const void *mat_data)
{
video_shader_ctx_mvp_t mvp;
D3DMATRIX proj, ortho, rot, tmp;
d3d_video_t *d3d = (d3d_video_t*)data;
LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev;
d3d_matrix_ortho_off_center_lh(&ortho, 0, vp_width, 0, vp_height, 0, 1);
d3d_matrix_identity(&rot);
d3d_matrix_rotation_z(&rot, rotation * (M_PI / 2.0));
d3d_matrix_multiply(&proj, &ortho, &rot);
d3d_matrix_transpose(&tmp, &proj);
hlsl_set_proj_matrix((void*)&d3d->shader, &rot);
mvp.data = d3d;
mvp.matrix = &rot;
video_driver_set_mvp(&mvp);
if(shader_data)
hlsl_set_proj_matrix(shader_data, mat_data);
else
hlsl_set_proj_matrix((void*)&d3d->shader, mat_data);
}
static void hlsl_d3d9_renderchain_clear(void *data)

View File

@ -798,9 +798,10 @@ typedef struct video_driver
typedef struct d3d_renderchain_driver
{
void (*set_mvp)(void *chain_data,
void *data, unsigned vp_width,
unsigned vp_height, unsigned rotation);
void (*set_mvp)(void *data,
void *chain_data,
void *shader_data,
const void *mat_data);
void (*chain_free)(void *data);
void *(*chain_new)(void);
bool (*reinit)(void *data, const void *info_data);

View File

@ -57,18 +57,10 @@ static const float *menu_display_d3d_get_default_tex_coords(void)
static void *menu_display_d3d_get_default_mvp(void)
{
static math_matrix_4x4 default_mvp;
D3DMATRIX ortho, mvp;
d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false);
static math_matrix_4x4 id;
matrix_4x4_identity(id);
if (!d3d)
return NULL;
d3d_matrix_ortho_off_center_lh(&ortho, 0,
1, 0, 1, 0, 1);
d3d_matrix_transpose(&mvp, &ortho);
memcpy(default_mvp.data, (float*)&mvp, sizeof(default_mvp.data));
return &default_mvp;
return &id;
}
static unsigned menu_display_prim_to_d3d_enum(
@ -112,12 +104,13 @@ static void menu_display_d3d_viewport(void *data)
#if 0
D3DVIEWPORT vp = {0};
menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data;
d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false);
if (!d3d || !draw)
return;
vp.X = draw->x;
vp.Y = draw->y;
vp.Y = d3d->video_info.height - (draw->y + draw->height);
vp.Width = draw->width;
vp.Height = draw->height;
vp.MinZ = 0.0f;
@ -148,7 +141,10 @@ static void menu_display_d3d_bind_texture(void *data)
static void menu_display_d3d_draw(void *data)
{
unsigned i;
d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false);
video_shader_ctx_mvp_t mvp;
math_matrix_4x4 mop, m1, m2;
unsigned width, height;
d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false);
menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data;
float* pv = NULL;
const float *vertex = NULL;
@ -158,13 +154,12 @@ static void menu_display_d3d_draw(void *data)
if (!d3d || !draw)
return;
if(draw->pipeline.id)
return;
if(d3d->menu_display.offset + draw->coords->vertices > d3d->menu_display.size)
return;
if (!draw->coords->vertex)
draw->coords->vertex = menu_display_d3d_get_default_vertices();
if (!draw->coords->tex_coord)
draw->coords->tex_coord = menu_display_d3d_get_default_tex_coords();
pv = (float*)d3d_vertex_buffer_lock(d3d->menu_display.buffer);
pv += d3d->menu_display.offset * 8;
@ -172,12 +167,17 @@ static void menu_display_d3d_draw(void *data)
tex_coord = draw->coords->tex_coord;
color = draw->coords->color;
if (!vertex)
vertex = menu_display_d3d_get_default_vertices();
if (!tex_coord)
tex_coord = menu_display_d3d_get_default_tex_coords();
for (i = 0; i < draw->coords->vertices; i++)
{
*pv++ = (*vertex++ * draw->width) + draw->x;
*pv++ = ((1.0 - *vertex++) * draw->height) + draw->y;
*pv++ = *vertex++;
*pv++ = *vertex++;
*pv++ = *tex_coord++;
*pv++ = *tex_coord++;
*pv++ = 1.0f - *tex_coord++;
*pv++ = *color++;
*pv++ = *color++;
*pv++ = *color++;
@ -185,6 +185,25 @@ static void menu_display_d3d_draw(void *data)
}
d3d_vertex_buffer_unlock(d3d->menu_display.buffer);
if(!draw->matrix_data)
draw->matrix_data = menu_display_d3d_get_default_mvp();
/* ugh */
video_driver_get_size(&width, &height);
matrix_4x4_scale(m1, 2.0, 2.0, 0);
matrix_4x4_translate(mop, -1.0, -1.0, 0);
matrix_4x4_multiply(m2, mop, m1);
matrix_4x4_multiply(m1, *((math_matrix_4x4*)draw->matrix_data), m2);
matrix_4x4_scale(mop, (draw->width / 2.0) / width, (draw->height / 2.0) / height, 0);
matrix_4x4_multiply(m2, mop, m1);
matrix_4x4_translate(mop, (draw->x + (draw->width / 2.0)) / width, (draw->y + (draw->height / 2.0)) / height,0);
matrix_4x4_multiply(m1, mop, m2);
matrix_4x4_multiply(m2, d3d->mvp_transposed, m1);
d3d_matrix_transpose(&m1, &m2);
mvp.data = d3d;
mvp.matrix = &m1;
video_driver_set_mvp(&mvp);
menu_display_d3d_bind_texture(draw);
d3d_draw_primitive(d3d->dev, menu_display_prim_to_d3d_enum(draw->prim_type), d3d->menu_display.offset,
draw->coords->vertices - (draw->prim_type == MENU_DISPLAY_PRIM_TRIANGLESTRIP? 2 : 0));