gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > gluPickMatrix

#150493 - iprice - Tue Feb 05, 2008 9:00 pm

When I use gluPickMatrix it makes the screen flicker.... I am rendering some MD2 files, then drawing the screen under the cursor and using gluPickMatrix as in the example on ndslibs.... but the quick draw to screen is messy, can I draw off screen for the touch recognition?

#150521 - Cydrak - Wed Feb 06, 2008 2:38 am

From nds/Graphics/3D/Misc/Picking/:
Quote:
glViewport(...);
... matrix setup ...
... draw scene ...

// set the viewport to just off-screen,
// this hides all rendering that will be done during picking
glViewport(0,192,0,192);

// setup the projection matrix for picking
// -- render only what is below the cursor
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPickMatrix((touchXY.px),(191-touchXY.py),4,4,viewport);
gluPerspective(... original settings ...);
glMatrixMode(GL_MODELVIEW);

... draw pickable objs ...
... watch poly count/pos test etc ...

glFlush(0);

Is that the one you mean? I think it's exactly what they do. Picking as normal, but their viewport is crammed into a single pixel above the first scanline, so it's never drawn.

Note that they do the picking in the same frame as the drawing; glViewport is a command just like the projections, not a global register. So an extra glFlush() is not required.

(I wish I could say I'd have thought of that picking method, it's really rather clever...)

#150549 - iprice - Wed Feb 06, 2008 6:31 pm

Yeah I've got that bit, but I draw some MD2 files, and some manual polys...when I am checking for the touch on the MD2s it displays the zoomed in area for polys over the top, sretched over the whole screen for just a flash.....

#150557 - ritz - Wed Feb 06, 2008 11:26 pm

I had the same issue. You need to hide everything as much as possible. Here's the code that I call (if I'm in pick mode) right after I draw everything and just before I call glFlush(1).

However, all you really need to do is use BIT(14) | POLY_ALPHA(1) to keep things almost completely hidden and don't use that viewport call (it adds to the flicker). The other stuff I have is kinda just fluff and other things.

Code:

object_t*
v_picknose (int ntpkos, object_t **tpkos, int *pxy)
{
   model_t *psom;
   object_t *pso, *cwo;
   int vport[4] = {0,0,255,191};
   int i, cw, plyram;

   cw  = 0x7FFFFFFF;
   cwo = NULL;

   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();
   gluPickMatrix(pxy[0], 191-pxy[1], V_PICKBIAS, V_PICKBIAS, vport);
   gluPerspectivef32(V_PFOV, V_PASPECT, V_PZNEAR, V_PZFAR);
   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();

   GFX_POLY_FORMAT = POLY_CULL_BACK | BIT(12) | BIT(13) | BIT(14) | V_POLY_ALPHA(1) | POLY_FOG;
   GFX_TEX_FORMAT = 0; GFX_COLOR = 0;

   for (i = 0; i < ntpkos; i++)
   {
      MATRIX_RESTORE = 28;

      pso = tpkos[i];
      glTranslate3f32(pso->pos[0], pso->pos[1], pso->pos[2]);
      glRotateZi(pso->rot[2]); glRotateYi(pso->rot[1]); glRotateXi(pso->rot[0]);

      psom = pso->model;
      GFX_BOX_TEST = VERTEX_PACK(psom->bbox[0],psom->bbox[1]);
      GFX_BOX_TEST = VERTEX_PACK(psom->bbox[2],psom->bbox[3]);
      GFX_BOX_TEST = VERTEX_PACK(psom->bbox[4],psom->bbox[5]);

      while (GFX_TEST_BUSY) ;
      if (!GFX_BOX_RESULT)
         continue;

      while (GFX_BUSY) ; // ||GFX_TEST_BUSY
      plyram = GFX_POLYGON_RAM_USAGE;

      GFX_POS_TEST = (psom->center[0] & 0xFFFF) | (psom->center[1] << 16);
      GFX_POS_TEST = (psom->center[2] & 0xFFFF);

      v_pdrawmod(psom);
      while (GFX_BUSY) ; // ||GFX_TEST_BUSY

      if (GFX_POLYGON_RAM_USAGE > plyram && GFX_POS_RESULT[3] < cw)
         { cw = GFX_POS_RESULT[3]; cwo = pso; }
   }

   glMatrixMode(GL_PROJECTION);
   glPopMatrix(1);
   glMatrixMode(GL_MODELVIEW);
   glPopMatrix(1);

   return cwo;
}