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

Продолжение этого вопроса, который я задал. В этом вопросе я показываю, как я даю 3 текстуры для opengl и отрисовываю одну из них. Я пытаюсь отредактировать одну из этих текстур, не заменяя их все, используя этот код:

public void Replace( string name, int index)
{
    Bitmap bmp = new Bitmap(name); //assumed to be MasterSize
    BitmapData thedata = bmp.LockBits(new Rectangle(new Point(0, 0), MasterSize), ImageLockMode.ReadOnly, WfPixelFormat.Format32bppArgb);
    GL.BindTexture(TextureTarget.Texture3D, Id);
    GL.TexSubImage3D(TextureTarget.Texture3D, 0, 0, 0, 0, MasterSize.Width, MasterSize.Height, index, GlPixelFormat.Bgra, PixelType.UnsignedByte, thedata.Scan0);
    GL.BindTexture(TextureTarget.Texture3D, 0);
    bmp.UnlockBits(thedata);
}

MasterSize - это то же Size, что и в предыдущем вопросе, а Id - int texId из предыдущего вопроса.

Когда я рендеринг 0-й текстуры в шейдере (как показано ранее) и Replace index = 0 ничего не меняется. Однако когда я Replace с index = 1 и рендеринг 0-го, он делает то, что ожидал index = 0.

Несмотря на 3 текстуры, я получаю ошибку повреждения памяти, когда index = 2 (но не для абсурдных значений, таких как -4 и 12).

System.AccessViolationException: 'Попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена. '

Я могу получить доступ ко всем 3 текстурам, используя 0, 0.5 и 1 для Z текстуры в шейдере, так что я знаю, что они там.

Восьмой параметр TexSubImage3D является целым числом, поэтому он не ожидает диапазон с плавающей запятой от 0 до 1.

Что я делаю не так?

1 Ответ

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

Во-первых, у вас нет 3 текстур.У вас есть одна текстура , которая представляет собой трехмерную текстуру определенного размера.

glTexSubImage3D загружает трехмерный прямоугольный объем данных пикселей в текстуру.Функции SubImage могут перезаписывать произвольные части текстуры данными пикселей, поэтому она имеет два набора координат.Ему дается смещение в текстуре, с которого начинается запись, и размер тома для записи.

Так как это трехмерный прямоугольный том, смещение и размер предоставляются 3 параметрами: смещение XYZв объем 3D, а также ширину / высоту / глубину объема для перезаписи.Обратите внимание, что размеры - это размеры входного объема, а не абсолютные позиции в 3D-изображении.

Вы пытаетесь обработать 3D-текстуру, как если бы это было несколько 2D-срезов 1 .Ну, 2D-изображение на самом деле просто 3D-изображение с глубиной один.Это то, что вы пытаетесь загрузить.

Итак ... скажем, что .Поскольку глубина 3D-изображения, которое вы предоставляете, равна 1, это должен быть параметр depth.Смещение Z указывает, какое изображение Z вы хотите перезаписать.

Ваш вызов функции должен быть:

GL.TexSubImage3D(TextureTarget.Texture3D, 0, 0, 0, index, MasterSize.Width, MasterSize.Height, 1, GlPixelFormat.Bgra, PixelType.UnsignedByte, thedata.Scan0);

1 : OpenGL уже имеет способ сделать это: 2D массив текстур .Это имеет двойное преимущество: никогда не смешивать слои массива и использовать целочисленные индексы слоев вместо текстурных координат для слоев.Но это не меняет ничего о вашей проблеме здесь, так как он также использует функции 3D для доступа к хранилищу текстуры.

...