Here’s the code I use to project the camera frusta from a set of unmanned arial vehicles. It’s pretty much the same as Dorbie’s example code. I ganked it from one of my Performer apps, so it’s a bit more complicated than an example should be but the main things you need to look at are the stencil commands…
edit: When you “fill the stenciled areas” like that the bottom of this example, it makes more sense to just redraw the geometry that you used to create your stencil mask. In this example I draw a big rectange over the whole screen, which is overkill.
// Project outline of viewing frusta onto terrain
void frustaProjectCallback(pfChannel* chan, void* data){
static int matrixmode;
static float horfov, hortan, vertan;
static float length = 1000000.0f;
// setup state variables
pfPushState();
glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
glMatrixMode(GL_MODELVIEW);
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_STENCIL_TEST);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
// draw into stencil buffer
for(int i=0; i<NUM_UAVS; i++){
glPushMatrix();
glTranslatef(ldata->uavs[i]->xyz[0], ldata->uavs[i]->xyz[1], ldata->uavs[i]->xyz[2]);
glRotatef(ldata->uavs[i]->hpr[0], 0.0f, 0.0f, 1.0f);
glRotatef(ldata->uavs[i]->hpr[1], 1.0f, 0.0f, 0.0f);
glRotatef(ldata->uavs[i]->hpr[2], 0.0f, 1.0f, 0.0f);
glRotatef(ldata->uavs[i]->camera_hpf[0], 0.0f, 0.0f, 1.0f);
glRotatef(ldata->uavs[i]->camera_hpf[1], 1.0f, 0.0f, 0.0f);
// calculate half FOVs and their tangents
horfov = ldata->uavs[i]->camera_hpf[2] * 0.5f;
hortan = tanf(horfov * 0.0174532925f);
vertan = hortan * 0.75f;
//verfov = atanf(vertan) * 57.2957795132f;
// draw outside of frustum in stencil buffer
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glBegin(GL_TRIANGLES);
glVertex3d(0, 0, 0);
glVertex3d(hortan * length, length, vertan * length);
glVertex3d(-hortan * length, length, vertan * length);
glVertex3d(0, 0, 0);
glVertex3d(hortan * length, length, -vertan * length);
glVertex3d(hortan * length, length, vertan * length);
glVertex3d(0, 0, 0);
glVertex3d(-hortan * length, length, -vertan * length);
glVertex3d(hortan * length, length, -vertan * length);
glVertex3d(0, 0, 0);
glVertex3d(-hortan * length, length, vertan * length);
glVertex3d(-hortan * length, length, -vertan * length);
glEnd();
// draw inside of frustum in stencil buffer
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glBegin(GL_TRIANGLES);
glVertex3d(0, 0, 0);
glVertex3d(-hortan * length, length, vertan * length);
glVertex3d(hortan * length, length, vertan * length);
glVertex3d(0, 0, 0);
glVertex3d(hortan * length, length, vertan * length);
glVertex3d(hortan * length, length, -vertan * length);
glVertex3d(0, 0, 0);
glVertex3d(hortan * length, length, -vertan * length);
glVertex3d(-hortan * length, length, -vertan * length);
glVertex3d(0, 0, 0);
glVertex3d(-hortan * length, length, -vertan * length);
glVertex3d(-hortan * length, length, vertan * length);
glEnd();
glPopMatrix();
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
pfTransparency(PFTR_BLEND_ALPHA);
// fill the stenciled areas
glStencilFunc(GL_NOTEQUAL, 0x0, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDisable(GL_DEPTH_TEST);
glColor4f(1.0f, 1.0f, 0.0f, 0.2f);
glPushMatrix();
glLoadIdentity();
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(-ldata->aspectRatio * ldata->viewRadius, -ldata->viewRadius, -10.0f);
glVertex3f(ldata->aspectRatio * ldata->viewRadius, -ldata->viewRadius, -10.0f);
glVertex3f(-ldata->aspectRatio * ldata->viewRadius, ldata->viewRadius, -10.0f);
glVertex3f(ldata->aspectRatio * ldata->viewRadius, ldata->viewRadius, -10.0f);
glEnd();
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_STENCIL_TEST);
// restore state
glMatrixMode(matrixmode);
pfPopState();
}
[This message has been edited by mogumbo (edited 01-02-2004).]