Este artículo contiene una colección de preguntas más frecuentes (P+F) sobre Microsoft DirectX.
Problemas generales de desarrollo de DirectX
¿Los desarrolladores de juegos deberían preocuparse por admitir ediciones x64?
Totalmente. La tecnología x64 está ampliamente disponible en el mercado. La mayoría de las CPU nuevas vendidas en los últimos años, y casi todas las líneas de procesador en desarrollo de AMD e Intel, son compatibles con x64. Windows XP Professional x64 Edition ha introducido la tecnología de habilitación del sistema operativo para x64 publicada en abril de 2005. Dado que las ediciones x64 requieren una nueva generación de controladores nativos de 64 bits, esta primera versión se limitó a la distribución OEM.
Con Windows Vista, los clientes pueden elegir ediciones de 32 o 64 bits al comprar equipos basados en Windows y las licencias de Windows Vista son válidas para las ediciones de 32 o 64 bits del sistema operativo. Además, hay muchos controladores de 64 bits disponibles en la caja y los fabricantes de dispositivos son necesarios para proporcionar controladores nativos de 32 y 64 bits como parte del programa de certificación de Windows.
Todos estos factores aumentarán considerablemente las implementaciones de ediciones de 64 bits de Windows. A medida que los nuevos equipos comienzan a enviarse con más de 2 GB de RAM física, el incentivo para usar un sistema operativo de 32 bits disminuye considerablemente en favor de las ediciones de 64 bits. La tecnología de sesenta y cuatro bits es totalmente compatible con código nativo de 32 bits, aunque se requieren implementaciones nativas de 64 bits para aprovechar al máximo el nuevo espacio de memoria de 64 bits. Cada aplicación de 32 bits debe tener compatibilidad de 64 bits como requisito mínimo de envío y cumplir ese requisito es un requisito de línea base para la compatibilidad de Windows Vista. Por lo general, las incompatibilidades se derivan del uso de código de 16 bits diseñado para el sistema operativo Windows 3.1 o de la instalación de controladores que no se proporcionan en formulario nativo de 32 y 64 bits.
Para obtener más información sobre la tecnología de 64 bits, consulte programación de 64 bits para desarrolladores de juegos.
¿Deberían seguir publicando juegos para Windows 95, Windows 98 o Windows ME?
Ya no por dos razones: rendimiento y conjunto de características.
Si la velocidad mínima de CPU necesaria para su juego es de 1,2 GHz o superior (que es más común para los títulos de alto rendimiento), la gran mayoría de los equipos elegibles ejecutarán Windows XP. En el momento en que se vendían equipos con velocidades de CPU superiores a 1,2 GHz, Windows XP se instaló como sistema operativo predeterminado por casi todos los fabricantes. Esto significa que hay muchas características que se encuentran en Windows XP que los desarrolladores de juegos actuales deben aprovechar las ventajas de incluir:
- Se ha mejorado la multitarea, lo que da como resultado una mejor experiencia más suave para vídeo, audio y juegos.
- Modelo de controlador de vídeo más estable, lo que permite una depuración más sencilla, un juego más suave y un mejor rendimiento.
- Configuración más sencilla para las redes, lo que permite un acceso más sencillo a los juegos de varios jugadores.
- Admite de manera predeterminada transferencias DMA desde discos duros, lo que permite cargar las aplicaciones con mayor fluidez y rapidez.
- Informes de errores de Windows: lo que da como resultado un sistema operativo, controladores y aplicaciones más estables.
- Compatibilidad con Unicode: lo que simplifica considerablemente los problemas de localización.
- Mejor seguridad y estabilidad, lo que da lugar a mejores experiencias de consumidor.
- Mejor compatibilidad con hardware moderno: la mayoría de los cuales ya no usa controladores de Windows 98.
- Administración mejorada de memoria, lo que da como resultado una mejor estabilidad y seguridad.
- Sistema de archivos NTFS mejorado, que es más resistente a los errores y tiene un mejor rendimiento con las características de seguridad.
¿Deberían seguir publicando juegos para Windows 2000?
Nunca más. Además de las razones enumeradas en ¿Los desarrolladores de juegos siguen publicando juegos para Windows 95, Windows 98 o Windows ME?, Windows 2000 no tiene estas características:
- Windows XP admite características avanzadas del procesador, como Hyper-Threading, Multi-Core y x64.
- Windows XP admite componentes en paralelo que reducen significativamente los conflictos de control de versiones de aplicaciones.
- Windows XP admite la protección de memoria sin ejecutar, lo que ayuda a evitar programas malintencionados y puede ayudar a la depuración.
- Windows XP ha mejorado la compatibilidad con tarjetas de vídeo avanzadas basadas en AGP y PCI Express.
- Windows XP admite el cambio de usuario rápido, el escritorio remoto y la asistencia remota, lo que puede ayudar a reducir los costes de soporte técnico de los productos.
- Las herramientas de rendimiento como PIX (en el SDK para desarrolladores de DirectX) ya no admiten Windows 2000.
En resumen, Windows 2000 nunca se ha diseñado ni comercializado como un sistema operativo de consumo.
¿Cuáles son las diferencias entre las distintas ediciones de Windows Vista? ¿Cómo afectan a mi aplicación DirectX?
La familia Windows Vista incluye cinco ediciones:
- Windows Vista Home Basic
- Windows Vista Home Premium
- Windows Vista Business
- Windows Vista Enterprise
- Windows Vista Ultimate
Home Basic y Home Premium son versiones centradas en el consumidor, con características como Family Safety (anteriormente conocidos como Controles Parentales) y Home Premium incluye Media Center. Empresas y Business son ediciones centradas en las empresas, con características como la unión de dominios y los servicios de terminal/escritorio remoto. La edición Ultimate combina todas las características de las ediciones consumidor y corporativa en una versión. Todas las ediciones vienen en ediciones de 32 bits (x86) y de 64 bits (x64) y los usuarios pueden usar el mismo identificador de producto para ambas plataformas.
La tecnología subyacente a las distintas ediciones es idéntica y todas tienen la misma versión del entorno de ejecución de DirectX y otros componentes. Sin embargo, las ediciones tienen algunas diferencias menores con respecto a los juegos:
- El explorador de juegos existe en todas las ediciones, pero el acceso directo a los juegos en el menú Inicio solo está en Home Basic, Home Premium y Ultimate. El explorador de juegos todavía se puede encontrar en todas las ediciones (haciendo clic en Inicio, todos los programas y después en Juegos) y las funciones de interfaz IGameExplorer en todas las ediciones.
- Los juegos que se incluyen con Windows no están disponibles de manera predeterminada en Business y Enterprise, pero el administrador puede habilitarlo.
- Las clasificaciones de Family Safety y de los juegos no se muestran ni influyen en el comportamiento de Business o Enterprise, y se deshabilitan en Ultimate cuando se une un dominio.
La configuración de Control de cuentas de usuario tiene los mismos valores predeterminados en todas las ediciones, pero se pueden invalidar mediante la configuración de directiva de grupo para el dominio en Business, Enterprise y Ultimate. Por ejemplo, la configuración de directiva en control de cuentas de usuario: el comportamiento de la solicitud de elevación para usuarios estándar bien puede estar configurada en denegar automáticamente las solicitudes de elevación en muchos entornos empresariales para mejorar la seguridad, y muchos usuarios en esos entornos siempre se ejecutarán como usuarios estándar sin la posibilidad siquiera de elegir ejecutarse como administrador. Cualquier programa (como un instalador) que requiera derechos administrativos, ya sea debido a la detección de configuración heredada o a tener un manifiesto que especifique el nivel de ejecución solicitado como "requireAdministrator", siempre no podrá iniciarse en tales situaciones. Otras configuraciones de directiva, como el control de cuentas de usuario: solo elevan los archivos ejecutables firmados y validados, también pueden impedir que el instalador funcione si no firma el archivo ejecutable mediante Authenticode.
Estos tipos de cambios de directiva se pueden aplicar a cualquier edición de Windows Vista, pero es más probable que se encuentren en equipos unidos a un dominio.
¿Cuáles son las diferencias entre las distintas ediciones de Windows 7? ¿Cómo afectan a mi aplicación DirectX?
La mayoría de los usuarios de Windows 7 probablemente tendrán una de estas dos ediciones: Windows 7 Home Premium, para usuarios domésticos o Windows 7 Professional, para usuarios empresariales y desarrolladores. Para grandes empresas, hay la edición de Windows 7 Enterprise con licencia por volumen, que incluye todas las características de Windows 7; Windows 7 Ultimate es el equivalente comercial de esa edición.
Windows 7 Starter Edition está disponible en todo el mundo para los fabricantes de equipos originales, y se espera que se implemente primordialmente con ultraportátil, equipos de cuadernos ultra bajo consumo. Windows 7 Home Basic solo está disponible en los mercados emergentes.
Tenga en cuenta que todas las ediciones de Windows 7 (excepto Starter Edition) están disponibles tanto para versiones de 32 bits (x86) como de 64 bits (x64) y todos los paquetes comerciales de Windows 7 incluyen medios para ambas versiones. Al igual que con Windows Vista, los usuarios pueden usar el mismo identificador de producto comercial en cualquiera de las plataformas.
La tecnología subyacente en las distintas ediciones son idénticas, y todas las ediciones tienen la misma versión del tiempo de ejecución de DirectX y otros componentes. Tienen algunas diferencias con respecto a las características de juego:
- El explorador de juegos está disponible en todas las ediciones, pero el acceso directo a juegos del menú Inicio está oculto de manera predeterminada en Windows 7 Professional y Enterprise. Todavía se puede encontrar el Explorador de juegos en el menú Inicio (haciendo clic en todos los programas y luego pulsando dos veces en Juegos), y el usuario puede habilitar el acceso directo a Juegos.
- Todos los juegos que se incluyen con Windows no están disponibles de manera predeterminada en Windows 7 Professional y Enterprise, pero pueden ser habilitados por el administrador.
- Las clasificaciones de seguridad y juegos familiares están disponibles en todas las ediciones, pero están deshabilitadas en Windows 7 Professional, Enterprise y Ultimate cuando el sistema operativo se une a un dominio. Al igual que con Windows Vista Ultimate, esta característica se puede volver a habilitar en el equipo que se ha unido a un dominio.
La configuración de control de cuentas de usuario (UAC) puede verse afectada por la configuración de directiva de grupo en las ediciones Windows 7 Professional, Enterprise y Ultimate, de forma muy similar a Windows Vista. Para obtener más información, consulte ¿Cuáles son las diferencias entre las distintas ediciones de Windows Vista? ¿Cómo afectan a mi aplicación DirectX?
¿DirectX 10 estará disponible para Windows XP?
No. Windows Vista, que tiene DirectX 10, incluye un tiempo de ejecución de DirectX actualizado basado en el tiempo de ejecución en Windows XP SP2 (DirectX 9.0c) con cambios para trabajar con el nuevo modelo de controlador de pantalla de Windows (WDDM) y la nueva pila de controladores de audio, y con otras actualizaciones en el sistema operativo. Además de Direct3D 9, Windows Vista admite dos interfaces nuevas cuando el hardware y los controladores de vídeo correctos están presentes: Direct3D9Ex y Direct3D10.
Dado que estas nuevas interfaces dependen de la tecnología WDDM, nunca estarán disponibles en versiones anteriores de Windows. Todos los demás cambios realizados en las tecnologías DirectX para Windows Vista también son específicos de la nueva versión de Windows. El nombre DirectX 10 es engañoso en que muchas tecnologías que se envían en el SDK de DirectX (XACT, XINPUT, D3DX) no están incluidos en este número de versión. Por lo tanto, hacer referencia al número de versión del tiempo de ejecución de DirectX en su conjunto ha perdido gran parte de su significado, incluso para 9.0c. La herramienta de diagnóstico de DirectX (DXdiag.exe) en Windows Vista notifica DirectX 10, pero esto solo hace referencia a Direct3D 10.
¿DirectX 11 estará disponible para Windows Vista o Windows XP?
DirectX 11 está integrado en Windows 7 y está disponible como una actualización para Windows Vista (consulte https://go.microsoft.com/fwlink/p/?linkid=160189). Esto incluye la API Direct3D 11, la infraestructura gráfica DirectX (DXGI) 1.1, los niveles de características 10Level9, el dispositivo de renderizado por el software de la plataforma de rasterización avanzada de Windows (WARP) 10, Direct2D, DirectWrite y una actualización de la API Direct3D 10.1 para que sea compatible con 10Level9 y WARP 10.
Por las mismas razones indicadas en la pregunta anterior (¿DirectX 10 estará disponible para Windows XP? ), Direct3D 11 y las API relacionadas no están disponibles en Windows XP.
¿Qué le pasó a DirectShow? No puedo encontrarlo en el SDK de DirectX.
DirectShow se ha quitado del SDK de DirectX a partir de abril de 2005. Puede obtener los encabezados, bibliotecas, herramientas y ejemplos de DirectShow en el Kit de desarrollo de software de Windows (anteriormente conocido como SDK de plataforma). DirectSetup en el SDK de DirectX sigue admitiendo la redistribución de los componentes del sistema de DirectShow, y los componentes más recientes ya están instalados en los siguientes sistemas operativos: Microsoft Windows XP Service Pack 2, Windows XP Professional x64 Edition, Windows Server 2003 Service Pack 1 y Windows Vista.
¿Qué cambios se realizaron en el entorno de ejecución de DirectX para Windows Vista?
Los cambios principales se realizaron para admitir el nuevo WDDM. Para obtener más información sobre el nuevo modelo de controladores, sobre los impactos en Direct3D 9 y en las dos nuevas interfaces de gráficos, Direct3D 9Ex y Direct3D 10, revise Las API de gráficos en Windows. Las nuevas API de gráficos para Windows 7: Direct3D 11, Direct2D, DirectWrite, DXGI 1.1 y una direct3D 10.1 actualizada están disponibles como actualización para Windows Vista (consulte https://go.microsoft.com/fwlink/p/?linkid=160189).
Windows Vista Service Pack 1 incluye una versión actualizada del entorno de ejecución de DirectX. Esta actualización amplía la compatibilidad con Windows Vista para incluir Direct3D 10.1, exponiendo nuevas características de hardware opcionales. (Todo el hardware que es capaz de admitir Direct3D 10.1 también es totalmente compatible con todas las características de Direct3D 10.)
DirectSound se ha actualizado para exponer las funcionalidades de la nueva pila de controladores de audio de Windows Vista, que admite búferes de software de varios canales. La API de modo retenido de Direct3D se ha quitado completamente de Windows Vista. DirectPlay Voice también se ha quitado, así como la interfaz de usuario del asistente NAT de DirectPlay y del asignador de acciones de DirectInput. La compatibilidad con las interfaces DirectX 7 y DirectX 8 para Visual Basic 6.0 no está disponible en Windows Vista.
¿Qué cambios se realizaron en el entorno de ejecución de DirectX para Windows 7?
Windows 7 incluye todos los componentes en tiempo de ejecución de DirectX que se encuentran en Windows Vista y agrega Direct3D 11, DXGI 1.1, 10Level9 niveles de características, el dispositivo de software WARP10, Direct2D, DirectWrite y una actualización de Direct3D 10.1 para admitir 10Level9 y WARP10. Para obtener más información, consulte Api de gráficos en Windows.
Todos los demás componentes son idénticos a Windows Vista, con la adición de compatibilidad nativa de 64 bits (x64) para la API principal de DirectMusic relacionada con MIDI con marca de tiempo. La capa de rendimiento de DirectMusic permanece en desuso y solo está disponible para aplicaciones de 32 bits en Windows 7 para la compatibilidad de aplicaciones. Tenga en cuenta que la compatibilidad nativa de 64 bits de DirectMusic no está disponible en Windows Vista.
Creo que he encontrado un error de conductor, ¿qué debo hacer?
Antes de nada, asegúrese de haber comprobado los resultados con el rasterizador de referencia. A continuación, compruebe los resultados con la versión más reciente certificada WHQL del controlador IHVs. Puede comprobar mediante programación el estado de WHQL mediante el método GetAdapterIdentifier() en la interfaz IDirect3D9 pasando la marca D3DENUM_WHQL_LEVEL.
¿Por qué obtengo tantos mensajes de error al intentar compilar los ejemplos?
Probablemente no tenga la ruta de acceso de inclusión establecida correctamente. Muchos compiladores, incluido Microsoft Visual C++, incluyen una versión anterior del SDK, por lo que si la ruta de acceso de inclusión busca primero los directorios de inclusión del compilador estándar, obtendrá versiones incorrectas de los archivos de encabezado. Para solucionar este problema, asegúrese de que la ruta de acceso de inclusión y las rutas de acceso de biblioteca están establecidas para buscar primero las rutas de acceso de la biblioteca e inclusión de Microsoft DirectX. Consulte también el archivo dxreadme.txt en el SDK. Si instala el SDK de DirectX y usa Visual C++, el instalador puede configurar opcionalmente las rutas de acceso de inclusión.
Obtengo errores del enlazador acerca de varios o que faltan símbolos para identificadores únicos globales (GUID), ¿qué debo hacer?
Los distintos GUID que use se deben definir una vez y solo una vez. La definición del GUID se insertará si #define el símbolo INITGUID antes de incluir los archivos de encabezado DirectX. Por lo tanto, debe asegurarse de que esto solo se produce para una unidad de compilación. Una alternativa a este método es vincular con la biblioteca dxguid.lib, que contiene definiciones para todos los GUID de DirectX. Si usa este método (que se recomienda), nunca debe #define el símbolo INITGUID.
¿Puedo convertir un puntero a una interfaz de DirectX a un número de versión inferior?
No. Las interfaces de DirectX son interfaces COM. Esto significa que no es necesario que las interfaces numeradas más altas se deriven de las correspondientes con números inferiores. Por lo tanto, la única manera segura de obtener una interfaz diferente a un objeto DirectX es usar el método QueryInterface de la interfaz. Este método forma parte de la interfaz IUnknown estándar, de la que deben derivarse todas las interfaces COM.
¿Puedo mezclar el uso de componentes de DirectX 9 y DirectX 8 o componentes anteriores dentro de la misma aplicación?
Puede mezclar libremente diferentes componentes de versión diferente; por ejemplo, podría usar DirectInput 8 con Direct3D 9 en la misma aplicación. Sin embargo, por lo general no puede mezclar versiones diferentes del mismo componente dentro de la misma aplicación; por ejemplo, no se puede mezclar DirectDraw 7 con Direct3D 9 (ya que estos son efectivamente el mismo componente que DirectDraw se ha subsumido en Direct3D a partir de DirectX 8). Sin embargo, hay excepciones, como el uso de Direct3D 9 y Direct3D 10 juntos en la misma aplicación, que se permite.
¿Puedo mezclar el uso de Direct3D 9 y Direct3D 10 dentro de la misma aplicación?
Sí, puede usar estas versiones de Direct3D juntas en la misma aplicación.
¿Qué significan los valores devueltos de los métodos Release o AddRef?
El valor devuelto será el recuento de referencias actual del objeto. Sin embargo, la especificación COM indica que no debe confiar en esto y el valor solo está disponible con carácter general para fines de depuración. Los valores que observe pueden ser inesperados, ya que otros objetos del sistema pueden contener referencias a los objetos DirectX que cree. Por este motivo, no debe escribir código que llame repetidamente a Release hasta que el recuento de referencias sea cero, ya que el objeto puede liberarse aunque otro componente todavía esté haciendo referencia a él.
¿Importa en qué orden ha liberado interfaces de DirectX?
No debe importar porque se cuentan las interfaces COM. Sin embargo, hay algunos errores conocidos con el orden de lanzamiento de las interfaces en algunas versiones de DirectX. Para la seguridad, se recomienda liberar interfaces en orden de creación inversa siempre que sea posible.
¿Qué es un puntero inteligente y debo usarlo?
Un puntero inteligente es una clase de plantilla de C++ diseñada para encapsular la funcionalidad de puntero. En concreto, hay clases de puntero inteligente estándar diseñadas para encapsular punteros de interfaz COM. Estos punteros realizan automáticamente QueryInterface en lugar de una conversión y controlan AddRef y Release automáticamente. Si debe usarlos en gran medida es una cuestión de gusto. Si el código contiene una gran cantidad de copias de punteros de interfaz, con varios AddRefs y Releases, es probable que los punteros inteligentes puedan hacer que el código sea más ordenado y menos propenso a errores. De lo contrario, puede hacerlo sin ellos. Visual C++ incluye un puntero inteligente COM estándar de Microsoft, definido en el archivo de encabezado "comdef.h" (busque com_ptr_t en la ayuda).
Tengo problemas para depurar mi aplicación DirectX, ¿alguna sugerencia?
El problema más común con la depuración de aplicaciones DirectX es intentar depurar mientras se bloquea una superficie de DirectDraw. Esta situación puede provocar un "Bloqueo win16" en sistemas Microsoft Windows 9x, lo que impide que la ventana del depurador pinte. La especificación de la marca D3DLOCK_NOSYSLOCK al bloquear la superficie normalmente puede eliminarla. Windows 2000 no sufre este problema. Al desarrollar una aplicación, resulta útil ejecutarse con la versión de depuración del entorno de ejecución de DirectX (seleccionado al instalar el SDK), que realiza algunas validaciones de parámetros y genera mensajes útiles a la salida del depurador.
¿Cuál es la manera correcta de comprobar los códigos de retorno?
Use las macros EXITOSO y FALLIDO. Los métodos DirectX pueden devolver varios códigos de éxito y error, por lo que es sencillo:
== D3D_OK
o una prueba similar no siempre será suficiente.
¿Cómo se deshabilita ALT+TAB y otra conmutación de tareas?
¡Usted no! Los juegos deben ser capaces de controlar el cambio de tareas correctamente, ya que muchas cosas hacen que suceda: ALT+TAB, conexiones de escritorio remoto, cambio rápido de usuario, límites de uso de controles parentales y muchos otros eventos.
Al mismo tiempo, dos orígenes comunes de cambio accidental de tareas en juegos con esquemas de control centrados en teclado presionan la tecla del logotipo de Windows y activan la característica de accesibilidad StickyKeys con la tecla MAYÚS. Para solucionar estos casos deshabilitando la funcionalidad, consulte las técnicas descritas en Deshabilitar teclas de método abreviado en Juegos.
¿Hay un libro recomendado que explique COM?
Dentro de COM por Dale Rogerson, publicado por Microsoft Press, es una excelente introducción a COM. Para obtener un vistazo más detallado a COM, el libro Essential COM de Don Box, publicado por Longman, también es muy recomendable.
¿Qué es el código administrado?
El código administrado es código que tiene su ejecución administrada por Common Language Runtime (CLR) de .NET Framework. Hace referencia a un contrato de cooperación entre la ejecución nativa de código y el tiempo de ejecución. Este contrato especifica que en cualquier punto de ejecución, el tiempo de ejecución puede detener una CPU en ejecución y recuperar información específica de la dirección de instrucción de CPU actual. La información que debe ser capaz de consultar generalmente pertenece al estado en tiempo de ejecución, como el registro o el contenido de la memoria de pila.
Antes de ejecutar el código, el IL se compila en código ejecutable nativo. Además, dado que esta compilación se produce mediante el entorno de ejecución administrado (o, más correctamente, por un compilador compatible con el entorno de ejecución en tiempo de ejecución que sabe cómo dirigirse al entorno de ejecución administrado), el entorno de ejecución administrado puede hacer garantías sobre lo que va a hacer el código. Puede insertar capturas y anclajes de colección de enlace no utilizados adecuados, control de excepciones, seguridad de tipos, límites de matriz y comprobación de índices, etc. Por ejemplo, este compilador se asegura de diseñar fotogramas de pila y todo justo para que el recolector de elementos no utilizados pueda ejecutarse en segundo plano en un subproceso independiente, caminando constantemente la pila de llamadas activa, buscando todas las raíces, persiguiendo todos los objetos activos. Además, dado que el IL tiene una noción de seguridad de tipo, el motor de ejecución mantendrá la garantía de seguridad de tipo eliminando una clase completa de errores de programación que a menudo conducen a agujeros de seguridad.
A diferencia de esto, en el mundo no administrado: los archivos ejecutables no administrados son básicamente una imagen binaria, código x86, cargado en memoria. El contador del programa se pone ahí y eso es el último que sabe el sistema operativo. Hay protecciones en vigor en torno a la administración de memoria y la E/S del puerto, etc., pero el sistema no sabe realmente lo que hace la aplicación. Por lo tanto, no puede garantizar lo que sucede cuando se ejecuta la aplicación.
¿Qué libros hay sobre la programación general de Windows?
Muchos. Sin embargo, los dos que son muy recomendados son:
- Programación de Windows por Charles Petzold (Microsoft Press)
- Aplicaciones de programación para Windows por Jeffrey Richter (Microsoft Press)
¿Cómo puedo depurar utilizando los archivos de símbolos de Windows?
Microsoft publica símbolos eliminados para todos los archivos DLL del sistema (además de algunos otros). Para acceder a ellos, agregue lo siguiente a la ruta de acceso del símbolo en la configuración del proyecto dentro de Visual Studio:
srv*https://msdl.microsoft.com/download/symbols
para almacenar los símbolos en caché localmente, use la sintaxis siguiente:
srv*c:\cache*https://msdl.microsoft.com/download/symbols
Donde c:\cache es un directorio local para almacenar en caché los archivos de símbolos.
Preguntas sobre Direct3D
Preguntas generales de Direct3D
¿Dónde puedo encontrar información sobre las técnicas de gráficos 3D?
El libro estándar sobre el tema es Computer Graphics: Principles and Practice by Foley, Van Dam et al. Es un recurso valioso para cualquier persona que quiera comprender las bases matemáticas de la geometría, la rasterización y las técnicas de iluminación. Las preguntas más frecuentes del grupo Usenet comp.graphics.algorithms también contienen material útil.
¿Direct3D emula la funcionalidad no proporcionada por el hardware?
Depende. Direct3D tiene una canalización de procesamiento de vértices de software completa (incluida la compatibilidad con sombreadores de vértices personalizados). Sin embargo, no se proporciona ninguna emulación para las operaciones de nivel de píxel; las aplicaciones deben comprobar los bits de límite adecuados y usar la API ValidateDevice para determinar la compatibilidad.
¿Hay un rasterizador de software incluido con Direct3D?
No para las aplicaciones de rendimiento. Se proporciona un rasterizador de referencia para la validación del controlador, pero la implementación está diseñada para la precisión y no para el rendimiento. Direct3D admite rasterizadores de software de complemento.
¿Cómo puedo realizar el uso de teclas de color con gráficos DirectX?
Las teclas de color no se admiten directamente, sino que tendrá que usar la combinación alfa para emular las teclas de color. La función D3DXCreateTextureFromFileEx() se puede usar para facilitar esto. Esta función acepta un parámetro de color de clave y reemplazará todos los píxeles de la imagen de origen que contiene el color especificado por píxeles negros transparentes en la textura creada.
¿Usa el código de geometría de Direct3D 3DNow! ¿o Instrucciones SIMD de Pentium III?
Sí. ¡La canalización de geometría de Direct3D tiene varias rutas de acceso de código diferentes, según el tipo de procesador, y usará las operaciones de punto flotante especiales proporcionadas por 3DNow! o las instrucciones SIMD de Pentium III en las que están disponibles. Esto incluye el procesamiento de sombreadores de vértices personalizados.
¿Cómo se impide que se escriban píxeles transparentes en el búfer z?
Puede filtrar píxeles con un valor alfa por encima o por debajo de un umbral determinado. Este comportamiento se controla mediante los estados de representación ALPHATESTENABLE, ALPHAREF y ALPHAFUNC.
¿Qué es un búfer de galería de símbolos?
Un búfer de galería de símbolos es un búfer adicional de información por píxel, como un búfer z. De hecho, reside en algunos de los bits de un búfer z. Los formatos comunes de galería de símbolos/z-buffer son de 15 bits z y galería de símbolos de 1 bits, o galería de símbolos z y 8 bits de 24 bits. Es posible realizar operaciones aritméticas simples en el contenido del búfer de galerías de símbolos por píxel a medida que se representan polígonos. Por ejemplo, el búfer de galería de símbolos se puede incrementar o disminuir, o bien se puede rechazar el píxel si el valor de la galería de símbolos produce un error en una prueba de comparación simple. Esto es útil para efectos que implican marcar una región del búfer de fotogramas y a continuación, realizar la representación solo de la región marcada (o sin marcar). Algunos ejemplos son efectos volumétricos, como volúmenes de sombras.
¿Cómo uso un búfer de galería de símbolos para representar volúmenes de sombras?
La clave de este y otros efectos de búfer de galería de símbolos volumétricos es la interacción entre el búfer de galería de símbolos y el búfer z. Una escena con un volumen de sombras se representa en tres fases. En primer lugar, la escena sin la sombra se representa como de costumbre mediante el búfer z. A continuación, la sombra se marca en el búfer de galería de símbolos como se indica a continuación. Las caras frontales del volumen de sombra se dibujan mediante polígonos invisibles, con z-testing habilitado, pero z-writes deshabilitados y el búfer de galería de símbolos se incrementa en cada píxel que pasa la prueba z. Las caras posteriores del volumen de sombra se representan de forma similar, pero disminuyendo el valor de la galería de símbolos en su lugar.
Ahora, considere un solo píxel. Suponiendo que la cámara no está en el volumen de sombras hay cuatro posibilidades para el punto correspondiente de la escena. Si el rayo de la cámara al punto no interseca el volumen de sombras, no se dibujarán polígonos de sombra allí y el búfer de galería de símbolos sigue siendo cero. De lo contrario, si el punto se encuentra delante del volumen de sombras, los polígonos de sombra se almacenarán en búfer z y la galería de símbolos de nuevo permanecerá sin cambios. Si los puntos se encuentran detrás del volumen de sombra, entonces se habrán representado el mismo número de caras de sombra frontal que las caras posteriores y la galería de símbolos será cero, habiendo sido incrementada tantas veces como disminuido.
La posibilidad final es que el punto se encuentra dentro del volumen de sombras. En este caso, la cara posterior del volumen de sombras se almacenará en búfer z, pero no la cara frontal, por lo que el búfer de galería de símbolos será un valor distinto de cero. El resultado es que las partes del búfer de fotogramas que se encuentran en la sombra tienen un valor de galería de símbolos distinto de cero. Por último, para representar realmente la sombra, toda la escena se lava con un polígono mezclado alfa establecido para que solo afecte a píxeles con un valor de galería de símbolos distinto de cero. Se puede ver un ejemplo de esta técnica en el ejemplo de "Volumen de sombras" que viene con el SDK de DirectX.
¿Cuáles son las reglas de alineación de elementos de textura? ¿Cómo puedo obtener una asignación uno a uno?
Esto se explica completamente en la documentación de Direct3D 9. Sin embargo, el resumen ejecutivo es que debe inclinar las coordenadas de la pantalla por -0,5 de un píxel para alinearse correctamente con los elementos de textura. La mayoría de las tarjetas ahora se ajustan correctamente a las reglas de alineación de elementos de textura, pero hay algunas tarjetas o controladores más antiguos que no. Para controlar estos casos, el mejor consejo es ponerse en contacto con el proveedor de hardware en cuestión y solicitar controladores actualizados o su solución alternativa sugerida. Tenga en cuenta que en Direct3D 10, esta regla ya no se mantiene.
¿Cuál es el propósito de la marca D3DCREATE\_PUREDEVICE?
Use la marca D3DCREATE_PUREDEVICE durante la creación del dispositivo para crear un dispositivo puro. Un dispositivo puro no guarda el estado actual (durante los cambios de estado), lo que a menudo mejora el rendimiento; este dispositivo también requiere el procesamiento de vértices de hardware. Normalmente, un dispositivo puro se usa cuando se completan el desarrollo y la depuración, y quiere lograr el mejor rendimiento.
Una desventaja de un dispositivo puro es que no admite todas las llamadas API Get*; esto significa que no puede usar un dispositivo puro para consultar el estado de la canalización. Esto dificulta la depuración mientras se ejecuta una aplicación. A continuación se muestra una lista de todos los métodos deshabilitados por un dispositivo puro.
- IDirect3DDevice9::GetClipPlane
- IDirect3DDevice9::GetClipStatus
- IDirect3DDevice9::GetLight
- IDirect3DDevice9::GetLightEnable
- IDirect3DDevice9::GetMaterial
- IDirect3DDevice9::GetPixelShaderConstantF
- IDirect3DDevice9::GetPixelShaderConstantI
- IDirect3DDevice9::GetPixelShaderConstantB
- IDirect3DDevice9::GetRenderState
- IDirect3DDevice9::GetSamplerState
- IDirect3DDevice9::GetTextureStageState
- IDirect3DDevice9::GetTransform
- IDirect3DDevice9::GetVertexShaderConstantF
- IDirect3DDevice9::GetVertexShaderConstantI
- IDirect3DDevice9::GetVertexShaderConstantB
Un segundo inconveniente de un dispositivo puro es que no filtra ningún cambio de estado redundante. Cuando se usa un dispositivo puro, la aplicación debe reducir el número de cambios de estado en el bucle de representación a un mínimo; esto puede incluir cambios de estado de filtrado para asegurarse de que los estados no se establezcan más de una vez. Esta compensación depende de la aplicación; si utiliza más de 1000 llamadas de conjunto por trama, debería considerar la posibilidad de aprovechar el filtrado de redundancia que realiza automáticamente un dispositivo no puro.
Al igual que con todos los problemas de rendimiento, la única manera de saber si la aplicación funcionará mejor con un dispositivo puro es comparar el rendimiento de la aplicación con un dispositivo puro frente a no puro. Un dispositivo puro tiene el potencial de acelerar una aplicación al reducir la sobrecarga de CPU de la API. ¡Pero, tenga cuidado! En algunos escenarios, un dispositivo puro ralentizará la aplicación (debido al trabajo adicional de CPU causado por cambios de estado redundantes). Si no está seguro de qué tipo de dispositivo funcionará mejor para la aplicación y no filtra los cambios redundantes en la aplicación, use un dispositivo no puro.
¿Cómo se enumeran los dispositivos de visualización en un sistema de varios monitores?
La enumeración se puede realizar a través de una iteración simple por parte de la aplicación mediante métodos de la interfaz IDirect3D9. Llame a GetAdapterCount para determinar el número de adaptadores de pantalla en el sistema. Llame a GetAdapterMonitor para determinar a cuál monitor físico está conectado un adaptador (este método devuelve un HMONITOR, que luego puede usar en la API De Win32 GetMonitorInfo para determinar información sobre el monitor físico). Determinar las características de un adaptador de pantalla determinado o crear un dispositivo Direct3D en ese adaptador es tan sencillo como pasar el número de adaptador adecuado en lugar de D3DADAPTER_DEFAULT al llamar a GetDeviceCaps, CreateDevice u otros métodos.
¿Qué ha ocurrido con la función Fixed de la asignación de protuberancias en D3D9?
A partir de Direct3D 9 ajustamos la validación en tarjetas que solo podían admitir > 2 texturas simultáneas. Algunas tarjetas anteriores solo tienen 3 fases de textura disponibles cuando se usa una operación específica de modulación alfa. El uso más común para el que las personas utilizan las 3 etapas es el mapeo de relieve, y todavía se puede hacer esto con D3D9.
El campo de altura debe almacenarse en el canal alfa y se usa para modular la contribución de las luces, es decir:
// Stage 0 is the base texture, with the height map in the alpha channel
m_pd3dDevice->SetTexture(0, m_pEmbossTexture );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
if( m_bShowEmbossMethod )
{
// Stage 1 passes through the RGB channels (SELECTARG2 = CURRENT), and
// does a signed add with the inverted alpha channel.
// The texture coords associated with Stage 1 are the shifted ones, so
// the result is:
// (height - shifted_height) * tex.RGB * diffuse.RGB
m_pd3dDevice->SetTexture( 1, m_pEmbossTexture );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_ADDSIGNED );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE|D3DTA_COMPLEMENT );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
// Set up the alpha blender to multiply the alpha channel
// (monochrome emboss) with the src color (lighted texture)
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
}
Este ejemplo, junto con otros ejemplos anteriores, ya no se incluyen en la versión actual del SDK y no se enviarán en futuras versiones del SDK.
Procesamiento de geometría (vértice)
Los flujos de vértices son muy confusos, ¿cómo funcionan?
Direct3D ensambla cada vértice que se introduce en la parte de procesamiento de la canalización desde uno o varios flujos de vértices. Tener solo una secuencia de vértices corresponde al modelo anterior a DirectX 8 anterior, en el que los vértices proceden de un único origen. Con DirectX 8, los distintos componentes de los vértices pueden proceder de diferentes orígenes; por ejemplo, un búfer de vértices puede contener posiciones y normales, mientras que un segundo contiene valores de color y coordenadas de textura.
¿Qué es un sombreador de vértices?
Un sombreador de vértices es un procedimiento para procesar un solo vértice. Se define mediante un lenguaje de tipo ensamblado simple que la biblioteca de utilidades D3DX ensambla en una secuencia de tokens que Acepta Direct3D. El sombreador de vértices toma como entrada un solo vértice y un conjunto de valores constantes; genera una posición de vértice (en el espacio de clip) y, opcionalmente, un conjunto de colores y coordenadas de textura, que se usan en la rasterización. Tenga en cuenta que cuando tiene un sombreador de vértices personalizado, los componentes de vértices ya no tienen ninguna semántica aplicada por Direct3D y los vértices son simplemente datos arbitrarios interpretados por el sombreador de vértices que cree.
¿Un sombreador de vértices realiza una división o recorte de perspectiva?
No. El sombreador de vértices genera una coordenada homogéneo en el espacio de clip para la posición transformada del vértice. La división de perspectiva y el recorte se realizan automáticamente después del sombreador.
¿Puedo generar geometría con un sombreador de vértices?
Un sombreador de vértices no puede crear ni destruir vértices; funciona en un solo vértice cada vez, tomando un vértice sin procesar como entrada y salida de un solo vértice procesado. Por lo tanto, se puede usar para manipular la geometría existente (aplicar deformaciones o realizar operaciones de skinning), pero no puede generar realmente una nueva geometría en sí.
¿Puedo aplicar un sombreador de vértices personalizado a los resultados de la canalización de geometría de función fija (o viceversa)?
No. Tiene que elegir uno u otro. Si usa un sombreador de vértices personalizado, es responsable de realizar toda la transformación de vértices.
¿Puedo usar un sombreador de vértices personalizado si mi hardware no lo admite?
Sí. El motor de procesamiento de vértices de software de Direct3D es totalmente compatible con sombreadores de vértices personalizados con un nivel sorprendentemente alto de rendimiento.
¿Cómo puedo determinar si el hardware admite mi sombreador de vértices personalizado?
Los dispositivos compatibles con sombreadores de vértices en hardware son necesarios para rellenar el campo D3DCAPS9::VertexShaderVersion para indicar el nivel de versión del sombreador de vértices que admiten. Cualquier dispositivo que solicite admitir un nivel determinado de sombreador de vértices debe admitir todos los sombreadores de vértices legales que cumplan la especificación de ese nivel o inferior.
¿Cuántos registros constantes están disponibles para sombreadores de vértices?
Los dispositivos compatibles con sombreadores de vértices 1.0 son necesarios para admitir un mínimo de 96 registros constantes. Los dispositivos pueden admitir más de este número mínimo y pueden informar de ello mediante el campo D3DCAPS9::MaxVertexShaderConst.
¿Puedo compartir datos de posición entre vértices con diferentes coordenadas de textura?
El ejemplo habitual de esta situación es un cubo en el que desea usar una textura diferente para cada cara. Desafortunadamente, la respuesta es no, actualmente no es posible indexar los componentes de vértices de forma independiente. Incluso con varios flujos de vértices, todos los flujos se indexan juntos.
Cuando envío una lista indexada de primitivas, ¿Direct3D procesa todos los vértices del búfer o solo aquellos que he indexado?
Al usar la canalización de geometría de software, Direct3D transforma primero todos los vértices en el intervalo enviado, en lugar de transformarlos "a petición" a medida que se indexan. Para los datos densamente empaquetados (es decir, donde se usa la mayoría de los vértices), esto es más eficaz, especialmente cuando hay instrucciones SIMD disponibles. Si los datos están empaquetados dispersamente (es decir, no se usan muchos vértices), es posible que quiera considerar la posibilidad de reorganizar los datos para evitar demasiadas transformaciones redundantes. Al usar la aceleración de geometría de hardware, los vértices normalmente se transforman a petición a medida que son necesarios.
¿Qué es un búfer de índice?
Un búfer de índice es exactamente análogo a un búfer de vértices, pero contiene índices para su uso en llamadas DrawIndexedPrimitive. Se recomienda encarecidamente usar búferes de índice en lugar de memoria asignada por la aplicación sin procesar siempre que sea posible, por las mismas razones que los búferes de vértices.
Noto que los índices de 32 bits son un tipo admitido; ¿Puedo usarlos en todos los dispositivos?
No. Debe comprobar el campo D3DCAPS9::MaxVertexIndex para determinar el valor de índice máximo admitido por el dispositivo. Este valor debe ser mayor que 2 a la 16ª potencia -1 (0xffff) para que se admita el búfer de índices de tipo D3DFMT_INDEX32. Además, tenga en cuenta que algunos dispositivos pueden admitir índices de 32 bits, pero admiten un valor de índice máximo inferior a 2 a la 32ª potencia -1 (0xffffffff); en este caso, la aplicación debe respetar el límite notificado por el dispositivo.
¿El procesamiento de vértices S/W admite 64 bits?
Hay una canalización de vértices optimizada para x64, pero no existe para IA64.
Optimización del rendimiento
¿Cómo puedo mejorar el rendimiento de mi aplicación Direct3D?
A continuación se muestran las áreas clave que se deben examinar al optimizar el rendimiento:
Tamaño del lote
Direct3D está optimizado para lotes grandes de primitivos. Cuantos más polígonos se puedan enviar en una sola llamada, mejor. Una buena regla general es apuntar a un promedio de 1000 vértices por llamada primitiva. Por debajo de ese nivel probablemente no obtenga un rendimiento óptimo, por encima de eso y va a disminuir los retornos y posibles conflictos con consideraciones de simultaneidad (consulte a continuación).
Cambios de estado
Cambiar el estado de representación puede ser una operación costosa, especialmente al cambiar la textura. Por este motivo, es importante minimizar tanto como sea posible el número de cambios de estado realizados por fotograma. Además, intente minimizar los cambios del búfer de vértices o índices.
Nota:
A partir de DirectX 8, el costo de cambiar el búfer de vértices ya no es tan caro como estaba con versiones anteriores, pero sigue siendo recomendable evitar cambios en el búfer de vértices siempre que sea posible.
Concurrencia
Si puede organizar la representación simultáneamente con otro procesamiento, aprovechará al máximo el rendimiento del sistema. Este objetivo puede entrar en conflicto con el objetivo de reducir los cambios de representación. Debe alcanzar un equilibrio entre el procesamiento por lotes para reducir los cambios de estado e insertar datos en el controlador antes para ayudar a lograr la simultaneidad. El uso de varios búferes de vértices en modo round robin puede ayudar con la simultaneidad.
Cargas de textura
La carga de texturas en el dispositivo consume ancho de banda y provoca una competencia de ancho de banda con datos de vértices. Por lo tanto, es importante no confirmar memoria de textura, lo que obligaría al esquema de almacenamiento en caché a cargar cantidades excesivas de texturas cada fotograma.
Búferes de vértices e índices
Siempre debe usar búferes de vértices e índices, en lugar de bloques sin formato de memoria asignada por la aplicación. Como mínimo, la semántica de bloqueo para los búferes de vértices e índices puede evitar una operación de copia redundante. Con algunos controladores, el búfer de vértices o índices puede colocarse en memoria más óptima (quizás en vídeo o memoria AGP) para el acceso por parte del hardware.
Bloques de macros de estado
Estos se introdujeron en DirectX 7.0. Proporcionan un mecanismo para grabar una serie de cambios de estado (incluidos los cambios de iluminación, material y matriz) en una macro, que luego se pueden reproducir mediante una sola llamada. Esto tiene dos ventajas:
- Para reducir la sobrecarga de llamadas, realice una llamada en lugar de muchas.
- Un controlador compatible puede analizar previamente y compilar previamente los cambios de estado, lo que hace que sea mucho más rápido enviar al hardware gráfico.
Los cambios de estado pueden seguir siendo costosos, pero el uso de macros de estado puede ayudar a reducir al menos algunos de los costos. Use solo un único dispositivo Direct3D. Si necesita representar en varios destinos, use SetRenderTarget. Si va a crear una aplicación con varias ventanas 3D, use la API CreateAdditionalSwapChain. El tiempo de ejecución está optimizado para un único dispositivo y hay una penalización de velocidad considerable para el uso de varios dispositivos.
¿Qué tipos primitivos (tiras, ventiladores, listas, etc.) debo usar?
Muchas mallas encontradas en vértices de características de datos reales compartidas por varios polígonos. Para maximizar el rendimiento, es conveniente reducir la duplicación en vértices transformados y enviados a través del bus al dispositivo de representación. Está claro que el uso de listas de triángulos simples no logra compartir vértices, lo que lo convierte en el método menos óptimo. A continuación, la elección es entre el uso de tiras y ventiladores, lo que implica una relación de conectividad específica entre polígonos y el uso de listas indexadas. Cuando los datos caen naturalmente en tiras y ventiladores, estas son la opción más adecuada, ya que minimizan los datos enviados al controlador. Sin embargo, la descomposición de mallas en tiras y ventiladores a menudo da como resultado un gran número de piezas independientes, lo que implica un gran número de llamadas DrawPrimitive. Por este motivo, el método más eficaz suele ser usar una sola llamada DrawIndexedPrimitive con una lista de triángulos. Una ventaja adicional de usar una lista indizada es que se puede obtener una ventaja incluso cuando los triángulos consecutivos solo comparten un solo vértice. En resumen, si los datos caen naturalmente en tiras o ventiladores grandes, use tiras o ventiladores; de lo contrario, use listas indexadas.
¿Cómo se determina la memoria total de textura que tiene una tarjeta, excepto la memoria AGP?
IDirect3DDevice9::GetAvailableTextureMem devuelve la memoria total disponible, incluido AGP. Asignar recursos en función de una suposición de la cantidad de memoria de vídeo que tiene no es una gran idea. Por ejemplo, ¿qué ocurre si la tarjeta se ejecuta en una arquitectura de memoria unificada (UMA) o puede comprimir las texturas? Es posible que haya más espacio disponible de lo que haya pensado. Debe crear recursos y comprobar si hay errores de "memoria insuficiente" y a continuación, reducir horizontalmente las texturas. Por ejemplo, podría eliminar los niveles mip superiores de sus texturas.
¿Cuál es un buen patrón de uso para los búferes de vértices si estoy generando datos dinámicos?
- Cree un búfer de vértices con las marcas de uso D3DUSAGE_DYNAMIC y D3DUSAGE_WRITEONLY y la marca de grupo de D3DPOOL_DEFAULT. (Especifique también D3DUSAGE_SOFTWAREPROCESSING si usa el procesamiento de vértices de software).
- I = 0.
- Establezca el estado (texturas, renderstates, etc.).
- Compruebe si hay espacio en el búfer, es decir, por ejemplo, I + M <= N? (Donde M es el número de vértices nuevos).
- Si es así, bloquee el VB con D3DLOCK_NOOVERWRITE. Esto indica a Direct3D y al controlador que va a agregar vértices y no modificará los que se procesaron previamente por lotes. Por lo tanto, si una operación DMA estaba en curso, no se interrumpe. Si no, goto 11.
- Rellene los vértices M en I.
- Desbloquear.
- Llamar a Draw[Indexed]Primitive. En el caso de primitivos no indexados, use I como parámetro StartVertex. En el caso de los primitivos indexados, asegúrese de que los índices apuntan a la parte correcta del búfer de vértices (puede ser más fácil usar el parámetro BaseVertexIndex de la llamada a SetIndices para lograrlo).
- I += M.
- Goto 3.
- Ok, así que estamos fuera del espacio, así que empecemos con un nuevo VB. No queremos usar la misma porque podría haber una operación DMA en curso. Nos comunicamos con esto a Direct3D y al controlador bloqueando el mismo VB con la marca D3DLOCK_DISCARD. Lo que esto significa es " puede darme un nuevo puntero ya que he terminado con el anterior y realmente ya no me importa el contenido anterior".
- I = 0.
- Goto 4 (o 6).
¿Por qué tengo que especificar más información en la estructura D3DVERTEXELEMENT9?
A partir de Direct3D 9, la declaración de secuencia de vértices ya no es solo una matriz DWORD, ahora es una matriz de D3DVERTEXELEMENT9 estructuras. El runtime usa la información de uso y semántica adicional para enlazar el contenido de flujos de vértices a registros o variables de entrada de sombreadores de vértices. Para Direct3D 9, las declaraciones de vértices se desacoplan de los sombreadores de vértices, lo que facilita el uso de sombreadores con geometrías de diferentes formatos, ya que el tiempo de ejecución solo enlaza los datos que necesita el sombreador.
Las nuevas declaraciones de vértices se pueden usar con la canalización de funciones fijas o con sombreadores. Para la canalización de función fija, no es necesario llamar a SetVertexShader. Sin embargo, si desea cambiar a la canalización de función fija y ha usado previamente un sombreador de vértices, llame a SetVertexShader(NULL). Cuando esto haya terminado, tendrá que llamar a SetFVF para declarar el código FVF.
Al usar sombreadores de vértices, llame a SetVertexShader con el objeto sombreador de vértices. Además, llame a SetFVF para configurar una declaración de vértices. Esto usa la información implícita en el FVF. Se puede llamar a SetVertexDeclaration en lugar de SetFVF porque admite declaraciones de vértices que no se pueden expresar con un FVF.
Biblioteca de utilidades D3DX
¿Qué formatos de archivo son compatibles con las funciones del cargador de archivos de imagen D3DX?
Las funciones del cargador de archivos de imagen D3DX admiten archivos BMP, TGA, JPG, DIB, PPM y DDS.
Las funciones de representación de texto en D3DX no parecen funcionar, ¿qué hago mal?
Un error común al usar las funciones ID3DXFont::D rawText es especificar un componente alfa cero para el parámetro de color; resultando en texto completamente transparente (es decir, invisible). Para texto totalmente opaco, asegúrese de que el componente alfa del parámetro de color está completamente saturado (255).
¿Cómo puedo guardar el contenido de una superficie o textura en un archivo?
El SDK de DirectX 8.1 ha agregado dos funciones a la biblioteca D3DX específicamente para este propósito: D3DXSaveSurfaceToFile() y D3DXSaveTextureToFile(). Estas funciones admiten guardar una imagen en un archivo en formato BMP o DDS. En versiones anteriores tendrá que bloquear la superficie y leer los datos de la imagen y a continuación, debe escribirlos en un archivo de mapa de bits. Para obtener información sobre cómo escribir una función para almacenar mapas de bits, consulte Almacenamiento de una imagen.
Como alternativa, GDI+ podría usarse para guardar la imagen en una amplia variedad de formatos, aunque esto requiere que se distribuyan archivos de soporte técnico adicionales con la aplicación.
¿Cómo puedo usar el lenguaje de sombreador de alto nivel (HLSL) en mi juego?
Hay tres maneras de incorporar el lenguaje de sombreador de alto nivel de Microsoft (HLSL) al motor de juego:
- Compile el origen del sombreador en ensamblado de sombreado de vértices o píxeles (mediante la utilidad de línea de comandos fxc.exe) y use D3DXAssembleShader() en tiempo de ejecución. De este modo, incluso un juego DirectX 8 puede incluso aprovechar el poder del HLSL.
- Use D3DXCompileShader() para compilar el origen del sombreador en forma de secuencia de tokens y tabla constante. En tiempo de ejecución, cargue la secuencia de tokens y la tabla constante y llame a CreateVertexShader() o CreatePixelShader() en el dispositivo para crear los sombreadores.
- La manera más fácil de ponerse en marcha es aprovechar el sistema D3DX Effects llamando a D3DXCreateEffectFromFile() o D3DXCreateEffectFromResource() con su archivo de efectos.
¿Cuál es el propósito de la nueva marca del compilador de sombreador?
A partir del SDK de DirectX de diciembre de 2006, el nuevo compilador HLSL desarrollado para Direct3D 10 se ha habilitado para destinos de Direct3D 9. El nuevo compilador no admite destinos de ps_1_x y ahora es el compilador predeterminado para todos los sombreadores HLSL de Direct3D. Se puede usar una marca para la compatibilidad con versiones anteriores para forzar que los destinos de ps_1_x se compilen como destinos ps_2_0.
Las aplicaciones que desean usar el compilador heredado pueden seguir haciéndolo proporcionando una marca en tiempo de ejecución (consulte marcas del compilador) o proporcionando un modificador al usar fxc.
¿Cuál es la manera correcta de obtener sombreadores de un Efecto?
Use D3DXCreateEffect para crear un ID3DXEffect y, a continuación, use GetPassDesc para recuperar un D3DXPASS_DESC. Esta estructura contiene punteros a sombreadores de vértices y píxeles.
No utilice ID3DXEffectCompiler::GetPassDesc. Los controladores de sombreador de vértices y píxeles devueltos desde este método son NULL.
¿Cuál es el elemento intrínseco HLSL noise() para?
La función intrínseca de ruido genera ruido perlin según lo definido por Ken Perlin. Actualmente, la función HLSL solo se puede usar para rellenar texturas en sombreadores de textura, ya que h/w actual no admite el método de forma nativa. Los sombreadores de textura se usan en conjucción con las funciones D3DXFill*Texture() que son funciones auxiliares útiles para generar texturas definidas por procedimientos durante el tiempo de carga.
¿Cómo detecto si se debe usar el modelo de sombreador de píxeles 2.0 o 2.a?
Puede usar las funciones D3DXGetPixelShaderProfile() y D3DXGetPixelShaderProfile() que devuelven una cadena que determina qué perfil de HLSL es más adecuado para el dispositivo que se ejecuta.
¿Cómo puedo acceder a los parámetros en mis sombreadores de efectos precompilados?
A través de la interfaz ID3DXConstantTable que se usa para acceder a la tabla de constantes. Esta tabla contiene las variables que usan los sombreadores y efectos de lenguaje de alto nivel.
¿Hay alguna manera de agregar datos de usuario a un efecto u otro recurso?
Sí, para establecer datos privados que llame a SetPrivateData (pReal es el objeto de textura D3D, pSpoof es el objeto de textura ajustada).
hr = pReal->SetPrivateData(IID_Spoof, &pSpoof,
sizeof(IDirect3DResource9*), 0)));
Para buscar el puntero ajustado:
IDirect3DResource9* pSpoof;
DWORD dwSize = sizeof(pSpoof);
hr = pReal->GetPrivateData(IID_Spoof, (void*) &pSpoof, &dwSize);
¿Por qué la representación de un objeto ID3DXMesh se ralentiza significativamente después de definir subconjuntos?
Probablemente no haya optimizado la malla después de definir los atributos de la cara. Si especifica atributos y a continuación llama a ID3DXMesh::DrawSubset(), este método debe realizar una búsqueda en la malla de todas las caras que contengan los atributos solicitados. Además, es probable que las caras representadas estén en un patrón de acceso aleatorio, por lo que no se usa la memoria caché de vértices. Después de definir los atributos de cara para los subconjuntos, llame a los métodos ID3DXMesh::Optimize o ID3DXMesh::OptimizeInPlace y especifique un método de optimización de D3DXMESHOPT_ATTRSORT o más seguro. Tenga en cuenta que para un rendimiento óptimo debe optimizar con el indicador D3DXMESHOPT_VERTEXCACHE, que también volverá a ordenar los vértices para una utilización óptima de la caché de vértices. La matriz de adyacencia generada para una malla D3DX tiene tres entradas por cara, aunque algunas caras pueden no tener caras adyacentes en los tres bordes. ¿Cómo se codifica este código? Las entradas en las que no hay caras adyacentes se codifican como 0xffffffff.
He oído mucho sobre la transferencia radiance preprocesada (PRT), ¿dónde puedo obtener más información?
PRT es una nueva característica de D3DX agregada en la actualización del SDK de verano de 2003. Permite renderizar en tiempo real situaciones de iluminación complejas, como la iluminación global, las sombras suaves y la dispersión bajo la superficie. El SDK contiene documentación y ejemplos de cómo integrar la tecnología en el juego. Los ejemplos de demostración PRT y LocalDeformablePRT muestran cómo utilizar el simulador para escenarios de iluminación por vértice y por píxel, respectivamente. Encontrará más información sobre este y otros temas en la página web de Peter Pike Sloan.
¿Cómo puedo representar en una textura y hacer uso de Anti Aliasing?
Cree un destino de representación multimuestreo mediante Direct3DDevice9::CreateRenderTarget. Después de representar la escena en ese destino de representación, StretchRect de ella a una textura de destino de representación. Si realiza algún cambio en el texto fuera de la pantalla (por ejemplo, desenfoque o florece), cópielo de nuevo en el búfer atrás antes de presentarlo().
Preguntas de DirectSound
¿Por qué obtengo una ráfaga de estática cuando se inicia mi aplicación? También noto este problema con otras aplicaciones.
Probablemente ha instalado el entorno de ejecución de DirectX de depuración. La versión de depuración del tiempo de ejecución rellena los búferes con estática para ayudar a los desarrolladores a detectar errores con búferes no inicializados. No se puede garantizar el contenido de un búfer DirectSound una vez creado; particularmente, no se puede asumir que un búfer se ponga a cero.
¿Por qué estoy experimentando un retraso entre cambiar los parámetros de efectos y escuchar los resultados?
Los cambios en los parámetros de efecto no siempre tienen lugar inmediatamente en DirectX 8. Para mejorar la eficacia, DirectSound procesa 100 milisegundos de datos de sonido en un búfer, empezando por el cursor de reproducción, antes de reproducir el búfer. Este preprocesamiento se produce después de todas las llamadas siguientes:
IDirectSoundBuffer8::SetCurrentPosition
IDirectSoundBuffer8::SetFX
IDirectSoundBuffer8::Stop
IDirectSoundBuffer8::Unlock
Gracias a DirectX 9, un nuevo algoritmo de procesamiento de FX que procesa los efectos just-in-time resuelve este problema y ha reducido la latencia. El algoritmo se ha agregado a la llamada IDirectSoundBuffer8::P lay(), junto con un subproceso adicional que procesa los efectos justo delante del cursor de escritura. Por lo tanto, puede establecer parámetros en cualquier momento y funcionarán según lo previsto. Sin embargo, tenga en cuenta que en un búfer de reproducción habrá un pequeño retraso (normalmente 100 ms) antes de escuchar el cambio del parámetro, ya que el audio entre los cursores de reproducción y escritura (y un poco más de relleno) ya se ha procesado en ese momento.
¿Cómo se detecta si DSound está instalado?
Si no necesita usar DirectSoundEnumerate() para enumerar los dispositivos DSound disponibles, no vincule la aplicación con dsound.lib y, en su lugar, úsela a través de COMs CoCreateInstance(CLSID_DirectSound...), inicialice el objeto DSound mediante Initialize(NULL). Si necesita usar DirectSoundEnumerate(), puede cargar dinámicamente dsound.dll mediante LoadLibrary("dsound.dll"); y acceden a sus métodos mediante GetProcAddress("DirectSoundEnumerateA/W") y GetProcAddress("DirectSoundCreateA/W") y así sucesivamente.
¿Cómo puedo crear audio multicanal con WAVEFORMATEXTENSIBLE?
Si no encuentra una respuesta a su pregunta en los archivos de ayuda de DirectSound, hay un buen artículo con más información disponible en Datos de audio de varios canales y archivos WAVE.
¿Cómo puedo usar directSound Voice Manager con conjuntos de propiedades como EAX?
En DirectSound 9.0 cuando se duplica un búfer ahora es posible obtener la interfaz IDirectSoundBuffer8 en el búfer duplicado, que le proporcionará acceso al método AcquireResources. Esto le permitirá asociar un búfer a la marca DSBCAPS_LOCDEFER con un recurso de hardware. A continuación, puede establecer los parámetros EAX en este búfer antes de tener que llamar a Play().
Tengo problemas con el comportamiento no confiable al usar notificaciones de posición del cursor. ¿Cómo puedo obtener información más precisa?
Hay algunos errores sutiles en varias versiones de DirectSound, la pila de audio principal de Windows y los controladores de audio que hacen que las notificaciones de posiciones de cursor no sean confiables. A menos que tenga como destino una configuración conocida de HW/SW en la que sepa que las notificaciones se comportan bien, evite las notificaciones de posición del cursor. Para el seguimiento de posición GetCurrentPosition() es una técnica más segura.
Estoy sufriendo una degradación del rendimiento al usar GetCurrentPosition(). ¿Qué puedo hacer para mejorar el rendimiento?
Cada llamada a GetCurrentPosition() en cada búfer provoca una llamada del sistema y las llamadas del sistema deben minimizarse, ya que son un componente grande de la superficie de CPU de DSound. En NT (Win2K y XP), los cursores de los búferes SW (y los búferes HW en algunos dispositivos) se mueven en incrementos de 10 ms, por lo que llamar a GetCurrentPosition() cada 10 ms es ideal. Llamarlo con más frecuencia que cada 5 ms provocará una degradación del rendimiento.
Mi aplicación DirectSound está tardando demasiado tiempo de CPU o se está realizando lentamente. ¿Hay algo que pueda hacer para optimizar mi código?
Hay varias cosas que puede hacer para mejorar el rendimiento del código de audio:
No llames a GetCurrentPosition con demasiada frecuencia. Cada llamada a GetCurrentPosition() en cada búfer provoca una llamada del sistema y las llamadas del sistema deben minimizarse, ya que son un componente grande de la superficie de CPU de DSound. En NT (Win2K y XP), los cursores de los búferes SW (y los búferes HW en algunos dispositivos) se mueven en incrementos de 10 ms, por lo que llamar a GetCurrentPosition() cada 10 ms es ideal. Llamarlo con más frecuencia que cada 5 ms provocará una degradación de la perf.
Utilice una velocidad de fotogramas independiente y inferior para el audio. En la actualidad, muchos juegos de Windows pueden superar los 100 fotogramas por segundo y no es necesario en la mayoría de los casos para actualizar los parámetros de audio 3D a la misma velocidad de fotogramas. Procesar el audio cada segundo o tercer fotograma gráfico, o cada 30 ms, puede reducir significativamente el número de llamadas de audio en toda la aplicación sin reducir la calidad del audio.
Use DS3D_DEFERRED para objetos 3D. La mayoría de las tarjetas de sonido responden inmediatamente a los cambios de parámetro y, en un solo fotograma, puede cambiar mucho, especialmente si cambia la posición o la orientación del agente de escucha. Esto hace que la tarjeta de sonido o CPU realice muchos cálculos innecesarios, por lo que otra optimización rápida y universal es aplazar algunos cambios de parámetro y confirmarlos al final del fotograma.
o al menos use SetAllParameters en lugar de llamadas Set3DParamX individuales en búferes.
Del mismo modo, debe usar al menos llamadas a SetAllParamenters en búferes 3D en lugar de las llamadas a Set3DParamX individuales. Solo tiene que intentar minimizar las llamadas del sistema siempre que sea posible.
No realice llamadas redundantes; almacenar y ordenar una lista de llamadas de reproducción. A menudo, en un marco de actualización de audio, hay 2 solicitudes para reproducir nuevos sonidos. Si las solicitudes se procesan a medida que llegan, se podría iniciar el primer sonido nuevo y a continuación, reemplazar inmediatamente el segundo sonido solicitado. Esto da como resultado cálculos redundantes, una llamada de reproducción innecesaria y una llamada de detención innecesaria. Es mejor almacenar una lista de solicitudes para que se reproduzcan nuevos sonidos, de modo que la lista se pueda ordenar, y solo las voces que deben empezar a reproducirse, se reproducen en realidad.
Además, debe almacenar copias locales de los parámetros 3D y EAX para cada origen de sonido. Si se realiza una solicitud para establecer un parámetro en un valor determinado, puede comprobar si el valor es realmente diferente del último conjunto de valores. Si no es así, no es necesario realizar la llamada.
Aunque el controlador de la tarjeta de sonido probablemente detectará este escenario y no volverá a realizar el cálculo (igual), la llamada de audio tendrá que llegar al controlador de audio (a través de una transición de anillo) y esto ya es una operación lenta.
Cuando transmita un búfer, tiende a tener problemas y funciona mal. ¿Cuál es la mejor manera de transmitir un búfer?
Al transmitir audio a un búfer hay dos algoritmos básicos: After-Write-Cursor (AWC) y Before-Play-Cursor (BPC). AWC minimiza la latencia a costa del brillo, mientras que BPC es lo contrario. Dado que normalmente no hay cambios interactivos en el sonido transmitido este tipo de latencia rara vez es un problema para juegos y aplicaciones similares, por lo que BPC es el algoritmo más adecuado. En AWC, cada vez que el subproceso de streaming ejecuta "top up" los datos de los búferes de bucle hasta N ms más allá de sus cursores de escritura (normalmente N=40 o así, para permitir la programación de Windows jitter). En BPC, siempre hay que escribir tantos datos como sea posible en los búferes, llenándolos hasta sus cursores de reproducción (o quizás 32 bytes antes para permitir a los controladores que informan incorrectamente del progreso de su cursor de reproducción).
Use BPC para minimizar el glitching, y use buffers de 100ms o más, incluso si su juego no tiene glitch en su hardware de prueba, tendrá glitch en alguna máquina por ahí.
Estoy jugando los mismos sonidos con mucha frecuencia y muy rápidamente y a veces no se reproducen correctamente, o la llamada a Play() tarda mucho tiempo. ¿Cuál debo hacer?
La latencia de inicio (que es diferente de la latencia de streaming mencionada anteriormente) puede ser un problema en el caso de alguna llamada de hardware (play() solo tarda mucho tiempo en determinadas tarjetas de sonido). Si realmente quiere reducir esta latencia, para los sonidos de twitch (disparos de pistola, pasos, etc.), un truco útil es mantener algunos búferes siempre en bucle y jugar silencio. Cuando necesite reproducir un sonido de twitch, elija un búfer libre, vea dónde está su cursor de escritura y coloque el sonido en el búfer justo más allá del cursor de escritura. Algunas tarjetas de sonido dan error al QuerySupport para propiedades diferidas que se que admiten. ¿Hay alguna solución alternativa? Solo puede consultarSupport para las versiones no diferidas de las propiedades y usar la configuración diferida de todos modos. Los controladores de tarjeta de sonido más recientes también pueden corregir este problema.
¿Cómo puedo codificar archivos WAV en WMA?
Consulte la documentación del codificador de Windows Media en: Windows Media Encoder 9 Series.
¿Cómo descodificar archivos MP3 con DirectSound?
DirectSound no admite de forma nativa la descodificación mp3. Puede descodificar los archivos de antemano (mediante un códec ACM de un filtro DirectShow) o simplemente usar DirectShow, que puede hacer la descodificación para usted; A continuación, puede copiar los datos de audio de PCM resultantes en los búferes de DirectSound.
Extensiones de DirectX para Alias Maya
¿Por qué no aparecen mis NURBS?
No se admiten NURBS. Puede convertirlos en mallas de polígono.
¿Por qué no aparecen mis SUBD?
No se admiten SUBD. Puede convertirlos en mallas de polígono.
¿Por qué mi animación en el archivo X tiene un aspecto diferente al de la animación en la ventana de vista previa?
La ventana de vista previa no se anima en el sentido más estricto del asunto. No está reproduciendo animación, sino que se sincroniza con el estado más actual de la escena de Maya. Cuando se exporta la animación, las matrices de cada transformación se descomponen en escala, rotación (cuaternión) y componentes de traducción (a menudo denominados SRT). Los SRT son más deseables que las matrices porque interpolan bien, proporcionan una forma más compacta de los datos y se pueden comprimir de forma independiente. No todas las matrices se pueden dividir en SRT. Si no se pueden descomponer, se desconocen los SRT resultantes, por lo que se pueden detectar pequeños errores en la animación. Las dos características de Maya que suelen causar problemas durante la descomposición son escalonamientos y rotaciones o escalas fuera del centro. Si experimenta este problema, ya que usa rotaciones o escalas fuera del centro, considere la posibilidad de agregar transformaciones adicionales que aumenten el nivel de jerarquía.
Donde la animación D3DX admite SRT, tiene el siguiente aspecto:
[S]x[R]x[T]
Las matrices de Maya son mucho más complicadas y requieren una cantidad significativa de proceso adicional, que tiene el siguiente aspecto:
[SpInv]x[S]x[Sh]x[Sp]x[St]x[RpInv]x[Ro]x[R]x[Rp]x[Rt]x[T]
He quitado la piel de mi malla con RigidSkin, pero la malla (o parte) no se mueve. ¿Por qué?
La piel rígida de Maya no se admite en este momento. Use piel suave.
¿Dónde se ha ido todo mi IK en el archivo X?
Los archivos X no admiten IK. En su lugar, las soluciones IK se almacenan en los fotogramas almacenados en el archivo X.
¿Por qué ninguno de mis colores de materiales aparece excepto DirectXShaders?
Las extensiones DirectX para Maya actualmente solo admiten materiales de DirectXShader para la versión preliminar y la exportación. En una versión futura se pueden admitir otros materiales.
Preguntas sobre XInput
¿Puedo usar DirectInput para leer los desencadenadores?
Sí, pero actúan como el mismo eje. Por lo tanto, no puede leer los desencadenadores de forma independiente con DirectInput. Con XInput, los desencadenadores devuelven valores independientes.
Para obtener más información sobre por qué DirectInput interpreta los desencadenadores como un eje, consulte Uso de un controlador con DirectInput.
¿Cuántos controladores admite XInput?
XInput admite 4 controladores conectados a la vez.
¿XInput admite controladores no comunes?
No, no es así.
¿Hay controladores comunes disponibles a través de DirectInput?
Sí, puede acceder a controladores comunes a través de DirectInput.
¿Cómo obtengo comentarios forzados sobre los controladores comunes?
Use la función XInputSetState.
¿Por qué cambia mi dispositivo de audio predeterminado?
Al conectar los auriculares, el casco del controlador actúa como un dispositivo de audio USB estándar, por lo que, cuando está conectado, Windows cambia automáticamente para usar este dispositivo de audio USB como valor predeterminado. Dado que es probable que el usuario no quiera que todo el audio pase por los auriculares, tendrá que ajustarlo manualmente a la configuración original.
¿Cómo puedo controlar las luces en el controlador?
Las luces del controlador están predeterminadas por el sistema operativo y no se pueden cambiar.
¿Cómo puedo acceder al botón Xbox 360 en mis aplicaciones?
Lo sentimos, este botón está reservado para uso futuro.
¿Dónde obtengo conductores?
Los controladores estarán disponibles a través de Windows Update.
¿Cómo se determina el identificador del controlador?
Al iniciarse XInput, el motor XInput y los controladores conectados determinan el identificador de forma no determinista. Si los controladores están conectados mientras se ejecuta una aplicación XInput, el sistema asignará al nuevo controlador el número más bajo disponible. Si un controlador está desconectado, su número estará disponible de nuevo.
¿Cómo puedo obtener los dispositivos de audio para el controlador?
Use la función XInputGetDSoundAudioDeviceGuids. Consulte el ejemplo audioController para obtener más información.
¿Qué debo hacer cuando un controlador está desconectado?
Si el mando estaba en uso por parte de un jugador, debe pausar el juego hasta que se vuelva a conectar el mando y el jugador presione un botón para indicar que están listos para dejar de usarse.