Объем рендеринга альфа-смешения

Я нашел этот урок http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering о Volume Rendering и попытался реализовать собственный рендер. Я дошел до того, что я могу нарисовать все фрагменты одновременно с помощью альфа-тестирования, что дает мне более или менее такой результат, как в учебнике. Теперь я хочу сделать шаг вперед и применить альфа-смешение, но после этого нет никаких изменений (и даже если они есть, это не выглядит так хорошо, как в учебнике).

Вот мой код рендеринга:

glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);

for (int i = 0; i < z; ++i)
{
glBindTexture(GL_TEXTURE_2D, texturesObjects[i]);

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, 2 * i / z - 1);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, 2 * i / z - 1);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, 2 * i / z - 1);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, 2 * i / z - 1);

glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}

glutSwapBuffers();

где z — количество срезов. Код генерации текстуры выглядит так:

GLuint* loadXZslices(const VR::DataAccessor& accessor, int& x, int& y, int& z)
{
x = accessor.getX();
y = accessor.getY();
z = accessor.getZ();

GLuint* texturesObjects = new GLuint[accessor.getZ()];

for (size_t i = 0; i < accessor.getZ(); ++i)
{
char* luminanceBuffer = accessor.getXYslice(i);
char* rgbaBuffer = new char[accessor.getX() * accessor.getY() * 4];

for (size_t j = 0; j < accessor.getX() * accessor.getY(); ++j)
{
rgbaBuffer[j * 4] = luminanceBuffer[j];
rgbaBuffer[j * 4 + 1] = luminanceBuffer[j];
rgbaBuffer[j * 4 + 2] = luminanceBuffer[j];
rgbaBuffer[j * 4 + 3] = 255;

if (luminanceBuffer[j] < 20)
{
rgbaBuffer[j * 4 + 3] = 0;
}
}

glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texturesObjects[i]);
glBindTexture(GL_TEXTURE_2D, texturesObjects[i]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, accessor.getX(), accessor.getY(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)rgbaBuffer);

delete[] luminanceBuffer;
delete[] rgbaBuffer;
}

return texturesObjects;
}

DataAccessor — это, конечно, класс, который предоставляет доступ к необработанным текстурным данным.

Я забыл о настройке чего-либо в моем окне или что-то не так с моим кодом?

0

Решение

Пара вещей выглядит сомнительно в вашем коде:

  1. Вы не настраиваете свои текстуры, чтобы иметь частичную прозрачность. Там, где вы строите свои текстуры, вы устанавливаете альфа-компонент либо на 255, либо на 0, если исходная яркость меньше 20. Чтобы получить фактические смешанные значения, вам нужно будет использовать значение яркости для альфа-компонента:

    rgbaBuffer[j * 4 + 3] = luminanceBuffer[j];
    

    Чтобы точно настроить результаты, вам, возможно, придется использовать какое-то другое отображение от исходной интенсивности до альфа. Но это, вероятно, все еще будет какая-то рампа, а не пошаговая функция.

  2. Пока код не показывает объявление для zэтот код выглядит подозрительно:

    glVertex3f(-1.0, -1.0, 2 * i / z - 1);
    

    Из контекста это выглядит так z это, вероятно, целое число. Если это правда, это будет целочисленное деление, которое будет производить 0 в то время как 2 * i меньше чем zи 1 для оставшихся значений цикла. По крайней мере одно из значений должно быть приведено к числу с плавающей точкой, чтобы сделать его делением с плавающей точкой.

0

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector