GLXWorkstation.st
author claus
Wed, 13 Oct 1993 01:46:50 +0100
changeset 5 e5942fea6925
parent 0 48194c26a46c
child 12 9f0995fac1fa
permissions -rw-r--r--
(none)

"
COPYRIGHT (c) 1993 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

XWorkstation subclass:#GLXWorkstation
       instanceVariableNames:''
       classVariableNames:   ''
       poolDictionaries:''
       category:'Interface-Graphics'
!

GLXWorkstation comment:'

COPYRIGHT (c) 1993 by Claus Gittinger
              All Rights Reserved

this class just to give a hint of what could be ...

$Header: /cvs/stx/stx/libview/GLXWorkstation.st,v 1.2 1993-10-13 00:45:42 claus Exp $
written june 93 by claus
'!

%{
#ifdef GLX

/*
 * this is stupid, GLX defines String, which is also defined here ...
 */
# define String GLX_String
# include <gl/glws.h>

typedef enum {
    GLXcolorIndexSingleBuffer,
    GLXcolorIndexDoubleBuffer,
    GLXrgbSingleBuffer,
    GLXrgbDoubleBuffer
} GLXWindowType;

extern Window GLXCreateWindow(Display*,Window,int,int,int,int,int,GLXWindowType);
#undef String

#endif

/*
 * some defines - tired of typing ...
 */
#define MKDPY(o)       (Display *)(_intVal(o))
#define MKWIN(o)       (Window)(_intVal(o))
#define MKGC(o)        (GC)(_intVal(o))
#define MKCURS(o)      (Cursor)(_intVal(o))
#define MKFONT(o)      (XFontStruct *)(_intVal(o))
#define MKDPSContext(o)      (DPSContext)(_intVal(o))

#define myDpy MKDPY(_INST(displayId))

#define _COORD_(arg, dst)               \
    if (_isFloat(arg))                  \
        dst = (Coord)(_floatVal(arg));  \
    else if (_isSmallInteger(arg))      \
        dst = (Coord)(_intVal(arg));    \
    else break;

#define _FLOAT_(arg, dst)               \
    if (_isFloat(arg))                  \
        dst = (float)(_floatVal(arg));  \
    else if (_isSmallInteger(arg))      \
        dst = (float)(_intVal(arg));    \
    else break;

#define _ANGLE_(arg, dst)               \
    if (_isSmallInteger(arg))           \
        dst = (Angle)(_intVal(arg));    \
    else break;

#define _INT_(arg, dst)                 \
    if (_isSmallInteger(arg))           \
        dst = (int)(_intVal(arg));      \
    else break;

%}

!GLXWorkstation methodsFor:'window creation'!

createGLXWindowFor:aView left:xpos top:ypos width:wwidth height:wheight
    |ext minWidth minHeight maxWidth maxHeight 
     bWidth bColor viewBg viewBgId wsuperView wsuperViewId wcreateOnTop 
     winputOnly wlabel wcursor wcursorId wicon wiconId windowId
     weventMask wiconView wiconViewId bitGravity viewGravity vBgColor
     vBgForm deepForm|

    wsuperView := aView superView.
    wsuperView notNil ifTrue:[
        wsuperViewId := wsuperView id
    ].

%{
#ifdef GLX
    Display *dpy = myDpy;
    int screen = _intVal(_INST(screen));
    Window newWindow, parentWindow;
    extern Window GLXCreateWindow();

    if (_isSmallInteger(xpos) && _isSmallInteger(ypos)
     && _isSmallInteger(wwidth) && _isSmallInteger(wheight)) {
        if (_isSmallInteger(wsuperViewId)) {
            parentWindow = MKWIN(wsuperViewId);
        } else {
            parentWindow = RootWindow(dpy, screen);
        }

        newWindow = GLXCreateWindow(dpy, parentWindow,
                           _intVal(xpos), _intVal(ypos),
                           _intVal(wwidth), _intVal(wheight),
                           0, GLXrgbSingleBuffer);

        if (! newWindow) {
            RETURN ( nil );
        }

        windowId = MKOBJ(newWindow);
    }
#endif
%}
.
    windowId notNil ifTrue:[
        self addKnownView:aView withId:windowId.
    ].
    ^ windowId
