Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Problema, opengl, Glut y Rubberband

Estas en el tema de Problema, opengl, Glut y Rubberband en el foro de C/C++ en Foros del Web. Estimados: Para un ramo de la universidad me pidieron aplicar algunas cosillas de Opengl, dentro de lo que aparecia Rubberband. La tarea consiste en que ...
  #1 (permalink)  
Antiguo 23/10/2008, 05:30
Avatar de v4mp1r0  
Fecha de Ingreso: febrero-2008
Mensajes: 36
Antigüedad: 16 años, 9 meses
Puntos: 0
Problema, opengl, Glut y Rubberband

Estimados:

Para un ramo de la universidad me pidieron aplicar algunas cosillas de Opengl, dentro de lo que aparecia Rubberband.

La tarea consiste en que cuando se pase el mouse por una ventana que el programa creara y se de click sobre ella, exista la posibilidad de dibujar un rectangulo.

Llevo gran parte de ella echa pero no encuentro el error, de por que no genera los rectangulitos malditos, y ya mi neurona se estreso. Les dejo el codigo y espero vuestros comentarios.

Salu2!

Código:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

int h=449, w=645, size, valor;  /*Medidas de la ventana*/
int moving=0;

void init()
{
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glEnable(GL_COLOR_LOGIC_OP);
  glLogicOp(GL_COPY);
}

/*Funcion Callback:
          Dibujara un cuadrado cuando el mouse de click*/

void drawSquare(int x, int y)
{
  y=h-y;

  glColor3f(1.0,0.0,1.0);

  if(moving)
  {
    size=(h-valor-y)/2;

    glBegin(GL_POLYGON);
      glVertex2i(x+size, y+size);
      glVertex2i(x-size, y+size);
      glVertex2i(x-size, y-size);
      glVertex2i(x+size, y-size);
    glEnd();
    glLogicOp(GL_XOR);
    glColor3f(1.0,1.0,1.0);
    glFlush();
  }
}

/*Funcion Callback:
       Genera la ventana donde se haran los dibujos*/

void generaWin()
{
  glClear(GL_COLOR_BUFFER_BIT);         /*Limpia la pantalla*/
  
  glBegin(GL_POLYGON);  /*Dibuja un poligono, triangulo especificamente.*/
    glColor3f(1.0,0.0,0.0);
    glVertex2f(0.2,0.2);   
    glColor3f(0.0,1.0,0.0);
    glVertex2f(0.8,0.2);   
    glColor3f(0.0,0.0,1.0);
    glVertex2f(0.48,0.9);  
    glColor3f(1.0,1.0,1.0);
  glEnd();
  glLogicOp(GL_XOR);
  glFlush();
}
 
 
/*Funcion Callback:
      Permite reescalar la figura si se reescala la ventana */
      
void reshape(int w, int h)
{
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D (0.0,  1.0, 0.0,  1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}
 
/*Funcion Callback:
          Uso del mouse sobre ventana*/

void mouse(int btn, int state, int x, int y)
{
  if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
  {
    if(moving==0)
      valor=y;   
    moving = 1;  
    drawSquare(x,y);
  }
   
  if(btn == GLUT_LEFT_BUTTON && state == GLUT_UP)
    moving=0;
}
 
/*Funcion Callback:
      Permite usar el teclado en el programa*/
void keyboard(unsigned char key, int x, int y)
{
  if(key==27)
    exit(0); 
}
 
int main(int argc, char **argv)
{
 
  glutInit(&argc, argv);        /*Negocia con el gestor de ventanas*/
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);  /*Modo de dibujo de la ventana*
  glutInitWindowSize(645,449);          /*Taman~o de la ventana*/
  glutInitWindowPosition(0,0);          /*Posicion de la ventana en la pantalla
  glutCreateWindow("Dibujando");        /*Nombre de la ventana*/
  
  glutDisplayFunc(generaWin);   /*Callback de Dysplay*/
  glutReshapeFunc(reshape);     /*Funcion para el re-size de una ventana, manti
  glutMouseFunc(mouse);         /*Funcion del Mouse*/
  glutKeyboardFunc(keyboard);   /*Funcion para el teclado*/
  glutPassiveMotionFunc(drawSquare);
  init();       /*Funcion que me inicializa parametros de la ventana*/
  glutMainLoop();       /*Loop de eventos de aplicacion   */
  
  return 0;
}
p.d: Sry me quedo un poco largo :P
  #2 (permalink)  
Antiguo 23/10/2008, 05:56
venkman
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Problema, opengl, Glut y Rubberband

No sé si acabo de entender del todo qué es lo que estás intentando hacer con alguna de las variables que utilizas. Pero he visto algunas cosas... extrañas.

Te las digo con algo de duda; si no es así, explícamelo :)

1. Hay un problema al calcular el tamaño.

Por lo que entiendo que haces, básicamente cuando aprieta el botón (p.ej. en x=100, y=50)...
-> Se ejecuta mouse que:
--> pone valor = y es decir, valor = 50
--> llama a drawSquare(x,y) que:
-----> y = h - y es decir y = 399
-----> size = (h - valor - y) / 2 = (449 - 50 - 399) / 2 = 0

(visto de otro modo size = (h - valor - y) / 2 = (h - y - (h - y)) / 2 = 0 sea donde sea que pinchemos)

Es decir, que cuando se aprieta el botón en cualquier sitio size siemrpe termina siendo 0. Con lo que intentas siempre pintar un rectángulo de tamaño 0.


2. Me confunde un poco que hagas: glutPassiveMotionFunc(drawSquare);
¿Para qué haces esto? Lo pregunto porque glutPassiveMotionFunc va a hacer que se llame a drawSquare siempre que el ratón pasa por encima sin ningún botón pulsado. Pero en ese caso, moving va a ser 0 y entonces drawSquare no hace nada.

Así que no entiendo muy bien por qué haces eso.
  #3 (permalink)  
Antiguo 23/10/2008, 06:38
Avatar de v4mp1r0  
Fecha de Ingreso: febrero-2008
Mensajes: 36
Antigüedad: 16 años, 9 meses
Puntos: 0
Respuesta: Problema, opengl, Glut y Rubberband

mmm... ok creo que estaba haciendo algunas estupideces producto de la falta de sueño :P... 12 hrs. programando afecta seriamente el cerebro. Corrigo y aviso

Gracias
  #4 (permalink)  
Antiguo 23/10/2008, 08:07
Avatar de v4mp1r0  
Fecha de Ingreso: febrero-2008
Mensajes: 36
Antigüedad: 16 años, 9 meses
Puntos: 0
Respuesta: Problema, opengl, Glut y Rubberband

ya ok... hice algunas correcciones... pero aun no logro entender como hacer lo que necesito...
Necesito que cuando de un click sobre la pantalla y hasta que termine de arrastrar el mouse (sin presionar) se me dibuje un rectangulo y termine de dibujarse cuando de el segundo click, indicando el fin. En la practica es como la herramienta de rectangulos del paint que termina de hacerlo cuando vuelves a dar click en algun lugar.

Si alguien me puede ayudar con esto seria genial.
  #5 (permalink)  
Antiguo 23/10/2008, 09:24
venkman
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Problema, opengl, Glut y Rubberband

Tienes 2 formas de hacerlo, según quieras que se maneje.

1. Si lo que quieres es que haya que hacer: aprieto el botón, arrastro, suelto el botón.

2. Si lo que quieres que haya que hacer es: aprieto y suelto el botón, muevo el ratón, aprieto y suelto el botón.


Lo que tú dices parece lo segundo, pero lo que hace el Paint es lo primero. Aprietas, arrastras y cuando sueltas se hace el rectángulo. Así que me voy a centrar en ese caso.


Una cosa que debes hacer en cualquier caso es guardar el primer punto. Ya luego, cuando se mueva el ratón, tienes que recordar desde dónde se hacía el rectángulo.

Entonces, el procedimiento podría ser algo así:

0. En lugar de moving, usaré pulsado, que me parece mejor nombre. Además, harán falta otras dos variables (x0, y0) que serán dodne guarde el primer punto.

1. mouse (parte 1):
Código:
si (GLUT_DOWN) entonces {
    pulsado = 1; // El botón está pulsado
    x0 = x; // Guardamos el punto donde se pulsó el botón
    y0 = y;
}
2. En lugar de glutPassiveMotionFunc a lo que hay que llamar es a glutMotionFunc y la función de callback que le pasamos la llamaremos mousedrag, que me gusta más el nombre.
En esa función básicamente llamamos a drawSquare(x0,y0,x,y). Es decir, con los dos puntos, el inicial y el actual.
Código:
void mousedrag(int x, int y) {
    drawSquare(x0,y0,x,y);
}
3. En drawSquare en lugar de tener que calcular el tamaño y luego hacer los vértices con el tamaño calculado, lo que hacemos es más simple, tenemos todos los vértices.

Código:
    //...
    glVertex2i(x0, y0);
    glVertex2i(x0, y);
    glVertex2i(x, y0);
    glVertex2i(x, y);
    //...
Aunque si no recuerdo mal, las Y van invertidas, no? Vamos que igual lo que tienes que hacer es más bien (x0,(h-y0)), (x0,(h-y)), etc

4. mouse (parte 2)
Cuando sea GLUT_UP entonces ponemos pulsado = 0




