"Ningún juego dura tanto hasta que te lo terminas como el que te programas tú mismo,
ninguno te absorbe tanto y ninguno te produce tanta satisfacción cuando lo has acabado"
Programacion de videojuegos
Inicio Curso de programación de juegos 14. Seleccion de objetos con raton
Domingo 22 de Octubre del 2017

Menu principal
Colaborar (con PayPal)

Para continuar con el trabajo de esta Web y poder pagar el hosting, viene bien la ayuda que sea. Gracias a todos.

Importe: 

Ultimas descargas
19.Jan

Clase que permite dibujar texto en OpenGL con mucha facilidad.Usa FreeType2.Para ver que hace y c...


14. Seleccion de objetos con raton Imprimir Correo electrónico
Videojuegos - Curso de Programación de juegos
Escrito por Vicengetorix   
Índice de Artículos
14. Seleccion de objetos con raton
Otro metodo
Posdata sobre C++
Todas las páginas
Llegamos a un tema interesante y muy util en cierto tipo de juegos. La seleccion de objetos.
Esta puede ser de objetos 3D o 2D, en todo caso veremos 2 metodos para hacerlo, el propio de OpenGL y otro marca de la casa (mio). Los metodos pueden ser muchos como ocurre en todos los temas de programacion. Estos dos metodos se pueden variar, mezclar, desechar y usar otro ... a gusto del programador.


El primero, como hemos dicho, es el propio de OpenGL. Hay gente que piensa que es anticuado, que ya no deberia soportarlo OpenGL. No se porque, por que a mi me gusta y me parece util y facil. En todo caso tengo entendido que en OpenGL 3.0 ya no es soportado (es declarado, en ingles, "deprecated", obsoleto). Como hasta OpenGL 2.1 (version anterior a la 3) si es soportado, lo veremos. Pasaran muuuuuuuuuchos años antes de que los drivers de las tarjetas no soporten OpenGL 2.1.
Aviso de todas formas que en tarjetas graficas INTEL con ciertos drivers, el retorno de las profundidades de los objetos seleccionados, en este metodo, no funciona bien. A mi me ha ocurrido tambien con una ATI (culpa de los fabricantes).
Dicho esto empezamos explicando el metodo.

OpenGL tiene un modo especial de pintar objetos llamado "modo de seleccion", que como su nombre indica, es para seleccionar objetos, en el cual, aunque pintes objetos no apareceran en pantalla. El proceso sera asi basicamente al hacer click (en este metodo los objetos seleccionables se pintan dos veces el frame del click, una vez para seleccion y otra el pintado normal).

  • Creamos un buffer para guardar los datos de los objetos seleccionados y le indicamos a OpenGL cual es con la funcion glSelectBuffer(...).
  • Obtenemos los datos del viewport en un buffer con glGetIntegerv(...) para usarlo mas tarde al componer la matriz para seleccion.
  • Componemos una matriz de proyeccion especial para seleccion con la funcion gluPickMatrix(...) y los datos del viewport de antes. Ponemos, ademas, la perspectiva actual en esta matriz y la camara en su ubicacion y direccion actual (la matriz de proyeccion igual que la que usamos en el momento de hacer click al raton pero usando gluPickMatrix(...) antes).
  • Pasamos a matriz modelo y desabilitamos texturas, iluminacion y todo lo que no sea necesario y pueda ralentizar el proceso.
  • Ponemos el modo seleccion con glRenderMode(GL_SELECT). A partir de aqui lo que pintemos no aparecera en pantalla.
  • Inicializamos la pila de nombres para objetos seleccionables (nombre=identificativo de cada objeto para poder identificarlo al seleccionarlo y luego como objeto seleccionado) con la funcion glInitNames().
  • Introducimos un primer valor en la pila de nombres con glPushName(0). Este valor lo cambiaremos por el identificativo de cada objeto durante su pintado para que, si esta seleccionado (se pinta en el area definido en gluPickMatrix(...) alrededor del raton), OpenGL lo introduzca en el buffer definido al principio de todo como un objeto seleccionado y al terminar el modo seleccion, podamos consultar en ese buffer los objetos que han sido seleccionado, si hay alguno.
  • Luego iremos cambiando el identificativo de los objetos en la pila de nombres con glLoadName(ID) (es lo mismo que hacer glPopName y glPushName(ID) ) y a continuacion pintando el objeto en su lugar y posicion.
  • Terminariamos de pintar todos los objetos seleccionables, cada uno con su nombre, y saldriamos del modo seleccion con la funcion glRenderMode(GL_RENDER) que ademas de dejar OpenGL en modo normal , retorna el numero de objetos seleccionados (0 es ninguno, claro). Si el buffer definido al principio se nos hubiera quedado pequeño y no cupieran los objetos seleccionados retornaria "-1".
  • Tras esto solo queda, si hubiera objetos seleccionados, investigar lo que hay en el buffer donde OpenGL habra dejado los objetos seleccionados (pintados en el area definida con la funcion gluPickMatrix(...) ). Cada objeto estara inentificado en el buffer con el nombre que le pusimos con glLoadName(ID) (el nombre es un numero) y tambien sabremos la profundidad maxima y minima del objeto en el z-buffer de OpenGL para poder saber cual esta mas cerca (esto es lo que comente arriba que no funciona con algunos drivers).

