Объемный рендеринг: Как я могу превратить файл.raw в opengl-дружественный isosurface?
Я хочу создать трехмерный визуализатор медицинских наборов данных.raw, используя марширующие тетраэдры.
Я нашел эту реализацию для лицензии GPL, которая выглядит красиво и основана на информации Пола Бурка, но я не знаю, как заставить работать файл.raw, который, как я обнаружил, люди загружают как 3d-текстуру.
//assuming that the data at hand is a 256x256x256 unsigned byte data
int XDIM=256, YDIM=256, ZDIM=256;
const int size = XDIM*YDIM*ZDIM;
bool LoadVolumeFromFile(const char* fileName) {
FILE *pFile = fopen(fileName,"rb");
if(NULL == pFile) {
return false;
}
GLubyte* pVolume=new GLubyte[size]; //<- here pVolume is a 1D byte array
fread(pVolume,sizeof(GLubyte),size,pFile);
fclose(pFile);
// now pVolume is passed to a 3d texture
//load data into a 3D texture
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_3D, textureID);
// set the texture parameters
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage3D(GL_TEXTURE_3D,0,GL_INTENSITY,XDIM,YDIM,ZDIM,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,pVolume);
delete [] pVolume;
return true;
}
Я не знаю, должен ли я: а) получить доступ к значениям непосредственно из pValue б) получить доступ к ним после загрузки их в 3D-текстуру
Я понятия не имею, как я должен индексировать pVolume, чтобы получить интенсивность изоповерхности в каждом x,y,z. если pVolume является одномерным массивом. Я знаю, что координаты x, y отображаются из одномерного массива с использованием деления и модуля, но как бы я отобразил x,y,z?
С другой стороны, если я загружу файл.raw как 3d-текстуру,
glTexCoord3f
дайте мне значение в данном x,y,z?
Пояснение: Вопрос не в том, "может ли OpenGL нарисовать изоповерхность непосредственно из этого?" вопрос заключается в том, как индексировать изоуровни по геометрии.raw, что необходимо для правильной оценки каждого тетраэдра. На изображении видно, что каждый случай тетраэдра отмечен в зависимости от того, находится ли изоповерхность над или под ней. Изоповерхность индексируется по координатам x, y, z в файле.raw, как я могу получить к ней доступ для каждого x, y, z в наборе данных? Даст ли мне glTexCoord3f свою интенсивность на данном x,y,z? Лучше сделать преобразование a x,y,z из массива pVolume напрямую?
2 ответа
Изоповерхность индексируется по координатам x,y,z в файле.raw, как я могу получить к ней доступ для каждого x,y,z в наборе данных?
Загружая изображение в виде трехмерного массива и индексируя его. Не загружая его как текстуру OpenGL.
Даст ли мне glTexCoord3f свою интенсивность на данном x,y,z?
Нет. Как говорится в документации, glTexCoord3f
просто предоставляет набор координат текстуры для следующей вершины, которая будет выдана. Он ничего не возвращает, пока ничего не происходит. Все, что он делает, это устанавливает состояние в OpenGL.
Лучше сделать преобразование a x,y,z из массива pVolume напрямую?
Да. Информация в OpenGL, как правило, должна перемещаться в одном направлении: от пользователя к экрану. Функции OpenGL существуют для того, чтобы вы могли передавать информацию OpenGL, которая будет использоваться для визуализации чего-либо. Вот как OpenGL работает лучше всего.
Любое обратное отслеживание (чтение изображений обратно в процессор и т. Д.) - это медленный путь.
Я думаю, что вы путаете несколько вещей здесь. OpenGL не является библиотекой обработки изображений. Это растеризатор API. 3D-текстуры не предназначены для загрузки данных и имеют произвольный доступ. Вы загружаете 3D-текстуры, чтобы отобразить их на поверхности, или используете их при прямом рендеринге объема.
Извлечение изоповерхностей выходит за рамки OpenGL.
RAW-файл означает, что заголовок отсутствует, и вы должны знать расположение данных, прежде чем что-то с ним делать. Ты должен знать
- ширина
- рост
- глубина
байтов на значение. Значения в x,y,z могут быть найдены по смещению данных.
(ширина * высота *z + ширина *y + z)*(байты)
Isovalue просто означает, что все пиксели набора данных равны заданному значению. Обычно вас интересуют пиксели, которые соседствуют с каждым пикселем ниже и выше его значения. Для эффективного определения сначала определяют градиент скалярного поля для каждого пикселя. Затем вы проверяете соседние пиксели вдоль градиента, если они находятся выше или ниже isoveue. Здесь не задействован OpenGL!