[racket] OpenGL sgl GL_TEXTURE_3D glTexImage3D

From: mosi (amosat+lisp at gmail.com)
Date: Sat Nov 27 14:08:21 EST 2010

Hi,

this is a question about how to run a code in DrRacket which displays a 3D
(volumetric) texture in an OpenGL window.
Displaying a 2D Texture works beautifully.
Displaying a 3D Texture returns an Error:

Racket\collects\sgl\gl.rkt:21:23: glTexImage3D: unavailable on this system
(I`m working on the windows version of DrRacket)

Does anybody know about the implementation of sgl/gl.rkt in detail ?
The problem is, i think, in the following:
The following C++ GLUT code works fine on my machine and needs an external
DLL glut32.dll and a dynamic load of the function "glTexImage3D" on the run.
However,  Racket\collects\sgl\gl.rkt only creates FFI functions for
C:\Windows\system32\glu32.dll
where the OpenGL extensions are not available in glu32.dll .

Is there a book,  or an example code which could help showing that Racket
can do magic with OpenGL in a REPL on volumetric textures ?
Backup plan: is there a good book on MZScheme, FFI, dynamic loading of DLL
functions ?
(The mzscheme examples in DrRacket don`t seem to work out of the box on
Windows)

I have experience with SBCL and C++, Racket is fairly new to me.

--------------------
Here is what I tried so far:

I used and modified the following code by Brendan Burns with modifications
by Scott Owens:

C:\Program Files\Racket\collects\sgl\examples\alpha.rkt
C:\Program Files\Racket\collects\sgl\examples\gl-frame.rkt

which displays 2D textures on a cube.

The following C++ GLUT code works fine on my machine, needs an external DLL
glut32.dll.
However,  Racket\collects\sgl\gl.rkt only creates FFI functions for
C:\Windows\system32\glu32.dll
where the OpenGL Extensions are not available.
...
#include <GL/glext.h>
...
    // VERY IMPORTANT:
    // this line loads the address of the glTexImage3D function into the
function pointer of the same name.
    // glTexImage3D is not implemented in the standard GL libraries and must
be loaded dynamically at run time,
    // the environment the program is being run in MAY OR MAY NOT support
it, if not we'll get back a NULL pointer.
    // this is necessary to use any OpenGL function declared in the glext.h
header file
    // the Pointer to FunctioN ... PROC types are declared in the same
header file with a type appropriate to the function name
    glTexImage3D = (glTexImage3D) wglGetProcAddress("glTexImage3D");
    if (glTexImage3D == NULL) {
        printf("Error in line %d: Couldn't load glTexImage3D function.
Aborting.\n", __LINE__);
        return -1;
    }
...

The code displays a nice 3D texture on a pyramid.

Now trying to do the same in DrRacket:
;;----------- Code Excerpt for GL_TEXTURE_3D -------------
(glEnable GL_3D)
(glEnable GL_TEXTURE_3D)
...

;; --- Create a 3D texture for OpenGL ---

  (define (get-tex3d fname)
    (let* ((xx 4)
           (yy 6)
           (zz 12)
           (pixels (* xx yy zz))
           (vec (make-gl-ubyte-vector (* pixels 3)))
           (data (make-bytes (* pixels 4)))
           (i 0)
           (cr (round (* (/ 255 pixels) 1))) ; color range increment from
pixel to pixel
           )

      (letrec
          ([loop
            (lambda ()
              (if (< i pixels)
                  (begin
                    (gl-vector-set! vec (* i  3) (- 255 (round (* cr i))))
                    (gl-vector-set! vec (+ (* i 3) 1) (round (* cr i)))
                    (gl-vector-set! vec (+ (* i 3) 2) (- 124 (round (* (/ cr
2) i))))
                    (set! i (+ i 1))
                    (loop))))])
        (loop))
      (list xx yy zz vec)))

;; ---------- Try to Load a 3D openGL texture into OpenGL ----------
  (define gl-load-texture3d
    (lambda (image-vector width height depth min-filter mag-filter ix)
      (glBindTexture GL_TEXTURE_3D (gl-vector-ref *textures* ix))
      (glTexParameteri GL_TEXTURE_3D GL_TEXTURE_MIN_FILTER min-filter)
      (glTexParameteri GL_TEXTURE_3D GL_TEXTURE_MAG_FILTER mag-filter)
      (let* ((new-img-vec (make-gl-ubyte-vector
                           (* width height depth 3)))
      ;       (new-img-vec image-vector)
             )
        (if (or (= min-filter GL_LINEAR_MIPMAP_NEAREST)
                (= mag-filter GL_LINEAR_MIPMAP_NEAREST))
            (gluBuild3DMipmaps GL_TEXTURE_3D 3 width height depth GL_RGB
GL_UNSIGNED_BYTE new-img-vec)           ;; this is not supported in my
Racket ! ? !
            (glTexImage3D GL_TEXTURE_3D 0 3 width height depth 0 GL_RGB
GL_UNSIGNED_BYTE new-img-vec)             ;; this is not supported in my
Racket ! ? !
            )))
    )

;;...
;; Perform the 3D Texture Load
(unless (gl-load-texture3d (list-ref res 3) (list-ref res 0) (list-ref res
1) (list-ref res 2) GL_NEAREST GL_NEAREST 0)
        (error "Couldn't load texture"))


Thank you for your comments.

mosi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20101127/25962de7/attachment.html>

Posted on the users mailing list.