# Heightmap problems

This topic is 933 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey everyone.

I have been following this tutorial http://www.mbsoftworks.sk/index.php?page=tutorials&series=1&tutorial=24 when trying to learn how to do a heightmap. I have managed to read in the vertex data but something is not correct.

When using the following grayscale image heightmap (in which i just display the vertex positions for now) Starts off very well but then it seems to duplicate the first part onto the end of the map (also seems like everything is a bit bunched up as the middle hole is not in the middle of the heightmap) Which results in it looking like this.

https://gyazo.com/cd642c41a92d4345bb4ca06dbc12ba1c

Atm I feel that the problem must be to do with the height of the pixel i read in but im not 100% sure. from what i have read up , the way i do it should be correct

Currently the grayscale image is a BMP 24 bitdepth 257*257. I use SDL to read in the image to calculate the vertex height

Below is the code i am currently using

getting the vertex points (like the tutorial i make sure the x and z are between -0.5 and 0.5 so it is centred)

	SDL_Surface* img = SDL_LoadBMP(imagepath);
if (!img)
{
std::cout << "could not load the image";
return;
}

rows = img->h;
cols = img->w;

std::vector< std::vector<glm::vec3> > Tvetrices (rows,std::vector<glm::vec3>(cols));
std::vector< std::vector<glm::vec3> > TFinalNormals = std::vector< std::vector<glm::vec3> >(rows, std::vector<glm::vec3>(cols));
std::vector< std::vector<glm::vec2> >  TUVs (rows , std::vector<glm::vec2>(cols));

float fTextureU = float(cols)*0.1f;
float fTextureV = float(rows)*0.1f;

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
float colscale = float(j) / float(cols - 1);
float rowscale = float(i) / float(rows - 1);

Uint32 pixle = ((Uint32*)img->pixels)[i * img->pitch/4 + j];
Uint8 r, g, b;
SDL_GetRGB(pixle, img->format, &r, &g, &b);
float hight = (float)r / 255.0;

Tvetrices[i][j] = glm::vec3((-0.5f + colscale) * 10, hight, (-0.5f + rowscale) * 10);
TUVs[i][j] = glm::vec2(fTextureU*colscale, fTextureV*rowscale);

}
}

vetrices = Tvetrices;


VBO set up (just want points for now so no intention for setup for tri's)

	for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
testver.push_back(vetrices[i][j]);
}

}

glBufferData(GL_ARRAY_BUFFER, testver.size() * sizeof(glm::vec3), &testver[0], GL_STATIC_DRAW);


draw call

	glUseProgram(_program);

glBindVertexArray(_VAO);

glDrawArrays(GL_POINTS, 0, testver.size());


Any help will be greatly appreciated

Edited by lexington

##### Share on other sites

It looks like you're sampling from the wrong location on the heightmap. Can you show us the original heightmap image?

##### Share on other sites

Uint32 pixle = ((Uint32*)img->pixels)[i * img->pitch/4 + j];

What's the significance of the /4 part? According to the wiki the pitch is the number of bytes per row, not sure why you are dividing it by 4. It might be worth you accessing the Pixel Format and checking the bytes per pixel to ensure everything matches up.

##### Share on other sites

What's the significance of the /4 part? According to the wiki the pitch is the number of bytes per row, not sure why you are dividing it by 4. It might be worth you accessing the Pixel Format and checking the bytes per pixel to ensure everything matches up.

without the /4, an access violation occurs. with ever example of 24 bitdepth image that i have seen, everyone puts the /4 after

also the bits per pixel came back as 24

and the bytes per pixel came back 3

Edited by lexington

##### Share on other sites

I don't know SDL, but if it's a 24bit image, each pixel might be 3 bytes instead of 4 (although sometimes 24 bit images store their data in 4 byte chunks for good memory alignment). You're treating it like if it were 4.

That is, each j that gets incremented reads from a position 4 bytes further in the buffer, since you're casting the array to a Uint32*.

Because your source image has equal values for r, g, and b, this error wouldn't be very obvious. You're basically reading an r value, then a g value, then a b value, and so on.

Instead, you may need to index it as a byte array, and increment by j * 3 (and remove the /4 from the pitch calculation).

##### Share on other sites

@Phil_T

Arr yes you are correct, i am treating the image as if it was 4 bytes per pixel instead of 3 (or it was a 32 bit bitmap ofcs).

Sorry to ask as just a little confused but what do you mean by "Instead, you may need to index it as a byte array, and increment by j * 3" (the "index it as a byte array" part mainly)

Cheers

##### Share on other sites

You're casting it to a Uint32* , meaning the when you index it like an array, it is indexed in 4 byte increments. You need to cast it to uint8_t* so you can index it in single byte increments (so you can obtain every third byte).

http://www.learncpp.com/cpp-tutorial/6-8a-pointer-arithmetic-and-array-indexing/

##### Share on other sites

@Phil_T

Like the following?

Uint8 *pixle = ((Uint8*)img->pixels);
pixle += (i * img->pitch) + (j * sizeof(Uint8) * 3);
Uint32 temppix = *((Uint32*)pixle);

Uint8 r, g, b;
SDL_GetRGB(temppix, img->format, &r, &g, &b);
float hight = (float)r / 255.0;


i had to change it back to uint32 at the end as that is only what the SDL_GetRGB function will take.

The results are much better

https://gyazo.com/10795f58b070189ea3e23f1fd376372f

##### Share on other sites

@Phil_T

Like the following?

Uint8 *pixle = ((Uint8*)img->pixels);
pixle += (i * img->pitch) + (j * sizeof(Uint8) * 3);
Uint32 temppix = *((Uint32*)pixle);

Uint8 r, g, b;
SDL_GetRGB(temppix, img->format, &r, &g, &b);
float hight = (float)r / 255.0;


i had to change it back to uint32 at the end as that is only what the SDL_GetRGB function will take.

The results are much better

https://gyazo.com/10795f58b070189ea3e23f1fd376372f

That looks a lot better. It's probably a good idea to replace that 3 with the BytesPerPixel value from the pixel format. It is probably 3 since it works but it might not always be 3.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 28
• 16
• 10
• 10
• 11
• ### Forum Statistics

• Total Topics
634114
• Total Posts
3015570
×