JOGL在球体中校正光线和反射

时间:2013-11-27 23:06:56

标签: java windows opengl graphics jogl

我正试图让我的程序中的灯光和反射正确。我有一个大球体,我可以移动鼠标,它应该是一个光源(LIGHT0),并且较小的球体会反射光线。我还需要一个方向灯,我可以用键盘改变方向

我定义了一些颜色:

float whitish[] = {0.8f, 0.8f, 0.8f, 1};
float white[] = {1, 1, 1, 1};
float blackish[] = {0.2f, 0.2f, 0.2f, 1};
float black[] = {0, 0, 0, 1}

我用

创建定向灯
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, blackish,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, white,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, white,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, spot_position,0); 

spot_position最初是[0,0,1,0],但可以通过按键盘键来改变。按键将0.05添加到位置矢量的特定组件,直到达到1,然后重置为-1(没什么特别的)。

中心球的光是:

gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, position,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, blackish,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, white,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, white,0);

此灯的位置始终位于我的大透明球体内。位置向量的w分量为1。

我有这个代码在后面绘制图片

gl.glBegin(GL_QUADS);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, white,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, white,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, white,0);
// Back Face
gl.glNormal3f(0, 0, 1);
gl.glTexCoord2f(texRight, texBottom);
gl.glVertex3f(rx2, ry1, rz1);
gl.glTexCoord2f(texRight, texTop);
gl.glVertex3f(rx2, ry2, rz1);
gl.glTexCoord2f(texLeft, texTop);
gl.glVertex3f(rx1, ry2, rz1);
gl.glTexCoord2f(texLeft, texBottom);
gl.glVertex3f(rx1, ry1, rz1);

要绘制球体,我使用以下功能:

public void drawtriangle(float[] v1, float[] v2, float[] v3) {
    gl.glBegin(GL.GL_TRIANGLES);
    gl.glNormal3fv(v1, 0);
    gl.glVertex3fv(v1, 0);
    gl.glNormal3fv(v2, 0);
    gl.glVertex3fv(v2, 0);
    gl.glNormal3fv(v3, 0);
    gl.glVertex3fv(v3, 0);
    gl.glEnd();
}

private void subdivideSphere2(float v1[], float v2[], float v3[], long depth) {
   float v12[] = new float[3];
   float v23[] = new float[3];
   float v31[] = new float[3];
    int i;

    if (depth==0) {
    float[] color= {v1[0]*v1[0], v2[1]*v2[1], v3[2]*v3[2], alpha};
    gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, blackish,0);
    gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, color,0);
    gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, color,0);
    gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, color,0);
      drawtriangle(v1, v2, v3);
      return;
    }
   for (i = 0; i<3; i++) {
       v12[i] = v1[i]+v2[i];
       v23[i] = v2[i]+v3[i];
       v31[i] = v3[i]+v1[i];
    }
    normalize(v12);
    normalize(v23);
    normalize(v31);
    subdivideSphere2(v1, v12, v31, depth-1);
    subdivideSphere2(v2, v23, v12, depth-1);
    subdivideSphere2(v3, v31, v23, depth-1);
    subdivideSphere2(v12, v23, v31, depth-1);
}


public void drawSphere() {
    subdivideSphere2(sVdata[0], sVdata[1], sVdata[2], depth);
    subdivideSphere2(sVdata[0], sVdata[2], sVdata[4], depth);
    subdivideSphere2(sVdata[0], sVdata[4], sVdata[5], depth);
    subdivideSphere2(sVdata[0], sVdata[5], sVdata[1], depth);

    subdivideSphere2(sVdata[3], sVdata[1], sVdata[5], depth);
    subdivideSphere2(sVdata[3], sVdata[5], sVdata[4], depth);
    subdivideSphere2(sVdata[3], sVdata[4], sVdata[2], depth);
    subdivideSphere2(sVdata[3], sVdata[2], sVdata[1], depth);
 }  

我的问题是,小球根本没有反射光。它们一直非常明亮。当我将大球体移近它们时,我可以看到一点点光线反射在立方体的绿线上,但对球体没有任何影响。此外,当我移动定向灯(LIGHT1)时,我看不出任何差异。我没有看到立方体线条,大球体,小球体或背面图片的任何反射。下面是我的程序的截图。如何让我的球体不发光,反射定向光和大球体的光?任何帮助将不胜感激。谢谢。

My program

3 个答案:

答案 0 :(得分:1)

在追踪你的小球体时,看起来闪电被禁用了。我没有看到你调用drawSphere的代码,但它看起来好像你正在跟踪启用了GL_LIGHTING的Big球体以​​及禁用了GL_LIGHTING的小球体。

答案 1 :(得分:0)

通过反射光线,你的意思是它被照亮了吗?反射涉及光线追踪,是一个更大的主题。

我没有JOGL的直接经验,但是我已经使用了相当数量的jME3,这种问题通常是由于使用了一种不亮的材料(这里似乎不是这种情况)由于物体上的法线不正确,或者仅仅是环境光和/或材料的环境颜色过高而被点亮了。

答案 2 :(得分:0)

据我所知,你没有正确设置法线。法线应该基本上指向你想要反射光的方向,这通常是距离三角形“90°”(使用十字产品)。然后,OpenGL将使用该法线计算表面反射的实际光照。有关详细说明,请参阅this tutorial

另一个问题是你使用过时的OpenGL 2.0功能,它执行基于顶点的光照,因此有效地将球体中的每个三角形减轻到相同的值。如果您正在寻找使用过时功能几乎不可能的逐像素照明,除非球体的顶点与屏幕上的像素一样多,您需要更新代码并使用着色器。

This tutorial不是Java,但它很好地解释了现代OpenGL的基础知识,并且应该可以轻松地转换为JOGL。