Pregunta

Muy bien, parece que mi pregunta estaba tan turbia como mi cabeza. Vamos a intentarlo de nuevo.

Tengo 3 propiedades al configurar viewports para un dispositivo D3D: - La resolución en la que se ejecuta el dispositivo (pantalla completa). - La relación de aspecto físico del monitor (como fracción y flotante: 1, por ejemplo, para 4: 3 y 1.33). - La relación de aspecto de la resolución de origen (la resolución de origen en sí es algo discutible y nos dice poco más que la relación de aspecto que el renderizado desea y el tipo de resolución que sería ideal para ejecutar).

Entonces nos encontramos con esto:

// -- figure out aspect ratio adjusted VPs  -- 

m_nativeVP.Width = xRes;
m_nativeVP.Height = yRes;
m_nativeVP.X = 0;
m_nativeVP.Y = 0;
m_nativeVP.MaxZ = 1.f;
m_nativeVP.MinZ = 0.f;

FIX_ME // this does not cover all bases -- fix!
uint xResAdj, yResAdj;  
if (g_displayAspectRatio.Get() < g_renderAspectRatio.Get())
{
    xResAdj = xRes;
    yResAdj = (uint) ((float) xRes / g_renderAspectRatio.Get());
}
else if (g_displayAspectRatio.Get() > g_renderAspectRatio.Get())
{
    xResAdj = (uint) ((float) yRes * g_renderAspectRatio.Get());
    yResAdj = yRes;     
}
else // ==
{
    xResAdj = xRes;
    yResAdj = yRes;
}

m_fullVP.Width = xResAdj;
m_fullVP.Height = yResAdj;
m_fullVP.X = (xRes - xResAdj) >> 1; 
m_fullVP.Y = (yRes - yResAdj) >> 1; 
m_fullVP.MaxZ = 1.f;
m_fullVP.MinZ = 0.f;

Ahora, siempre que g_displayAspectRatio iguale la relación de xRes / yRes (= adaptado de la resolución del dispositivo), todo está bien y este código hará lo que se espera de él. Pero tan pronto como esos 2 valores ya no están relacionados (por ejemplo, alguien ejecuta una resolución de 4: 3 en una pantalla de 16:10, estirada por hardware) se requiere otro paso para compensar, y tengo problemas para averiguar cómo exactamente .

(y p.s uso yesos de estilo C en tipos atómicos, vivo con él :-))

¿Fue útil?

Solución

Supongo que lo que quieres lograr es un "cuadrado". proyección, p. cuando dibujas un círculo, quieres que se vea como un círculo en lugar de una elipse.

Lo único con lo que debes jugar es con la relación de aspecto de la proyección (cámara). En casos normales, los monitores mantienen los píxeles cuadrados y todo lo que tiene que hacer es configurar la relación de aspecto de su cámara igual a la relación de aspecto de su ventana gráfica:

viewport_aspect_ratio = viewport_res_x / viewport_res_y;
camera_aspect_ratio = viewport_aspect_ratio;

En el caso extendido que describe (imagen 4: 3 extendida en una pantalla de 16:10, por ejemplo), los píxeles ya no son cuadrados y debe tener eso en cuenta en la relación de aspecto de su cámara:

stretch_factor_x = screen_size_x / viewport_res_x;
stretch_factor_y = screen_size_y / viewport_res_y;
pixel_aspect_ratio = stretch_factor_x / stretch_factor_y;
viewport_aspect_ratio = viewport_res_x / viewport_res_y;
camera_aspect_ratio = viewport_aspect_ratio * pixel_aspect_ratio;

Donde screen_size_x y screen_size_y son múltiplos del tamaño real del monitor (por ejemplo, 16:10).

Sin embargo, simplemente debe asumir píxeles cuadrados (a menos que tenga una razón específica para no hacerlo), ya que el monitor puede informar al sistema información incorrecta del tamaño físico, o ninguna información. Además, los monitores no siempre se estiran, el mío, por ejemplo, mantiene una relación de aspecto de 1: 1 píxeles y agrega bordes negros para resoluciones más bajas.

Editar

Si desea ajustar su ventana gráfica a una relación de aspecto y ajustarla en una resolución arbitraria, puede hacer eso:

viewport_aspect_ratio = 16.0 / 10.0; // The aspect ratio you want your viewport to have
screen_aspect_ratio = screen_res_x / screen_res_y;

if (viewport_aspect_ratio > screen_aspect_ratio) {
    // Viewport is wider than screen, fit on X
    viewport_res_x = screen_res_x;
    viewport_res_y = viewport_res_x / viewport_aspect_ratio;
} else {
    // Screen is wider than viewport, fit on Y
    viewport_res_y = screen_res_y;
    viewport_res_x = viewport_res_y * viewport_aspect_ratio;
}

camera_aspect_ratio = viewport_res_x / viewport_res_y;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top