我发现本教程http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering关于体积渲染并尝试实现我自己的渲染器。我已经到了可以通过 alpha 测试一次绘制所有切片的地步,这给了我或多或少像教程中那样的结果。现在,我想向前迈出一步并应用 alpha 混合,但在那之后没有任何变化(即使有,它看起来也不像教程中的那么好)。
这是我的渲染代码:
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 当然是可以访问原始纹理数据的类。
我是否忘记在窗口中设置某些内容或者我的代码有问题?