! !

!GLXWorkstation methodsFor:'glx access'!

glxWinSet:aGLXWindowId 
    "set the current graphics window"

%{  /* NOCONTEXT */
#ifdef GLX
    if (GLXwinset(myDpy, MKWIN(aGLXWindowId)) >= 0)
        RETURN (true);
#endif
%}
.
    ^ false
!

glxPerspectiveFovy:fovy aspect:aspect near:near far:far
    "define perspective projection"

%{  /* NOCONTEXT */

#ifdef GLX
    Angle a_fovy;
    Coord c_near, c_far;
    float f_aspect;

    do {
        _ANGLE_ (fovy, a_fovy);
        _FLOAT_ (aspect, f_aspect);
        _COORD_ (near, c_near);
        _COORD_ (far, c_far);
        perspective(a_fovy, f_aspect, c_near, c_far);

        RETURN (true);
    } while(0);
#endif
%}
.
    ^ false
!

glxTranslateX:x y:y z:z
    "translate current matrix"

%{  /* NOCONTEXT */

#ifdef GLX
    Coord c_x, c_y, c_z;

    do {
        _COORD_ (x, c_x);
        _COORD_ (y, c_y);
        _COORD_ (z, c_z);
        translate(c_x, c_y, c_z);
        RETURN (true);
    } while(0);
#endif
%}
.
    ^ false
!

glxScaleX:x y:y z:z
    "scale & mirror current matrix"

%{  /* NOCONTEXT */

#ifdef GLX
    float f_x, f_y, f_z;

    do {
        _FLOAT_ (x, f_x);
        _FLOAT_ (y, f_y);
        _FLOAT_ (z, f_z);
        scale(f_x, f_y, f_z);
        RETURN (true);
    } while(0);
#endif
%}
.
    ^ false
!

glxRotate:angle axis:axis
    "rotate the current matrix"

    "{ Symbol: x }"
    "{ Symbol: y }"
    "{ Symbol: z }"

%{  /* NOCONTEXT */

#ifdef GLX
    Angle a_angle;
    float f_angle;
    char c_axis;

    do {
        if (axis == _x)
            c_axis = 'x';
        else if (axis == _y)
            c_axis = 'y';
        else if (axis == _z)
            c_axis = 'z';
        else break;

        if (_isFloat(angle)) {
            f_angle = (float)(_floatVal(angle));
            rot(f_angle, c_axis);
            RETURN (true);
        } else {
            if (_isSmallInteger(angle)) {
                a_angle = (Angle)(_intVal(angle));
                rotate(a_angle, c_axis);
                RETURN (true);
            }
        }
    } while(0);
#endif
%}
.
    ^ false
!

glxLookatVx:vx vy:vy vz:vz px:px py:py pz:pz twist:twist
    "define viewing transformation"

%{  /* NOCONTEXT */

#ifdef GLX
    Coord f_vx, f_vy, f_vz, f_px, f_py, f_pz;
    Angle a_twist;

    do {
        _COORD_ (vx, f_vx);
        _COORD_ (vy, f_vy);
        _COORD_ (vz, f_vz);
        _COORD_ (px, f_px);
        _COORD_ (py, f_py);
        _COORD_ (pz, f_pz);
        _ANGLE_ (twist, a_twist);
        lookat(f_vx, f_vy, f_vz, f_px, f_py, f_pz, a_twist);
        RETURN (true);
    } while(0);
#endif
%}
.
    ^ false
!

glxLmdef:what index:index np:np props:props
    "define a material, light source or lighting model;
     props must be a FloatArray"

    "{ Symbol: material }"
    "{ Symbol: light }"
    "{ Symbol: lightModel }"

%{  /* NOCONTEXT */
#ifdef GLX
    short defType;
    short i_index, i_np;
    extern OBJ FloatArray;
    float *fp;

    do {
        if (what == _material)
            defType = DEFMATERIAL;
        else if (what == _light)
            defType = DEFLIGHT;
        else if (what == _lightModel)
            defType = DEFLMODEL;
        else break;

        _INT_ (index, i_index);
        _INT_ (np, i_np);

        if (props == nil) fp = NULL;
        else if (_Class(props) == FloatArray)
            fp = _FloatArrayInstPtr(props)->f_element;
        else break;

        lmdef(defType, i_index, i_np, fp);
        RETURN (true);
    } while(0);
#endif
%}
.
    ^ false
!

glxLmbind:target index:index
    "select a material, lighyt or lighting model"

    "{ Symbol: material }"
    "{ Symbol: backMaterial }"
    "{ Symbol: light0 }"
    "{ Symbol: light1 }"
    "{ Symbol: light2 }"
    "{ Symbol: light3 }"
    "{ Symbol: light4 }"
    "{ Symbol: light5 }"
    "{ Symbol: light6 }"
    "{ Symbol: light7 }"
    "{ Symbol: lightModel }"

%{  /* NOCONTEXT */
#ifdef GLX
    short defType;
    short i_index;

    do {
        if (target == _material)
            defType = MATERIAL;
        else if (target == _backMaterial)
            defType = BACKMATERIAL;
        else if (target == _light0)
            defType = LIGHT0;
        else if (target == _light1)
            defType = LIGHT1;
        else if (target == _light2)
            defType = LIGHT2;
        else if (target == _light3)
            defType = LIGHT3;
        else if (target == _light4)
            defType = LIGHT4;
        else if (target == _light5)
            defType = LIGHT5;
        else if (target == _light6)
            defType = LIGHT6;
        else if (target == _light7)
            defType = LIGHT7;
        else if (target == _lightModel)
            defType = LMODEL;
        else break;

        _INT_ (index, i_index);
        lmbind(defType, i_index);
        RETURN (true);
    } while(0);
#endif
%}
.
    ^ false
!

glxColor:index
    "set color, for non gouraud shading, we dont care if the
     argument is integer or float; otherwise, better results are
     expected with float values."

%{  /* NOCONTEXT */

#ifdef GLX
    if (_isSmallInteger(index)) {
        color((Colorindex)(_intVal(index)));
        RETURN (true);
    }
    if (_isFloat(index)) {
        colorf((float)(_floatVal(index)));
        RETURN (true);
    }
#endif
%}
.
    ^ false
!

glxClear
    "clear to current color"

