¿Qué es OpenGL?

Directorio OpenGL

Descripción general

Situación actual de Open GL

Funciones avanzadas

Introducción a la programación OpenGL

p>

La diferencia entre OpenGL y DirectX

Descripción general

OpenGL: el estándar de la industria para algoritmos gráficos de alto rendimiento

¿OpenGL es el más extendido? Aceptado 2D/ La API de gráficos 3D ha generado miles de excelentes aplicaciones en diversas plataformas informáticas y dispositivos desde sus inicios. OpenGL? es independiente de Windows u otros sistemas operativos y es transparente en la red. En industrias que incluyen CAD, creación de contenido, energía, entretenimiento, desarrollo de juegos, manufactura, productos farmacéuticos y realidad virtual, OpenGL ayuda a los programadores a lograr software extremadamente potente y de alto rendimiento en dispositivos de hardware como PC, estaciones de trabajo y supercomputadoras. Desarrollo de gráficos impactantes. Software de procesamiento con alta expresividad visual.

OpenGL (nombre completo Open Graphics Library) es una especificación que define un lenguaje de programación cruzada y una interfaz de programación multiplataforma para imágenes tridimensionales (también bidimensionales). OpenGL es una interfaz de programa de gráficos profesional, una biblioteca de gráficos subyacente potente y fácil de llamar. El predecesor de OpenGL es IRIS GL desarrollado por SGI para su estación de trabajo gráfica. IRIS GL es una interfaz de software de gráficos 3D estándar de la industria. Aunque es potente, tiene poca portabilidad, por lo que SGI desarrolló OpenGL basado en IRIS GL. El nombre completo en inglés de OpenGL es "Open Graphics Library". Como sugiere el nombre, OpenGL es una "interfaz de programación de gráficos abierta". Aunque DirectX lidera el mercado interno, en el campo de los gráficos profesionales de alta gama, OpenGL es el protagonista irreemplazable.

OpenGL es una interfaz de software independiente del hardware que se puede trasplantar entre diferentes plataformas como Windows 95, Windows NT, Unix, Linux, MacOS y OS/2. Por lo tanto, el software que admite OpenGL tiene buena portabilidad y puede usarse ampliamente. Dado que OpenGL es la biblioteca de gráficos subyacente para gráficos, no proporciona primitivas de entidades geométricas y no se puede usar directamente para describir escenas. Sin embargo, a través de algunos programas de conversión, los archivos de modelos DXF y 3DS producidos por software de diseño de gráficos 3D como AutoCAD y 3DS/3DSMAX se pueden convertir fácilmente en matrices de vértices OpenGL.

Basado en OpenGL, también existen diversas librerías gráficas avanzadas como Open Inventor, Cosmo3D, Optimizer, etc. para adaptarse a diferentes aplicaciones. Entre ellos, Open Inventor es el más utilizado. El software es un conjunto de herramientas orientado a objetos basado en OpenGL, que proporciona objetos y métodos para crear aplicaciones de gráficos 3D interactivos, proporciona objetos predefinidos y módulos de procesamiento de eventos para la interacción y unidades de aplicación avanzadas para crear y editar escenas 3D. objetos e intercambiar datos con otros formatos gráficos.

El desarrollo de OpenGL siempre ha estado en una situación relativamente lenta. Cada vez que se mejora la versión, se agregan muy pocas tecnologías nuevas, y la mayoría de ellas son solo modificaciones y mejoras de algunas de ellas. En julio de 1992, SGI lanzó la versión 1.0 de OpenGL y luego desarrolló conjuntamente la versión Windows NT de OpenGL con Microsoft, de modo que algunos programas de procesamiento de gráficos 3D a gran escala que originalmente debían ejecutarse en estaciones de trabajo de gráficos de alta gama también puedan usarse en microordenador. En 1995, se lanzó la versión 1.1 de OpenGL. Esta versión tenía muchas mejoras de rendimiento con respecto a la 1.0 y agregó algunas características nuevas.

Estos incluyen soporte mejorado para impresoras, inclusión de llamadas OpenGL en metarchivos mejorados, nuevas características para matrices de vértices, velocidad de transferencia mejorada de posiciones de vértices, normales, colores, índices de color, coordenadas de textura, marcadores de bordes poligonales y la introducción de nuevas características de textura, etc. OpenGL 1.5 agrega "OpenGL Shading Language", que es el núcleo de "OpenGL 2.0" y se utiliza para funciones extendidas de sombreado de objetos, sombreado de vértices y tecnología de sombreado de fragmentos.

El principal desarrollador del estándar OpenGL 2.0 no es el SGI original, sino 3DLabs, que poco a poco va tomando la iniciativa en ARB. Lo primero que debe hacer la versión 2.0 es total compatibilidad con versiones anteriores, mientras trabaja con DirectX *** en la administración de vértices, píxeles y memoria para mantener el equilibrio. OpenGL 2.0 constará de las funciones existentes de OpenGL 1.3 más nuevas funciones que son totalmente compatibles con él (Figura 1). De esta manera, los diversos conjuntos de instrucciones extendidos enredados lanzados por varias empresas durante la era estancada de ARB se pueden simplificar por completo. Además, la implementación de la programabilidad del hardware también proporciona una mejor manera de integrar las instrucciones de extensión existentes.

En la actualidad, con el continuo desarrollo y mejora de DirectX, las ventajas de OpenGL se están perdiendo gradualmente. Aunque hasta ahora se ha lanzado la versión 2.0 desarrollada por 3Dlabs, se han agregado muchos diseños similares a las unidades programables en. DirectX, pero el conocimiento de los usuarios de los fabricantes no es alto y las perspectivas futuras de desarrollo de OpenGL no están claras.

[Editar este párrafo] Estado actual de Open GL

Open GL sigue siendo la única API que puede reemplazar el control total de Microsoft sobre la tecnología de gráficos 3D. Todavía tiene cierta vitalidad, pero Silicon Graphics ya no promueve Open GL de ninguna manera que desagrade a Microsoft, por lo que conlleva un mayor riesgo. Los desarrolladores de juegos son un grupo de mentalidad independiente y muchos desarrolladores importantes todavía utilizan Open GL. Como resultado, los desarrolladores de hardware buscan reforzar su soporte. Direct3D actualmente no admite dispositivos gráficos de alta gama y las aplicaciones profesionales dominan estas áreas; Finalmente, la comunidad de código abierto (especialmente el proyecto Mesa) ha estado trabajando arduamente para llevar soporte Open GL a cualquier tipo de computadora, ya sea que usen el sistema operativo de Microsoft o no.

La versión OpenGL3.0 se anunció oficialmente en 2008. Y cuenta con el respaldo de nv, cuyo sitio web oficial proporciona la descarga de SDK para tarjetas N.

[Editar este párrafo] Funciones avanzadas

OpenGL está diseñado para ser solo de salida, por lo que solo proporciona funciones de renderizado. La API principal no tiene ningún concepto de sistema de ventanas, audio, impresión, teclado/ratón u otros dispositivos de entrada. Si bien esto puede parecer una limitación al principio, permite que el código que realiza el renderizado sea completamente independiente del sistema operativo en el que se ejecuta, lo que permite el desarrollo multiplataforma. Sin embargo, algunas integraciones con el sistema de ventanas nativo deben permitir la interacción con el sistema host. Esto se logra a través de las siguientes API adicionales:

* GLX - X11 (incluidas las redes transparentes)

* WGL - Microsoft Windows

* AGL - Apple MacOS

p>

Además, la biblioteca GLUT puede proporcionar funciones básicas de ventana de forma portátil.

[Editar este párrafo] Introducción a la programación OpenGL

El dibujo OpenGL es muy conveniente, por lo que se está volviendo cada vez más popular. Sin embargo, para muchas personas, se realiza en una microcomputadora. Y lo primero que encuentran es La pregunta es cómo adaptarse al entorno de microcomputadoras. Éste suele ser el paso más crítico, aunque también el más elemental.

En términos generales, no recomiendo usar el paquete glut. Será difícil aprovechar al máximo las funciones de la interfaz de Windows.

A continuación se describe cómo realizar la programación OpenGL en VC. El proceso general de dibujo OpenGL se puede ver de la siguiente manera: primero, use declaraciones OpenGL para dibujar la imagen en el entorno de dibujo OpenGL RenderContext (RC) y luego pase la imagen al entorno de dibujo del sistema operativo DeviceContext (DC) a través de un búfer de intercambio. Process y dibújelo en la pantalla.