Conviene saber bien cual es la estructura que tiene el buffer que definimos para almacenar los objetos seleccionados.
Contiene 4 campos.

  • 1 GLuint. El numero de nombres en la pila de nombres en el momento de pintarlo en seleccion. En nuestro caso va a ser siempre 1 pero podrian ser mas (no se muy bien para que).
  • 1 GLuint. La profundidad en el z-buffer minima de ese objeto. Internamente multiplica la profundidad, que es un float de 0.0 a 1.0, por "232-1" y convierte el resultado al GLuint mas cercano, de forma que el resultado sera un entero menor cuanto mas cerca este el objeto, para poder hacer una simple comparacion de enteros.
  • 1 GLuint. La profundidad en el z-buffer maxima de ese objeto convertida a entero como el de antes.
  • Varios GLuint. Los nombres que estaban en la pila al pintar el objeto en modo seleccion. En nuestro caso solo sera 1 GLuint ya que nos hemos preocupado de poner solo un nombre a cada objeto (el primer campo era el numero de GLuint que ocupa este).

Tras la explicacion teorica, sera mejor empezar con la practica y asi verlo en accion.
Empezamos con el codigo del capitulo anterior (13. Pantalla completa y cambio de resolucion).

Como siempre con las definiciones globales.

Primero definimos mas indicadores de los que usamos para limitar cada pulsacion de tecla a una accion unica.

1
2
3
4
// Tecla L
bool LevantaTeclaL=true;
// Tecla Raton Izquierda
bool LevantaTeclaRI=true;

En la estructura que usamos para guardar los datos del raton incluimos un indicador para saber si se pulse el boton derecho.

1
bool derecho;
Una variable para elidentificativo del objeto seleccionado, definimos un numero como el maximo numero de objetos seleccionados (por si implementaramos seleccionar varios) y un indicador para que la leyenda aparezca en pantalla o no (ya va ocupando mucho).

1
2
3
4
5
6
7
8
9
10
11
// Variable para guardar el nonbre (identificador)
// del objeto seleccionado.
int ObjetoSel = 0;
 
// Definimos el maximo numero de objetos que se
// pueden seleccionar.
#define MAX_SEL 64
 
// Identificador de si se ve la leyenda o no.
bool ImprimeLeyenda=false;
 

Las funciones GeneraFuente, Escribe, CargaTextura, GeneraLista, ImprimeResoluciones (esta deberiamos quitarla ya) y CambiaPantalla no cambian.

En la funcion IniciaGL() incluiremos dos cosas conocidas para quien haya seguido los capitulos 11 y 12 (los Rompe Ladrillos).
Indicaremos a OpenGL que pinte solo las caras delanteras del los objetos para ahorrar tiempo y hacemos el ancho de las lineas mayor para ver mejor los objetos seleccionados, que los pondremos en wireframe (pintaremos solo las aristas de los lados).

