我不知道着色器,但我对他们的概念有基本的了解。
我需要实现深度剥离,所以我想知道我是否应该更深入到着色器世界,或者它可以在没有着色器的情况下实现,只需巧妙地使用glDepthFunc ..
答案 0 :(得分:1)
是的,如果你有GL_ARB_depth_texture& GL_ARB_shadow,虽然它很繁琐。
GL_ARB_occlusion_query也非常有用,因为它允许您决定何时停止剥离。如果你没有这个,那么你仍然可以做到这一点,但需要在你的循环中进行固定数量的迭代。太高,你浪费时间&内存太低,你可能会引入视觉瑕疵。
这个代码被我用来调试一些深度剥离算法的一些测试代码破解了。我已经删除了所有系统特定的东西,用pseudocode&做了一些重组,所以不要期望它编译。希望你能够得到这个想法。
对于使用此方法的顺序无关透明度,您可能会创建深度纹理列表,然后以相反的顺序遍历。
[代码] bool DrawNthSurface(size_t pass) { GLboolean cached_stencil_test_enabled; GLboolean cached_alpha_test_enabled; GLboolean cached_depth_test_enabled; GLboolean cached_face_cull_enabled;
glGetBooleanv(GL_STENCIL_TEST, &cached_stencil_test_enabled);
glGetBooleanv(GL_ALPHA_TEST, &cached_alpha_test_enabled);
glGetBooleanv(GL_DEPTH_TEST, &cached_depth_test_enabled);
glGetBooleanv(GL_CULL_FACE, &cached_face_cull_enabled);
if(HasShadow()) // Checks GL_ARB_shadow
{
return false;
}
else
{
GLuint depthTexture(0);
bool status(true);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// Draw geometry into the depth buffer. No textures, shaders etc.
//
// This could easily be folded into next part by restructuring into
// do...while()
status&= DrawSimpleGeometry();
if(status)
{
// for transparency etc. you would build a list of these inside the
// loop. For finding the nth surface we can recycle one.
glGenTextures(1, &depthTexture);
if(depthTexture)
{
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0,
GL_DEPTH_COMPONENT,
ctx->GetViewportWidth(),
ctx->GetViewportHeight(), 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
// Set up texture unit.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glEnable(GL_TEXTURE_2D);
// Set up texture coord generation. Should get bias from depth buffer
// precision.
SetupTexGen(-0.004);
// Set up shadow test.
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_COMPARE_FUNC_ARB,
GL_GREATER);
glTexParameteri(GL_TEXTURE_2D,
GL_DEPTH_TEXTURE_MODE_ARB,
GL_ALPHA);
glAlphaFunc(GL_GREATER, 0.5f);
glEnable(GL_ALPHA_TEST);
for(size_t n=0;(n<passes) && status;n++)
{
// Update depth texture.
glBindTexture(GL_TEXTURE_2D, depthTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
ctx->GetViewportWidth(),
ctx->GetViewportHeight());
glClear(GL_DEPTH_BUFFER_BIT);
status&= DrawSimpleGeometry();
}
// deactivate shadow test.
{
// Texgen
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
// Texture unit
glDisable(GL_TEXTURE_2D);
// Shadow comparison
glDisable(GL_ALPHA_TEST);
}
glDeleteTextures(1, &depthTexture);
}
else
{
status = false;
}
}
// Restore some of the rendering state.
if(cached_face_cull_enabled)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
else
{
glDisable(GL_CULL_FACE);
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
if(cached_face_cull_enabled)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
else
{
glDisable(GL_CULL_FACE);
}
if(!cached_stencil_test_enabled)
{
glDisable(GL_STENCIL_TEST);
}
else
{
glEnable(GL_STENCIL_TEST);
}
if(!cached_alpha_test_enabled)
{
glDisable(GL_ALPHA_TEST);
}
else
{
glEnable(GL_ALPHA_TEST);
}
if(!cached_depth_test_enabled)
{
glDisable(GL_DEPTH_TEST);
}
else
{
glEnable(GL_DEPTH_TEST);
}
// FINALLY: Draw everything.
if(status)
{
glDepthFunc(GL_EQUAL);
status&= DrawAllGeometry();
}
glDepthFunc(GL_LEQUAL);
return status;
}
}
[/代码]
恕我直言,最棘手的一点是正确设置texgen。代码非常简单。我已经包含了一个偏差参数来避免z战斗伪影。
[代码] Matrix CreateTextureMatrix(双偏) { 矩阵投影,cmay;
double tmp[16];
glGetDoublev(GL_PROJECTION_MATRIX, tmp);
projection = Matrix(tmp);
Matrix bias_matrix(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5 + bias, 1.0);
return (projection * bias_matrix);
}
void SetupTexGen(double bias)
{
Matrix texmat;
Matrix mv, imv;
{
double tmp[16];
glGetDoublev(GL_MODELVIEW_MATRIX, tmp);
mv = Matrix(tmp);
imv = mv.GetInverse();
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_S, GL_EYE_PLANE, imv.Row(0));
glEnable(GL_TEXTURE_GEN_S);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_T, GL_EYE_PLANE, imv.Row(1));
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_R, GL_EYE_PLANE, imv.Row(2));
glEnable(GL_TEXTURE_GEN_R);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_Q, GL_EYE_PLANE, imv.Row(3));
glEnable(GL_TEXTURE_GEN_Q);
texmat = CreateTextureMatrix(bias);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMultMatrixd(texmat);
glMatrixMode(GL_MODELVIEW);
}
[/代码]
HTH。