A continuación se toma el dibujo de una curva de Bézier como ejemplo para presentar en detalle el método de programación OpenGL en VC. En el texto se incluyen notas detalladas para ofrecer una orientación clara a los principiantes. Sigue las instrucciones paso a paso y dibujarás con éxito tus primeros gráficos en la plataforma OpenGL.

1. Genere el marco del programa Test.dsw

Nuevo proyecto | Asistente de aplicación MFC (EXE) "Prueba" OK

*Nota*: Agregar " " se refiere a la cadena que se escribirá manualmente

2. Importe el archivo de curva Bezier

Utilice el siguiente método para generar los dos archivos BezierCurve.h y BezierCurve.cpp:

WorkSpace | ClassView | Clases de prueba| lt; haga clic derecho para abrir gt; Clase genérica (sin clase MFC) | y definición de implementación de la clase de curva Bezier

Escriba los dos archivos siguientes:

BezierCurve.h BezierCurve.cpp

4. Configure el entorno de compilación:

1. Agregue lo siguiente a BezierCurve.h y TestView.h:

#include lt; GL/gl.hgt

#include lt; .hgt;

#include lt; GL/glaux.hgt;

2. En el entorno integrado

Configuración del proyecto | | "opengl32.lib glu32 .lib glaux.lib" | OK

5. Configure el entorno de trabajo OpenGL: (Las siguientes operaciones son todas para TestView.cpp)

1. Procesar PreCreateWindow(): configurar el estilo de ventana de dibujo OpenGL

cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC

2. Procesar OnCreate(): crear un dispositivo de dibujo OpenGL.

El mecanismo del dibujo OpenGL es: primero use el contexto de dibujo OpenGL Contexto de representación (conocido como RC) para dibujar la imagen y luego pase el resultado del dibujo al contexto de dibujo de Windows Contexto del dispositivo (conocido como RC) a través de la función SwapBuffer() Marcado como DC). Cabe señalar que durante la ejecución del programa, puede haber varios DC, pero solo puede haber un RC. Por lo tanto, cuando un DC termina de dibujar el dibujo, el RC debe liberarse inmediatamente para que otros DC también puedan usarlo. En el siguiente código, habrá comentarios detallados.

int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

devolver -1;

myInitOpenGL();

devolver 0

}

void CTestView::myInitOpenGL()

