Open GL - ayuda, girar una escena completa en openGL

 
Vista:

ayuda, girar una escena completa en openGL

Publicado por miguelo (3 intervenciones) el 25/11/2004 18:56:13
Hola buenas, soy novato en openGL, y estoy modificando un ejemplo que cogi de internet, sobre el cual voy añadiendo las cosas que necesito para hacer la visualizacion de un armario en 3D. Lo que hago es pintar toda la estructura de las tablas que componen mi armario, pero mi gran duda es si cada vez q giro, esccalo todo el armario es necesario que este vuelva a ser repintado?, supongo que no, ya que relentiza muchisimo el movimiento al tener q volver a repintar toda la escena, sobre todo si mi armario es tocho.

Aqui os pongo el código, a ver si alguno, me dice como hacer para en el mousemove, quitar la llamada al procedimiento "Draw" donde construyo el armario, pos algo que mueva la escena que ya esta pintada. GRACIAS

var
v3D: Tv3D;
rocas, tierra, zebrano: TTextura;
Text_Tablas: array [1..MAXTABLAS] of TTextura;
RC:HGLRC;
armario: TArmario;
desplazx, desplazy: integer;

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=( 0.5, 0.5, 0.5, 0.0);
specular: array [0..3] of GLfloat=( 1.0, 1.0, 1.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 Tv3D.FormCreate(Sender: TObject);
var
DC:HDC;
begin
//Creamos un control para correr OpenGL sobre él...
GLC:=TGLControl.Create(self);
GLC.Parent:=self;
GLC.Left:=10;
GLC.Top:=10;
GLC.Width:=550;
GLC.Height:=450;
//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;

Text_Tablas[1]:=TTextura.Create;
Text_Tablas[1].Cargarde(1,ExtractFileDir(Application.ExeName)+'\images\textures\roble.bmp');

end;

procedure Tv3D.Draw;
var
i,j: byte;
begin
glClearColor(0,0.2,0,0); // Ponemos un color Oscuro de Fondo...
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Algo así como borrar la Pizarra...
glenable(GL_DEPTH_TEST); //usamoe el Z-Buffer para darle realismo a la escena...

//Y empezamos a dibujar...
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

//*(
//aqui es donde aplicamos el zoom a toda la escena y tambien rotamos
glTranslatef(0.0, 0.0, -TrackBar1.Position/7);
glRotatef(alpha+dx,0.0,1.0,0.0);
glRotatef(betha+dy,1.0,0.0,0.0);
//*)

GLPushMatrix;
Text_Tablas[1].UsaTextura(1);
for j:=1 to armario.ntablas[1] do begin
PintarTabla(1,j);
end;
GLPopMatrix;

//Mostramos la escena construida...
SwapBuffers(wglGetCurrentDC);
end;

procedure Tv3D.TrackBar1Change(Sender: TObject);
begin
Draw;
end;

procedure Tv3D.FormPaint(Sender: TObject);
begin
Draw;
end;

procedure Tv3D.GLMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
mStartX:=X;
mStartY:=Y;
end;

procedure Tv3D.GLMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
//Ajustamos los nuevos ángulos de visualización...
alpha:=alpha+dx;
dx:=0.0;
betha:=betha+dy;
dy:=0.0;
end;

procedure Tv3D.GLMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (ssLeft in Shift) then begin
Cursor:=crHandPoint;
dx:=(x-mStartX)/2;
dy:=(y-mStartY)/2;
(*
glTranslatef(0.0, 0.0, -TrackBar1.Position/7);
glRotatef(alpha+dx,0.0,1.0,0.0);
glRotatef(betha+dy,1.0,0.0,0.0);
SwapBuffers(wglGetCurrentDC);
//*)
Draw;
end;
end;
procedure Tv3D.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Text_Tablas[1].free;
wglMakeCurrent(0,0);
end;

Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:ayuda, girar una escena completa en openGL

Publicado por miguelo (3 intervenciones) el 25/11/2004 20:01:46
tambien he probado, mover la camara con gluLookAt(, , , , , ), pero tampoco lo refresca, es decir donde tengo la llamada al procedimiento Draw que se encarga de construir el armario, cambiarlo por una llamada al gluLookat para ir cambiando la posicion de la camara y dar la sensación de mover el armario, pero supongo que a parte del gluLookat me debe faltar algo para que vaya refrescando la escena sin tener que volver a construirla entera.
AYUDA POR FAVOR
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:ayuda, girar una escena completa en openGL

Publicado por Daniel Luque León (3 intervenciones) el 21/05/2006 18:33:22
Hola ,te recomiendo que simplemente gires la cámara desde el pto de vista en la funcion

gluLookAt

Para ello tienes que pasar de coordenadas cartesianas a polares ,pruebalo , y si no te sale me envias un correo y te paso un ejemplo , sino tb puedes utilizar un rotatef que creo q hace el mismo efecto .

Salu2!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:ayuda, girar una escena completa en openGL

Publicado por FENIXadr (2 intervenciones) el 14/12/2007 03:57:48
Hola miguelo... yo tambien soy nuevo en OpenGL y ese ejemplo que mostraste es el mismo que estoy usando .... a veces los objetos que dibujamos tienen formas complejas y para poder calcular los vértices es necesario hacer unas cuantas operaciones matemáticas (multiplicaciones, divisiones, senos, cosenos, etc) que llevan mucho tiempo de ejecución y suele ser este el problema de velocidad.... lo que te aconsejaría es que hagas una rutina que calcule todos los vertices y los guarde en algun lugar de la memoria, esta rutina se llamaria solo una vez... y despues pasas los vertices ya calculados a las rutinas de OpenGL, esto es considerablemente mas rapido que recalcular el objeto cada vez... espero que esto te pueda ser de ayuda... yo estoy teniendo problemas para rotar objetos sobre su propio pivote... o sea... rotar la escena es una cosa... pero necesito rotar cada objeto sobre su propio pivote ademas... si sabes algo de esto te agradeceria la ayuda... nos vemos... bye bye
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar