OpenGL雾不会出现

问题描述 投票:0回答:2

我已经用Google搜索了解决方案,但一无所获。我想创建一个包含一些线的坐标系,并希望显示一个带有深度雾的窗口。

我的“雾代码”看起来像这样:

glEnable(GL_FOG);
float fogColor[4] = {0.8, 0.8, 0.8, 1};
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, fogColor); 
glFogf(GL_FOG_DENSITY,0.8); 
glHint(GL_FOG_HINT, GL_NICEST);
glFogf(GL_FOG_START,0.1); 
glFogf(GL_FOG_END,200);

并且放在我的主要函数中(尚不知道这是否会引起任何问题,但只是要确定),就在init()调用之后和我的display-function-call之前。

更新:这个问题实际上非常简单:我的问题是,我只从事GL_MODELVIEW矩阵的工作,认为与GL_PROJECTION矩阵没有真正的区别。根据this article和Reto Koradi的帖子,有很大的不同。我强烈建议阅读全文,以更好地了解OpenGL背后的系统(肯定对我有很大帮助)。

然后(对于我的init()调用,正确的代码将是:

void init2() {
glClearColor (1.0, 1.0, 1.0, 0.0); // set background color to white
glMatrixMode(GL_PROJECTION); // switch to projection mode
glLoadIdentity(); // initialize a projection matrix
glOrtho(-300, 300, -300, 300, -800, 800); // map coordinates to the viewport 
gluLookAt(2,2,10, 0,0,-0.5, 0,1,0);
glMatrixMode(GL_MODELVIEW); // now switch to modelview mode
}
c++ opengl graphics glut
2个回答
2
投票

基于((来自OpenGL 2.1规范的引号)的值评估雾方程:

否则,如果雾源是FRAGMENT DEPTH,则c是从眼睛坐标(0,0,0,1)到眼睛片段中心的眼睛坐标距离。

FRAGMENT_DEPTH是默认设置,因此适用于您的情况。眼睛坐标是指应用了模型视图变换后的坐标。因此,它是应用模型视图变换后到原点的距离。该规范还允许实现使用z坐标的绝对值而不是距原点的距离。

对您的代码的一个小发现:如果模式为GL_FOG_DENSITY,则GL_LINEAR无关紧要。它仅用于指数模式。

对于GL_LINEAR模式,其行为与您预期的差不多。在GL_FOG_STARTGL_FOG_END的范围内,原始片段颜色与雾色线性混合。因此,小于GL_FOG_START的所有内容均具有原始片段颜色,GL_FOG_END之后的所有内容均具有雾色,并且介于两者之间的值是二者之间的线性插值,雾色逐渐增加,原始片段颜色则减少。

为了获得良好的结果,您必须使用GL_FOG_STARTGL_FOG_END值。如果您没有得到满意的结果,则可以从减小GL_FOG_END的值开始。

我偷看了链接的代码,发现一个问题:在GL_MODELVIEW矩阵模式下,您正在指定投影矩阵。您需要注意以正确的矩阵模式指定矩阵,投影模式为GL_PROJECTION

混合矩阵模式不会对最终的顶点坐标产生不利影响,因为模型视图矩阵和投影矩阵都应用于顶点。因此,对于非常简单的使用而言,有时您可以避免使用错误的模式。但是一旦照明开始发挥作用,就必须使用正确的矩阵模式,因为照明计算是在应用模型视图变换之后但在投影变换之前完成的。

是的,正如其他人已经指出的那样,如果您编写自己的着色器,实际上很多方法会变得更简单。我引用了OpenGL 2.1规范这一事实可能暗示此功能已过时且过时。


1
投票

与OpenGL-1.1所做的许多事情一样,雾是在每个顶点级别上计算的。因此,如果您有一条只有两个点的长线,则仅针对端点计算雾度,然后在其间插值颜色。根据线条的对齐方式和使用的阴影模式,可能不会导致明显的雾化。

两种解决方案:

  • 将线细分为几十个线段,以便在两个以上的点上对雾进行采样。

  • 改为使用片段着色器,并在其中计算雾化项。我建议这样做。
© www.soinside.com 2019 - 2024. All rights reserved.