2012-05-25 25 views
1

我在Clojure中使用LWJGL並且無法照亮場景。我正在繪製GLU.Sphere對象,這些對象在照明關閉時可見,但在啓用照明時全黑。當在LWJGL中啓用照明時,面部是黑色/黑色

我在做什麼錯?

(ns gltest.core 
    (:import [org.lwjgl.opengl Display DisplayMode GL11] 
      [org.lwjgl.util.glu GLU Sphere] 
      [org.lwjgl Sys] 
      [org.lwjgl.input Keyboard] 
      [java.nio ByteBuffer ByteOrder]) 
    (:gen-class)) 

(declare get-time) 

(def temp-buf (ByteBuffer/allocateDirect 16)) 

(def s (Sphere.)) 

(def display-state (atom {:mode nil 
          :max-fps 60})) 
(def render-state (atom {:last-frame nil 
         :last-fps (float 0) 
         :fps (float 0)})) 
(def world-state (atom {:x 400 
         :y 300 
         :rotation 0})) 

(defn get-time [] 
    (/ (* (Sys/getTime) 1000) 
     (Sys/getTimerResolution))) 

(defn update-fps [] 
    (let [time (get-time)] 
    (when (> (- time (@render-state :last-fps)) 
      1000) 
     (Display/setTitle (format "FPS: %s" (@render-state :fps))) 
     (swap! render-state 
      assoc :fps (float 0) :last-fps time))) 
    (swap! render-state assoc :fps (float (+ (@render-state :fps) 
              1)))) 

(defn update [delta] 
    (swap! world-state assoc :rotation (+ (:rotation @world-state) 
             (* (float 0.15) delta))) 

    (update-fps)) 

(defn init-gl [] 
    (GL11/glClearColor 0.1 0.1 0.1 0.0) ; background 
    (GL11/glClearDepth 1) 
    (GL11/glDepthFunc GL11/GL_LEQUAL) 
    (GL11/glHint GL11/GL_PERSPECTIVE_CORRECTION_HINT GL11/GL_NICEST) 
    (GL11/glShadeModel GL11/GL_SMOOTH) 
    (GL11/glEnable GL11/GL_DEPTH_TEST) 

    ;; fovy, aspect ratio, zNear, zFar 
    (let [width (.getWidth (:mode @display-state)) 
     height (.getHeight (:mode @display-state)) 
     aspect-ratio (float (/ width height))] 
    ;; select projection matrix (controls perspective) 
    (GL11/glMatrixMode GL11/GL_PROJECTION) 
    (GL11/glLoadIdentity) 
    (GLU/gluPerspective 45 aspect-ratio 0.1 100) 

    (GL11/glMatrixMode GL11/GL_MODELVIEW) 
    (GL11/glLoadIdentity) 
    (GL11/glViewport 0 0 width height)) 

    (GL11/glMaterial GL11/GL_FRONT GL11/GL_SPECULAR (-> temp-buf 
                 .clear 
                 .asFloatBuffer 
                 (.put (float-array [1 1 1 1])) 
                 .flip)) 
    (GL11/glMaterial GL11/GL_FRONT GL11/GL_AMBIENT (-> temp-buf 
                .clear 
                .asFloatBuffer 
                (.put (float-array [1 1 1 1])) 
                .flip)) 
    (GL11/glMaterial GL11/GL_FRONT GL11/GL_DIFFUSE (-> temp-buf 
                .clear 
                .asFloatBuffer 
                (.put (float-array [1 1 1 1])) 
                .flip)) 

    (GL11/glMaterialf GL11/GL_FRONT_AND_BACK GL11/GL_SHININESS 10) 

    ;; setup light 
    (let [ambient-light (float-array [0.5 0.5 0.5 0]) 
     diffuse-light (float-array [0 1.0 0 0])] 
    (GL11/glLight GL11/GL_LIGHT0 GL11/GL_AMBIENT (-> temp-buf 
                .clear 
                .asFloatBuffer 
                (.put ambient-light) 
                .flip)) 
    (GL11/glLight GL11/GL_LIGHT0 GL11/GL_DIFFUSE (-> temp-buf .clear 
                .asFloatBuffer 
                (.put diffuse-light) 
                .flip)) 
    (GL11/glLight GL11/GL_LIGHT0 GL11/GL_POSITION (-> temp-buf 
                 .clear 
                 .asFloatBuffer 
                 (.put (float-array [0 -1 0 0])) 
                 .flip))) 

    (GL11/glEnable GL11/GL_LIGHTING) 
    (GL11/glEnable GL11/GL_LIGHT0) 

    (swap! render-state assoc :last-frame (get-time))) 

(defn render [] 
    ;; Clear The Screen And The Depth Buffer 
    (GL11/glClear (bit-or GL11/GL_COLOR_BUFFER_BIT GL11/GL_DEPTH_BUFFER_BIT)) 

    ;; setup camera 
    (GL11/glLoadIdentity) 
    (GL11/glTranslatef (float 0) (float 0) (float -3)) 
    (GL11/glRotatef 30 1 0 0) 

    (GL11/glPushMatrix) 
    (GL11/glTranslatef 0 1 0) 
    (.draw s 0.1 50 50) 
    (GL11/glPopMatrix)) 

(defn -main [] 
    (let [display-mode (first (filter #(and 
             (== (.getWidth %) 800) 
             (== (.getHeight %) 600) 
             (== (.getBitsPerPixel %) 32)) 
            (Display/getAvailableDisplayModes)))] 
    (swap! display-state assoc :mode display-mode) 

    (Display/setDisplayMode display-mode) 
    (Display/setTitle "Test") 
    (Display/create)) 

    (init-gl) 

    (while (not (Display/isCloseRequested)) 
    (let [time (get-time) 
      last-frame (@render-state :last-frame)] 
     (swap! render-state assoc :last-frame time) 
     (update (int (- time last-frame)))) 
    (render) 
    (Display/update) 
    (Display/sync (@display-state :max-fps))) 

    (Display/destroy) 
    (System/exit 0)) 
+1

這是解決您遇到的問題的解釋嗎? –

+1

你的'報告'不構成問題。即使它是一個,也沒有足夠的信息讓其他人能夠幫助你。投票結束。 –

+0

應該可能閱讀這篇博客文章:http://blog.stackoverflow.com/2012/05/encyclopedia-stack-exchange/ –

回答

3

在這種情況下,設置在glLightglMaterial調用中使用的ByteBuffer的順序固定的問題。

// Java 
ByteBuffer buf = ByteBuffer.allocateDirect(16); 
buf.order(ByteOrder.nativeOrder); 

;; Clojure 
(def buf (doto (ByteBuffer/allocateDirect 16) 
      (.order (ByteOrder/nativeOrder))) 
+1

我很困惑,要麼是我的SO搞砸了,要麼是你在1秒內回答了你自己的問題? – RoneRackal

+1

@RoneRackal我這樣做是爲了自我回答,因爲很難找到照明問題的解決方案,並且可能會出現一些錯誤。我經歷了幾個小時搜索後發現的任何文檔中沒有提及我設置ByteBuffer順序時遇到的錯誤。 – mattrepl