1
2
3
4
5
6
7
8
9
10
11
// Estas dos funciones indican a OpenGL
// que no pinte las caras traseras de los
// objetos (vertices en orden de las manillas
// del reloj, desde donde miramos).
// Ahorran tiempo de computo.
glCullFace(GL_BACK) ;
glEnable(GL_CULL_FACE);
 
// Hago que OpenGL pinte lineas
// un poco mas anchas.
glLineWidth(2);

La funcion ProcesaMensajes(...) cambia para incluir en los eventos correspondientes, el boton derecho del raton.

1
2
3
4
5
6
// En caso de presionar el boton derecho del raton
case WM_RBUTTONDOWN:
// Pongo true en la variable para el boton
// derecho de nuestra estructura.
Raton.derecho = true;
break;

y

1
2
3
4
5
6
// En caso de soltar el boton derecho del raton
case WM_RBUTTONUP:
// Pongo false en la variable para el boton
// derecho de nuestra estructura.
Raton.derecho = false;
break;

La funcion CreaVentana() no cambia y la funcion principal WinMain(...) tampoco.

Ya solo queda la funcion Pinta(), como es habitual, con la mayor parte del trabajo.

Lo primero aqui sera cambiar lo que se hacia en anteriores versiones presionando el boton izquierdo (mover la camara) y que pase a hacerse con el derecho para que dejemos libre el izquierdo para seleccionar objetos.

