Dado que el OpenGL.pas de Delphi es la versión 1.0, y lo que realmente se usa ahora es al menos la versión 1.1, y el método de simulación de software puro de Windows también es la versión 1.1, por lo que debe importar algunas funciones necesarias usted mismo. También están disponibles algunas unidades gratuitas de código abierto, como OpenGL12.pas de Mike Lischke. Por supuesto, escribirlo usted mismo puede hacer que el diseño sea más conciso y no tendrá que encontrar errores en un código enorme que sea demasiado avanzado y completo.
Primero introduzca las unidades necesarias Windows, Mensajes, OpenGL.
Para agregar algunas extensiones necesarias.
constante
//GL_EXT_bgra
GL_BGR_EXT = $80E0;
GL_BGRA_EXT = $80E1;
// desplazamiento del polígono
GL_POLYGON_OFFSET_UNITS = $2A00;
GL_POLYGON_OFFSET_POINT = $2A01;
GL_POLYGON_OFFSET_LINE = $2A02;
GL_POLYGON_OFFSET_FILL = $8037;
GL_POLYGON_OFFSET_FACTOR = $8038;
Procedimiento glBindTexture(destino: GLEnum; textura: GLuint stdcall; opengl32 externo);
procedimiento glDeleteTextures(n: GLsizei; texturas: PGLuint stdcall; opengl32 externo);
procedimiento glGenTextures(n: GLsizei; texturas: PGLuint; stdcall externo;
función glIsTexture(textura: GLuint): GLboolean; stdcall externo opengl32;
procedimiento glPolygonOffset(factor, unidades: GLfloat; stdcall externo;
// Esta declaración se utiliza para corregir un error en OpenGL.pas
función gluBuild2DMipmaps(objetivo: GLEnum; componentes, ancho, alto: GLint; formato, tipo: GLEnum; Datos: Puntero): GLint external stdcall;
Ahora la interfaz se ha actualizado básicamente a la versión 1.1. Si se necesitan otras extensiones, se pueden agregar de manera similar.
A continuación, debe crear el contexto de dibujo OpenGL RC, para lo cual necesita el contexto de dispositivo DC de la ventana GDI. La propiedad TForm.Handle u otras propiedades Handle de TWinControl son DC. Puede utilizar la siguiente función para crear RC desde DC, y el valor de retorno es el identificador de RC. Luego puedes dibujar usando OpenGL. Generalmente se puede utilizar dentro del evento OnCreate del formulario. Las opciones de esta función significan búfer de profundidad, búfer de plantilla, búfer de acumulación y generar valor de canal alfa.
tipo
TRCOptions = conjunto de (roDepth, roStencil, roAccum, roAlpha);
función CreateRC(dc: HDC; opt: TRCOptions): HGLRC;
var
PFDescriptor: TPixelFormatDescriptor;
Formato de píxel: entero;
comenzar
FillChar(PFDescriptor, TamañoDe(PFDescriptor), 0);
con PFDescriptor hacer
comenzar
nTamaño := TamañoDe(PFDescriptor);
nVersión := 1;
dwFlags := PFD_SUPPORT_OPENGL o PFD_DRAW_TO_WINDOW o PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := GetDeviceCaps(DC, BITSPIXEL) * GetDeviceCaps(DC, AVIONES);
si roDepth está en opt, entonces cDepthBits := 24;
si roStencil está en opt entonces cStencilBits := 8;
si roAccum está en opt entonces cAccumBits := 64;
iLayerType := PFD_MAIN_PLANE;
fin;
PixelFormat := ElijaPixelFormat(DC, @PFDescriptor);
Afirmar (PixelFormat <> 0);
Afirmar(SetPixelFormat(DC, PixelFormat, @PFDescriptor));
Resultado := wglCreateContext(DC);
Afirmar (Resultado <> 0);
wglMakeCurrent(dc, Resultado);
fin;
Dibuja en el evento OnPaint del formulario. Recuerde, una vez completado el dibujo, debe usar SwapBuffers (dc: HDC) para intercambiar el búfer de dibujo y el búfer de visualización para que se muestre la imagen. Recuerde también llamar a glViewport(0, 0, ClientWidth, ClientHeight); en el evento OnResize del formulario para que RC y DC puedan sincronizarse.
Destruye RC en el evento OnDestroy del formulario.
procedimiento DestroyRC(rc: HGLRC);
comenzar
si rc = 0 entonces Salir;
wglMakeCurrent(0, 0);
wglDeleteContext(rc);
fin;
En este punto, el marco de un programa OpenGL ya ha tomado forma. Pero aún quedan problemas por resolver.
Primero, evite que Windows borre el fondo y afecte la velocidad. Agregar funciones miembro al formulario
privado
procedimiento WMEraseBkgnd(var Mensaje: TWmEraseBkgnd); mensaje WM_ERASEBKGND;
procedimiento TGLWindow.WMEraseBkgnd(var Mensaje: TWmEraseBkgnd);
comenzar
Mensaje.Resultado := 1;
fin;
En segundo lugar, estar más seguros. Agregue las siguientes funciones miembro.
protegido
procedimiento CreateParams(var Params: TCreateParams anulación);
procedimiento TGLWindow.CreateParams(var Params: TCreateParams);
comenzar
heredado;
con parámetros hacer
comenzar
Estilo := Estilo o WS_CLIPCHILDREN o WS_CLIPSIBLINGS;
WindowClass.Style:= CS_VREDRAW o CS_HREDRAW o CS_OWNDC;
fin;
fin;
Bien, ahora puedes olvidarte de estas cosas problemáticas y escribir tu maravillosa pantalla 3D :)
Tengo que decir algunas palabras: no cree varios RC en un hilo, ya que esto afectará seriamente el rendimiento. Algunas demostraciones personales de controles de ventanas OpenGL colocan múltiples controles en un formulario, lo que en realidad no es una buena idea. Se deben mostrar varias vistas con una ventana OpenGL. Además, no acceda a funciones OpenGL a través de subprocesos.
Además, cuando Windows instala automáticamente el controlador de la tarjeta gráfica, no instalará la aceleración de hardware OpenGL. ¡Debe instalar usted mismo el controlador del fabricante de la tarjeta gráfica!
Además, se proporciona una función de visualización de pantalla completa gratuita :)
función Pantalla completa(win: TWinControl; ancho, alto, profundidad de bits: entero): booleano;
var modo de visualización: DEVMODE;
comenzar
FillChar(modo de visualización, tamaño de (modo de visualización), 0);
con modo de visualización hacer
comenzar
dmSize := tamaño de(modo de visualización);
dmPelsWidth:= ancho;
dmPelsHeight := altura;
dmBitsPerPel := profundidad de bits;
dmFields := DM_BITSPERPEL o DM_PELSWIDTH o DM_PELSHEIGHT;
fin;
si ChangeDisplaySettings(modo de visualización, CDS_FULLSCREEN) = DISP_CHANGE_SUCCESSFUL
entonces comienza
ShowWindow(win.Handle, WS_MAXIMIZE);
resultado: = verdadero;
fin
de lo contrario resultado: = falso;
fin;
procedimiento RestoreDisplay(win: TWinControl);
comenzar
Cambiar configuración de pantalla (PDEVMODE (0) ^, 0);
MostrarWindow(win.Handle, SW_RESTORE);
fin;