Nick Bolton
Nick Bolton

Reputation: 39550

Can I use a grayscale image with the OpenGL glTexImage2D function?

I have a texture which has only 1 channel as it's a grayscale image. When I pass the pixels in to glTexImage2D, it comes out red (obviously because channel 1 is red; RGB).

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGBA,
    dicomImage->GetColumns(), dicomImage->GetRows(),
    0, GL_RGBA, GL_UNSIGNED_BYTE, pixelArrayPtr);

Do I change GL_RGBA? If so, what to?

Upvotes: 21

Views: 24726

Answers (4)

G.Azma
G.Azma

Reputation: 37

You would use GL_LUMINANCE format in old versions of openGL, but now in modern 3.0+ OpenGL versions GL_LUMINANCE is deprecated, so new way of doing it is to use GL_RED format, but that would result in a red texture, so to get around this you should create a costum shader as above answers have shown, in that shader you grab red component of the texture, as it's the only one with data you have given and set green/blue channels to red channel's value, that will convert is to grayscale, because grayscale textures have all 3 RGB channels the same and Alpha/Transparency channel set to 1.

Upvotes: 0

ypnos
ypnos

Reputation: 52357

Change it to GL_LUMINANCE. See https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml

Upvotes: 22

Ming
Ming

Reputation: 111

in the FragmentShader, you can write:

uniform sampler2D A;
vec3 result = vec3(texture(A, TexCoord).r);

in the cpp file,you can write:

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RED,
    dicomImage->GetColumns(), dicomImage->GetRows(),
    0, GL_RED, GL_UNSIGNED_BYTE, pixelArrayPtr);

Upvotes: 11

Nick Bolton
Nick Bolton

Reputation: 39550

It appears that I should use GL_LUMINANCE instead of GL_RGBA for the 3rd argument.

Edit (in reply to comments):

When I set the 7th argument to GL_LUMINANCE (as well as the 3rd), the picture goes completely distorted. With the DICOM pixel format, it appears that the 7th argument must be GL_RGBA for some reason.

The strange behavior is because I'm using the DICOM standard. The particular DICOM reader I am using outputs integer pixel values (as pixel values may exceed the normal maximum of 255). For some strange reason the combination of telling OpenGL that I am using an RGBA format, but passing in integer values rendered a perfect image.

Because I was truncating the DICOM > 255 pixel values anyway, it seemed logical to copy the values in to a GLbyte array. However, after doing so, a SIGSEGV (segmentation fault) occurred when calling glTexImage2D. Changing the 7th parameter to GL_LUMINANCE (as is normally required) returned the functionality to normal.

Weird eh?

So, a note to all developers using the DICOM image format: You need to convert the integer array to a char array before passing it to glTexImage2D, or just set the 7th argument to GL_RGBA (the later is probably not recommended).

Upvotes: 1

Related Questions