【问题标题】:OpenGL: Turning on and off LightsOpenGL:打开和关闭灯光
【发布时间】:2015-11-05 20:13:07
【问题描述】:

我正在编写一个程序,其中有一个“polyman”小家伙在0,-3 跳舞。我已经把他染成白色,现在正试图让一个迪斯科般的场景开始,我创造了一个蓝色和红色的灯光,并试图通过使用计数器和ifelse 语句来交替它们。这都是我的renderscene

float ambientlight[] = {0.0,0.0,1.0,1.0};
float diffuselight[] = {1.0,1.0,1.0,1.0};
float specular[] = {1.0,1.0,1.0,1.0};
float lightpos[] = {0.0,10.0,0.0,1.0};  //light 1
float specref[]={1.0,1.0,1.0,1.0};
float spotdir[]={0.0,-10.0,0.0};

float rectX[6][5], rectY[6][5], rectZ[6][5];

float ambientlight2[] = {1.0,0.0,0.0,1.0};
float diffuselight2[] = {1.0,1.0,1.0,1.0};
float specular2[] = {1.0,1.0,1.0,1.0};
float lightpos2[] = {0.0,10.0,0.0,1.0}; //light 2
float specref2[]={1.0,1.0,1.0,1.0};
float spotdir2[]={0.0,-10.0,0.0};


glColor3f(1.0,1.0,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,540,440);
glOrtho(-7.0,7.0,-7.0,7.0,5.0,-5.0);

glEnable(GL_LIGHTING);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (counterForLights % 2 == 0)   //if counter even
{
    glLightfv(GL_LIGHT0, GL_POSITION,lightpos);
    glLightfv(GL_LIGHT0,GL_AMBIENT,ambientlight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuselight);
    glLightfv(GL_LIGHT0,GL_SPECULAR, specular);
    glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,10.0);  //light 1
    glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,15.0);
    glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spotdir);
    glEnable(GL_LIGHT0);
    counterForLights++;
}
else  //if counter odd
    {

        glLightfv(GL_LIGHT1,GL_AMBIENT,ambientlight2);
        glLightfv(GL_LIGHT1,GL_DIFFUSE,diffuselight2);
        glLightfv(GL_LIGHT1,GL_SPECULAR, specular2);
        glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,10.0);
        glLightf(GL_LIGHT1,GL_SPOT_EXPONENT,15.0);  //light2
        glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,spotdir2);
        glEnable(GL_LIGHT1);
        counterForLights++;
    }

counterForLights 是一个全局变量,等于1。它运行,但从不显示红灯,只显示蓝光。关于我在哪里出错的任何想法?

另外,如果您需要查看我的代码,请告诉我! :)

【问题讨论】:

  • 据我所知,第二盏灯唯一的“红色”是环境光部分。由于在典型材料中,环境系数非常低,因此它的影响很小。

标签: c++ opengl if-statement counter light


【解决方案1】:
else  //if counter odd
{

    glLightfv(GL_LIGHT1,GL_AMBIENT,ambientlight2);
    glLightfv(GL_LIGHT1,GL_DIFFUSE,diffuselight2);
    glLightfv(GL_LIGHT1,GL_SPECULAR, specular2);
    glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,10.0);
    glLightf(GL_LIGHT1,GL_SPOT_EXPONENT,15.0);  //light2
    glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,spotdir2);
    glEnable(GL_LIGHT1);
    counterForLights++;
}

您似乎没有为 LIGHT1 指定位置。

另外,我将/强烈/建议不要使用 Fixed-Function-Pipeline 在 OpenGL 中进行绘图。 There's lots of tutorials online for transitioning to modern OpenGL.

【讨论】:

  • 我希望灯光来自同一个位置
  • 太棒了。您仍然需要明确定义 LIGHT1 的位置。您只为 LIGHT0 定义了它。
  • 哦,我明白你现在在说什么了
【解决方案2】:

您正在启用灯光 0,然后启用灯光 1,然后再也不禁用任何一个。所以从第二帧开始,光照应该是恒定的。坚持和更新光 0 可能更聪明,或者加载一次系数,然后在任一条件分支中执行启用和禁用。

【讨论】:

  • Awww 我现在看到了,所以理论上我可以使用与计数器相同的原理,但只有Light0 然后使用if counter is even, glLightfv(GL_LIGHT0,GL_AMBIENT,ambientlight) 然后else 将是glLightfv(GL_LIGHT0,GL_AMBIENT,ambientlight2); ?
  • 是的——OpenGL有很多全局状态;如果您启用了灯,那么它会一直保持启用状态,直到您另有说明。但这只是一个编号的插槽。因此,如果更方便,您可以更新该插槽中的信息,而不是在不同的插槽中有不同的数据并在它们之间切换。 OpenGL 中的一条经验法则是,调用越少,代码就越快,但老实说,如果您仍然使用固定管道,那么我认为它不会产生太大的可能性。这充其量只是过早的优化。
猜你喜欢
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多