Sign in to follow this  
MaimaVanPersie

OpenGL My terrain contains some strange line segments

Recommended Posts

Hey guys, I need your help again if somebody here would kindly help me out.

I recently loaded my very first terrain using a heightmap image for the first time. It worked great! However, I noticed some strange line segments that are being drawn from the top of the terrain stretching all the way down to the very bottom. I will post images of this below so you could see what I mean, I will also link you the resource I used to generate my terrain (which is really just 1 YouTube video) here:  https://www.youtube.com/watch?v=pAHzHcUXsYA

I'd be very thankful if somebody could review the code with me and help me identify the problem...

Oddly enough, the person in the YouTube video seemed to have had a very similar (if not the exact same) problem I am having at 18:38 but he fixed it by adding one simple thing which I also added but didn't do the trick for me :( Also he is using the fixed function pipeline to demonstrate the technique, I am using the programmable pipeline for better performance. Anyway, here is the result of my terrain: 

Capture.thumb.jpg.dd6aa05a6c83b352989b41bf7dfebf6e.jpg
The unwanted line segments:

Capture3.thumb.JPG.7b41ab9c3e1aa7ce012d6bbd4b4c5fe1.JPGCapture2.thumb.jpg.855d9a50393411d13c2a5830281f020c.jpg

As you can see, I also have grass (very awful looking grass too :p) on top of my terrain while playing around with the geometry shader the other day.

Here is how I am loading the heightmap, and here is where I believe the problem lies: 

 
void TerrainLoader::LoadHeightmapImage(const char* file)
{
	// Load the bitmap
	m_pImage = SDL_LoadBMP(file);
	Uint32 Pixel = 0;
 
	// Check for errors
	if (m_pImage == nullptr)
	{
		std::cerr << "error: Heightmap image could not be loaded.\n";
		return;
	}
 
	// Get bitmap's width and height
	m_HeightmapHeight = m_pImage->h;
	m_HeightmapWidth = m_pImage->w;
 
	// Read the bitmap (stores in this 2D STL vector of floats: vector<vector<float> > m_vHeights;)
	std::vector<float> tmp;
	for (int i = 0; i < m_HeightmapHeight; ++i)
	{
		for (int j = 0; j < m_HeightmapWidth; ++j)
		{
			Pixel = ((Uint32*)m_pImage->pixels)[i * m_pImage->pitch / 4 + j];
			unsigned char r, g, b;
			SDL_GetRGB(Pixel, m_pImage->format, &r, &g, &b);
			tmp.push_back((float)r / 255.0);
		}
 
		m_vHeights.push_back(tmp);
		tmp.clear();
	}
 
	SDL_FreeSurface(m_pImage);
 
	float h = 0.4f, terrainSize = 0.005f;
 
	std::vector<glm::vec3> Vertices;
	std::vector<glm::vec2> Textures;
 
	for (int i = 0; i < m_vHeights.size() - 1; ++i)
	{
		for (int j = 0; j < m_vHeights.size() - 1; ++j)
		{
			// Put the vertices and texture coordinates in their respective buffers
			Textures.push_back(glm::vec2(0.0f, 0.0f));
			Vertices.push_back(glm::vec3(i * terrainSize, m_vHeights[i][j] * h, j * terrainSize));
 
			Textures.push_back(glm::vec2(1.0f, 0.0f));
			Vertices.push_back(glm::vec3((i + 1) * terrainSize, m_vHeights[i + 1][j] * h, j * terrainSize));
 
			Textures.push_back(glm::vec2(1.0f, 1.0f));
			Vertices.push_back(glm::vec3(i * terrainSize, m_vHeights[i][j + 1] * h, (j + 1) * terrainSize));
 
			Textures.push_back(glm::vec2(0.0f, 1.0f));
			Vertices.push_back(glm::vec3((i + 1) * terrainSize, m_vHeights[i + 1][j + 1] * h, (j + 1) * terrainSize));
		}
	}
 
	// Send the data to the GPU
	glGenVertexArrays(1, &m_VAO);
	glBindVertexArray(m_VAO);
 
	glGenBuffers(1, &m_VBO[0]);
	glBindBuffer(GL_ARRAY_BUFFER, m_VBO[0]);
	glBufferData(GL_ARRAY_BUFFER, Vertices.size() * sizeof(glm::vec3), &Vertices[0], GL_STATIC_DRAW);
 
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
 
	glGenBuffers(1, &m_VBO[1]);
	glBindBuffer(GL_ARRAY_BUFFER, m_VBO[1]);
	glBufferData(GL_ARRAY_BUFFER, Textures.size() * sizeof(glm::vec2), &Textures[0], GL_STATIC_DRAW);
 
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
 
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
 
	// This concludes the function 
}

