Sistema solar con OpenGL [Delphi 7]

Buenas noches!!, aqui estoy una vez mas tratando de no dejar en el olvido este blog! y claro sigo de obsesionado con OpenGL y delphi y ahora les traigo una aplicacion de post anteriores!, sera un sistema solar( o almenos algunos planetas) utilizando luz y texturas que ya lo hemos visto en post anteriores. De nuevo para no entrar con detalles de post anteriores el contexto lo haremos siguiendo este proyecto. En este proyecto tenemos todo el contexto creado con las librerias necesarias y ademas tiene dibujado un cubo en el comentario “//Aqui podremos dibujar lo que queramos” en delante podremos dibujar asi que borramos las 3 lineas de codigo (glutSolidCube u otras que esten) y empezemos a graficar 😀

Creando el Sol y Mercurio.

Primero que nada crearemos en nuestro evento “OnPaint” los primeros trazos para simular nuestro sistema solar, para eso dibujaremos una esfera central que sera nuestro sol, por el momento sera de color amarilla y una esfera mas diminuta que este girando alrededor del sol que sera mercurio. Para eso nos dirigimos a nuestro procedimiento onPaint y debajo del comentario //Aqui podremos dibujar lo que queramos, ponemos lo siguiente:

 //Aqui podremos dibujar lo que queramos
     glTranslatef(0,0,-10);
     glRotatef(115,1,0,0);
 glPushMatrix;
    glColor3f(1,1,0);
    glutSolidSphere(1,20,20);
 glPopMatrix;

 glPushMatrix;
    glColor3f(0.5,0.5,0.5);
    glRotatef(angle,0,0,1);
    glTranslatef(3,0,0);
    glutSolidSphere(0.1,20,20);
 glPopMatrix;


Para que inicie la animacion tendremos que tener un timer y crear su evento dando doble clic (el proyecto ya trae el codigo para ese evento, solo olvide poner el componente timer) si no este seria el codigo:

procedure TForm2.Timer1Timer(Sender: TObject);
begin
inc(angle,1);
if angle > 360 then angle:=0;
Repaint;
end;

Lo unico que hace es aumentar la variable Angle que es la que nos dara una animacion de rotacion.
Si corremos el programa tendremos lo siguiente:

Agregando las primeras texturas
Primero que nada hay que crear nuestras texturas, primero haremos el sol y el primer planeta que seria mercurio:

Textura: Sol, Mercurio (guarden las fotos en el proyecto)

Como en el post pasado que hicimos de texturas, en nuestro form agregamos 2 TImage y le cambiamos el nombre a cada uno “imgSol” y “imgMercurio” y a cada uno le cargamos la foto desde el inspector de objetos en la propiedad “Picture” quedando de la siguiente manera:

Es importante que a cada TImage le asignemos la propiedad visible a “false”.

Ahora crearemos 2 variables publicas llamadas “SolTex” y “MercurioTex” tipo TTextura ( que es nuestra libreria anteriormente usada) y en el procedimiento onCreate las inicializamos:

//en evento onCreate
    SolTex:=TTextura.Create;
    SolTex.Cargarde(imgSol.Picture.Bitmap);
    SolTex.ModeEnv:=GL_MODULATE;
    SolTex.Definicion:=dAlta;
    MercurioTex:=TTextura.Create;
    MercurioTex.Cargarde(imgMercurio.Picture.Bitmap);
    MercurioTex.ModeEnv:=GL_MODULATE;
    MercurioTex.Definicion:=dAlta;

Esto ha sido lo mismo que el post de texturas, cargamos los BitMap desde los TImage y ponemos sus propiedades. Para aplicarlas a cada esfera que tenemos ya dibujadas usaremos el procedimiento “UsaTextura” pero ademas tendremos que habilitar ciertas caracteristicas para que las texturas actuen de diferente manera. Al sol dejaremos el tipo de mapeado respecto al objeto y a los demas objetos con mapeado esferico( creo lo explique en el post anterior) si no ustedes notaran la diferencia!. Entonces el procedimient onPain en la parte en donde estamos dibujando haremos lo siguiente:

//Aqui podremos dibujar lo que queramos
  //conf texturas
  glEnable(GL_TEXTURE_GEN_S) ;
  glEnable(GL_TEXTURE_GEN_T) ;
  glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR) ;
  glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR) ;
  //fin conf texturas
     glTranslatef(0,0,-10);
     glRotatef(115,1,0,0);
 glPushMatrix;
    glColor3f(1,1,0);
    SolTex.UsaTextura;
    glutSolidSphere(1,20,20);
 glPopMatrix;

  glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ;
  glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ;

 glPushMatrix;
    glColor3f(0.5,0.5,0.5);
    glRotatef(angle,0,0,1);
    glTranslatef(3,0,0);
    MercurioTex.UsaTextura;
    glutSolidSphere(0.1,20,20);
 glPopMatrix;

