Convierta el marco VC OPENGL de NeHe traducido por CKER a la versión Delphi.
Espero que sea útil para los hermanos que usan Delphi para aprender OPENGL.
No sé por qué, pero no se puede ejecutar directamente en mi entorno Delphi, pero parece funcionar bien en otras máquinas.
Mi máquina sólo puede compilar y ejecutar archivos EXE.
Gracias a NeHe por proporcionar un marco tan bueno y gracias a CKER por traducir la información de VC.
PROgrama Proyecto1;
Usos
opengl,
ventanas,
Mensajes;
constante
WND_TITLE = 'Marco básico OPenGl'; //Título
var
//================================================== ============================
// Cada OpenGL está conectado a un contexto de sombreado. La tabla de contexto de sombreado conecta todas las llamadas OpenGL a
// Reciba el contexto del dispositivo (tabla de descripción del dispositivo) y defina la tabla de descripción de sombreado OpenGL como hRC, para que el programa pueda
// Si es suficiente dibujar la ventana, también necesita crear una tabla de descripción del dispositivo. La tabla de descripción del dispositivo de Windows se define como hDC.
// DC conecta la ventana a GDI (Interfaz de dispositivo gráfico). Y RC conecta OpenGL
// a CC.
//================================================== ============================
h_RC: HGLRC; // Contexto de representación (tabla de descripción de sombreado).
h_DC: HDC // Contexto del dispositivo (tabla de descripción del dispositivo)
h_Wnd: HWND // identificador de ventana
h_Instance: HINST; // Instancia del programa (instancia).
teclas: Array[0..255] Of Boolean; // Matriz para rutinas de teclado
{$R*.res}
//================================================== ===============================
//Restablece el tamaño de la escena OpenGL independientemente de si el tamaño de la ventana ha cambiado (suponiendo que no se utilice el modo de pantalla completa).
//Incluso cuando no se puede cambiar el tamaño de la ventana (por ejemplo, en modo de pantalla completa), se ejecutará al menos una vez————————
//Establece la perspectiva al comienzo del programa. El tamaño de la escena OpenGL se establecerá según el tamaño de la ventana en la que se muestra.
//================================================== ===============================
Procedimiento glResizeWnd(Width, Height: Integer); //Restablece e inicializa el tamaño de la ventana GL
Comenzar
If (Altura = 0) Entonces // Evita que la altura sea 0 y provoque una excepción de división por 0.
Altura := 1;
glViewport(0, 0, Ancho, Alto); //Restablecer la ventana gráfica actual (Viewport)
//Las siguientes líneas configuran la pantalla de perspectiva. Esto significa que las cosas que están más lejos parecen más pequeñas. Hacerlo crea una realidad
//Escena de aparición. La perspectiva aquí se calcula como un ángulo de visión de 45 grados según el ancho y el alto de la ventana. 0,1f, 100,0f son
//El punto inicial y final de la profundidad que podemos dibujar en la escena.
//glMatrixMode(GL_PROJECTION) especifica que las siguientes dos líneas de código afectarán la matriz de proyección.
//La matriz de proyección se encarga de agregar perspectiva a nuestra escena.
//glLoadIdentity() es similar a restablecer. Restaura el estado de la matriz seleccionada a su estado original.
//Después de llamar a glLoadIdentity() configuramos la perspectiva de la escena.
glMatrixMode(GL_PROJECTION); //Selecciona la matriz de proyección
glLoadIdentity(); // Restablecer la matriz de proyección
gluPerspective(45.0, Ancho/Alto, 0.1, 100.0); // Calcula la proporción de apariencia de la ventana.
//glMatrixMode(GL_MODELVIEW) especifica que cualquier nueva transformación afectará la matriz de vista del modelo (matriz de observación del modelo).
// La información de nuestro objeto se almacena en la matriz de observación del modelo.
glMatrixMode(GL_MODELVIEW); //Seleccionar matriz de observación del modelo
glLoadIdentity(); //Restablecer matriz de observación del modelo
//Si aún no entiendes lo que significan estos términos, no te preocupes.
//Solo debes saber que tienes que hacer esto si quieres obtener una escena en perspectiva excelente.
Fin;
//================================================== ===============================
// Realice todas las configuraciones para OpenGL. Configure el color para borrar la pantalla, active el caché de profundidad,
// Habilitar sombreado suave (suavizado de sombras), etc. Esta rutina no se llama hasta que se crea la ventana OpenGL.
// Este proceso tendrá un valor de retorno. Pero la inicialización aquí no es tan complicada y todavía no hay necesidad de preocuparse por el valor de retorno.
//================================================== ===============================
Procedimiento glInit();
Comenzar
//Establece el color utilizado al borrar la pantalla. Si no está seguro de cómo funciona el color, aquí tiene una explicación rápida.
//Los valores de color oscilan entre 0,0f y 1,0f. 0,0f representa la situación más oscura y 1,0f es la situación más brillante.
// El primer parámetro después de glClearColor es Red Intensity (componente rojo), el segundo es verde y el tercero es azul.
//El valor máximo también es 1,0f, que representa el caso más brillante de un componente de color específico. El último parámetro es el valor Alfa.
// Cuando se usa para borrar la pantalla, no te importa el cuarto número. Ahora sea 0.0f.
//Al mezclar tres colores primarios (rojo, verde, azul), puedes obtener diferentes colores
//Entonces, usa glClearColor(0.0f,0.0f,1.0f,0.0f), tu azul para borrar la pantalla.
//Si usa glClearColor(0.5f,0.0f,0.0f,0.0f), se usará rojo medio para borrar la pantalla.
//Ni el más brillante (1.0f), ni el más oscuro (0.0f). Para obtener un fondo blanco, todos los colores deben configurarse al máximo brillo (1,0f).
//Si quieres un fondo negro, configura todos los colores al más oscuro (0.0f).
glClearColor(0.0, 0.0, 0.0, 0.0); // fondo negro
//El suavizado de sombras combina finamente los colores a través de polígonos y suaviza la luz externa.
glShadeModel(GL_SMOOTH); // Habilitar suavizado de sombras
// Lo siguiente que se debe hacer es el búfer de profundidad. Piense en el búfer de profundidad como una capa detrás de la pantalla.
//El búfer de profundidad realiza un seguimiento continuo de la profundidad con la que el objeto ingresa a la pantalla. En realidad, este programa no utiliza el caché profundo.
//Pero casi todos los programas OpenGL que muestran escenas 3D en la pantalla utilizan buffers de profundidad. Su orden determina qué objeto se dibuja primero.
//De esta manera no dibujas un cuadrado detrás de un círculo dentro del círculo. El búfer de profundidad es una parte muy importante de OpenGL.
glClearDepth(1.0); //Establece el búfer de profundidad
glEnable(GL_DEPTH_TEST); // Habilitar pruebas de profundidad
glDepthFunc(GL_LESS); // Tipo de prueba de profundidad realizada
// Luego dile a OpenGL que queremos la mejor corrección de perspectiva posible.
//Esto afectará ligeramente el rendimiento. Pero hace que la perspectiva se vea un poco mejor.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Corrección de perspectiva realmente buena.
Fin;
//================================================== ===============================
//Todo el código de dibujo. Todo lo que quieras mostrar en la pantalla aparecerá en este código.
// Cada programa futuro agregará código nuevo aquí.
//================================================== ===============================
Procedimiento glDraw();
Comenzar
glClear(GL_COLOR_BUFFER_BIT O GL_DEPTH_BUFFER_BIT // Borrar pantalla y búfer de profundidad);
glLoadIdentity(); //Restablecer la matriz de observación del modelo actual
Fin;
Función WndProc(hWnd: HWND; // identificador de ventana
Mensaje: UINT; // Mensaje de ventana
wParam: WPARAM; // Contenido del mensaje adicional
lParam: LPARAM // Contenido adicional del mensaje
): LRESULTADO; llamada estándar;
Comenzar
Resultado := 0;
Caso (mensaje) de // Comprobar mensajes de Windows
WM_ACTIVATE: // Monitorear mensaje de activación de ventana
Comenzar
Fin;
WM_CREATE: // Crear
Comenzar
Fin;
WM_CLOSE: // cerrar
Comenzar
PostQuitMessage(0); //Enviar mensaje de salida
Resultado := 0
Fin;
WM_KEYDOWN: // tecla presionada
Comenzar
claves[wParam] := Verdadero; // Si es así, configúrelo en VERDADERO
Resultado := 0;
Fin;
WM_KEYUP: // Suelta la clave
Comenzar
claves[wParam] := False // Si es así, configúrelo en FALSE;
Resultado := 0;
Fin;
WM_SIZE: //Ajustar el tamaño de la ventana OpenGL
Comenzar
glResizeWnd(LOWord(lParam), HIWORD(lParam)); //LoWord=Ancho,HiWord=Alto
Resultado := 0;
Fin;
WM_TIMER: //temporizadores
Comenzar
Fin;
De lo contrario //Deja que Windows se encargue del resto.
Resultado := DefWindowProc(hWnd, Msg, wParam, lParam); // Pasa todos los mensajes no procesados a DefWindowProc.
Fin;
Fin;
//================================================== ===============================
// Solo se llama antes de que salga el programa. La función es liberar la tabla de contexto de color, la tabla de contexto del dispositivo y el identificador de ventana en secuencia.
// Se agregó mucha verificación de errores. Si el programa no puede destruir alguna parte de la ventana, aparecerá un mensaje de error apropiado.
// ventana de mensaje,
//================================================== ===============================
Procedimiento glKillWnd(Pantalla completa: booleano);
Comenzar
//Lo primero que se hace en KillGLWindow() es comprobar si está en modo de pantalla completa.
//En caso afirmativo, vuelva al escritorio. La ventana debería haberse destruido antes de desactivar el modo de pantalla completa,
//Pero hacer esto en algunas tarjetas gráficas puede bloquear el escritorio. Por lo tanto, es mejor desactivar primero el modo de pantalla completa.
//¡Esto evitará fallas en el escritorio y funciona muy bien tanto en tarjetas gráficas Nvidia como en 3dfx!
Si es pantalla completa, entonces // ¿En modo de pantalla completa?
Comenzar
// Utilice ChangeDisplaySettings(NULL,0) para volver al escritorio original.
// Toma NULL como primer parámetro,
// Pasar 0 como segundo parámetro obliga a Windows a utilizar el valor actualmente almacenado en el registro
// (resolución predeterminada, profundidad de color, frecuencia de actualización, etc.) para restaurar efectivamente mi escritorio original.
// Después de volver al escritorio, el puntero del mouse debe volver a ser visible.
ChangeDisplaySettings(devmode(Nil^), 0); // En caso afirmativo, vuelva al escritorio.
ShowCursor(True); //Mostrar mouse
Fin;
//Si tiene una tabla de descripción de colores (hRC).
Si h_RC > 0 Entonces
//Ver si podemos liberarlo (separar hRC de hDC).
Si (no wglMakeCurrent (h_DC, 0)) entonces
MessageBox(0, '¡DC y RC no se pueden liberar!', 'Error', MB_OK O
MB_ICONERROR);
// ¿Se puede eliminar la tabla de descripción de sombreado?
Si (no wglDeleteContext(h_RC)) entonces
Comenzar
MessageBox(0, '¡Error al eliminar la tabla de contexto de sombreado!', 'Error', MB_OK O
MB_ICONERROR);
h_RC := 0;
Fin;
//Si la tabla de contexto del dispositivo existe y, de ser así, intenta liberarla.
Si ((h_DC > 0) y (ReleaseDC(h_Wnd, h_DC) = 0)) entonces
Comenzar
MessageBox(0, '¡Error al liberar el contexto del dispositivo!', 'Error', MB_OK O
MB_ICONERROR);
h_DC := 0;
Fin;
//Si hay un identificador de ventana, llama a DestroyWindow(hWnd) para intentar destruir la ventana
Si ((h_Wnd <> 0) y (no DestroyWindow(h_Wnd))) entonces
Comenzar
MessageBox(0, '¡No se puede destruir el formulario!', 'Error', MB_OK O
MB_ICONERROR);
h_Wnd := 0;
Fin;
//Cerrar sesión en la clase de ventana
//Esto nos permite destruir la ventana normalmente y luego abrir otras ventanas,
//No recibirás mensajes de error como "Clase de Windows ya registrada" (clase de ventana ya registrada).
Si (no UnRegisterClass('OpenGL', hInstance)) entonces
Comenzar
MessageBox(0, '¡No se puede cerrar sesión en la clase de ventana!', 'Error', MB_OK O
MB_ICONERROR);
hInstancia := 0;
Fin;
Fin;