Hello,
I'll start by saying I'm fairly new to Common Lisp and almost entirely new to doing any practical graphics programming, and I could well have missed something hugely obvious here.. but I hope not.
I'm going to need to write some graphics code in the phd program I've just started. Someone pointed me at nehe.gamedev.net's opengl tutorials and after slogging through up to number 5 - http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=05 - reading through people's objective C, I decided to try and port it to Lisp using cl-opengl. I looked at a couple of examples (cube.lisp and gears.lisp) to get the boilerplate about window generation, and from there it was pretty much just a case of porting the drawRect method from the Objective C version to the glut:display method for my code.
I have clearly missed something though, as the visibility for my geometry is all off - for example the base of the triangle is drawn in front of anything else and most faces of the cube do something a bit whacky. I know that which order points are drawn in is crucial because that defines the 'front' of a triangle/quad, but I'm pretty sure I have copied the points in the same order as my Objective C version (which works fine, see screenshots)
Working version (objective C): http://img260.imageshack.us/i/picture3g.png/ Non working version: http://img209.imageshack.us/i/picture4k.png/
In case it's not clear, in the non-working version above the corner you see in the pyramid is actually the back corner. It shouldn't be visible. When the pyramid rotates so that you should be looking down on the point at it, you see only the base instead of only the four top faces. I have similar issues with the cube faces, some of them only being visible from the 'inside'.
From what I can tell from M-.'ing through the source, cl-opengl passes
directly through to the corresponding C functions, so I'm pretty confident the 'which order to specify points' hasn't changed. This means presumably something in my setup is off, something to do with the depth buffer maybe? I guess the issue might be in the keyword args in function calls in #'glut:display-window method but it's hard to figure out exactly what the arguments to these functions will be except a guess at translating them into lisp-ish hyphenated lowercase.
Here's the entire source to my lisp program: http://paste.lisp.org/display/88230
and the relevant file from my Obj-C version (I basically tried to copy everything from the drawRect and reshape methods): http://paste.lisp.org/display/88231
If anyone can point me in the right direction that would be most appreciated.. I'm looking forward to using Lisp for some serious work once I get these niggles sorted out.
Cheers,
Malcolm
On Mon, Oct 5, 2009 at 1:43 PM, Malcolm Reynolds malcolm.reynolds@gmail.com wrote:
Working version (objective C): http://img260.imageshack.us/i/picture3g.png/ Non working version: http://img209.imageshack.us/i/picture4k.png/
In case it's not clear, in the non-working version above the corner you see in the pyramid is actually the back corner. It shouldn't be visible. When the pyramid rotates so that you should be looking down on the point at it, you see only the base instead of only the four top faces. I have similar issues with the cube faces, some of them only being visible from the 'inside'.
means presumably something in my setup is off, something to do with the depth buffer maybe? I guess the issue might be in the keyword args in function calls in #'glut:display-window method but it's hard to figure out exactly what the arguments to these functions will be except a guess at translating them into lisp-ish hyphenated lowercase.
Right, you probably need to enable a depth buffer, and you probably also want double buffering on modern platforms, both are controlled by the :mode parameter to glut:window instance creation, easiest way to fix that is changing the ":mode '(:single :rgb)" in the (defclass test-window ...) form to ":mode '(:double :rgb :depth)".
If you switch to double buffering (using :double instead of :single there), you will also need to do (glut:swap-buffers) after drawing each frame, probably in place of the (gl:flush) in the glut:display method.
You may also want to get rid of the (glut:post-redisplay) in the keyboard method, since that kills my lisp when i try to exit the window (yay for C libraries that think exit() is a good response to unexpected situations)
Seems to work with those changes though.
-- 3b
Right, you probably need to enable a depth buffer, and you probably also want double buffering on modern platforms, both are controlled by the :mode parameter to glut:window instance creation, easiest way to fix that is changing the ":mode '(:single :rgb)" in the (defclass test-window ...) form to ":mode '(:double :rgb :depth)".
If you switch to double buffering (using :double instead of :single there), you will also need to do (glut:swap-buffers) after drawing each frame, probably in place of the (gl:flush) in the glut:display method.
Lovely. This is now working properly, thankyou!
You may also want to get rid of the (glut:post-redisplay) in the keyboard method, since that kills my lisp when i try to exit the window (yay for C libraries that think exit() is a good response to unexpected situations)
Okay. Is putting #'glut:post-redisplay into my method on #'glut-idle the preferred way (or at least, not a discouraged way) of keeping the model updating?
One final difference between my two versions is that resizing the window on the lisp version scales the inside accordingly (squares become squashed) which doesn't happen on the C version. Obviously this is a bit more of an involved question, but the part that will make this happen is in the #'glut:reshape method, correct?
Many thanks for your quick reply!
Malcolm
On Mon, Oct 5, 2009 at 4:10 PM, Malcolm Reynolds malcolm.reynolds@gmail.com wrote:
You may also want to get rid of the (glut:post-redisplay) in the keyboard method, since that kills my lisp when i try to exit the window
Okay. Is putting #'glut:post-redisplay into my method on #'glut-idle the preferred way (or at least, not a discouraged way) of keeping the model updating?
Yeah, it looks like that is the correct way to do that.
One final difference between my two versions is that resizing the window on the lisp version scales the inside accordingly (squares become squashed) which doesn't happen on the C version. Obviously this is a bit more of an involved question, but the part that will make this happen is in the #'glut:reshape method, correct?
Right, you could either switch it to use glu:perspective and translate the objc code directly, or you could use for example +/- (/ height width) in place of +/- 1 for the bottom/top args to gl:frustum.
-- 3b
cl-opengl-devel@common-lisp.net