I'm writing a class to render a height map from a 32-bit bmp using modern OpenGL techniques. I had it working with immediate mode but wanted to try converting it to a modern OpenGL context. I'm using an element array buffer with the index data for the map and a vbo which has the vertex data where the y component is taken from the height (pixel color) of the bitmap.
Right now, I'm getting an unhandled exception/access violation at the draw call. Here's my code:
void HeightMap::initHeightMap(const char* filePath, float size, float height){
SDL_Surface* image = SDL_LoadBMP(filePath);
if (!image)
{
smodgine::fatalError("Image could not be loaded!");
}
std::vector<float> tmp;
for (int y = 0; y< image->h; y++)
{
tmp.clear();
for (int x = 0; x < image->w; x++)
{
Uint32 pixel = ((Uint32*)image->pixels)[y * image->pitch/4 + x];
Uint8 r, g, b;
SDL_GetRGB(pixel, image->format, &r, &g, &b);
tmp.push_back((float)r / 255.0f);
}
heights.push_back(tmp);
}
for (int z = 0; z < heights.size(); z++)
{
for (int x = 0; x < heights[0].size(); x++)
{
vertices.push_back(x * size);
vertices.push_back(heights[z][x] * height);
vertices.push_back(z * size);
}
}
if (_vbo == 0) {
glGenBuffers(1, &_vbo);
}
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
_numRows = heights.size() - 1;
_numColumns = heights[0].size() - 1;
SDL_FreeSurface(image);
createElementBuffer();
}
void HeightMap::renderHeightMap()
{
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _eleBuffer);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
}
void HeightMap::createElementBuffer()
{
for (int z = 0; z < _numRows; z++)
{
for (int x = 0; x < _numColumns; x++)
{
//top left
indices.push_back(z * _numRows + x);
//bottom left
indices.push_back((z + 1) * _numRows + x);
//top right
indices.push_back(z * _numRows + (x + 1));
//top right
indices.push_back(z * _numRows + (x + 1));
//bottom left
indices.push_back((z + 1) * _numRows + x);
//bottom right
indices.push_back((z + 1) * _numRows + (x + 1));
}
}
if (_eleBuffer == 0){
glGenBuffers(1, &_eleBuffer);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _eleBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
I've only been using modern OpenGL for about a week or so, any help is appreciated :D
You're using the
sizeofoperator for instances ofstd::vector, expecting that it will give you the size of the data in the vector:That will not produce the expected result.
sizeofgives you the size in memory of thevectorobject, not of the data stored in the vector. That data is dynamically allocated, and not stored in thevectorinstance itself.To get the correct size, you can use: