Reputation: 3124
I am drawing an OpenGL texture for a colorbar. The input image comes from OpenCV, therefore its format is BGRA. The output format is RGBA.
This is how I draw it:
// This drawer is for a texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_colorbarTextureID);
glBegin(GL_QUADS);
int width = m_colorbar.cols;
int height = m_colorbar.rows;
static const float inverse_scale = 2; // inverse scale value to resize the colormap image
float x = static_cast<float>(width) / (2 * inverse_scale);
float y = static_cast<float>(height) / (2 * inverse_scale);
static const float border = 10;
// Send the texture to minz in order to guarantee it will show up behind all the other elements
glTexCoord2f(0.0f, 0.0f); glVertex3f(m_lastCx - x - border, border, static_cast<GLfloat>(m_min2DDepth));
glTexCoord2f(0.0f, 1.0f); glVertex3f(m_lastCx - x - border, border + y, static_cast<GLfloat>(m_min2DDepth));
glTexCoord2f(1.0f, 1.0f); glVertex3f(m_lastCx - border, border + y, static_cast<GLfloat>(m_min2DDepth));
glTexCoord2f(1.0f, 0.0f); glVertex3f(m_lastCx - border, border, static_cast<GLfloat>(m_min2DDepth));
glEnd();
glDisable(GL_TEXTURE_2D);
This is how I create it:
glEnable(GL_TEXTURE_2D);
// Resize image
cv::Mat colorbar_flip;
cv::resize(m_colorbar, colorbar_flip, cv::Size(), m_colorbarScale, m_colorbarScale);
// Flip y axis due to openGL convention (0 on bottom, positive pointing up)
cv::flip(colorbar_flip, colorbar_flip, 0);
glGenTextures(1, &m_colorbarTextureID);
if (m_colorbarTextureID == 0) {
LoggerPublic::debug("Error creating colorbar texture");
return;
}
glBindTexture(GL_TEXTURE_2D, m_colorbarTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Set texture clamping method
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//use fast 4-byte alignment (default anyway) if possible
//glPixelStorei(GL_UNPACK_ALIGNMENT, (colorbar_flip.step & 3) ? 1 : 4);
//set length of one complete row in data (doesn't need to equal image.cols)
//glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(colorbar_flip.step) / static_cast<GLint>(colorbar_flip.elemSize()));
glTexImage2D(GL_TEXTURE_2D, // Type of texture
0, // Pyramid level (for mip-mapping) - 0 is the top level
GL_RGBA, // Internal colour format to convert to
colorbar_flip.cols, // Image width
colorbar_flip.rows, // Image height
0, // Border width in pixels (can either be 1 or 0)
GL_BGRA, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
GL_UNSIGNED_BYTE, // Image data type
colorbar_flip.ptr()); // The actual image data itself
glDisable(GL_TEXTURE_2D);
wglMakeCurrent(nullptr, nullptr);
However, I get this strange output, with a blueish tone where it should be white:
What could be wrong?
EDIT
Maybe this has something to do with drawing 3d vertices with RGB colors only, with glVertex3f
and glEnableClientState(GL_COLOR_ARRAY)
Upvotes: 3
Views: 915
Reputation: 22157
The problem here seems to be that the color of the texture is modulated with the vertex color. By default glTexEnv
is set to GL_MODULATE
, which basically means that the color coming from the texture is multiplied with the vertex color.
You can change the mode to only use the texture color by
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
Siden note: The fixed function pipeline is reeeeeeealy old and deprecated, so if there is not a good reason to use it, one should avoid it.
Upvotes: 4