Проблемы с использованием GLTexImage3D правильно - PullRequest
0 голосов
/ 14 сентября 2018

Так я передаю растровые изображения 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;
}

Я нашел описание того, как должны быть организованы данные здесь , которое я интерпретировал как означающее, что изображения должны располагаться вертикально и, возможно, отражаться или что-то в этом роде.

Итак, для своего теста я использовал 2 изображения, на фрагментный шейдер я наложил текстуру следующим образом:

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

В результате два изображения слились примерно в равных пропорциях.Это то, что я ожидал бы, если бы я сделал vec3.z параметр 0.5.Итак, я попробовал это с тремя изображениями.Это дает 50-50 комбинаций первого и последнего изображения (?!?!).Это его поведение без учета значения, которое я даю для vec3.z.

Я ожидал, что этот параметр будет осью Z для поставляемых изображений.Или, если бы я использовал целые числа, чтобы он был индексом для поставляемого массива изображений.

РЕДАКТИРОВАТЬ: Это индекс, но проецируется в диапазоне от 0 до 1, как х, координаты y:

Где я ошибся?

Что я даю OpenGL (по порядку):

What I'm giving to OpenGL

Результат:

The result.

РЕДАКТИРОВАТЬ: Как объясняет 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);

1 Ответ

0 голосов
/ 14 сентября 2018

Параметры обтекания текстур 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.

Если вы используете параметр обтекания GL_CLAMP_TO_EDGE, то первый и последний воксель не будут смешиваться, потому что координата текстуры зажата.

Обратите внимание, что координата текстуры первого вокселя (или текселя) равна 1/(2*N), а координата последнего вокселя - 1 - 1/(2*N), где N - количество вокселей в строке, столбце или слое. Из-за этого координата 0.0 находится точно в середине первого и последнего вокселя. GL_REPEAT будет ограничивать координату от 0,0 до 1/(2*N).

...