# OpenGL Terrain editing question (with screenshots)

## Recommended Posts

Using the opengl selection buffer, i'm currently able to determine which terrain vertex has been clicked, and paint some trees in its contiguous right-top terrain patch (see the screenshot). I'd like to have the freedom to click on any part of the terrain and being able to put an object there (therefore retrieving its coordinates) without relying on opengl selection, that needs a vertex to work. Any idea ? Thanks

##### Share on other sites
Sure. Cast a ray with the mouse pointer projected into the view frustum and do collision detection with your terrain mesh.

You can extract the frustum from the world matrices. The line cast by the mouse is just a ray starting on the near clip plane and ending on the far clip plane with the same relative coordinates on each as the relative coords of the mouse in screenspace.

-me

##### Share on other sites

Can you give me some more details please ?
First, the ray is starting from 0,0,0 ? The ray end-point coordinates can be retrieved using screen-to-world coordinates conversion (i suppose) ?

Once i have the start and end coordinates of the line, how do i test collision with the terrain ? There is a specific method for it ?

##### Share on other sites
Your start and end points are given in screen space as s=(mouse.x, mouse.y, 0) and e=(mouse.x, mouse.y, 1). Then unproject both (screen-to-world) convert them to world coodinates.

Determining the intersection point is not that trivial. You could either check each triangle or build a quadtree of bounding boxes and traverse the hierarchy until you've found the triangle (or region where testing each triangle is feasible). Then it's a ray-triangle intersection.

Another approach just comes to my mind. If your terrain is a heightmap an always aligned to the x,z-plane you could traverse the ray and for each 'grid cell' you check the corresponding quad (imagine drawing your ray into your heightmap and checking each affected pixel).

##### Share on other sites
What I do is render the entire scene, then when I click in the viewport, call glReadPixels to get the current depth value at that point. I then call gluUnproject using the x, y window coordinates and this z value, to return actual world x y z coordinates. This (x,y,z) point is now the 3D position to place the object.

          Vector3 ConvertScreenToWorld(int x, int y) {				static GLint viewport[4];		static GLdouble modelview[16];		static GLdouble projection[16];		static GLfloat winX, winY, winZ;		glGetDoublev( GL_MODELVIEW_MATRIX, modelview );		glGetDoublev( GL_PROJECTION_MATRIX, projection );		glGetIntegerv( GL_VIEWPORT, viewport );		winX = (float)x;		winY = (float)viewport[3] - (float)y;		glReadPixels(int(winX), int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );		double worldX, worldY, worldZ;		gluUnProject( winX, winY, winZ, modelview, projection, viewport, &worldX, &worldY, &worldZ);		return Vector3((float)worldX, (float)worldY, (float)worldZ);	}

Now you have to render your scene in SOLID POLYGON mode for this to work, NOT wireframe, or else all the z values will not be correctly written to the screen. What you can do is when the user clicks, re-render the scene in solid mode but only allow writing to the depth buffer by calling glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE).

##### Share on other sites
Don't involve reading values from the depthbuffer. You may run into precisional problems, you'll force a transfer from video memory to system memory, and you'll be restricted to solid rendering.
Building a simple hierarchy and using a regular ray/triangle check is a much better option.

One tutorial on picking should be here.

##### Share on other sites
Well guys, thanks for all these suggestions, i will try both methods.
About the ray-triangle intersection test, i found the following code built on Moller-Trumbore abstract, and, if anyone has used it, i have some questions:

#define EPSILON 0.000001#define CROSS(dest,v1,v2)           dest[0]=v1[1]*v2[2]-v1[2]*v2[1];           dest[1]=v1[2]*v2[0]-v1[0]*v2[2];           dest[2]=v1[0]*v2[1]-v1[1]*v2[0];#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])#define SUB(dest,v1,v2)           dest[0]=v1[0]-v2[0];           dest[1]=v1[1]-v2[1];           dest[2]=v1[2]-v2[2]; /* the original jgt code */int intersect_triangle(double orig[3], double dir[3],		       double vert0[3], double vert1[3], double vert2[3],		       double *t, double *u, double *v){   double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];   double det,inv_det;   /* find vectors for two edges sharing vert0 */   SUB(edge1, vert1, vert0);   SUB(edge2, vert2, vert0);   /* begin calculating determinant - also used to calculate U parameter */   CROSS(pvec, dir, edge2);   /* if determinant is near zero, ray lies in plane of triangle */   det = DOT(edge1, pvec);   if (det > -EPSILON && det < EPSILON)     return 0;   inv_det = 1.0 / det;   /* calculate distance from vert0 to ray origin */   SUB(tvec, orig, vert0);   /* calculate U parameter and test bounds */   *u = DOT(tvec, pvec) * inv_det;   if (*u < 0.0 || *u > 1.0)     return 0;   /* prepare to test V parameter */   CROSS(qvec, tvec, edge1);   /* calculate V parameter and test bounds */   *v = DOT(dir, qvec) * inv_det;   if (*v < 0.0 || *u + *v > 1.0)     return 0;   /* calculate t, ray intersects triangle */   *t = DOT(edge2, qvec) * inv_det;		return(true);   return 1;}

1) orig[3] is the ray origin point: i guess i have to get it with glUnProject and (mouse.x, mouse.y, 0) ?
2) the direction vector dir[3] is formed using glUnproject and (mouse.x, mouse.y, 1) ?
3) double *t, double *u, double *v are passed empty (are used to store calculations inside the function)
4) *t is the point where the ray intersects the triangle: how do i calculate x,y,z of the intersection point ?

##### Share on other sites
I haven't used it myself but let me try and answer your questions:

1.) Orig seems to be the start of your ray, you get it by unprojecting (mouse.x, mouse.y, 0).
2.) Dir is the direction vector. First you need the end point which you get by unprojecting (mouse.x, mouse.y, 1). Then dir = end - start. I don't know if you need to normalize it but I'd suggest doing it, so dir = (end - start) / length(end - start).
3. and 4.) t, u and v seem to be the barycentric coordinates of the intersection point, so if the function returns true (everything except 0) you have to convert those coordinates to a vector.

Basically a ray-triangle test can be done as follows:

1. get the triangle's plane
2. do a ray-plane intersection test and get the intersection point
3. check whether the interesction point lies within the triangle (or on its edges)

##### Share on other sites
*t is the point where the ray intersects the triangle: how do i calculate x,y,z of the intersection point ?

i assume its (origin + dir * t) // i assume dir is not normallized

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627657
• Total Posts
2978467
• ### Similar Content

• Both functions are available since 3.0, and I'm currently using glMapBuffer(), which works fine.
But, I was wondering if anyone has experienced advantage in using glMapBufferRange(), which allows to specify the range of the mapped buffer. Could this be only a safety measure or does it improve performance?
Note: I'm not asking about glBufferSubData()/glBufferData. Those two are irrelevant in this case.
• By xhcao
Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness.
• By cebugdev
hi guys,
are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic
let me know if you guys have recommendations.
• By dud3
How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below?
Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.

References:
Code: https://pastebin.com/Hcshj3FQ
The video shows the difference between blender and my rotation:

• By Defend
I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
* make lots of VAO/VBO pairs and flip through them to render different objects, or
* make one big VBO and jump around its memory to render different objects.
I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?

• 10
• 12
• 22
• 13
• 33