剪切并粘贴cl-glut-examples代码我向显示器渲染了一个球体。现在如何使用键盘在x,y和z轴上移动它。还有一个在线资源来学习CL-OpenGL中的游戏编程或如何制作墙壁和泥土以及房屋和角色等东西,这样我就可以创建一个3D世界并在其中移动角色并为其提供游戏逻辑。
到目前为止,这是我的代码:
(defclass glut-teapot-window (glut:window)
()
(:default-initargs :width 948 :height 990 :title "glut-teapot.lisp"
:mode '(:single :rgb :depth)))
(defmethod glut:display-window :before ((window glut-teapot-window))
(gl:clear-color 0 0 0 0)
(gl:cull-face :back)
(gl:depth-func :less)
(gl:disable :dither)
(gl:shade-model :smooth)
(gl:light-model :light-model-local-viewer 1)
(gl:color-material :front :ambient-and-diffuse)
(gl:enable :light0 :lighting :cull-face :depth-test))
(defmethod glut:display ((window glut-teapot-window))
(gl:load-identity)
(gl:translate 0 0 -5)
(gl:rotate 100 1 1 0)
(gl:light :light0 :position '(6000 1000 15 0))
(gl:light :light0 :position '(2000 300 3000 0))
(gl:clear :color-buffer :depth-buffer)
(gl:color 1 1 1)
(gl:front-face :cw)
(glut:Solid-Sphere 1 10 10)
(gl:front-face :ccw)
(gl:flush))
(defmethod glut:reshape ((window glut-teapot-window) width height)
(gl:viewport 0 0 width height)
(gl:matrix-mode :projection)
(gl:load-identity)
(glu:perspective 50 (/ width height) 0.5 20)
(gl:matrix-mode :modelview)
(gl:load-identity))
(defmethod glut:keyboard ((window glut-teapot-window) key x y)
(declare (ignore x y))
(when (eql key #\Esc)
(glut:destroy-current-window)))
(defun glut-teapot ()
(glut:display-window (make-instance 'glut-teapot-window)))
(glut-teapot)
答案 0 :(得分:8)
由于我不知道你对opengl的体验,我将在一年前为我写这个答案(当时我对opengl一无所知,并试图学习使用普通的lisp)。
cl-opengl库是关于opengl的一个相当紧密的包装器,我的意思是大多数opengl函数在cl-opengl中具有直接等价物。这很好,因为这意味着您将能够使用c& amp; s进行opengl的在线教程。 c ++,只有一点精神压力,将它们转换为lisp。
它是一个非常紧密的opengl包装器的缺点是opengl不是非常lispy,我的意思是良好的opengl代码的风格与良好的lisp代码非常不同。一旦你掌握了cl-opengl,这肯定是可以改进的。
接下来,opengl是一个包含两种截然不同的范例的库。有旧式 opengl(使用gl-begin和gl-end)和基于着色器的新风格opengl可能是你想要的,如果你想在未来做奇特的效果!痛苦的是,大多数在线的好教程都是旧式的opengl,或者以我发现超级混乱的方式混合两者。因此,我个人建议学习现代opengl的以下教程: http://www.arcsynthesis.org/gltut/
一旦完成前4章,你就会明白足够的opengl能够使用opengl wiki而不会有太多的痛苦。我说这一开始我发现opengl语言wiki真的很混乱,因为我没有关于所有信息应该如何组合在一起的背景。
现在就到了GLUT。 GLUT很酷......但它的速度非常快。我真的建议切换到SDL。幸运的是,一些出色的人在lisp中使SDL非常适合在common-lisp中使用并称之为lispbuilder-sdl。 http://code.google.com/p/lispbuilder/wiki/LispbuilderSDL
好的,你该怎么办?:
我在这条路上只比你提前几个月,开始是一个真正的痛苦,但完全值得。如果你熟练掌握opengl,我很抱歉,这个答案对你来说太基础了!如果是这样,请告诉我,我会尽力提出更好的答案。
下面是在SDL中启动opengl窗口和上下文,处理事件(你的用户输入将在这里)和重绘框架的基本代码(没有什么可以绘制但是你将用它填充它的东西弧综合教程!)。
我还添加了辅助函数和宏。首先是'可持续',这意味着如果在其中的代码中发生错误,则会在错误结果中有一个选项来继续程序(非常方便,这样您就不会一次又一次地继续启动演示)。还有更新swank,这意味着即使在演示运行时你仍然可以使用Slime(你正在使用slime吗?如果没有获得它!)
(defun init ()
(print 'initialise-stuff-here))
(defun draw ()
(gl:clear-color 0.0 0.0 0.0 0.0)
(gl:clear-depth 1.0)
(gl:clear :color-buffer-bit :depth-buffer-bit)
(gl:flush)
(sdl:update-display))
(defun reshape (width height)
(print width )
(print height)
(gl:viewport 0 0 width height))
(defmacro continuable (&body body)
"Helper macro since we use continue restarts a lot
<remember to hit C in slime or pick the restart so errors don't kill the app>"
`(restart-case (progn ,@body)
(continue () :report "Continue")))
(defun update-swank ()
(let ((connection (or swank::*emacs-connection*
(swank::default-connection))))
(when connection
(swank::handle-requests connection t))))
(defun run-demo ()
(sdl:with-init ()
(sdl:window
640 480 :opengl t
:resizable t
:opengl-attributes '((:sdl-gl-doublebuffer 1)
(:sdl-gl-alpha-size 0)
(:sdl-gl-depth-size 16)
(:sdl-gl-stencil-size 8)
(:sdl-gl-red-size 8)
(:sdl-gl-green-size 8)
(:sdl-gl-blue-size 8)))
(init)
(reshape 640 480)
(setf cl-opengl-bindings:*gl-get-proc-address* #'sdl-cffi::sdl-gl-get-proc-address)
(sdl:with-events ()
(:quit-event () t)
(:VIDEO-RESIZE-EVENT (:w width :h height)
(reshape width height))
(:idle ()
(continuable (update-swank))
(continuable (draw))))))
好的,就是这样,玩得开心!