PDA

View Full Version : Problems and confusion with glTexSubImage3D



Manuli
03-28-2017, 05:32 AM
Hi guys!
I'm an Italian developer and i'm beginner in the OpenGL world.
I use OpenTK in order to use OpenGL with C# language, but, I think, this is not the cause of my problem.
(I post the code in C#, but it is easy to see the corresponding command in c++)

I've a problem with the function glTexSubImage3D.

I define my texture 3d in this way:



GL.GenTextures(1, out _textureID);
GL.BindTexture(TextureTarget.Texture3D, _textureID);

GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureMagFilter, (int)TextureMinFilter.Linear);

GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapS,
(int)TextureWrapMode.ClampToBorder);
GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapT,
(int)TextureWrapMode.ClampToBorder);
GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapR,
(int)TextureWrapMode.ClampToBorder);

GL.TexImage3D<ushort>(TextureTarget.Texture3D, 0, PixelInternalFormat.Rgba16, _sizeX, _sizeY, _sizeZ, 0,
PixelFormat.Alpha, PixelType.UnsignedShort, _texelsObj);

var err = GL.GetError(); // --> NO ERROR


Up to this point everything ok, i render my texture 3d handling the alpha values in the glsl shader, defining the colors for each voxel.

Now, i want to change a "plane" of the texture, coloring it with a single colour.
I use the texSubImage3D function:

(_planeTexelsX,_planeTexelsY, _planeTexelsZ are filled of ushort.MaxValue )



GL.BindTexture(TextureTarget.Texture3D, _textureID);
GL.TexSubImage3D<ushort>(TextureTarget.Texture3D, 0, 0, 0, planeZ, _sizeX, _sizeY, 1, PixelFormat.Red,
PixelType.UnsignedShort, _planeTexelsZ);

This works, it make the plane, with z = planeZ, red.(for each x, y)



GL.BindTexture(TextureTarget.Texture3D, _textureID);
GL.TexSubImage3D<ushort>(TextureTarget.Texture3D, 0, 0, planY, 0, _sizeX, 1, _sizeZ,
PixelFormat.Green, PixelType.UnsignedShort, _planeTexelsY);

This works, it make the plane, with y = planeY, green.(for each z, x)



GL.BindTexture(TextureTarget.Texture3D, _textureID);
GL.TexSubImage3D<ushort>(TextureTarget.Texture3D, 0, planeX, 0, 0, 1, _sizeY, _sizeZ,
PixelFormat.Blue, PixelType.UnsignedShort, _planeTexelsX);

This should make the plane, with x = planeX, blue, but doesn't work.
If i call the function


ushort[] pix = new ushort[_texels.Length];
GL.GetTexImage<ushort>(TextureTarget.Texture3D, 0, PixelFormat.Blue, PixelType.UnsignedShort, pix);

(that gives me the values of the texture3D) i see that the first values are correct but some values are wrong.
Any idea?
I can't figure out why the first two cases works and the last doesn't.
It is allowed defines the texture3D with internalPixelFormat rgba16, and defines the subTexture for red, green or blue component only?

(Sorry for the bad english, hope you can understand)

Thanks!

Osbios
03-29-2017, 03:31 PM
It is allowed defines the texture3D with internalPixelFormat rgba16, and defines the subTexture for red, green or blue component only?

Red yes, but not solo green or blue.

I don't know your C# library definitions but the allowed color format for that function are:

RED, RG, RGB, BGR, RGBA (And some depth and stencil stuff)

Also note if you have a RGBA texture and use the RED format in this function, it will use default values to set the other colors for the involved pixels.

The default values are (normalized):

R G B A
0 0 0 1

Edit: Actually im not sure about GREEN and BLUE. Its listed in some references and not in others.

GClements
03-29-2017, 04:51 PM
Red yes, but not solo green or blue.

I don't know your C# library definitions but the allowed color format for that function are:

RED, RG, RGB, BGR, RGBA (And some depth and stencil stuff)

Legacy OpenGL allows format to be GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_LUMINANCE or GL_LUMINANCE_ALPHA, as well as the RGB(A)/BGR(A) formats, and depth, stencil and colour-index formats. It doesn't support GL_RG or any (unnormalised) integer formats.

Omitted components are set to 0 for green or blue and 1 for alpha.

Manuli
03-30-2017, 08:24 AM
Dear All,
thank you for the prompt reply, I try to explain better my issue.
The first image is a cube, created with a 3D Texture, to load it to the GPU I'm using this code:


GL.TexImage3D<ushort>(TextureTarget.Texture3D, 0, PixelInternalFormat.Rgba16, _sizeX, _sizeY, _sizeZ, 0, PixelFormat.Alpha, PixelType.UnsignedShort, _texelsObj);


When I want to highlight a plane over the cube, I'm loading a SubTexture 3D using this function:


GL.BindTexture(TextureTarget.Texture3D, _textureID);
GL.TexSubImage3D<ushort>(TextureTarget.Texture3D, 0, 0, 0, planeAxialZ, _sizeX, _sizeY, 1, PixelFormat.Red/* or Blue or Green*/, PixelType.UnsignedShort, _planeTexelsAxial);


Here below the used Fragment Shader


void main()
{
vec4 coord = textureMatrix * vec4(fragTexCoord, 1.0);
vec4 col = (texture(tex, vec3(coord.xyz)));
float color = col.a * 65535.0f; // Mapping from 0 -> 1 to 0 -> UShort.MaxValue

if(col.r != 0.0f)
finalColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
else if(col.g != 0.0f)
finalColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
else if(col.b != 0.0f)
finalColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);
else
{

// Shader Color Manipulation
// from here the color values will be 0 -> 255
color = color / 255.0f; // Mapping from 0 -> 255 to 0 -> 1
finalColor = vec4(color, color, color, color); // Result color in Gray Scale
}
}




As you can see in the images it works pretty fine for the Red and Green Axis planes; the Blue Axis works completely in a different way and
mainly destroy the texture itselves.

Thanks in advanced

:dejection::sorrow::doh::confused: