unit Unit1;
interface
uses
OpenGL, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls;
type
{Nuestra nueva clase para controlar el movimiento del ratón sobre una
región del formulario}
TGLControl=class(TCustomControl)
public
property OnMouseDown;
property OnMouseUp;
property OnMouseMove;
property OnKeyDown;
end;
{Un tipo enumerado para los cuerpos que podemos dibujar}
TCuerpo =(cono,cilindro,esfera);
{La definición de nuestro formulario}
TForm1 = class(TForm)
TrackBar1: TTrackBar;
Label1: TLabel;
ComboBox1: TComboBox;
procedure FormCreate(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
private
//Para el movimiento del Ratón usamos estas variables...
alpha, betha:GLfloat; //angulo para los eventos del Ratón
dx,dy:GLFloat; //Actual desplazamiento de los angulos
mStartX,mStartY:integer; //Punto de inicio del movimiento del ratón
cuerpo:TCuerpo;
GLC:TGLControl; //Control para controlar la salida OpenGL
procedure Draw; //Dibuja la escena...
//Nuestro evento de OnMouseDown para el nuevo control...
procedure GLMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
//Nuestro evento de OnMouseUp para el nuevo control...
procedure GLMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
//Nuestro evento de OnMouseMove para el nuevo control...
procedure GLMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
public
{ Declaraciones públicas}
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure setupPixelFormat(DC:HDC);
const
pfd:TPIXELFORMATDESCRIPTOR = (
nSize:sizeof(TPIXELFORMATDESCRIPTOR); // Tamaño
nVersion:1; // versión
dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or
PFD_DOUBLEBUFFER; // Usamos un soporte para el double-buffering
iPixelType:PFD_TYPE_RGBA; // tipo de colores
cColorBits:16;
cRedBits:0; cRedShift:0; // ignoramos los colores
cGreenBits:0; cGreenShift:0;
cBlueBits:0; cBlueShift:0;
cAlphaBits:0; cAlphaShift:0; // sin buffer de transparencias
cAccumBits: 0;
cAccumRedBits: 0;
cAccumGreenBits: 0; // Ignoramos la acumulación
cAccumBlueBits: 0;
cAccumAlphaBits: 0;
cDepthBits:16; // usamos un buffer de profundidad de 16 bits
cStencilBits:0; // ni buffer de Stencil
cAuxBuffers:0; // sin buffers auxiliares
iLayerType:PFD_MAIN_PLANE; // Solo usamos un plano principal
bReserved: 0;
dwLayerMask: 0;
dwVisibleMask: 0;
dwDamageMask: 0;
);
var pixelFormat:integer;
begin
pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then begin
MessageBox(WindowFromDC(DC), 'Fallo el la elección del formato.', 'Error',
MB_ICONERROR or MB_OK);
exit;
end;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then begin
MessageBox(WindowFromDC(DC), 'Fallo en la elección del formato.', 'Error',
MB_ICONERROR or MB_OK);
exit;
end;
end;
procedure GLInit;
const
light0_position:array [0..3] of GLfloat=( 4.0, 4.0, 4.0, 0.0);
specular: array [0..3] of GLfloat=( 1.0, 1.0, 0.0, 1.0);
diffuse: array [0..3] of GLfloat=( 1.0, 1.0, 1.0, 0.7);
begin
// Asignamos una posición de observación para la escena
glMatrixMode(GL_PROJECTION);
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
//Cargamos la matriz de modelado...
glMatrixMode(GL_MODELVIEW);
//Definimos un nuevo modelo de despliegue...
glShadeModel(GL_FLAT);
//Habilitamos la prueba de profundidad...
glEnable(GL_DEPTH_TEST);
//Habilitamos una luz...
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_POSITION, @light0_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, @diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, @specular);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
end;
procedure TForm1.FormCreate(Sender: TObject);
var DC:HDC;
RC:HGLRC;
begin
//Creamos un comtrol para correr OpenGL sobre él...
GLC:=TGLControl.Create(self);
GLC.Parent:=self;
GLC.Left:=10;
GLC.Top:=10;
GLC.Width:=300;
GLC.Height:=300;
//Obtenemos el manejador del control para crear un contexto OpenGL en él...
DC:=GetDC(GLC.Handle);
//Asignamos un formato de pixelado al contexto...
SetupPixelFormat(DC);
RC:=wglCreateContext(DC); //creamos propiamente el Contexto...
wglMakeCurrent(DC, RC); //y lo activamos
GLInit; //Inicializamos las variables OpenGL
//Conectamos los eventos de nuestro control con los procedimientos que definimos...
GLC.OnMouseDown:=GLMouseDown;
GLC.OnMouseMove:=GLMouseMove;
GLC.OnMouseUp:=GLMouseUp;
//Empezamos dibujando un Cono...
ComboBox1.ItemIndex:=0;
end;
procedure TForm1.Draw;
var quad:GLUquadricObj; //Usamos una variable de este tipo para dibujar figuras complejas...
begin
// Borramos los buffers...
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
//Trasladamos la escena respecto al TrackBar...
glTranslatef(0.0, 0.0, -TrackBar1.Position/10);
//Rotamos la escena respecto a nuestras variables de control...
glRotatef(alpha+dx,0.0,1.0,0.0);
glRotatef(betha+dy,1.0,0.0,0.0);
// Ahora dibujamos el cuerpo ...
quad:=gluNewQuadric;
case cuerpo of
cono: gluCylinder(quad,0.5,0.0,1,48,1);
cilindro:gluCylinder(quad,0.5,0.5,1,48,1);
esfera: gluSphere(quad,0.5,32,32);
end;
glTranslatef(-2,0,0);
gluDeleteQuadric(quad);
//Mostramos la escena construida...
SwapBuffers(wglGetCurrentDC);
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
Draw;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
Draw;
end;
procedure TForm1.GLMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Label1.Caption:=Format('abajo: %d, %d',[X,Y]);
mStartX:=X;
mStartY:=Y;
end;
procedure TForm1.GLMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Label1.Caption:=Format('arriba: %d, %d',[X,Y]);
//Ajustamos los nuevos ángulos de visualización...
alpha:=alpha+dx;
dx:=0.0;
betha:=betha+dy;
dy:=0.0;
end;
procedure TForm1.GLMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (ssLeft in Shift) then begin
Label1.Caption:=Format('moviendo: %d, %d',[X,Y]);
dx:=(x-mStartX)/2;
dy:=(y-mStartY)/2;
Draw;
end;
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
// Con esto seleccionamos el tipo de cuerpo que deseamos dibujar...
cuerpo :=TCuerpo(ComboBox1.ItemIndex);
Draw;
end;
end.
评论0