Reputation: 504
I have a 2D floating point array with values mapped within the range 0.0f to 1.0f. I load it into OpenGL using a single channel i.e
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_FLOAT, data);
which works fine. However, I'm trying to add two more channels in order to eventually convert it into RGB colours, as below:
// Get the current grid
Array2D<real_t> currentGrid = m_Continuum->getCurrentGrid();
float R, G, B;
std::vector<GLfloat> image;
image.resize(currentGrid.size()*3, 0.0f);
for (size_t i = 0; i != currentGrid.sizeWd(); ++i)
{
for (size_t j = 0; j != currentGrid.sizeHt(); ++j)
{
// I have to switch i and j in currentGrid due to the way the Array2D type is layed out
image[( i * currentGrid.sizeWd() + j) + 0] = currentGrid(j, i);
image[( i * currentGrid.sizeWd() + j) + 1] = currentGrid(j, i);
image[( i * currentGrid.sizeWd() + j) + 2] = currentGrid(j, i);
}
}
Now, when I update and use glTexImage2D:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT,data);
the image is malformed, as shown in the comparison below:
My texture loading function is below. I believe I've used the correct pixelstore and texture mapping parameters.
bool Texture::load(const size_t width, const size_t height, const float *data)
{
glPixelStoref(GL_UNPACK_ALIGNMENT, 1);
// Allocate a texture name
//glGenTextures(1, &m_TextureObj); called in another function
// select current texture
glBindTexture(GL_TEXTURE_2D, m_TextureObj);
// select replace to ensure texture retains each texel's colour
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// if texture wraps over at the edges
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT,data);
glGenerateMipmap(GL_TEXTURE_2D);
m_Loaded = true;
return true;
}
Any ideas of what I could try? Here's what I've looked up:
EDIT:
Updated resulting image, based on @Podgorskiy answer, by changing
( i * currentGrid.sizeWd() + j) + c
to
( 3 * i * currentGrid.sizeWd() + j) + c
where c is the channel 0,1,2. Resulting image below:
Upvotes: 3
Views: 1988
Reputation: 1582
You access elements by the index that you calculate as:
( i * currentGrid.sizeWd() + j) + c
Where c is a channel, and it takes the values of: 0, 1, 2.
However, this expression likely to be wrong. From this expression follows that two neighboring texels have offset of one float, but should have offset of three floats. Try this instead:
3 * ( i * currentGrid.sizeWd() + j) + c
Upvotes: 3