OpenGL首先使用光和法线

时间:2016-03-25 10:22:58

标签: java opengl lwjgl light normals

我正在玩一些基本的OpenGL东西,我试图设置一个启用了照明的简单方块,但是光线不正确所以我的法线有些不对劲。

或者我对法医的理解完全错了?

enter image description here

这是我的渲染代码(顺便说一句,我使用lwjgl): 公共类渲染器{

DisplayMode displayMode;
int i;
int width;
int height;
private boolean drawAxes = false;
private float rotation = 40.0f;
private float zoom = -20f;

// ----------- Variables added for Lighting Test -----------//
private FloatBuffer matSpecular;
private FloatBuffer lightPosition;
private FloatBuffer whiteLight;
private FloatBuffer lModelAmbient;

public Renderer(int width, int height) {
    this.width = width;
    this.height = height;
}

public static Renderer start() throws LWJGLException {
    Renderer r = new Renderer(800, 600);
    r.initContext();
    r.run();
    return r;
}

private void initContext() throws LWJGLException {
    Display.setFullscreen(false);
    DisplayMode d[] = Display.getAvailableDisplayModes();
    for (int i = 0; i < d.length; i++) {
        if (d[i].getWidth() == width && d[i].getHeight() == height && d[i].getBitsPerPixel() == 32) {
            displayMode = d[i];
            break;
        }
    }
    Display.setDisplayMode(displayMode);
    Display.create();
}

private void run() {
    initGL();
    while (!Display.isCloseRequested()) {
        preRender();
        render();
        Display.update();
        Display.sync(60);
    }
    Display.destroy();
}

private void initGL() {

    GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
    GL11.glClearDepth(1.0); // Depth Buffer Setup
    GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
    GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do

    GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
    GL11.glLoadIdentity(); // Reset The Projection Matrix

    // Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(45.0f, (float) displayMode.getWidth() / (float) displayMode.getHeight(), 0.1f, 100.0f);
    GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix

    // Really Nice Perspective Calculations
    GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

    GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);

    initLightArrays();
    glShadeModel(GL_SMOOTH);
    glMaterial(GL_FRONT, GL_SPECULAR, matSpecular); // sets specular material color
    glMaterialf(GL_FRONT, GL_SHININESS, 100.0f); // sets shininess

    glLight(GL_LIGHT0, GL_POSITION, lightPosition); // sets light position
    glLight(GL_LIGHT0, GL_SPECULAR, whiteLight); // sets specular light to white
    glLight(GL_LIGHT0, GL_DIFFUSE, whiteLight); // sets diffuse light to white
    glLightModel(GL_LIGHT_MODEL_AMBIENT, lModelAmbient); // global ambient light

    glEnable(GL_LIGHTING); // enables lighting
    glEnable(GL_LIGHT0); // enables light0

    glEnable(GL_COLOR_MATERIAL); // enables opengl to use glColor3f to define material color
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // tell opengl glColor3f effects the ambient and diffuse properties of material

}

private void preRender() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    GL11.glTranslatef(0f, 0f, zoom);
    GL11.glRotatef(-60f, 1f, 0f, 0f);
    GL11.glRotatef(rotation, 0f, 0f, 1f);
}

private void render() {

    FloatBuffer cBuffer = BufferUtils.createFloatBuffer(6*3);
    float[] cArray = {  1f,1f,1f,
                        1f,1f,1f,
                        1f,1f,1f,
                        1f,1f,1f,
                        1f,1f,1f,
                        1f,1f,1f};
    cBuffer.put(cArray);
    cBuffer.flip();

    FloatBuffer vBuffer = BufferUtils.createFloatBuffer(6*3);
    float[] vArray = {  1f,1f,0f,
                        -1f,-1f,0,
                        1f,-1f,0,
                        1f,1f,0f,
                        -1f,1f,0,
                        -1f,-1f,0};
    vBuffer.put(vArray);
    vBuffer.flip();

    FloatBuffer nBuffer = BufferUtils.createFloatBuffer(6*3);
    float[] nArray = {  0f,0f,1f,
                        0f,0f,1f,
                        0f,0f,1f,
                        0f,0f,1f,
                        0f,0f,1f,
                        0f,0f,1f};
    nBuffer.put(nArray);
    nBuffer.flip();

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glColorPointer(3, 0, cBuffer);
    glVertexPointer(3, 0, vBuffer);
    glNormalPointer(3, nBuffer);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);

    if (drawAxes) {
        drawAxes(6);
    }

    glTranslatef(0.0f, 0.0f, 3);
    glColor3f(0.1f, 0.4f, 0.9f);
}

public static void main(String[] args) throws LWJGLException {
    System.setProperty("org.lwjgl.opengl.Display.allowSoftwareOpenGL", "true");
    Renderer.start();
}

2 个答案:

答案 0 :(得分:1)

您将正常指针设置错误:

glColorPointer(3, 0, cBuffer);
glVertexPointer(3, 0, vBuffer);
glNormalPointer(3, nBuffer);

固定函数GL可能总是期望法线为三维向量,而size参数(告诉GL每个向量中有多少个值)不是{出现在glNormalPointer。您在此处设置的3stride参数,它指定连续数组元素之间的字节偏移量。现在3没有任何意义,它会将第二个法线解释为开始3个字节进入arry,这意味着它将第一个普通&s; sx组件的最后一个字节与第一个普通&#39;中的3个字节组合在一起。 sy组件读取第二个普通的&xs组件时,依此类推...

由于您的数组紧凑,您可以在此处使用快捷方式0,就像使用其他指针一样。

但是,您必须意识到所有这些都是已弃用,因为在OpenGL中差不多十年,现代核心版本的OpenGL 根本不支持固定功能管道 。如果您现在正在学习OpenGL,我强烈建议您学习基于着色器的现代GL。

答案 1 :(得分:0)

如果没有看到更多的代码,很难确切地看出错误是什么。

但是,我确实看到一件可能有问题的事情:

FloatBuffer vBuffer = BufferUtils.createFloatBuffer(6*3);
float[] vArray = {  1f,1f,0f,
                    1f,-1f,0,
                    -1f,-1f,0,
                    1f,1f,0f,
                    -1f,1f,0,
                    -1f,-1f,0};
vBuffer.put(vArray);
vBuffer.flip();

三角形的上弦顺序不一样。第一个三角形顺时针旋转,而第二个三角形逆时针旋转。您需要对顶点重新排序,以确保它们朝同一方向旋转。 OpenGL通常喜欢逆时针旋转的东西,所以如果我是你,我会翻转第一个三角形。

如果您在完成此操作后仍然遇到问题,请发布剩余的绘图代码,因为您在此处显示的内容并未提供大量信息