Hasta aquí sería un sistema muy básico. Si lo pruebas, verás que tiene un problema, no borra los rectángulos que se pintan al arrastrar. Es decir, se pintan un montón de rectángulos según arrastras el ratón.


¿Qué hay que hacer para solucionar esto? Hay varias soluciones, claro. Lo más chapuza sería ir recordando también el punto anterior y borrando el rectángulo anterior antes de pintar el nuevo. Ve probando a hacer eso y luego piensa mejores soluciones (como utilizar un buffer de objetos y tener algunos fijos y otros temporales...).
  #6 (permalink)  
Antiguo 23/10/2008, 17:07
Avatar de v4mp1r0  
Fecha de Ingreso: febrero-2008
Mensajes: 36
Antigüedad: 16 años, 9 meses
Puntos: 0
Respuesta: Problema, opengl, Glut y Rubberband

ok... dadas diversas correcciones y preguntas al profe al respecto publico el codigo por si a alguien mas le puede servir.

salu2! Gracias por sus respuestas

Código:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

int h=449, w=645;
float xf, yf,xm,ym;     /*Guarda las sucesivas posiciones del mouse*/
int moving=0;
float sizex, sizey, antx=0, anty=0;

void init()
{
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glEnable(GL_COLOR_LOGIC_OP);
  glLogicOp(GL_COPY);
}

/*Funcion Callback:
          Dibujara un cuadrado cuando el mouse de click*/

void drawSquare(int x, int y)
{
  y=h-y;
  sizey=((float)(h-yf-y)/h);
  sizex=((float)(x-xf)/w);
  glColor3f(1.0,0.0,1.0);

  glLogicOp(GL_XOR);
  if(moving)
  {
    glColor3f(1.0,1.0,1.0);

    glBegin(GL_POLYGON);
      glVertex2f(xm+antx,ym-anty);
      glVertex2f(xm,ym-anty);
      glVertex2f(xm,ym);
      glVertex2f(xm+antx,ym);
    glEnd();
    glFlush();

    glBegin(GL_POLYGON);
      glVertex2f(xm+sizex,ym-sizey);
      glVertex2f(xm,ym-sizey);
      glVertex2f(xm,ym);
      glVertex2f(xm+sizex,ym);
    glEnd();
    glFlush();
    antx=sizex;
    anty=sizey;
  }  
}    
     
/*Funcion Callback:
       Genera la ventana donde se haran los dibujos*/
void generaWin()
{
  glClear(GL_COLOR_BUFFER_BIT);         /*Limpia la pantalla*/
  
  glBegin(GL_POLYGON);  /*Dibuja un poligono, triangulo especificamente.*/
    glColor3f(1.0,0.0,0.0);
    glVertex2f(0.2,0.2);   
    glColor3f(0.0,1.0,0.0);
    glVertex2f(0.8,0.2);   
    glColor3f(0.0,0.0,1.0);
    glVertex2f(0.48,0.9);  
  glEnd();
  glFlush();
}
  
/*Funcion Callback:
      Permite reescalar la figura si se reescala la ventana */
      
void reshape(int w, int h)
{
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D (0.0,  1.0, 0.0,  1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}
 
/*Funcion Callback:
          Uso del mouse sobre ventana*/

void mouse(int btn, int state, int x, int y)
{
  if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
  {
    if(moving == 0)
    {
      xf=x;
      yf=y;
      moving=1;
      xm=((float)x/w);
      ym=((float)(h-y)/h);
    }
    drawSquare(x,y);
  }
   
  if(btn == GLUT_LEFT_BUTTON && state == GLUT_UP)
  {
    moving = 0;
    antx = 0;  
    anty = 0;  
  }
}  
/*Funcion Callback:
      Permite usar el teclado en el programa*/
void keyboard(unsigned char key, int x, int y)
{
  if(key==27)
    exit(0); 
}
 
int main(int argc, char **argv)
{
 
  glutInit(&argc, argv);        /*Negocia con el gestor de ventanas*/
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);  /*Modo de dibujo de la ventana*
  glutInitWindowSize(645,449);          /*Taman~o de la ventana*/
  glutInitWindowPosition(0,0);          /*Posicion de la ventana en la pantalla
  glutCreateWindow("Dibujando");        /*Nombre de la ventana*/
  
  glutDisplayFunc(generaWin);   /*Callback de Dysplay*/
  glutReshapeFunc(reshape);     /*Funcion para el re-size de una ventana, manti
  glutMouseFunc(mouse);         /*Funcion del Mouse*/
  glutMotionFunc(drawSquare);
  glutPassiveMotionFunc(drawSquare);
  glutKeyboardFunc(keyboard);   /*Funcion para el teclado*/
  init();       /*Funcion que me inicializa parametros de la ventana*/
  glutMainLoop();       /*Loop de eventos de aplicacion   */
 
 return 0;
}
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 13:56.