PDA

View Full Version : moving a rectangle in a terrain



mithun_daa
12-31-2003, 10:17 AM
alright, id like to say thank u to all those who helped me get my gluunproject working. now, i get my points right. what approach would u ppl suggest for my next step ( no extenstions plz)
i want a small rectangle to move on my terrain as i move my cursor on the window. i also want to have an effect which would look like as though the rectangle has been drapped onto the terrain. if the terrain is flat, i want it to appear like a regular rectangle, if there are some elevations then the rectangle should look as though its going over the terrain. i hope i made myself clear, cause this is very difficult to explain.
the only alternative i c is to read in the elevation values along the contuors of the rectange, make a texture out of it and map it. but this, i think would take a lot of time and slow down the whole app, cause every mouse movement i'll need to get the values and draw a new texture.
is it possible to generate shadows or some special lighting effect that would highlight a particular area as i move the mouse?
thank u

[This message has been edited by mithun_daa (edited 12-31-2003).]

mogumbo
12-31-2003, 11:01 AM
You can play a stencil buffer trick where you draw a box that intersects your terrain. Front faces increment the stencil buffer and back faces decrement it, and you end up with an area in your stencil buffer that looks like a rectangle that has been draped over the terrain. Then you can draw whatever you want into that area.

Dorbie had a good example of this technique on the web, but I don't know where it is now. Dorbie?

I might be able to send you some sample code if Dorbie's example doesn't exist anymore.

mithun_daa
12-31-2003, 11:13 AM
Originally posted by mogumbo:
You can play a stencil buffer trick where you draw a box that intersects your terrain. Front faces increment the stencil buffer and back faces decrement it, and you end up with an area in your stencil buffer that looks like a rectangle that has been draped over the terrain. Then you can draw whatever you want into that area.

Dorbie had a good example of this technique on the web, but I don't know where it is now. Dorbie?

I might be able to send you some sample code if Dorbie's example doesn't exist anymore.

i would really appreciate if u send me some sample or the link to dorbiez site.
thank u

Overmind
12-31-2003, 11:56 AM
I would render the terrain twice (not necessarily the whole terrain, just the part where the rectangle should be) and put a texture on it with texture coordinates being basically the x,z coordinates of the vertex, translated by the position where you want your rectangle to be and scaled to the correct size. Another possibility would be projective texturing, that depends on how exactly you want the rectangle to be wrapped onto the terrain.

The texture image should contain whatever you want to display on top of the terrain with alpha=0 on the parts where you don't want to be anything. Draw this second pass with texture clamping, blending or alpha test, depth write disabled and depth function GL_EQUAL.

mithun_daa
01-01-2004, 08:26 PM
dorbie, plz. need the link to ur site showin how to use the stencil buffer.

mogumbo
01-02-2004, 12:01 PM
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).]