Problem with my sky dome - big hole in the top!

Started by
4 comments, last by swiftcoder 11 years, 3 months ago

I have an issue with my sky dome in a terrain project. I'm generating the vertices and indices for a hemisphere in a function, but for some reason when testing using texture triangles and open gl's line mode, there is a huge gaping hole in the top of the sky dome. I have tried changing the draw distance to see if it's a clipping problem but no luck!

Here is my code, sorry about the formatting as pasting it into the code reader squashed some lines together


bool	SkyDome::Init(const std::string& textureName,const std::string& shader){

	//TODO: Texture stuff
	//TODO shader stuff

	//init the objectbuffer and vertex info!

	int numVertices = (m_latSlices+1) * (m_longSlices+1); 

	vec3* vertexData = new vec3[numVertices];

	for(int latSlice = 0; latSlice <= m_latSlices; latSlice++){

          for(int longSlice = 0; longSlice <= m_longSlices; longSlice++){
			
            vertexData[latSlice * m_longSlices + longSlice] = 
                                vec3(m_radius * cos( (float)(latSlice)/(m_latSlices-1) * PI/2.0 ) * cos( 2.0 * (float)longSlice/(m_longSlices-1) * PI ),
				m_radius * sin( (float)(latSlice)/(m_latSlices-1) * PI/2.0 ),
			        m_radius * cos( (float)(latSlice)/(m_latSlices-1) * PI/2.0 ) * sin( 2.0 * (float)longSlice/(m_longSlices-1) * PI ) );
		 }
     
   }

   //generate indices
	int index = 0;
	unsigned int* indices = new unsigned int[numVertices * 6];
	//generate indices
	for(int row = 0; row <= m_latSlices; row++){
		for(int column = 0; column <= m_longSlices; column++){
			int start   = row * m_longSlices + column;
			indices[index++] = start;
			indices[index++] = start + 1;
			indices[index++] = start + m_longSlices;

			indices[index++] = start + 1;
			indices[index++] = start + 1 + m_longSlices ;
			indices[index++] = start + m_longSlices ;
		}
	}


	m_objectData = new ObjectData(1,numVertices);
	m_objectData->Init(indices,numVertices,vertexData,3);

    //delete [] vertexData;
	delete [] indices;

	return true;

Advertisement

It would probably be easier to identify the issue if you could post a screenshot of the problem.

Your spherical equation works fine - with those parameters it should generate a half-shere oriented along the +y axis - so I'm assuming your 'up' direction is +y.

I don't think this is exactly the problem, but when calculating the vertex positions you have:

latSlice in the range of [0, m_latSlices] and longSlice in the range of [0, m_longSlices] (I'm starting to bold these since there's no inline <code> tag)

- meaning you include both boundary values, but in your calculations you have:


(latSlice)/(m_latSlices-1) and longSlice/(m_longSlices-1)

- from that it looks like you're overshooting the values - you want both of them to range from 0..1 - and this will make them go to 0.. slightly above 1

The calculation of angle should probably be (latSlice)/(m_latSlices) and longSlice/(m_longSlices) - without the -1

Also, in your loop to assign indices.. there's something odd (meaning, I can't put my finger on it yet) going on if you take a look at your very last run through that loop:


for(int row = 0; row <= m_latSlices; row++)
{
  for(int column = 0; column <= m_longSlices; column++)
  {

Here row and column also range to m_latSlices and m_longSlices inclusive.

Then in your calcuation:


int start = row * m_longSlices + column;

the maximum value of start (which occurs at the last run through that loop) will therefore be

m_latSlices*m_longSlices + m_longSlices or (m_latSlices + 1)*m_longSlices

Then one of your indices becomes

indices[index++] = start + 1 + m_longSlices - which then, for your maximum value of start, actually becomes:

(m_latSlices + 1)*m_longSlices + 1 + m_longSlices or m_longSlices*(m_latSlices + 2) + 1

which seems like it's incorrect... From what I see you're making triangles out of 1 'column' ahead - but that usually means that you should limit your loop so that it doesn't do that for the last column, since the last column has no 'one column ahead'.

I need to take a closer look at this later, when I can run your code (my brain can only hold so much of this info in my head at once), and try with really low values of m_longSlices and m_latSlices - which should probably give a good indication of what's messing up.

I was running just a numeric version of this -
What I said above seems to be a problem - your division of (latSlice)/(m_latSlices-1) and longSlice/(m_longSlices-1) - should not have that -1, and your indexing does indeed set an index that is out of bounds - only one index it sets is out of bounds, but it's still not accurate - and I don't have a quick solution to that right now.

There's also another problem: if you check how you calculate which vertex's position you're calculating, it looks like this:
latSlice * m_longSlices + longSlice - however, this calcuation actually gives inaccurate results. For 4 latSlices and 4longSlices, you make an array of 25 vertices, but you end up doing this:


vertexData[0] = 1 0 0
vertexData[1] = 0 0 1
vertexData[2] = -1 0 0
vertexData[3] = 0 0 -1
vertexData[4] = 1 0 0
vertexData[4] = 0.92388 0.382683 0
vertexData[5] = 0 0.382683 0.92388
vertexData[6] = -0.92388 0.382683 0
vertexData[7] = 0 0.382683 -0.92388
vertexData[8] = 0.92388 0.382683 -0
vertexData[8] = 0.707107 0.707107 0
vertexData[9] = 0 0.707107 0.707107
vertexData[10] = -0.707107 0.707107 0
vertexData[11] = 0 0.707107 -0.707107
vertexData[12] = 0.707107 0.707107 0
vertexData[12] = 0.382683 0.92388 0
vertexData[13] = 0 0.92388 0.382683
vertexData[14] = -0.382683 0.92388 0
vertexData[15] = 0 0.92388 -0.382683
vertexData[16] = 0.382683 0.92388 0
vertexData[16] = 0 1 0
vertexData[17] = 0 1 0
vertexData[18] = 0 1 0
vertexData[19] = 0 1 0
vertexData[20] = 0 1 0

You can see that some of the indices get repeated (because latSlice * m_longSlices + longSlice has the same value for (latSlice = n, longSlice = m_longSlices) and (latSlice = n + 1, longSlice = 0) - and because of that, you don't set all your indices - in the above, there are 4 repetitions and you should have also set vertexData[21...24] as well, but the program did not. Making an incremental counter to which vertex you're setting fixes that, but I still don't know if this will fix your problems.

I'm pretty sure that the hole you're getting on the top of your hemi-sphere is due to the fact that your last m_longSlices number of vertices don't get filled at all.


By incremental counter, I mean setting vertexData like this:


int index = 0;
for(int latSlice = 0; latSlice <= m_latSlices; latSlice++){
  for(int longSlice = 0; longSlice <= m_longSlices; longSlice++){
    vertexData[index++] =...

I think you need to carefully re-examine the boundaries of your loops, and re-write them while making sure they don't overlap and the way you calculate your angles varies between the 0..pi/2 and 0..2pi values correctly (as I posted in my previous post).
Edit: fixing weird gap that occured

Edit2: added additional comment clarifying cause of your 'hole'

Thanks gentlemen. However, now I have taken the sensible route - using a sphere .obj mesh and using a cube map to texture it. I don't know why I didn't think of doing it in the first place!

Don't feel bad - the first time anyone sits down to write a sphere tessellator, they usually mess up the indices like this (I certainly did).

If you end up revisiting this code, it's worth sketching the indices up on a piece of paper, and then reasoning very carefully about where your indices should/shouldn't wrap around.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement