2016-03-25 23 views
0

Ich spiele mit einigen grundlegenden OpenGL Zeug und ich versuche, ein einfaches Quadrat mit Beleuchtung aktiviert, aber die Beleuchtung ist nicht richtig, so ist etwas falsch mit meiner Normalen i vermuten.OpenGL erste Schritte mit Licht und Normalen

Oder ist mein Verständnis von Normalen total falsch?

enter image description here

Hier ist meine Rendering-Code (btw lwjgl Ich verwende): public class Renderer {

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(); 
} 
+0

Das ist veraltet, folgen [dieses Tutorial] (https://bitbucket.org/alfonse/gltut/wiki/Home), es ist wirklich hervorragend zu erklären alles, ich habe einen Port in Jogl [hier] (https: // github .com/elect86/modern-jogl-examples), sollte es einfach sein, es in lwjgl zu übersetzen – elect

+0

Ok, danke für die Antwort. Aber selbst wenn es veraltet ist, sollte es nicht richtig funktionieren? – dagon

+0

Es gibt viel mehr Code als der, den Sie gezeigt haben, der falsch sein kann – elect

Antwort

1

Sie Ihren normalen Zeiger falsche Einstellung:

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

Die Fest Funktion GL könnte immer Normalen erwartet 3-dimensionale Vektoren zu sein, Henze den size Parameter (die die GL sagt, wie viele Werte gibt es in Alle Vektor) ist nicht in glNormalPointer. Die 3, die Sie hier einstellen, ist der stride Parameter, der den Byte-Versatz zwischen aufeinanderfolgenden Array-Elementen angibt. Nun macht 3 keinen Sinn, es interpretiert die zweite Normale als zu Beginn 3 Bytes in die arry, was bedeutet, dass es das letzte Byte der ersten X-Komponente der ersten Norm zusammen mit 3 Bytes von der Y-Komponente der ersten Normalen kombiniert, wenn es das liest zweite normal'x s Komponente, und so weiter ...

Da Ihr Array dicht gepackt ist, können Sie die Verknüpfung 0 hier verwenden, wie Sie es mit den anderen Zeigern tun.

jedoch Sie müssen sich bewusst sein, dass das alles ist in OpenGL seit fast einem Jahrzehnt als veraltet, moderne Core-Versionen von OpenGL keine feste Funktion Pipeline an allen unterstützen. Wenn Sie heutzutage OpenGL lernen, empfehle ich Ihnen dringend, stattdessen einen modernen, shaderbasierten GL zu lernen.

+0

Das ist es! Vielen Dank! Kannst du einige grundlegende (!) Moderne OpenGL-Tutorials empfehlen?Ich würde Java bevorzugen, aber C++ wäre auch in Ordnung. Edit: Tippfehler – dagon

+0

@dagon: Ich denke [Learning Modern 3D Graphics Programming] (http://alfonse.bitbucket.org/oldtut/index.html) und [open.gl] (https://open.gl/) sind ziemlich gut. Ich kenne jedoch keine speziell für Java. – derhass

0

Ohne mehr des Codes zu sehen, ist es sehr schwierig, genau zu sehen, was los ist falsch .

Allerdings muss ich eine Sache sehen, dass ein Problem sein könnte:

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(); 

Die Wicklung um auf Dreiecke sind nicht das gleiche. Das erste Dreieck windet sich im Uhrzeigersinn, während das zweite Dreieck gegen den Uhrzeigersinn windet. Sie müssen die Scheitelpunkte neu anordnen, um sicherzustellen, dass sie sich in dieselbe Richtung bewegen. OpenGL zieht normalerweise Dinge vor, die sich gegen den Uhrzeigersinn drehen. Wenn ich Sie wäre, würde ich das erste Dreieck umdrehen.

Wenn das Problem weiterhin auftritt, posten Sie den Rest Ihres Zeichencodes, da das, was Sie hier zeigen, nicht viele Informationen enthält.

+0

Vielen Dank für Ihre Antwort! Leider hat das Umdrehen des Dreiecks das Problem nicht gelöst. Ich habe den ursprünglichen Beitrag bearbeitet, um meinen gesamten Code hinzuzufügen, damit Sie sich das ansehen können. – dagon