Hemos agregado una nueva seccion que es //conf texturas que es donde habilitamos en opengl la generacion de cordenadas y ademas establecemos que tipo de mapeado sera, en este caso el sol estara respecto al objeto y los planetas estaran respecto al observador ( u ojo) y ahora se vera de esta forma:

Agregando luz
Al igual que el post pasado tendremos que declarar los siguientes arreglos como globales para asi usarlos al configurar nuestra luz

var
  Form2: TForm2;
  glfLightPosition : Array[0..3] of GLfloat = (0,0,-10,1.0);
  glfLightDiffuse : Array[0..3] of GLfloat= (0.7, 0.7, 0.7, 1.0);
  glfLightSpecular: Array[0..3] of GLfloat = (0.7, 0.7, 0.7, 1.0);

y para configurar esas luces en nuestro evento onPaint debajo de la configuracion de las texturas agregamos lo siguiente:

  //fin conf texturas

  //conf luz
  glLightfv(GL_LIGHT0, GL_POSITION, @glfLightPosition); // Se definen las
  glLightfv(GL_LIGHT0, GL_DIFFUSE, @glfLightDiffuse); //carácterísticas de la
  glLightfv(GL_LIGHT0, GL_SPECULAR,@glfLightSpecular);// luces
  glenable(GL_LIGHT0);
  //Fin cinf luz

Si se fijan en el arreglo glfLightPosition son las simples cordenadas x,y,z ( los primeros 3 lugares) y le estamos dando una posicion de -10 en z por lo tanto la luz le estara pegando solo por un lado a los planetas! simulando asi la luz del sol. Aqui no tenemos activadas las luces en openGL asi que lo que tenemos que hacer es usar glEnable(GL_LIGHTING), pero lo usaremos despues de haber creado el sol, y antes de crear el sol poner glDisable(GL_LIGHTING) esto para que las luces no afecten al sol y solo a los planetas, por lo tanto el sol estara brilloso todo el tiempo. Entonces nuestro codigo quedaria de la siguiente manera:

//Aqui podremos dibujar lo que queramos

  //conf texturas
  glEnable(GL_TEXTURE_GEN_S) ;
  glEnable(GL_TEXTURE_GEN_T) ;
  glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR) ;
  glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR) ;
  //fin conf texturas

  //conf luz
  glLightfv(GL_LIGHT0, GL_POSITION, @glfLightPosition); // Se definen las
  glLightfv(GL_LIGHT0, GL_DIFFUSE, @glfLightDiffuse); //carácterísticas de la
  glLightfv(GL_LIGHT0, GL_SPECULAR,@glfLightSpecular);// luces
  glenable(GL_LIGHT0);
  //Fin cinf luz

 glTranslatef(0,0,-10);
 glRotatef(115,1,0,0);
 glDisable(GL_LIGHTING);//deshabilitamos la luz para que no le afecte al sol
 glPushMatrix;
    glColor3f(1,1,0);
    SolTex.UsaTextura;
    glutSolidSphere(1,20,20);
 glPopMatrix;

  glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ;
  glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ;

 glEnable(GL_LIGHTING);//Se habilitan las luces para los planetas
 //mercurio
 glPushMatrix;
    glRotatef(angle,0,0,1);
    glTranslatef(3,0,0);
    glRotatef(angle,0,0,1);
    MercurioTex.UsaTextura;
    glutSolidSphere(0.1,20,20);
 glPopMatrix;

El resultado sera el siguiente:

Agregando mas planetas
Ahora lo que solo falta sera agregar mas planetas, y se hace de la misma manera y explicare como y ustedes lo haran. Primero para crear a mercurio usamos esto:

 //mercurio
 glPushMatrix;
    glRotatef(angle,0,0,1);//rotamos segun la variable angle cambia(forma parte de la traslacion)
    glTranslatef(3,0,0); // con esta traslacion se logra obtener una traslacion del planeta respecto al sol
    glRotatef(angle,0,0,1);//rota sobre su propio eje
    MercurioTex.UsaTextura;//se usa la textura cargada en el procedimiento onCreate
    glutSolidSphere(0.1,20,20);//se crea la figura a la cual se le aplicara todo lo anterior
 glPopMatrix;

Entonces si queremos poner venus que podriamos hacer?, primero crear una variable tipo TTextura por ejemplo venusTex:TTextura; declarada en la seccion publica, y se hace lo mismo que las otras texturas y para crear venus solo tendriamos que variar el tamaño de la creacion de la esfera y la traslacion para que este un poco mas alejado y la primer rotacion para cambiar la velocidad entonces por ejemplo despues de crear mercurio asi quedaria venus

 //venus
 glPushMatrix;
    glRotatef(2*angle-45,0,0,1);
    glTranslatef(3.5,0,0);
    glRotatef(angle,0,0,1);
    VenusTex.UsaTextura;
    glutSolidSphere(0.3,20,20);
 glPopMatrix;

