这就是我将位图提供给OpenGL的方式。 (C#)
public static int Generate3DTexture( string[] names ) // file paths
{
//basically merging the images into one vertical column of images
MagickImageCollection allimages = new MagickImageCollection();
foreach (string eachname in names)
allimages.Add(new MagickImage(eachname));
MagickImage template = new MagickImage(MagickColor.FromRgba(0, 0, 0, 0), MasterSize.Width, MasterSize.Height * names.Length);
Point drawpnt = new Point(0, 0);
foreach (MagickImage each in allimages)
{
template.Composite(each, drawpnt.X, drawpnt.Y, CompositeOperator.Overlay);
drawpnt.Y += each.Height;
}
Bitmap merged = template.ToBitmap();
//saving the bitmap here is confirmed to stack them vertically
BitmapData thedata = merged.LockBits(new Rectangle(new Point(0, 0), merged.Size), ImageLockMode.ReadOnly, WfPixelFormat.Format32bppArgb);
int texId = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture3D, texId);
GL.TexImage3D(TextureTarget.Texture3D, 0, PixelInternalFormat.Rgba, MasterSize.Width, MasterSize.Height, names.Length, 0, GlPixelFormat.Bgra, PixelType.UnsignedByte, thedata.Scan0);
GL.GenerateMipmap(GenerateMipmapTarget.Texture3D);
GL.BindTexture(TextureTarget.Texture3D, 0);
merged.UnlockBits(thedata);
return texId;
}
我找到了关于如何组织数据here的描述,我将其解释为意味着图像应垂直排列,并且可能会翻转或其他东西。
因此,对于我的测试,我使用了2张图像,在片段着色器上,我像这样应用纹理:
void main()
{
outputColor = texture3D(ThreeDTexture,vec3(texcoord.x, 1.0 - texcoord.y, 0));
}
结果是两个图像以大致相等的比例合并。如果我做了vec3.z
参数0.5
,那就是我所期望的。所以我尝试了三个图像。它提供所提供的第一张和最后一张图像的50-50组合(?!?!)。这是它的行为,而不考虑我为vec3.z
赋予的价值。
我希望该参数为所提供图像的Z轴。或者,如果我使用整数作为所提供图像数组的索引。
编辑:它是索引,但与x,y坐标一样,投影在0到1的范围内。
我哪里出错了?
我给OpenGL的东西(按顺序):
结果:
编辑:如Rabbid76所述,解决方案是将其插入到对GL.TexImage3D
的调用之后:
GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapR, (int)TextureParameterName.ClampToEdge);
答案 0 :(得分:2)
纹理环绕参数GL_TEXTURE_WRAP_S
,GL_TEXTURE_WRAP_T
和GL_TEXTURE_WRAP_R
默认为GL_REPEAT
。
缩小功能(GL_TEXTURE_MIN_FILTER
)和放大功能(GL_TEXTURE_MAG_FILTER
)的默认参数分别为GL_NEAREST_MIPMAP_LINEAR
GL_LINEAR
。
参见glTexParameter
。
“ REPEAT”和“ LINEAR”的组合会导致将第一个体素与行,列或深度层的最后一个体素混合(内插)(如果将纹理坐标参数传递给查找功能是0.0。
如果要使用wrap参数GL_CLAMP_TO_EDGE
,则第一个和最后一个体素将不会混合,因为纹理坐标已被钳位。
请注意,第一个体素(或体素)的纹理坐标为1/(2*N)
,最后一个体素的坐标为1 - 1/(2*N)
,其中N
是一行中的体素数,列或图层。因此,坐标0.0正好位于第一个和最后一个体素的中间。 GL_REPEAT
会将坐标0.0钳位到1/(2*N)
。