Then, this is how I'm simply drawing the terrain to the scene:

void TerrainLoader::Draw()
{
	glBindVertexArray(m_VAO);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, (m_HeightmapWidth - 1) * (m_HeightmapHeight - 1) * 4);
}

Alright, I hope that's enough information for someone to help me figure out the issue with this...

Thank you very much for taking the time to read my thread, I really appreciate it! Enjoy your day! 

Edited by MaimaVanPersie

Share this post


Link to post
Share on other sites

Only had a very brief look, but wild guess, off by one error? i.e. to make a fence 10 metres long with fenceposts every 1 metre, you need 11 fenceposts, not 10...

Edit .. Ah no I think I see it ... you are using triangle strip, are you using an index buffer too? You need to reset the triangle strip after each row with a degenerate triangle or something like that.

Edited by lawnjelly

Share this post


Link to post
Share on other sites

If indexed draw, the glDrawElements call would be used to fire the render. I'm looking at the third parameter calculation in the glDrawArrays call as the bad guy, as a guess because it seems way too many for triangle strip.

 

Edit: looks like you're not building your triangle strip properly. Graph what you're doing on paper of what your double for loop does. When the loop starts, the first two triangles are correct. At the second iteration the first and second triangles are degenerate then the third and fourth fill the grid location hiding the problem. The error is repeated to the end. When a grid like this is built using triangle strip, a degenerate triangle is needed when you complete building a row and advance to the next row then repeat.

 

Edited by GoliathForge
Came back after work to look proper.

Share this post


Link to post
Share on other sites

Thank you both for your reply.

On 9/29/2017 at 1:09 AM, lawnjelly said:

Edit .. Ah no I think I see it ... you are using triangle strip, are you using an index buffer too? You need to reset the triangle strip after each row with a degenerate triangle or something like that.

I'm not using an index buffer to draw my triangles, how do I reset the triangle strip after each row? 

Share this post


Link to post
Share on other sites

Okay, problem fixed (FINALY!!!). Thank you so much for the help guys. Here's what I did for anyone interested, I stopped using triangle strips and I used indices instead with GL_TRIANGLES. That fixed the problem. I'm really glad I fixed this, for whoever encounters this problem and somehow stumbles upon this thread in the future, there were numerous solutions I researched to fixing this issue, I simply chose the indices/triangle approach as it seemed simple, but I will leave links for you here: 

https://gamedev.stackexchange.com/questions/143448/opentk-terrain-triangle-strip-issue (<-- This is basically my problem)

https://www.opengl.org/discussion_boards/archive/index.php/t-177729.html

The problem is really mentioned by the users above. I am very thankful for your help guys! 

Share this post


Link to post
Share on other sites
15 hours ago, MaimaVanPersie said:

Okay, problem fixed (FINALY!!!). Thank you so much for the help guys. Here's what I did for anyone interested, I stopped using triangle strips and I used indices instead with GL_TRIANGLES. That fixed the problem. I'm really glad I fixed this, for whoever encounters this problem and somehow stumbles upon this thread in the future, there were numerous solutions I researched to fixing this issue, I simply chose the indices/triangle approach as it seemed simple, but I will leave links for you here: 

https://gamedev.stackexchange.com/questions/143448/opentk-terrain-triangle-strip-issue (<-- This is basically my problem)

https://www.opengl.org/discussion_boards/archive/index.php/t-177729.html

The problem is really mentioned by the users above. I am very thankful for your help guys! 

The indexed triangle list is indeed the right thing to use, but you need to generate a proper triangle index ordering or your GPU will have very poor cache utilization. There is many tool and algo to optimize this NP complete problem, one i like is this one : https://tomforsyth1000.github.io/papers/fast_vert_cache_opt.html

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Announcements

  • Forum Statistics

    • Total Topics
      628385
    • Total Posts
      2982391
  • Similar Content

    • By KarimIO
      Hey guys,
      I'm trying to work on adding transparent objects to my deferred-rendered scene. The only issue is the z-buffer. As far as I know, the standard way to handle this is copying the buffer. In OpenGL, I can just blit it. What's the alternative for DirectX? And are there any alternatives to copying the buffer?
      Thanks in advance!
    • By sveta_itseez3D
      itSeez3D, a leading developer of mobile 3d scanning software, announced today a new SDK for its automatic 3D avatar generation technology, Avatar SDK for Unity. The Avatar SDK for Unity is a robust plug-n-play toolset which enables developers and creatives to integrate realistic user-generated 3D avatars into their Unity-based applications. SDK users can allow players to create their own avatars in the application or integrate the SDK into their own production processes for character design and animation.
      “Virtual avatars have recently become increasingly popular, especially in sports games and social VR apps. With the advance of VR and AR, the demand to get humans into the digital world is only increasing”, said Victor Erukhimov, itSeez3D CEO. “Our new Avatar SDK for Unity makes it super-easy to bring the avatar technology into any Unity-based game or VR/AR experience. With the Avatar SDK for Unity now every developer can bring face scanning technology into their games and allow players to create their own personalized in-game avatars, making the gameplay much more exciting and immersive.”
      Key features of the Avatar SDK for Unity:
      Automatic generation of a color 3D face model from a single selfie photo in 5-10 seconds (!). Works best with selfies, but can be used with any portrait photo.
      Shape and texture of the head model are unique for each person, synthesized with a deep learning algorithm crafted by computer vision experts
      Head models support runtime blendshape facial animations (45 different expressions)
      Generated 3D heads include eyes, mouth, and teeth
      Algorithms synthesize 3D meshes in mid-poly resolution, ~12k vertices, and ~24k triangles
      Six predefined hairstyles with hair-recoloring feature (many more available on request)
      Avatar generation API can be used in design-time and in run-time, which means you can allow users to create their own avatars in your game
      Cloud version is cross-platform, and offline version currently works on PCs with 64-bit Windows (support for more platforms is coming soon)
      Well-documented samples showcasing the functionality.
       
      Availability
      The Avatar SDK for Unity is offered in two modes - “Cloud” and “Offline”. The “Cloud” version is available at http://avatarsdk.com/ and the “Offline” version is available by request at support@itseez3d.com.
      ###
      About itSeez3D
      At itSeez3D, we are working on the computer vision technology that turns mobile devices into powerful 3D scanners. itSeez3D has developed the world's first mobile 3D scanning application that allows to create high-resolution photorealistic 3D models of people's' faces, bodies and objects. The application is available for iOS and Windows OS mobile devices powered with 3D cameras. In 2016 the company introduced Avatar SDK that creates a realistic 3D model of a face from a single selfie photo. To learn more about itSeez3D scanning software and 3D avatar creation technology, please visit www.itseez3d.com and www.avatarsdk.com.

      View full story
    • By sveta_itseez3D
      itSeez3D, a leading developer of mobile 3d scanning software, announced today a new SDK for its automatic 3D avatar generation technology, Avatar SDK for Unity. The Avatar SDK for Unity is a robust plug-n-play toolset which enables developers and creatives to integrate realistic user-generated 3D avatars into their Unity-based applications. SDK users can allow players to create their own avatars in the application or integrate the SDK into their own production processes for character design and animation.
      “Virtual avatars have recently become increasingly popular, especially in sports games and social VR apps. With the advance of VR and AR, the demand to get humans into the digital world is only increasing”, said Victor Erukhimov, itSeez3D CEO. “Our new Avatar SDK for Unity makes it super-easy to bring the avatar technology into any Unity-based game or VR/AR experience. With the Avatar SDK for Unity now every developer can bring face scanning technology into their games and allow players to create their own personalized in-game avatars, making the gameplay much more exciting and immersive.”
      Key features of the Avatar SDK for Unity:
      Automatic generation of a color 3D face model from a single selfie photo in 5-10 seconds (!). Works best with selfies, but can be used with any portrait photo.
      Shape and texture of the head model are unique for each person, synthesized with a deep learning algorithm crafted by computer vision experts
      Head models support runtime blendshape facial animations (45 different expressions)
      Generated 3D heads include eyes, mouth, and teeth
      Algorithms synthesize 3D meshes in mid-poly resolution, ~12k vertices, and ~24k triangles
      Six predefined hairstyles with hair-recoloring feature (many more available on request)
      Avatar generation API can be used in design-time and in run-time, which means you can allow users to create their own avatars in your game
      Cloud version is cross-platform, and offline version currently works on PCs with 64-bit Windows (support for more platforms is coming soon)
      Well-documented samples showcasing the functionality.
       
      Availability
      The Avatar SDK for Unity is offered in two modes - “Cloud” and “Offline”. The “Cloud” version is available at http://avatarsdk.com/ and the “Offline” version is available by request at support@itseez3d.com.
      ###
      About itSeez3D
      At itSeez3D, we are working on the computer vision technology that turns mobile devices into powerful 3D scanners. itSeez3D has developed the world's first mobile 3D scanning application that allows to create high-resolution photorealistic 3D models of people's' faces, bodies and objects. The application is available for iOS and Windows OS mobile devices powered with 3D cameras. In 2016 the company introduced Avatar SDK that creates a realistic 3D model of a face from a single selfie photo. To learn more about itSeez3D scanning software and 3D avatar creation technology, please visit www.itseez3d.com and www.avatarsdk.com.
    • By glportal
      GlPortal is a free and open source first person 3D teleportation based puzzle game and platformer. But we have already integrated a physics engine and are planning for some physics based puzzles.
      We want to improve our Visual Studio support. Check out this project:
      https://github.com/kungfooman/glportal-vs
      You can chat with us on gitter https://gitter.im/GlPortal/glPortal
    • By Canislupus54
      I'm looking for programmers for an rpg I want to make. If you're wondering what "semi-turn based" means, it means that you take turns, but instead of a rigid back and forth like Pokemon, a timer determines when you can act, a sort of modernization of the classic Final Fantasy Active Time Battle system. Right now, I'm looking for programmers to create a prototype of both the combat system and the movement outside of combat. Preferably for Unity C#. Concept artists, particularly for characters, and writers to help me flesh out the character and story aspects, would also be helpful.
      Here's a concept doc to fully explain things: https://docs.google.com/document/d/1ObDMAUWsndSAJ1EpQGRDxtR8Xl9xPotx89OZ0sgRaIw/edit?usp=sharing
      If you can fill another role and are interested, feel free to let me know as well.
      At the moment, this is purely a hobby project, with no payment planned. If we produce something we feel we can release, then of course we'll work out something for compensation. But, again, don't join this project counting on payment.
      If you're interested, contact me on here, or at jordestoj@yahoo.com . Thanks.
  • Popular Now