{

m_pDC = new CClientDC(this); //Crear DC

ASSERT(m_pDC != NULL

if ( !mySetupPixelFormat()) //Establece el formato de mapa de bits para dibujar, las funciones se enumeran a continuación

return

m_hRC = wglCreateContext(m_pDC-gt; m_hDC);

wglMakeCurrent(m_pDC-gt; m_hDC, m_hRC); //RC está asociado con el DC actual

} //CClient * m_pDC es una variable miembro de CTestView;

p>

BOOL CTestView:: mySetupPixelFormat()

{// No nos importa el contenido específico del formato por ahora, cambiaremos el formato cuando nos familiaricemos con él más adelante

static PIXELFORMATDESCRIPTOR pfd =

{

sizeof(PIXELFORMATDESCRIPTOR), // tamaño de este pfd

1, // número de versión

PFD_DRAW_TO_WINDOW | // ventana de soporte

PFD_SUPPORT_OPENGL | // soporte OpenGL

PFD_DOUBLEBUFFER, // doble buffer

PFD_TYPE_RGBA, // tipo RGBA

24, // profundidad de color de 24 bits

0, 0, 0, 0, 0, 0, // bits de color ignorados

0, // sin búfer alfa

0, // bit de desplazamiento ignorado

0, // sin búfer de acumulación

0, 0, 0, 0, // bits acumulados ignorados

32 , // búfer z de 32 bits

0, // sin búfer de plantilla

0 , // sin búfer auxiliar

PFD_MAIN_PLANE, // capa principal

0, // reservada

0,

0, 0 // máscaras de capa ignoradas

};

int pixelformat;

if ( (pixelformat = ChoosePixelFormat(m_pDC-gt; m_hDC, amp; pfd )) == 0 )

{

MessageBox("Error al elegirPixelFormat");

return FALSE

}

if (SetPixelFormat(m_pDC-gt; m_hDC, pixelformat, amp; pfd) == FALSE)

{

MessageBox("SetPixelFormat falló"); >

devolver FALSO;

}

devolver VERDADERO

}

3. Manejar OnDestroy()

void CTestView::OnDestroy()

{

wglMakeCurrent(m_pDC-gt; m_hDC, NULL // Libera el RC correspondiente a m_hDC

wglDeleteContext(m_hRC); //Eliminar RC

if (m_pDC)

eliminar m_pDC; //Eliminar el DC propiedad de la Vista actual

CView: :OnDestroy ();

}

4. Manejar OnEraseBkgnd()

BOOL CTestView::OnEraseBkgnd(CDC* pDC)

{

// TODO: Agregue su código de controlador de mensajes aquí y/o llame al valor predeterminado

// return CView::OnEraseBkgnd(pDC); Coloque este comentario en la oración; de lo contrario, la ventana

// se actualizará con una vista norte blanca, lo que provocará que la pantalla parpadee

return TRUE // Simplemente regrese vacío.

}

5. Manejo de OnDraw()

void CTestView::OnDraw(CDC* pDC)

{

wglMakeCurrent(m_pDC-gt; m_hDC, m_hRC); //Asociar RC con el DC actual

myDrawScene( ); //Función de dibujo específica, dibujar en RC

SwapBuffers (m_pDC-gt; m_hDC); //Transfiere los dibujos en RC al DC actual, así

//Mostrar en pantalla

wglMakeCurrent(m_pDC- gt; m_hDC, NULL ); // Libera RC para que otros DC puedan dibujar

}

void CTestView::myDrawScene()

{

glClearColor (0.0f, 0.0f, 0.0f, 1.0f); //Establece el color de fondo en negro

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT

glPushMatrix()

glTranslated(0.0f, 0.0f, -3.0f); //Traduce el objeto a lo largo de la dirección (0, 0, -1)

//Para que sea visible durante la proyección. Debido a que el punto de vista predeterminado está en (0, 0, 0), el objeto solo puede ser visible si se aleja

//.

//Este ejemplo es para demostrar la curva de Bézier plana. Simplemente haz una rotación.

//Transforma para ver su efecto 3D con mayor claridad.

//Dibuja una curva de Bezier debajo

bezier_curve.myPolygon(); //Dibuja el polígono de control de la curva de Bezier

bezier_curve.myDraw(); // CBezierCurve bezier_curve

//Es una variable miembro de CTestView

//Consulte el apéndice para funciones específicas

glPopMatrix()

;

glFlush( ); //Finalizar dibujo RC

return;

}

6. Procesar OnSize()

void CTestView::OnSize( UINT nType, int cx, int cy)

{

CView::OnSize(nType, cx, cy)

VERIFY( wglMakeCurrent(m_pDC-gt ; m_hDC, m_hRC)); // Confirma que RC está asociado con el DC actual

w=cx

h=cy

<; p> VERIFY(wglMakeCurrent(NULL, NULL)); // Confirma las versiones de DC RC

}

7 Procesar OnLButtonDown()

void CTestView::OnLButtonDown (UINT nFlags, punto CPoint)

{

CView::OnLButtonDown(nFlags, punto

if(bezier_curve.m_Ngt;MAX-1)

{

MessageBox("El número de vértices excede el número máximo MAX=50");

return

}

//Lo siguiente es Prepararse para la transformación de coordenadas

GetClientRect(amp; m_ClientRect //Obtener el tamaño del área de la ventana gráfica

w=m_ClientRect.right-); m_ClientRect.left; //Ancho de la ventana gráfica w

p>

h=m_ClientRect.bottom-m_ClientRect.top; //Altura de la ventana gráfica h

//w, h son variables miembro de CTestView

centerx=(m_ClientRect. left m_ClientRect.right)/2; //Posición central,

centery=(m_ClientRect.top m_ClientRect.bottom)/2; el origen

//centerx, centery es una variable miembro de CTestView

GLdouble tmpx, tmpy

tmpx=scrx2glx(point.x); Las coordenadas de los puntos en la pantalla se convierten en las coordenadas estándar del dibujo OpenGL

tmpy=scry2gly(point.y

bezier_curve.m_Vertex[bezier_curve.m);

_N].x=tmpx; //Agrega un vértice

bezier_curve.m_Vertex[bezier_curve.m_N].y=tmpy;

bezier_curve.m_N; de vértices

InvalidateRect(NULL, TRUE); //Enviar mensaje de actualización y redibujado

}

double CTestView::scrx2glx(int ​​​​scrx)

{

return (doble)(scrx-centerx)/doble(h

}

doble CTestView::scry2gly(int); scry)

p>

{

}

Apéndice:

1.Declaración de CBezierCurve: (BezierCurve.h)

class CBezierCurve

{

public:

myPOINT2D m_Vertex[MAX] //Control de vértices, almacenados en matrices

;

//myPOINT2D es una estructura para almacenar puntos bidimensionales

//Los miembros son Gldouble x, y

int m_N; p>

público:

CBezierCurve();

virtual ~CBezierCurve();

void bezier_generación(myPOINT2D P[MAX], nivel int) ;

// Implementación específica del algoritmo

void myDraw(); //Función de dibujo de curva

void myPolygon() //Dibujo de polígonos de control

};

2. Implementación de CBezierCurve: (BezierCurve.cpp)

CBezierCurve:: CBezierCurve()

{

m_N=4;

m_Vertex[0].x=-0.5f

m_Vertex[0].y=-0.5f; > m_Vertex[1].x=-0.5f

m_Vertex[1].y=0.5f

m_Vertex[2].x=0.5f;

m_Vertex[2].y=0.5 f

m_Vertex[3].x=0.5f

m_Vertex[3].y=-0.5f; p>

}

CBezierCurve::~CBezierCurve()

{

}

void CBezierCurve::myDraw()

{

bezier_generación(m_Vertex, LEVEL

}

void CBezierCurve::bezier_gene);

ration(myPOINT2D P[MAX], int nivel)

{ //Para obtener una descripción detallada del algoritmo, consulte los libros relevantes

int i, j

<; p> nivel --;

if(levellt;0)return

if(level==0)

{

glColor3f(1.0 f, 1.0f, 1.0f);

glBegin(GL_LINES); //Dibujar segmentos de línea

glVertex2d(P[0].x, P[0]. y);

glVertex2d(P[m_N-1].x, P[m_N-1].y

glEnd(); //Finalizar segmento de línea de dibujo

p>

return; // La recursividad llega al final, salta de la recursión

}

myPOINT2D Q[MAX], R[MAX]

;

for(i=0 ;i {

Q.x=P.x;

Q.y=P.y;

}

for( i=1; m_N; i )

{

R[m_N-i].x=Q[m_N-1].x; R[m_N-i].y =Q[m_N-1].y

for(j=m_N-1;jgt;=i;j--)

{

Q[j].x=(Q[j-1].x Q[j].x)/double(2);

Q[j].y=; (Q[j-1]. y Q[j].y)/double(2

}

}

R[0]. x=Q[m_N-1] .x;

R[0].y=Q[m_N-1].y

bezier_generación(Q, nivel

bezier_generación(R , nivel);

}

void CBezierCurve::myPolygon()

{

glBegin (GL_LINE_STRIP); //Dibujar segmento de conexión

glColor3f(0.2f, 0.4f, 0.4f

for(int i=0; ilt; m_N; i)

p>

{

glVertex2d(m_Vertex.x, m_Vertex.y);

}

glEnd() //Finalizar el dibujo de los segmentos de conexión

}

[Editar este párrafo] La diferencia entre OpenGL y DirectX

OpenGL es solo una biblioteca de funciones gráficas.

DirectX incluye módulos de gráficos, sonido, entrada, red y otros.

OpenGL es estable y se puede utilizar en todas las plataformas. DirectX solo se puede utilizar en plataformas de la serie Windows, incluidas la serie Windows Mobile/CE y XBOX/XBOX360.

------------------------------------------------- ---- ---------------------------------------------- ---- -

De 1995 a 1996, Microsoft implementó un nuevo plan para soportar la ejecución de juegos en Windows 95, con el objetivo de expandir el mercado a áreas de juegos controladas por Nintendo y Sega. Sin embargo, Microsoft no quiso utilizar la tecnología OpenGL que ya está disponible en NT. Microsoft adquiere Rendermorphics, Ltd. y obtiene su API 3D llamada RealityLab. Después de la reorganización, Microsoft lanzó una nueva API 3D: Direct3D.

¡Microsoft, promueve Direct3D y congela OpenGL!

Microsoft se negó a admitir OpenGL en Windows95 en ese momento. No sólo eso, Microsoft tomó medidas inusuales para retirar el soporte para la interfaz del controlador MCD de OpenGL, por lo que los fabricantes de hardware tuvieron que abandonar el controlador OpenGL que había entrado en la prueba final. El departamento de marketing de Microsoft comenzó a promover Direct3D entre los desarrolladores de juegos, fabricantes de hardware y organizaciones editoriales y de noticias, mientras rechazaba OpenGL.

¡Guerra de API!

Silicon Graphics y muchos usuarios de OpenGL confían en la tecnología innovadora y de alto rendimiento de OpenGL. Pero está claro que Microsoft tiene la intención de utilizar Direct3D para reemplazar a OpenGL, aunque D3D tiene muchos problemas y no puede ser ampliado por fabricantes de hardware como OpenGL. Silicon Graphics decidió hacer una demostración en la conferencia SIGGRAPH de 1996. La demostración demuestra que OpenGL es al menos tan rápido como D3D, refutando así el argumento de marketing de Microsoft. Debido a que OpenGL es un estándar reconocido por la industria, tiene más funciones que D3D y tiene una mayor calidad de imagen, la demostración generó un acalorado debate en las comunidades de desarrollo de juegos y gráficos por computadora.

¡Los desarrolladores de juegos exigen que OpenGL y D3D estén en pie de igualdad!

Cuando los problemas técnicos y de mercado quedaron expuestos, comenzó un fuerte apoyo a OpenGL. El desarrollador de Doom, John Carmack, manifestó su rechazo a D3D, y Chris Hecker publicó un análisis exhaustivo de las dos API en Game Development Magazine, concluyendo que Microsoft debería abandonar D3D. Los desarrolladores de juegos han presentado peticiones a Microsoft dos veces. Por primera vez, 56 desarrolladores jefe de juegos pidieron a Microsoft que lanzara un controlador MCD OpenGL, pero fracasaron porque permitiría a OpenGL competir con D3D. La segunda carta abierta comenzó con 254 firmas y terminó con 1.400 firmas. La respuesta de Microsoft fue reiterar su antigua posición en el mercado. Aunque los peticionarios solicitaron claramente una competencia igualitaria entre las dos API para promover el desarrollo, Microsoft respondió aumentando la inversión en D3D y reduciendo la inversión en OpenGL.

Fahrenheit——¿La fusión de D3D y OpenGL?

Silicon Graphics, Microsoft, HP e Intel han llegado a un acuerdo para desarrollar conjuntamente la API-Fahrenheit 3D de próxima generación. Pero no salió nada, porque el plan de Microsoft era utilizar la tecnología OpenGL en D3D y con este nombre eliminar la amenaza de OpenGL. (Se estima que DirectX 8 Graphics es el único Fahrenheit desarrollado solo por Microsoft y que absorbe muchas cosas de OpenGL).

¡OpenGL sigue siendo tan heroico como en aquel entonces!

OpenGL sigue siendo la única API que puede competir con D3D, que está controlada únicamente por Microsoft, aunque Silicon Graphics ya no promueve OpenGL de ninguna manera que sea inaceptable para Microsoft.

El desarrollo de juegos es independiente y muchos actores clave utilizan OpenGL, por lo que los fabricantes de hardware están trabajando arduamente para aumentar su soporte. D3D todavía no puede soportar gráficos de alta gama y aplicaciones profesionales, y OpenGL domina estas tierras. En la comunidad de código abierto, el proyecto Mesa proporciona un controlador OpenGL independiente de Microsoft.

Nota del traductor: en la superficie, parece que D3D admite más funciones que OpenGL. De hecho, porque D3D no admite extensiones de hardware, como sombras panorámicas de hardware, materiales translúcidos independientes del orden de renderizado de hardware y otros. Las nuevas tecnologías no se pueden utilizar en absoluto. Sin embargo, solo una pequeña parte de las funciones proporcionadas por D3D (específicamente D3D8) se pueden simular cuando se usa HAL y el hardware no lo admite. Debe usar mucho código para analizar el hardware. capacidades y adoptar diferentes estrategias