Donde venus es esta textura. Y que es lo que se hace aqui?, en la primera rutacion (glRotatef(2*angle-45,0,0,1);) al multiplicar la variable angle por dos, estamos aumentando la velocidad de la traslacion de ese planeta respecto al sol, y cuando le restamos -45, lo estamos desfasando 45 grados para que no esten todos los planetas alineados, el resultado sera el siguiente:

Y asi sucesivamente lo haremos con los demas planetas!.

Code4Fun!

Anuncios

34 comentarios sobre “Sistema solar con OpenGL [Delphi 7]

  1. muy buena explicacion de como usar opengl tambien soy programador de delphi que al igual que tu sigo obsecionado con este lenguaje me gustaria que me enviara el proyecto a mi correo para analizarlo mas detalladamente quisiera tambien saber si son las lib glscene que usas en el proyecto

    1. Claro te envio el proyecto a tu correo!, pero el proyecto lo tengo un poco alterado ya que use OpenAL para intentar usar audio en 3D, asi que lo que veas de OpenAL podras ignorarlo ya que no esta muy bien elaborado. Saludos y te recomiendo leer bien el post si tienes alguna pregunta no dudes en preguntar 😉

    1. Oh! una disculpa por eso!, para hacer los anillos lo único que vamos a hacer es un torus y lo escalamos, lo podemos hacer de la siguiente manera:
      // sexto planeta saturno
      glPushMatrix;
      TexSaturno.UsaTextura;
      glRotatef(2*angle+45,0,0,1);
      glTranslatef(-4,0,0);
      glRotatef(angle*2,0,0,1);
      glutSolidSphere(0.2,15,15);
      glPushMatrix;
      glDisable(GL_TEXTURE_2D);
      glScalef(0.9,0.9,0.01);
      glColor3f(1,1,1);
      glutSolidTorus(0.08,0.38,20,20);//anillo!
      glPopMatrix;
      glPopMatrix;

  2. Hola me podrias dejar todo el proyecto a este mi correo por favor amigo, es fabulosa toda la informacion que aportas, sigue adelante que a futuro tendras tu recompesa, claro a parte que te divierte 4fun really?
    renyuni@hoymail.com

  3. hola amigo necesito una mega ayuda estoy creando el sistema solar con java y opngl pero no logro ponerle las texturas a mis planetas y quiero agregarle menús e iluminacion para cada planeta me podrías ayudar o me podrias proporciaonar el tuyo bueno .te djo mi correo: ediv_mir@live.com.mx

  4. Hola, tengo una duda, en estos momentos estoy programando en C++ con Qt Creator, mi duda es que cuando hago el anillo para el caso de saturno, las esferas que tengo dibujadas debajo de esta, se hacen chatas, es decir dejan de tener volumen, esto es debido a que estoy usando la funcion glScalef() cuando dibujo el anillo. Mi pregunta es, como hago para que las esferas no se vean afectadas por esto???
    he probado de volver a utilizar la funcion glScalef(1,1,1) colocando esos valores para volver a la normalidad las esferas, pero siguen igual. Desde ya muchas gracias!!

  5. Hola amigo, excelente aporte. Ahorita estoy trabajando con OpenGL y estoy haciendo unos proyectos me gustaría ver tu código fuente para ver que puedo aprender de ella. Estaría muy agradecido si compartieras tu codigo conmigo. Espero tu respuesta. Gracias.
    Mi correo es: alber_titanio_89@outlook.com

    Saludos.

  6. Cuando el piden el código tengo la ligera sospecha que solo lo quieren para terminar alguna tarea… el código fuente esta en este post, no hay porque pasarles nada.

    Hagan su tarea jóvenes 🙂 y si sinceramente no es lo que yo pienso, bueno les envío el código.

    Saludos

  7. si quisiera modificar la luz que proviene desde el sol, como lo haria ? en el sentido de que sea mas brillante o menos, lo controlaria con un tecla

    1. En este ejemplo el sol no es afectado por sombras, la verdad esto es de hace mucho tiempo y ya no recuerdo mucho, creo mejor deberías indagar en alguna guía de opengl (open gl la verdad es genérico, no importa el lenguaje, cualquier guía te podrá ayudar)

  8. Hola. Yo también estoy muy interesado en el proyecto. Alguna vez lo realice pero de eso a esta fecha de verdad no recuerdo bien como se usa lo estoy retomando y me ayudaría mucho si pudiera ver tu código. Me lo podrías pasar a mi correo y yo a cambio te lo regresaría con las mejoras que le pudiera implementar. Igual Voy a subir vídeo tutoriales en cuanto lo retome para la comunidad dado que no hay mucho material en español. udsg07@gmail.com

  9. Gente, si a alguno le interesa tengo el código fuente sobre C++, Framework QtCreator. No tengo ningún problema en dar el código, lo que si es complicado la configuración para hacerlo funcionar. Es para que les sirva de guía.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s