1
2
3
// Si el boton derecho del raton esta presionado
if(Raton.derecho)
{

(antes aqui ponia izquierdo dende ahora pone derecho).

Despues pasamos a programar lo que pasa cuando se presiona el boton izquierdo (la seleccion). Usamos el metodo habitual con un indicador para que solo se ejecute una vez por pulsacion de la tecla.

1
2
3
4
5
6
// En caso de presionar el boton izquierdo del raton 
// comprobaremos si el raton esta sobre algun objeto.
// Usaremos el metodo habitual con un indicador auxiliar
// para que solo se haga una vez por pulsacion.
if(LevantaTeclaRI && Raton.izquierdo)
{

A partir de aqui, y hasta nuevo aviso, todo estara dentro de este if.

Primero reservamos sitio para nuestro buffer de seleccion y para guardar el viewport, tal y como dijimos al principio.

1
2
3
4
5
6
7
8
9
10
11
// Reservamos la suficiente memoria para almacenar
// los datos que nos retornara el sistema de seleccion
// de OpenGL. Retornara 4 unsigned int por objeto
// seleccionado. En nuestro codigo hemos elegido un
// numero maximo de objetos (MAX_SEL) que multiplicamos
// por los 4 int de cada objeto seleccionado.
GLuint BufferSeleccion[4*MAX_SEL] = {0};
// Un array de 4 int's para guardar las dimensiones
// de nuestro viewport para luego usarlo de
// parametro.
GLint viewport[4] = {0};

Luego decimos a OpenGL cual va a ser el buffer de seleccion y su tamaño con la funcion glSelectBuffer(...), con el tamaño del buffer como primer parametro. Lo calculamos en base al numero maximo de objetos que pensamos que necesitamos seleccionar y el tamaño que almacenara por objeto, tal y como vimos al principio, y sabiendo que usaremos un nombre por objeto. El segundo parametro es la direccion del buffer.

1
2
3
4
// Decimos a OpenGL que use el buffer que hemos
// definido y su tamaño. Aqui dejara OpenGL los
// objetos seleccionados.
glSelectBuffer(4*MAX_SEL, BufferSeleccion);

Recuperamos luego el viewport con la funcion adecuada de OpenGL (esto tambien es nuevo).

1
2
3
// Cargamos en el array que hemos definido el 
// viewport con la funcion de OpenGL para ello.
glGetIntegerv(GL_VIEWPORT, viewport);

Despues nos disponemos a preparar la matriz de proyeccion para acotar el area de pantalla en el cual consideramos que si un objeto se pinta, esta seleccionado. En el caso de un click de raton sera una zona muy pequeña de pantalla alrededor del puntero del raton. Se podria implementar que dejando el boton pulsado marcaramos un cuadrado dentro del cual todo estaria seleccionado (eso lo dejo a la habilidad y tiempo libre de quien quiera hacerlo).

1
2
3
4
5
6
// Ponemos matriz proyeccion.
glMatrixMode(GL_PROJECTION);
// Guardamos en la pila la matriz proyeccion.
glPushMatrix();
// Cargamos la matriz identidad.
glLoadIdentity();

Ahora es cuando marcamos los limites del cuadrado de seleccion. en nuestro caso y para un solo click sera un cuadradode 2x2 pixels con centro en las coordenadas del raton. Remarco la palabra centro para quien quiera implementar seleccion en un cuadrado mas grande.
Para esto usaremos la funcion de la libreria glu gluPickMatrix(...) cuyos parametros son por orden estos.

  • Coordenada X del centro del cuadrado (en nuestro caso del raton).
  • Coordenada Y del centro del cuadrado (empezando abajo, por eso se resta del tercer parametro del viewport -como rect.bottom-).
  • Ancho del cuadrado en pixels.
  • Alto del cuadrado en pixels.
  • Direccion de un array con los datos del viewport.

1
2
3
4
5
6
7
8
9
10
11
// Usamos la funcion de la libreria glu para
// crear una matriz especial para seleccion.
// Le indicamos las coordenadas del raton (la Y
// la cambiamos para que comienzen abajo) y el tamaño
// de una ventana, con centro en las coordenadas
// anteriores, de 2 x 2 pixels(solo la punta del raton)
// dentro de las cuales, si en modo seleccion pinta
// algo, guardara su identificativo (glPushName o
// glLoadName) en el array de seleccion como objeto
// seleccionado.
gluPickMatrix(Raton.x, viewport[3]-Raton.y, 2, 2, viewport);

Tras crear la matriz proyeccion con gluPickMatrix para restringir la zona de seleccion, multiplicamos la matriz proyeccion por la que tenemos en ese momento en el programa.
No nos asustemos con lo de multiplicar matrices, tan solo usaremos gluPerspective o cualquier otro metodo que usemos normalmante para establecer la proyeccion y gluLookAt o, glTranslate y glRotate para colocar la camara. el caso es que la proyeccion y la situacion de la camara sea la misma que en este frame del programa. Si no fuera asi el pintado de los objetos de forma normal y en modo selecion no seria el mismo y no funcionaria la selecion.

1
2
3
4
5
6
7
8
// Pongo la perspectiva actual...
gluPerspective(50.0f, (float)rect.right/(float)rect.bottom, 0.1f, 50.0f);
// ... y coloco la camara en el mismo sitio donde esta.
// Mismos giros que antes.
glRotatef(ang_camaraX,0,1,0);
glRotatef(ang_camaraY,1,0,0);
// Misma traslacion de antes.
glTranslatef(0,0,0-dist);

Deshabilito texturas e iluminacion, que ahora no hacen falta, regreso a la matriz de modelo y la guardo en la pila para luego recuperarla.

1
2
3
4
5
6
7
8
// No necesito luz ni texturas
// para seleccionar.
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
// Pongo matriz de modelo.
glMatrixMode(GL_MODELVIEW);
// Guardo la matriz de modelo.
glPushMatrix();

Ahora entro en modo seleccion, modo en que OpenGL no pinta pero va rellenando con los datos de los objetos seleccionados el buffer de seleccion.

1
2
3
4
5
6
// Pongo a OpenGL en modo seleccion.
// En este modo OpenGL no pinta pero
// lo que pintaria en el cuadrado definido
// por gluPickMatrix sera incluido en el
// buffer de seleccion como objeto seleccionado.
glRenderMode(GL_SELECT);

Inicio la pila de nombres y empujo en ella un primer valor que ire cambiando por el identificativo de los objetos.

1
2
3
4
5
6
// Inicializa, limpia, la pila de nombres
// de seleccion.
glInitNames();
// Guarda un primer numero en la pila de
// nombres.
glPushName(0);

Despues voy pintando los objetos, pero antes de pintar cada uno dejo en la pila (cambio el valor que meti de principio) el identificativo del objeto a pintar. Con este identificativo podre luego saber que objetos estan seleccionados al ver lo que hay en el buffer de seleccion.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Cambia el 0 que metimos antes
// en la pila por un 1 (como hacer
// glPopName y glPushName(1) ).
// El 1 sera el identificativo (nombre)
// de todo o que pinto despues si es
// seleccionado.
glLoadName(1);
// Pito ahora el cubo con nombre 1.
glCallList(Cubo);
// Muevo el siguiente cubo.
glTranslatef(0,0,-2.0f);
// Cambio el nombre del objeto,
// ahora sera 2.
glLoadName(2);
// Pinto el cubo que tendra el nombre 2.
glCallList(Cubo);
// Muevo el siguiente cubo.
glTranslatef(2,0,2.0f);
// Cambio el nombre del objeto,
// ahora sera 3.
glLoadName(3);
// Pinto el cubo que tendra el nombre 3.
glCallList(Cubo);
// Muevo el siguiente cubo.
glTranslatef(2,0,-4.0f);
// Cambio el nombre del objeto,
// ahora sera 4.
glLoadName(4);
// Pinto el cubo que tendra el nombre 4.
glCallList(Cubo);
// Cargo matriz identidad para pintar
// donde esta la esfera.
glLoadIdentity();
// La pongo donde esta.
glTranslatef(-2.0,0,-4.0f);
// Cambio el nombre del objeto,
// ahora sera 5.
glLoadName(5);
// Pinto la esfera, que sera el objeto
// con nombre 5
auxSolidSphere(1);

Terminado el pintado de objetos seleccionables en modo seleccion, dejo vacia la pila de nombres, restablezco la matriz modelo anterior y lo mismo con la matriz proyeccion anterior.
Dejo como siempre, la de modelo como la de trabajo.

1
2
3
4
5
6
7
8
9
10
11
12
13
// Dejo vacia la pila de nombres 
// al terminar.
glPopName();
// Habilito iluminacion.
glEnable(GL_LIGHTING);
// Restablezco la matriz modelo.
glPopMatrix();
// Selecciono la matriz proyeccion
glMatrixMode(GL_PROJECTION);
// La restablezco.
glPopMatrix();
// Dejo la de matriz modelo.
glMatrixMode(GL_MODELVIEW);

Ahora salgo del modo seleccion y dejo el modo normal, en el que se pintan las cosas.
Al terminar el modo seleccion la funcion retorna los objetos que han sido seleccionados mientras estaba el modo selecion puesto. Si retorna "-1" es que nos habiamos quedado cortos al dar tamaño al buffer de selecion.

1
2
3
4
5
6
7
8
9
10
// Ahora salgo del modo seleccion y 
// vuelvo al modo normal (render).
int NumSel = glRenderMode(GL_RENDER);
 
// Si el numero de objetos seleccionados supera
// el que permite nuestro buffer de seleccion,
// OpenGL retornara -1.
// Si es asi hago que el numero de objetos
// seleccionados sea el maximo.
if(NumSel==-1) NumSel=MAX_SEL;

Por ultimo, para saber quien esta seleccionado, lo miro en el buffer de seleccion, si es que hay alguno seleccionado. Si no hay ninguno pongo 0 en la variable "ObjetoSel".
Si hay alguno recorro todos los objetos seleccionados (1 o mas) y me quedo con el que esta mas cerca. Recordad que cada objeto seleccionado son 4 GLuint's. A nosotros nos interesa el segundo (indice 1 porque el primero es 0), la profundidad minima del z-buffer de OpenGL y el cuarto (indice 3), el nombre o identificativo del objeto. Al final "ObjetoSel" tendra el nombre del objeto seleccionado mas cercano.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Si ha habido algun objeto seleccionado.
if(NumSel > 0)
{
// Seleccionare el que esta mas cerca en caso
// de haber mas de 1.
// Una variable para guardar dato de profundidad.
GLuint z1;
// Guardo el nombre del primer objeto seleccionado.
ObjetoSel=BufferSeleccion[(0*4)+3];
// Guardo en z el dato de profundidad del
// primer objeto seleccionado.
GLfloat z=(float)BufferSeleccion[(0*4)+1];
// Un bucle para recorrer todos los objetos
// seleccionados e ir comparando sus profundidades.
for(GLuint i=0; i<NumSel; i++)
{
// Obtengo la profundidad del objeto en curso...
z1=BufferSeleccion[(i*4)+1];
// ... y si es menos que z ...
if(z1 < z)
{ // ... la pongo en z...
z=z1;
// ... y el nombre del objeto en la
//variable para eso.
ObjetoSel=BufferSeleccion[(i*4)+3];
}
}
}
// Si no hay ninguno seleccionado pongo 0 en la variable
// con el nombre del objeto seleccionado.
else ObjetoSel=0;
 

Tras esto terminamos el if en el que tenemos el codigo de seleccion al presionar el boton izquierdo del raton.

1
2
3
4
5
	// El resto del codigo para control de la
// tecla Raton Izquierdo
LevantaTeclaRI=false;
}
else if( !Raton.izquierdo) LevantaTeclaRI=true;

Despues, lo unico que hay que hacer es pintar distinto el objeto que ha sido seleccionado en caso de haberlo. En la variable "ObjetoSel" esta el nombre eleccionado. Si es 0 pintaremos todo normal, si no pintaremos en wireframe el objeto cuyo identificativo coincida con el de esta variable.
Al pintar cada objeto comprobare si esta o no seleccionado y lo pintare como corresponda.
Pongo aqui uno como ejemplo. La unica diferencia con otros es que si no se pintaba originalmente con textura, cuando esta seleccionado no hara falta que la deshabilite.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Si el objeto seleccionado es este (el 1)
// lo pintamos en wireframe (solo las lineas),
// sin textura y deshabilitando la iluminacion.
if(ObjetoSel==1)
{
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT, GL_LINE);
}
// Pinto el objeto, normal o en wireframe.
glCallList(Cubo);
// Si lo he pintado en lineas regreso al modo
// normal.
if(ObjetoSel==1)
{
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT, GL_FILL);
}

acordaos que cada objeto tiene su identificador (nombre). El del ejemplo es el 1, los demas seran es 2, 3, 4 y 5 en nuestro programa.

Tras relizar esto ultimo con cada objeto el programa (todos son seleccionables), ya habriamos terminado.
He aprovechado para actualizar la layenda y hacer que aparezca solo si presionamos la tecla "L" (si sigue creciendo, cuando este en pantalla, no se se vera la escena).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// De la misma manera que antes, controlo que
// solo se ejecuta una vez lo que hace la tecla L.
// Cambia el estado del indicador de si se ve o no la
// leyenda.
if(LevantaTeclaL && Teclas['L'])
{ ImprimeLeyenda=!ImprimeLeyenda; LevantaTeclaL=false; }
else if( !Teclas['L']) LevantaTeclaL=true;
 
// En base al indicador InprimeLeyenda pintara o no
// la leyenda.
if(ImprimeLeyenda)
{
// Escribo la leyenda de lo que se puede hacer en nuestro
// programa. La situo segun el tamaño de la ventana, sea
// cual sea.
Escribe(rect.right-300,rect.bottom-180,
"8: Cambiar a Pantalla completa y de resolución");
Escribe(rect.right-300,rect.bottom-160,
"U: Cambiar entre Pantalla completa y normal");
Escribe(rect.right-300,rect.bottom-140,
"P: Ver resoluciones de la tarjeta");
// Ahora para mover el con el boton derecho
// del raton
Escribe(rect.right-300,rect.bottom-120,
"Click derecho presionado para mover");
Escribe(rect.right-300,rect.bottom-100,
"con el raton (rueda para distancia)");
Escribe(rect.right-300,rect.bottom-80,
"F - Ver FPS");
Escribe(rect.right-300,rect.bottom-60,
"A Z - Modificar FPS");
Escribe(rect.right-300,rect.bottom-40,
"Q W - Rotar cubos");
Escribe(rect.right-300,rect.bottom-20,
"Arriba Abajo - Acercar y alejar");
}
// Si no pinta la Leyenda escribe como hacer que aparezca.
else
Escribe(rect.right-100,rect.bottom-20,"L: Leyenda");

Damos asi por terminado el primer metodo de seleccion, el propio de OpenGL.
El resultado en pantalla sera asi.



El codigo completo seria: usw14a.cpp




¡Sólo los usuarios registrados pueden escribir comentarios!
+/- Comentarios
Buscar
janezo   |79.108.43.xxx |28-07-2012 10:18:22
Quillo, lo mejor de lo mejor.

Yo tambien tengo mujer e hijos y no se de donde
coño sacas el tiempo o cuantos platos tienes que fregar a cambio, :)

De verdad
muchas gracias por el esfuerzo porque los tutoriales son faciles de seguir y muy
instructivos.

Un saludo.
Vicengetorix   |87.221.224.xxx |08-08-2012 00:13:33
Gracias por el comentario.
Platos he fregado millones pero cada vez tengo menos
tiempo.
Espero que, por lo menos lo que va hasta ahora, sea útil y os sirva.
UnKnow   |186.68.128.xxx |09-07-2011 03:01:17
Hmmm... Yo uso el dev-c++, y tira muchos errores, los estába eliminando de a
poco, pero me trabé, y me quedé con 13 errores. :'(
ezequielher  - felicitaciones     |190.179.156.xxx |25-01-2010 22:05:43
hola, que tal? lo felicito por sus tutoriales, yo me topé de casualidad con
esta web, y creo que resulta muy útil en mi caso, ya que requiero de código
para armar mi proy en opengl para la facultad, veo el gran esfuerzo q hace p/
que los internautas tengamos conocimiento de opengl, y como he estado viendo la
información en este ámbito no abunda en castellano. Gracias por todo!
RICARDO  - SIGUE ASI     |200.24.193.xxx |22-12-2010 01:31:41
Hola,
Yo solo se vb6 asi que me cuesta un poco pasar el código a este, lo hago
porque no hay manuales que enseñen a programar en visual basic, la página de
Paul Dahuach tiene bastantes ejemplos para vb6 pero le entiendo muy poco, en
cambio esta página me ha sido util, despues me internaré a C++. Muchas
gracias.
Vicengetorix   |194.179.126.xxx |22-12-2010 16:24:17
Gracias a vosotros por dar vuestra opinión y aportar vuestras impresiones.
Zaidan  - Gracias por no abandonar.   |62.57.251.xxx |27-07-2009 17:01:15
Acabo de encontrarme con tus tutoriales y tengo que estarte agradecido por
seguir adelante ya que muchos autores de tutoriales lo acaban abandonando(sera
gracias a tu cabezoneria como dices :P).
Acabo de empezar leyendo los primeros
articulos y he dedecir que para mi entender el open gl es algo titanico puesto
que sol ohe visto un poco de visula basic y actionscript, asi que intentare ir
paso a paso lentamente hasta que pueda entenderlo bien.

Muchas gracias de
nuevo por tu aporte.
Un saludo. :D
Pedro  - Pues al final abandonó como todos   |83.43.184.xxx |23-12-2009 17:15:36
Parece que al final el autor ha acabado haciendo lo que hace la mayoría,
abandonar el barco. Cuando la cosa se complica es hora de desertar y es ahí
cuando nos damos cuenta de que todo había sido un capricho más como comprarse
una moto.
Vicengetorix   |85.53.218.xxx |23-12-2009 19:04:02
El autor es aficionado y lo hace por amor al arte, tiene trabajo, mujer e hijos
pequeños.
Si cuando te dan algo gratis, tu te quejas de que quieres más o
criticas lo que te dan, solo conseguirás que nunca más te den algo gratis.

El
autor (yo) continuará cuando tenga tiempo, a ratos perdidos.
De momento el
autor usa esos ratos libres para mejorar la librería de UnSitioWeb y añadirle
un entorno gráfico de usuario para OpenGL (menús, botones, checkboxes,...)y
cuando sea un producto digno de ser compartido lo colgará en la página.
No hay
continuos artículos en esta página porque no me paga nadie por escribir
reseñas y no me interesa escribir por escribir. Solo escribo aquí cuando hay
algo que me parece interesante. Con eso intento conseguir que la página tenga
contenido utíl, que sea el contenido lo que la haga una buena página (si es
que algún día lo consigo).

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 


Banner
Spanish Chinese (Simplified) English French German Japanese Portuguese Russian