🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

How do I create a terrain editor with OpenGL?

Started by
12 comments, last by Valakor 1 year, 11 months ago

Ok, so I found something out. I tried to only change the terrain without going through the loop 256 times. However, that only changed the pixel coordineates of the pixel that was at the end of the terrain.

So this is what I have currently:

int vertexPointer = 0;

	for (int i = 0; i < 256; i++) {
		for (int j = 0; j < 256; j++) {
			vertice[vertexPointer * 3] = (float)i / ((float)256 - 1) * SIZE;

			if (i == x && j == y)
			{
				vertice[vertexPointer * 3 + 1] = 10;
				heights[i][j] = vertice[vertexPointer * 3 + 1];
			}

			vertice[vertexPointer * 3 + 2] = (float)j / ((float)256 - 1) * SIZE;

			textureCoord[vertexPointer * 2] = (float)i / ((float)256 - 1);
			textureCoord[vertexPointer * 2 + 1] = (float)j / ((float)256 - 1);
			vertexPointer++;
		}
	}

	
	return loader.postToVAO(vertice, textureCoord, normal, indice);

As you can see, I have made the tex coords, vertices, normals, and indices global values, so they can be changed in real time if it is necessary, and then I follow up by reposting to the VAO, as I did some tests with it and doing so is not very taxing for the computer.

However, I tried the following code (approximately):

int vertexPointer = 0;

	
		vertice[vertexPointer * 3] = (float)x / ((float)256 - 1) * SIZE;

	
			vertice[vertexPointer * 3 + 1] = 10;
			heights[x][y] = vertice[vertexPointer * 3 + 1];
		

			vertice[vertexPointer * 3 + 2] = (float)x / ((float)256 - 1) * SIZE;

			textureCoord[vertexPointer * 2] = (float)x / ((float)256 - 1);
			textureCoord[vertexPointer * 2 + 1] = (float)x / ((float)256 - 1);
			vertexPointer++;


	
	return loader.postToVAO(vertice, textureCoord, normal, indice);
	}

but this only moved the vertex point, not the rest of the terrain along with it, and it created this weird thing… but it was much quicker and less taxing because of the lack of a for loop.

It now sort of works… It can increase the terrain heights at random places, and it sets the terrain heights to such values. However, I still do struggle with the fact that it is slow… very slow… but I found out a way to make it go a little bit quicker. It still has to go through a for loop running through 256 times within another for loop, which is also running through 256 times.
Advertisement

yaboiryan said:
@JoeJ I dont need the terrain stuff to be able to make my own terrains… I wanted to make an in-game terrain editor. There is no way that I could use commercial software because I would literally have to program commercial software into my game. Because not only am I trying to do a terrain editor, but on top of this, I was going to do a scenario editor as well, where the player could create their own scenarios from a script file type I have created. XD

I see. Agree that's ambitious, but games with a community to create new content are often the best, so can be worth the effort.
A tool with many manual design features is world creator. Surely an interesting reference. I've tried World Machine 20 years ago, but this was too complicated and involved for me. So maybe that's still a negative example regarding end users.
I could imagine you provide a library of heightmap brushes (various mountains, sand dunes, a river delta, etc.), and the user can first compose a coarse landscape from that. Than you run a simulation to blend the seams and make it more natural.
Such simulation may take few seconds, but it's no problem for users to wait that long.
A lot of work and time, but doable. Maybe you can make it easier by using a less realistic artstyle, so no simulation is needed at all. This way you could commercial tools to make the library of brushes you provide, but no need to work on advanced simulation yourself.

One simulation detail i did not mention is tiled simulations. That's needed if your terrain is too big to fit in memory as a whole. Then simulating tiles with some overlap to blend them is the obvious option.
This works quite well, but it prevents global effects like a river network. I plan to resolve this by somehow calculating where rivers should be from a low resolution full map, and tiles can use this as a guide. That's one ‘devil in detail’ problem i still have to work on.

yaboiryan said:
So, in VAO terms, I would need to, @Valakor , get the address where all the verticx data is passed? This terrain is created and set equal to a model file, which manages all the VAO data, and then the glDrawElements function is called.

Another option would be to upload only texture tiles, no vertices at all. A compute shader could generate the vertices and mesh normals from that.

But i'm sure such technical details are your least problem for quite some time.

Notice there are alternatives to simulation, some comparison here.

	for (int i = 0; i < 256; i++) {
		for (int j = 0; j < 256; j++) {
			vertice[vertexPointer * 3] = (float)i / ((float)256 - 1) * SIZE;

			if (i == x && j == y)
  • Don't work with 3D vertices. Work with 1D height. This reduces your bandwidth by 3 and is more intuitive to work with. You can always easily calculate 3D coordinates from grid indices and height if needed.
  • Don't quantize to integer coordinates. Use floating point numbers, e.g. to describe the center of a user brush tool. A brush usually has a bound (rectangle bounding it's top left / bottom right coordinates.) Use this bound to process only the smaller image area which can be affected form the brush.

@yaboiryan - I agree with JoeJ. Unless your terrain can't be a heightmap texture for some reason, I'd stick to generating a regular grid of 2D points (either as an actual vertex buffer or implicitly on the GPU) on the ground plane that you displace to their final locations in your vertex shader by sampling a heightmap texture. This is way less data than using full 3D coordinates for everything.

Further, this means heightmap painting is actually more like painting in photoshop or other image-editing softwares since you're just working with a texture.

To your point of knowing “where” each vertex is in your data, that's a bit harder if you're using arbitrary meshes for your heightmap (and not regular-grid heightmaps like I've discussed above). If you can't use a regular grid and heightmap textures, then you'll have to have functions that do some kind of nearest-vertex search in your data (e.g. to the mouse location) to determine “where” the mouse is on the terrain. This is effectively raycasting against the terrain geometry.

This topic is closed to new replies.

Advertisement