正确使用GLTexImage3D时出现问题 [英] Problems using GLTexImage3D correctly

查看:141
本文介绍了正确使用GLTexImage3D时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这就是我将位图提供给OpenGL的方式. (C#)

This is how I give the Bitmaps to 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;
}

我找到了有关如何组织数据的描述

I found a description for how the data should be organized here, which I interpreted to mean the images should be arranged vertically, and possibly flipped or something.

因此,对于我的测试,我使用了2张图像,在片段着色器上,我像这样应用纹理:

So for my test I used 2 images, on the fragment shader I apply the texture like so:

void main()
{
    outputColor =  texture3D(ThreeDTexture,vec3(texcoord.x, 1.0 - texcoord.y, 0));
}

结果是两个图像以大致相等的比例合并.如果我将vec3.z参数设置为0.5,这就是我所期望的.所以我尝试了三个图像.它提供了所提供的第一张和最后一张图像的50-50组合(?!?!).这是它的行为,与我为vec3.z给出的值无关.

The result is the two images merged in roughly equal proportions. That's what I would expect if I made the vec3.z parameter 0.5. So I tried it with three images. It gives a 50-50 combination of the first and last images supplied (?!?!). This is it's behavior without regard to the value I give for vec3.z.

我希望该参数为所提供图像的Z轴.或者,如果我使用整数作为所提供图像数组的索引.

I expected that parameter to be the Z axis for the images supplied. Or if I used whole numbers for it to be an index for the array of images supplied.

编辑:它是索引,但与x,y坐标一样,投影在0到1的范围内.

It is the index, but projected on the range 0 through 1, like the x,y coordinates are.

我哪里出错了?

我给OpenGL的东西(按顺序):

What I'm giving to OpenGL (in order):

结果:

正如Rabbid76所述,解决方案是在调用GL.TexImage3D之后插入该代码:

As Rabbid76 explains, the solution was to insert this after the call to 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);

推荐答案

纹理环绕参数GL_TEXTURE_WRAP_SGL_TEXTURE_WRAP_TGL_TEXTURE_WRAP_R默认为GL_REPEAT.
缩小功能(GL_TEXTURE_MIN_FILTER)和放大功能(GL_TEXTURE_MAG_FILTER)的默认参数分别为GL_NEAREST_MIPMAP_LINEARGL_LINEAR. 参见
glTexParameter .

The texture wrap parameters GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T and GL_TEXTURE_WRAP_R are by default GL_REPEAT.
The default parameters for the minifying function (GL_TEXTURE_MIN_FILTER) and magnification function are (GL_TEXTURE_MAG_FILTER) are GL_NEAREST_MIPMAP_LINEAR respectively GL_LINEAR.
See glTexParameter.

"REPEAT"和"LINEAR"的组合会导致将第一个体素与行,列或深度层的最后一个体素混合(内插)(如果将纹理坐标参数传递给)查找功能是0.0.

The combination of "REPEAT" and "LINEAR" causes, that the first voxel is mixed (interpolated) with the last voxel of a row, column, or depth-layer, if the the texture coordinate parameters, which is passed to the lookup function, is 0.0.

如果使用wrap参数GL_CLAMP_TO_EDGE,则第一个和最后一个体素将不会混合,因为纹理坐标已被钳位.

If you would use the wrap parameter GL_CLAMP_TO_EDGE, then the first and the last voxel won't become mixed, because the texture coordinate is clamped.

请注意,第一个体素(或体素)的纹理坐标为1/(2*N),最后一个体素的坐标为1 - 1/(2*N),其中N是行,列或层中体素的数量.因此,坐标0.0正好位于第一个和最后一个体素的中间. GL_REPEAT会将坐标0.0钳位到1/(2*N).

Note the texture coordinate of the first voxel (or texel) is 1/(2*N) and the coordinate of the last voxel is 1 - 1/(2*N), where N is the number of voxels in a row, column or layer. Because of that the coordinate 0.0, is exactly in the middle of the first and the last voxel. GL_REPEAT would clamp the coordinate 0.0 to 1/(2*N).

这篇关于正确使用GLTexImage3D时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