Re: World Coords -> Screen Coords

New Message Reply Date view Thread view Subject view Author view

Nicolas Gauvin (nicolas++at++cae.ca)
Thu, 12 Sep 1996 11:36:20 -0400


Tanner Lovelace <lovelace++at++netcom.com> wrote:
> I'm trying to take a specific location in 3-D world coordinates and
> draw a 2-box on the screen surrounding this particular location.

Here are a few ways to do this in a draw callback:

// use Performer's matrices
static void
drawCB1( pfChannel* chan, void* data )
{
  chan->clear();
  pfDraw();

  // get Performer viewing matrix
  pfMatrix pfViewMat;
  chan->getViewMat(pfViewMat);

  // GL needs the inverse of the Performer viewing matrix
  pfMatrix pfInvViewMat;
  pfInvViewMat.invertOrtho(pfViewMat);

  // Apply 90deg rotation around X to convert from Performer
  // coordinate systems to GL
  pfMatrix rotMat;
  rotMat.makeRot(-90.0f,1.0f,0.0f,0.0f);
  pfInvViewMat = pfInvViewMat * rotMat;

  pfMatrix pfProjMat;
  frustum->getGLProjMat(pfProjMat);

  // compute full final transformation matrix that
  // converts from 3D world coord to 2D screen coord
  pfMatrix fullMat;
  fullMat.mult(pfInvViewMat, pfProjMat);

  // since the full transformation includes the projection we
  // must use pfVec3::fullXformPt here
  pfVec3 pos2D;
  pos2D.fullXformPt(pos3D, fullMat);

  // get channel aspect ratio
  int xs,ys;
  chan->getSize(&xs,&ys);
  float aspect = (float)xs / (float)ys;
  float xScale = 0.1f; // change it to whatever scale you want
  float yScale = xScale * aspect;

  pfPushState();
  pfBasicState();

  pfPushIdentMatrix();
  ortho2(-1.0f,1.0f,-1.0f,1.0f);
  pfTranslate(pos2D[PF_X],pos2D[PF_Y],0.0f);
  pfScale(xScale,yScale,1.0f);

  static pfVec2 vlist2[4] = { pfVec2(-0.5f, -0.5f),
                              pfVec2( 0.5f, -0.5f),
                              pfVec2( 0.5f, 0.5f),
                              pfVec2(-0.5f, 0.5f) };

// draw a square at position
#ifdef IRISGL
  // disable zbuffer test and update
  zbuffer(FALSE);
  bgnclosedline();
  cpack(0xffffffff);
  v2f(vlist2[0].vec);
  v2f(vlist2[1].vec);
  v2f(vlist2[2].vec);
  v2f(vlist2[3].vec);
  endclosedline();
  zbuffer(TRUE);
#endif

  pfPopMatrix();
  pfPopState();

}

// use IrisGL cmov and getcpos (thanks to Allan Shaffer suggestion)
static void
drawCB2( pfChannel* chan, void* data )
{
  chan->clear();
  pfDraw();

#ifdef IRISGL
  cmov(pos3D[PF_X],pos3D[PF_Y],pos3D[PF_Z]);
  getcpos(&sx, &sy);
#endif

  /* draw your 2D stuff */
}

// use IrisGL's matrices
static void
drawCB3( pfChannel* chan, void* data )
{
  chan->clear();
  pfDraw();

  pfMatrix glProjMat;
  pfMatrix glViewMat;

#ifdef IRISGL
  mmode(MPROJECTION);
  getmatrix(glProjMat.mat);
  mmode(MVIEWING);
  getmatrix(glViewMat.mat);
#endif

  // compute full final transformation matrix that
  // converts from 3D world coord to 2D screen coord
  pfMatrix fullMat;
  fullMat.mult(glViewMat, glProjMat);

  // since the full transformation includes the projection we
  // must use pfVec3::fullXformPt here
  pfVec3 pos2D;
  pos2D.fullXformPt(pos3D, fullMat);

  /* draw your 2D stuff */
}

Nicolas Gauvin CAE Electronics Ltd., 8585 Cote De Liesse
Software Developer Saint-Laurent, Quebec, Canada, H4L-4X4
3-D Graphics Applications tel: +1 514 341 2000 extension 2275
nicolas++at++cae.ca fax: +1 514 340 5496
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
            Submissions: info-performer++at++sgi.com
        Admin. requests: info-performer-request++at++sgi.com


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:53:31 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.