From: Frank Goenninger DG1SBG
Subject: Macro question: multiple values ...
Date: 
Message-ID: <m2ac5059k8.fsf@pcsde001.local>
Hi all:

A FFI function gl-color3f required three floats r g b as parameters
as the RGB values for color specification.

Now as I am lazy I wanted to define some helper funcions macros to
access colors by well-known names:

;;; ---------------------------------------------------------------------------
;;; Utilities / Helper functions and macros
;;; ---------------------------------------------------------------------------

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun rgb-2-ogl-color3f (r g b)
    (values (coerce (/ r 256) 'float)
	    (coerce (/ g 256) 'float)
	    (coerce (/ b 256) 'float))))

(defmacro define-ogl-rgb-color (name r g b)
  `(defconstant ,name (rgb-2-ogl-color3f ,r ,g ,b)))

;;; ---------------------------------------------------------------------------
;;; Color definitions
;;; ---------------------------------------------------------------------------

(define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-YELLOW-C         249 227   0)

Now, when calling 

(ogl-color3f  OGL-COLOR-PANTONE-YELLOW-C)

I get:

GL-COLOR3F got 1 arg, wanted 3 args.
   [Condition of type PROGRAM-ERROR]

Hmmm, yes, of course, I see the error. I just can't seem to think of a
way to do the defconstant such that the three values are returned...

Any hints really appreciated.

TIA!

Frank

From: Ken Tilton
Subject: Re: Macro question: multiple values ...
Date: 
Message-ID: <5cUOg.26$Su.11@newsfe10.lga>
Frank Goenninger DG1SBG wrote:
> Hi all:
> 
> A FFI function gl-color3f required three floats r g b as parameters
> as the RGB values for color specification.

and gl-color3fv requires a single vector of three floats. :)
> 
> Now as I am lazy I wanted to define some helper funcions macros to
> access colors by well-known names:
> 
> ;;; ---------------------------------------------------------------------------
> ;;; Utilities / Helper functions and macros
> ;;; ---------------------------------------------------------------------------
> 
> (eval-when (:compile-toplevel :load-toplevel :execute)
>   (defun rgb-2-ogl-color3f (r g b)
>     (values (coerce (/ r 256) 'float)
> 	    (coerce (/ g 256) 'float)
> 	    (coerce (/ b 256) 'float))))

if you know your vax/vms edt editor:

    s/values/vector/w

:)

hth,kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Frank Goenninger DG1SBG
Subject: Re: Macro question: multiple values ...
Date: 
Message-ID: <m2k643hkfi.fsf@pcsde001.local>
Ken Tilton <·········@gmail.com> writes:

> Frank Goenninger DG1SBG wrote:
>> Hi all:
>> A FFI function gl-color3f required three floats r g b as parameters
>> as the RGB values for color specification.
>
> and gl-color3fv requires a single vector of three floats. :)

And you know what I am working on ... ;-)

>> (eval-when (:compile-toplevel :load-toplevel :execute)
>>   (defun rgb-2-ogl-color3f (r g b)
>>     (values (coerce (/ r 256) 'float)
>> 	    (coerce (/ g 256) 'float)
>> 	    (coerce (/ b 256) 'float))))
>
> if you know your vax/vms edt editor:
>
>    s/values/vector/w
>
> :)
>
> hth,kt

Cute! Helped. Even simpler.

As always I learned a lot from both kt and Pascal - I do love
c.l.l. <g>

Frank
From: Ken Tilton
Subject: Re: Macro question: multiple values ...
Date: 
Message-ID: <ehUOg.196$Su.95@newsfe10.lga>
Frank Goenninger DG1SBG wrote:
> Hi all:
> 
> A FFI function gl-color3f required three floats r g b as parameters
> as the RGB values for color specification.
> 
> Now as I am lazy I wanted to define some helper funcions macros to
> access colors by well-known names:
> 
> ;;; ---------------------------------------------------------------------------
> ;;; Utilities / Helper functions and macros
> ;;; ---------------------------------------------------------------------------
> 
> (eval-when (:compile-toplevel :load-toplevel :execute)
>   (defun rgb-2-ogl-color3f (r g b)
>     (values (coerce (/ r 256) 'float)
> 	    (coerce (/ g 256) 'float)
> 	    (coerce (/ b 256) 'float))))

And I am perty sure gl-color3iv will be happy to take the 0-255 values 
as is and do The Right Thing. Oh wait:

"Unsigned integer color components, when
  specified, are linearly mapped to floating-point values such  that  the
  largest representable value maps to 1.0 (full intensity), and 0 maps to
  0.0 (zero intensity)."

Hmmm. Would that be gl-color3ubv, then?

kt
From: Frank Goenninger DG1SBG
Subject: Re: Macro question: multiple values ...
Date: 
Message-ID: <m2slisgf2e.fsf@pcsde001.local>
I found a solution using EVAL ...

(defparameter *colors-ht* (make-hash-table :test 'eq))

;;; ---------------------------------------------------------------------------
;;; Utilities / Helper functions and macros
;;; ---------------------------------------------------------------------------

(defmacro define-ogl-rgb-color (name r g b)
  `(setf (gethash ',name *colors-ht*)
      '(values (coerce (/ ,r 256) 'float)
	       (coerce (/ ,g 256) 'float)
	       (coerce (/ ,b 256) 'float))))

(defun set-color (name)
  (multiple-value-bind(r g b)
      (eval (gethash name *colors-ht*))
    (gl-color3f r g b)))

;;; ---------------------------------------------------------------------------
;;; Color definitions
;;; ---------------------------------------------------------------------------

(define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-YELLOW-C         249 227   0)
(define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-MAGENTA-C        209   0 116)
(define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-CYAN-C             0 159 218)
(define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-BLACK-C           30  30  30)


My inner voice cries NO, NO, NO! with this solution. It is not only
using EVAL as a means for destructuring the hashed (VALUES ...)
statement but also requires a different interface using
SET-COLOR. Both the new interface and the EVAL are elements I'd like
to avoid.

Still looking for a better solution...

Thx!

Frank
From: Pascal Bourguignon
Subject: Re: Macro question: multiple values ...
Date: 
Message-ID: <87mz902bwl.fsf@thalassa.informatimago.com>
Frank Goenninger DG1SBG <·············@nomail.org> writes:

> I found a solution using EVAL ...

This is not a solution (EVAL is almost never a solution).
 
> (defparameter *colors-ht* (make-hash-table :test 'eq))
>
> ;;; ---------------------------------------------------------------------------
> ;;; Utilities / Helper functions and macros
> ;;; ---------------------------------------------------------------------------
>
> (defmacro define-ogl-rgb-color (name r g b)
>   `(setf (gethash ',name *colors-ht*)
>       '(values (coerce (/ ,r 256) 'float)
> 	       (coerce (/ ,g 256) 'float)
> 	       (coerce (/ ,b 256) 'float))))
>
> (defun set-color (name)
>   (multiple-value-bind(r g b)
>       (eval (gethash name *colors-ht*))
>     (gl-color3f r g b)))
>
> ;;; ---------------------------------------------------------------------------
> ;;; Color definitions
> ;;; ---------------------------------------------------------------------------
>
> (define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-YELLOW-C         249 227   0)
> (define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-MAGENTA-C        209   0 116)
> (define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-CYAN-C             0 159 218)
> (define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-BLACK-C           30  30  30)

Try:

(let ((g (random 256)))
   (define-ogl-rgb-color OGL-COLOR-random-grey g g g))

(set-color OGL-COLOR-random-grey)


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.
From: Frank Goenninger DG1SBG
Subject: Re: Macro question: multiple values ...
Date: 
Message-ID: <m2odtfhkwy.fsf@pcsde001.local>
Pascal Bourguignon <···@informatimago.com> writes:

> Frank Goenninger DG1SBG <·············@nomail.org> writes:
>
>> I found a solution using EVAL ...
>
> This is not a solution (EVAL is almost never a solution).

I knew - that's why I asked ... ;-) 

Thx for showing the way to go. Works now, using the struct
approach. Feels like being the simplest way to do it.

Frank
From: Pascal Bourguignon
Subject: Re: Macro question: multiple values ...
Date: 
Message-ID: <87r6yc2c8k.fsf@thalassa.informatimago.com>
Frank Goenninger DG1SBG <·············@nomail.org> writes:

> Hi all:
>
> A FFI function gl-color3f required three floats r g b as parameters
> as the RGB values for color specification.
>
> Now as I am lazy I wanted to define some helper funcions macros to
> access colors by well-known names:
>
> ;;; ---------------------------------------------------------------------------
> ;;; Utilities / Helper functions and macros
> ;;; ---------------------------------------------------------------------------
>
> (eval-when (:compile-toplevel :load-toplevel :execute)
>   (defun rgb-2-ogl-color3f (r g b)
>     (values (coerce (/ r 256) 'float)
> 	    (coerce (/ g 256) 'float)
> 	    (coerce (/ b 256) 'float))))
>
> (defmacro define-ogl-rgb-color (name r g b)
>   `(defconstant ,name (rgb-2-ogl-color3f ,r ,g ,b)))
>
> ;;; ---------------------------------------------------------------------------
> ;;; Color definitions
> ;;; ---------------------------------------------------------------------------
>
> (define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-YELLOW-C         249 227   0)
>
> Now, when calling 
>
> (ogl-color3f  OGL-COLOR-PANTONE-YELLOW-C)

First, try to see what value OGL-COLOR-PANTONE-YELLOW-C is:

Evaluate:   OGL-COLOR-PANTONE-YELLOW-C


> I get:
>
> GL-COLOR3F got 1 arg, wanted 3 args.
>    [Condition of type PROGRAM-ERROR]
>
> Hmmm, yes, of course, I see the error. I just can't seem to think of a
> way to do the defconstant such that the three values are returned...
>
> Any hints really appreciated.

You must store the values somewhere. A list, a vector, a structure?

For example, with a structure:

(defstruct color red green blue)
(defmacro define-ogl-rgb-color (name r g b)
   `(defconstant ,name 
       (multiple-value-bind (r g b) (rgb-2-ogl-color3f ,r ,g ,b)
           (make-color :red r :green g :blue b))))

;; Then, after:

(define-ogl-rgb-color OGL-COLOR-PANTONE-PROCESS-YELLOW-C         249 227   0)

;; you'll see that the value of:

OGL-COLOR-PANTONE-YELLOW-C

;; will be more interesting.


Then, since ogl-color3f expects three values, not a single structure,
you'll need to write another function:

(defun ogl-color (color)
  (ogl-color3f (color-red color) (color-green color) (color-blue color)))

;; and use it insteaad of ogl-color3d:

(ogl-color  OGL-COLOR-PANTONE-YELLOW-C)



If you used lists instead of structures, you could write:

   (apply (function ogl-color3f) OGL-COLOR-PANTONE-YELLOW-C)

but I think:

   (ogl-color  OGL-COLOR-PANTONE-YELLOW-C)

is simplier.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

CONSUMER NOTICE: Because of the "uncertainty principle," it is
impossible for the consumer to simultaneously know both the precise
location and velocity of this product.