%{  /* NOCONTEXT */
#ifdef GLX
    clear();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxZClear
    "clear z buffer"

%{  /* NOCONTEXT */
#ifdef GLX
    zclear();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxPushmatrix
    "push down transformation stack"

%{  /* NOCONTEXT */
#ifdef GLX
    pushmatrix();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxPopmatrix
    "pop transformation stack"

%{  /* NOCONTEXT */
#ifdef GLX
    popmatrix();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxSwapBuffers
    "swap double buffers"

%{  /* NOCONTEXT */
#ifdef GLX
    swapbuffers();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxRGBmode
    "set true color mode (no colormap)"

%{  /* NOCONTEXT */
#ifdef GLX
    RGBmode();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxDoubleBuffer
    "set double buffer mode"

%{  /* NOCONTEXT */
#ifdef GLX
    doublebuffer();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxGconfig
    "must be sent after RGBmode, doubleBuffer etc. to have these
     changes really take effect. See GLX manual"

%{  /* NOCONTEXT */
#ifdef GLX
    gconfig();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxZbuffer:aBoolean
    "enable/disable z-buffer operation"

%{  /* NOCONTEXT */
#ifdef GLX
    zbuffer(aBoolean == false ? FALSE : TRUE);
    RETURN (true);
#endif
%}
.
    ^ false
!

glxMmode:aSymbol
    "set matrix mode: #single, #viewing, #projection or #texture"

    "{ Symbol: single }"
    "{ Symbol: viewing }"
    "{ Symbol: projection }"
    "{ Symbol: texture }"

%{  /* NOCONTEXT */
#ifdef GLX
    if (aSymbol == _single) {
        mmode(MSINGLE);
        RETURN (true);
    }
    if (aSymbol == _viewing) {
        mmode(MVIEWING);
        RETURN (true);
    }
    if (aSymbol == _projection) {
        mmode(MPROJECTION);
        RETURN (true);
    }
    if (aSymbol == _texture) {
        mmode(MTEXTURE);
        RETURN (true);
    }
#endif
%}
.
    ^ false
!

glxBeginPolygon
    "start a polygon definition"

%{  /* NOCONTEXT */
#ifdef GLX
    bgnpolygon();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxEndPolygon
    "end a polygon definition"

%{  /* NOCONTEXT */
#ifdef GLX
    endpolygon();
    RETURN (true);
#endif
%}
.
    ^ false
!

glxLoadMatrix:arrayOf16Floats
    "argument must be an array(a matrix) of 16 floats containing the
     transformation matrix"

%{  /* NOCONTEXT */
#ifdef GLX
    OBJ cls;
    extern OBJ FloatArray, DoubleArray, Array;
    Matrix matrix;
    int nByte;
    OBJ o;

    cls = _Class(arrayOf16Floats);
    nByte = _qSize(arrayOf16Floats) - OHDR_SIZE;

    do {
        /* best speed for float array */
        if (cls == FloatArray) {
            int x = 0;
            int i,j;

            if (nByte < (16 * sizeof(float))) break;
            for (i=0; i<4; i++) {
                for (j=0; j<4; j++) {
                    matrix[i][j] = _FloatArrayInstPtr(arrayOf16Floats)->f_element[x];
                    x++;
                }
            }
            loadmatrix(matrix);
            RETURN (true);
        }
        /* a little bit slower for double array */
        if (cls == DoubleArray) {
            int x = 0;
            int i,j;

            if (nByte < (16 * sizeof(double))) break;
            for (i=0; i<4; i++) {
                for (j=0; j<4; j++) {
                    matrix[i][j] = _DoubleArrayInstPtr(arrayOf16Floats)->d_element[x];
                    x++;
                }
            }
            loadmatrix(matrix);
            RETURN (true);
        }
        /* a little bit slower for normal array of floats */
        if (cls == Array) {
            int x = 0;
            int i,j;

            if (nByte < (16 * sizeof(OBJ))) break;
            /* get elements one-by-one */
            for (i=0; i<4; i++) {
                for (j=0; j<4; j++) {
                    o = _ArrayInstPtr(arrayOf16Floats)->a_element[x];
                    if (! _isFloat(o)) goto bad;
                    matrix[i][j] = _floatVal(o);
                    x++;
                }
            }
            loadmatrix(matrix);
            RETURN (true);
        }
bad: ;
    } while(0);
#endif
%}
.
    ^ false
!

glxN3f:arrayOf3FloatsWithNormal
    "argument must be an array of 3 floats containing the
     current vertex normal"

%{  /* NOCONTEXT */
#ifdef GLX
    OBJ cls;
    extern OBJ FloatArray, DoubleArray, Array;
    float vector[3];
    int nByte;
    OBJ o;

    cls = _Class(arrayOf3FloatsWithNormal);
    nByte = _qSize(arrayOf3FloatsWithNormal) - OHDR_SIZE;

    do {
        /* best speed for float array */
        if (cls == FloatArray) {
            if (nByte < (3 * sizeof(float))) break;
            n3f(_FloatArrayInstPtr(arrayOf3FloatsWithNormal)->f_element);
            RETURN (true);
        }
        /* a little bit slower for double array */
        if (cls == DoubleArray) {
            if (nByte < (3 * sizeof(double))) break;
            vector[0] = _DoubleArrayInstPtr(arrayOf3FloatsWithNormal)->d_element[0];
            vector[1] = _DoubleArrayInstPtr(arrayOf3FloatsWithNormal)->d_element[1];
            vector[2] = _DoubleArrayInstPtr(arrayOf3FloatsWithNormal)->d_element[2];
            n3f(vector);
            RETURN (true);
        }
        /* a little bit slower for normal array of floats */
        if (cls == Array) {
            if (nByte < (3 * sizeof(OBJ))) break;
            /* get elements one-by-one */
            o = _ArrayInstPtr(arrayOf3FloatsWithNormal)->a_element[0];
            if (! _isFloat(o)) break;
            vector[0] = _floatVal(o);
            o = _ArrayInstPtr(arrayOf3FloatsWithNormal)->a_element[1];
            if (! _isFloat(o)) break;
            vector[1] = _floatVal(o);
            o = _ArrayInstPtr(arrayOf3FloatsWithNormal)->a_element[2];
            if (! _isFloat(o)) break;
            vector[2] = _floatVal(o);
            n3f(vector);
            RETURN (true);
        }
    } while(0);
#endif
%}
.
    ^ false
!

glxC3f:arrayOf3FloatsWithColor
    "argument must be an array of 3 floats containing the color"

%{  /* NOCONTEXT */
#ifdef GLX
    OBJ cls;
    extern OBJ FloatArray, DoubleArray, Array;
    float vector[3];
    int nByte;
    OBJ o;

    cls = _Class(arrayOf3FloatsWithColor);
    nByte = _qSize(arrayOf3FloatsWithColor) - OHDR_SIZE;

    do {
        /* best speed for float array */
        if (cls == FloatArray) {
            if (nByte < (3 * sizeof(float))) break;
            c3f(_FloatArrayInstPtr(arrayOf3FloatsWithColor)->f_element);
            RETURN (true);
        }
        /* a little bit slower for double array */
        if (cls == DoubleArray) {
            if (nByte < (3 * sizeof(double))) break;
            vector[0] = _DoubleArrayInstPtr(arrayOf3FloatsWithColor)->d_element[0];
            vector[1] = _DoubleArrayInstPtr(arrayOf3FloatsWithColor)->d_element[1];
            vector[2] = _DoubleArrayInstPtr(arrayOf3FloatsWithColor)->d_element[2];
            c3f(vector);
            RETURN (true);
        }
        /* a little bit slower for normal array of floats */
        if (cls == Array) {
            if (nByte < (3 * sizeof(OBJ))) break;
            /* get elements one-by-one */
            o = _ArrayInstPtr(arrayOf3FloatsWithColor)->a_element[0];
            if (! _isFloat(o)) break;
            vector[0] = _floatVal(o);
            o = _ArrayInstPtr(arrayOf3FloatsWithColor)->a_element[1];
            if (! _isFloat(o)) break;
            vector[1] = _floatVal(o);
            o = _ArrayInstPtr(arrayOf3FloatsWithColor)->a_element[2];
            if (! _isFloat(o)) break;
            vector[2] = _floatVal(o);
            c3f(vector);
            RETURN (true);
        }
    } while(0);
#endif
%}
.
    ^ false
!

glxV3f:arrayOf3FloatsWithVertex
    "argument must be an array of 3 floats containing the vertex"

%{  /* NOCONTEXT */
#ifdef GLX
    OBJ cls;
    extern OBJ FloatArray, DoubleArray, Array;
    float vector[3];
    int nByte;
    OBJ o;

    cls = _Class(arrayOf3FloatsWithVertex);
    nByte = _qSize(arrayOf3FloatsWithVertex) - OHDR_SIZE;

    do {
        /* best speed for float array */
        if (cls == FloatArray) {
            if (nByte < (3 * sizeof(float))) break;
            n3f(_FloatArrayInstPtr(arrayOf3FloatsWithVertex)->f_element);
            RETURN (true);
        }
        /* a little bit slower for double array */
        if (cls == DoubleArray) {
            if (nByte < (3 * sizeof(double))) break;
            vector[0] = _DoubleArrayInstPtr(arrayOf3FloatsWithVertex)->d_element[0];
            vector[1] = _DoubleArrayInstPtr(arrayOf3FloatsWithVertex)->d_element[1];
            vector[2] = _DoubleArrayInstPtr(arrayOf3FloatsWithVertex)->d_element[2];
            n3f(vector);
            RETURN (true);
        }
        /* a little bit slower for normal array of floats */
        if (cls == Array) {
            if (nByte < (3 * sizeof(OBJ))) break;
            /* get elements one-by-one */
            o = _ArrayInstPtr(arrayOf3FloatsWithVertex)->a_element[0];
            if (! _isFloat(o)) break;
            vector[0] = _floatVal(o);
            o = _ArrayInstPtr(arrayOf3FloatsWithVertex)->a_element[1];
            if (! _isFloat(o)) break;
            vector[1] = _floatVal(o);
            o = _ArrayInstPtr(arrayOf3FloatsWithVertex)->a_element[2];
            if (! _isFloat(o)) break;
            vector[2] = _floatVal(o);
            n3f(vector);
            RETURN (true);
        }
    } while(0);
#endif
%}
.
    ^ false
! !