2012-05-25 29 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