Gleemex is a high-level interface to OpenGL functionality for GNU Octave and MATLAB. It uses FreeGLUT to provide windowing and peripheral access for various platforms, GLEW for determining OpenGL features, and the MEX API to communicate with the host program. It allows writing interactive graphical applications entirely in the M scripting language.
The graphics systems of MATLAB and Octave are geared towards producing plots of moderate complexity for offline display and printout, but are less suited for writing applications that interact with the user. Gleemex enables the creation of event-driven graphical tools, on one hand aiming at simplicity of usage, but without sacrificing performance where it is needed. Its main virtues are in
-
Being a higher level interface to OpenGL. Thus, rather than exposing OpenGL functions directly, they are wrapped in commands that perform a composite function. At the same time, it tries to add as little overhead as possible.
-
Providing safety as a consequence of the above. It must not be possible to invoke erratic behavior (such as crashes caused by accessing memory out of some allowed bounds) by providing invalid data to Gleemex. Input is validated where necessary. If undefined behavior can be invoked from M code, it is always a Gleemex bug.
-
Aiming at simplicity of both usage and concept. For example,
-
After creating a window and adding the desired callbacks, starting the FreeGLUT main loop makes it run in a single thread of execution. This is in contrast to the native MATLAB "handle graphics" system, that allows for some form of concurrency, sometimes making program behavior hard to predict.
-
Drawing proceeds in a "fire and forget" fashion familiar from game programming. Instead of having to manage objects (such as lines) by writing separate code for their creation, potential update, and deletion, a customary Gleemex app only keeps some state in a global M variable. In the display callback, that state is then used to render one frame.
-
-
Being strict with regard to errors. Any error from M code while the main loop is active makes Gleemex close all of its windows and report it. This eases debugging of graphical apps, since otherwise an erroneous condition may produce followup failures, obscuring the original cause.
The Gleemex core is implemented in a single source file, glcall.c
. On a
supported combination of OS, architecture and M-language implementation, and
assuming a compatible C compiler is installed (see help mex
), running
mkglcall
usually suffices to build a dynamically loaded MEX library that can
be used with the given setup.
Gleemex depends on FreeGLUT and GLEW. For convenience, on Windows, GLEW is packaged together with Gleemex and does not need to be installed separately.
The glcall
MEX function is the only entry point to Gleemex. It consolidates
various sub-functions which are selected depending on the first argument passed
to it, the command. Invoking glcall
without input arguments returns a
struct containing a mapping of names to numeric constants denoting these
commands, as well as those of callback functions to be registered once a window
has been created.
This struct should be stored in a global named glc
.
Another function, glconstants
, returns a struct containing mappings for
OpenGL and FreeGLUT constants, together with some auxiliary definitions. By
convention, it is stored into a global GL
. [Note: Conceptually, one does
not need to use the names glc
and GL
. However, currently Gleemex
references these named globals in M-file auxiliary functions "behind a user's
back" without first assigning to them. In the future, the restriction to use
these particular names may be lifted by substituting the numerical values for
these references.]
Thus, in the "main" function of an application, one usually initializes these two globals for future use as follows:
hello_gleemex.m
function hello_gleemex()
global GL glc
glc = glcall();
GL = glconstants();
% ...
end
Callback functions are user-defined functions that are invoked when a
particular event, such as a mouse press, happens. Because the MEX API provides
no means of inspecting function handle objects, callbacks are passed to
Gleemex by name. For example, the preceding hello-world app could register
a display callback named hg_display
like this:
function hello_gleemex()
% ...
glcall(glc.setcallback, glc.cb_display, 'hg_display');
% ...
end
function hg_display()
global GL glc
glcall(glc.clear, [1 0 0]); % clear the window to a red color
end
How the actual function corresponding to a particular name is looked up
differs between Octave and MATLAB. In Octave, it is possible to call secondary
functions by name when the primary function is active, but only when the latter
(here, hello_gleemex
) has been invoked from the top level!
In MATLAB, secondary functions appear to never be considered. For this reason,
they can either be written in separate files from the start, or have to be
extracted from the common file. A helper function extractsecfuncs
is provided
for this task.
Creates a new (sub-)window with the given properties and a separate, new OpenGL context. To make the window do something useful, it needs to have callbacks attached afterwards.
CAUTION: Gleemex windows and MATLAB handle graphics figures should never be open at the same time. Mixing them may entail crashes or other undesired behavior.
-
WINDOWNAME
: the name of the window, to be shown in the top bar -
POS
: the initial (x, y) position of the window, must be of typedouble
-
EXTENT
: the initial (width, height) pair of the window, must be of typedouble
When creating a top-level window (
OPTS.subwindow
not given or false),POS
andEXTENT
are passed toglutInitWindowPosition
andglutInitWindowSize
, respectively. Otherwise, they are passed toglutCreateSubWindow
. -
OPTS
: A struct containing additional options:-
subwindow
: If true, creates a sub-window in the current window instead of a new top-level one. -
menus
: A special kind of struct (called menu struct from now on) that defines a menu to be opened when a particular mouse button is pressed in the window to be created. The menu has some top-level properties and may recursively include sub-menus. Consequently, some of its fields may only appear in the outermost struct, while others are also allowed to exist in those nested deeper.button
(top level only): the button that needs to be pressed in order to open the menucbfunc
: The name of the callback function to be invoked when the user activates a menu entry. It may appear in both root and child menu structs, with semantics detailed below.entries
: A cell array{ e_1, e_2, ..., e_n }
sequence of the menu's entries, in the order they ultimately appear. An elemente_i
can be either a leaf that can be activated, or another sub-menu. Where this cell's element is a string, the entry is considered a leaf, and the string is taken as its label in the menu. Otherwise, the element is expected to be a menu struct describing the child, and its label is taken from the child'slabel
field.label
: (child only): the label of the sub-menu which this menu struct describes in its parent's menu
-
When the user activates a menu entry, a suitable callback function is searched first. Conceptually, this is done by traversing the menu tree, starting at the selected entry and working towards the root (i.e. following the parent links). When a menu struct containing a
cbfunc
field is encountered, the named function is invoked with two arguments:cbfunc(label, idx)
.label
: the label of the menu entry, as given in the menu structidx
: TODO (not yet specified)
-
The return value WINID
is a small integer identifying the window for as long
as it is live. Note that it is not the identifier passed from FreeGLUT but
one specific to Gleemex. Its values are in the range [1 .. MAXACTIVEWINDOWS
],
where at most MAXACTIVEWINDOWS
can be open at the same time (currently,
32). The identifiers of windows that have been closed may subsequently be
reused.
The FreeGLUT window index can be obtained in the second output argument
GLUTWINID
. Currently, the only place where Gleemex accepts a FreeGLUT window
index is as the second element of a pair to glc.set
/ GL.WINDOW_ID
.
Closes the window given by the Gleemex identifier WINID
, or the current
window if WINID
is omitted.
Sets the specified callback CALLBACK_KIND
of the current window to the
function named CBFUNC_NAME
. The following values are permissible for
CALLBACK_KIND
; the names in angle brackets denote the respective GLUT
registration functions.
-
glc.cb_display
, [glutDisplayFunc
]Invoked with no arguments when the windows is about to be redrawn. At the end, Gleemex always issues a call to
glutSwapBuffers()
.
-
glc.cb_reshape
, [glutReshapeFunc
]Invoked with two arguments
(width, height)
when the window has been resized, and on initialization. Thus, it is possible to e.g. set up a projection matrix in this callback. If no custom reshape callback is registered, Gleemex registers one that issuesglViewport(0, 0, width, height)
. -
glc.cb_position
, [glutPositionFunc
]Invoked with two arguments
(x, y)
when the window is repositioned/moved programatically or by the user. -
glc.cb_keyboard
, [glutKeyboardFunc
,glutSpecialFunc
]Invoked with four arguments
(key, x, y, mods)
when a keyboard key has been pressed. Gleemex consolidates the two GLUT callback functions into one for ease of use. Thekey
argument can be checked for equality with either a single-character string such as'a'
, or with constantsGL.KEY_*
. Themods
argument denotes which modifier keys are pressed and can be checked against theGL.MOD_*
bit constants.NOTE: For "key chords" such as
Ctrl + a
, FreeGLUT may pass different combinations ofkey
andmods
on different platforms.
-
glc.cb_mouse
, [glutMouseFunc
]Invoked with five arguments
(button, downp, x, y, mods)
when a mouse button is pressed (downp
is true) or released (downp
is false). Thebutton
arguments can be checked against theGL.BUTTON_*
andGL.MWHEEL_*
bit constants,mods
are the pressed modifier keys as with the keyboard callback.NOTE: The reported position has the origin at the origin at the topmost and leftmost pixel. Thus, it is reversed with
glc_setup2d
in the y screen dimension.
-
glc.cb_motion
, [glutMotionFunc
,glutPassiveMotionFunc
]Invoked with three arguments
(buttons, x, y)
when the mouse is moved. Thebuttons
argument has theGL.BUTTON_*
bits set which are depressed at the time the movement happens. The(x, y)
position is reported like for thecb_mouse
callback.NOTE: Currently,
buttons
may not be entirely reliable in multi-window scenarios.
Enters the FreeGLUT main loop once. Issuing glc.entermainloop
while the main
loop is active is a no-op.
Instructs FreeGLUT to stop executing the main loop. This will close all
Gleemex windows and return to the prompt of the M-language implementation.
In most cases, glc.closewindow
should be preferred.
Returns information about the last error.
Currently, on Octave, when an error happens, Gleemex immediately issues
mexErrMsgText
and thus effectively jumps back to the prompt. TODO: it is
not clear by itself that this is correct, i.e. doesn't leak resources (or
worse).
On MATLAB, issuing mexErrMsgText
while the FreeGLUT main loop is active has
been found to produce crashes, which is why a different approach is taken: the
error message is backed up in persistent variables, and control is returned to
the prompt by normally returning from all active Gleemex functions and
terminating the FreeGLUT main loop.
The glc.geterrstr
command can be used to query the messages of the last error
(STR1
and STR2
) as well as obtain the MException
associated with it,
EX
, from the MATLAB prompt. Thus, after your Gleemex app terminates
abnormally, you would usually issue
global glc
[a,b,c] = glcall(glc.geterrstr);
c.getReport()
to pretty-print the error together with a backtrace.
Sets the viewport by calling glViewport
with the elements of XYWH
, which
must be a 4-vector of type double
.
Defines a scissor box by calling glScissor
with the elements of XYWH
,
which must be a 4-vector of type int32
.
Toggles the enable state of various server-side GL capabilities.
-
KV_PAIRS
: A vector of even length containing successive pairs ofKEY
andVALUE
. Must be of typeint32
; this is automatically ensured ifKV_PAIRS
is constructed as concatenation of values containingGL.*
values, as detailed below.-
KEY
: An allowed GL constant denoting the capability: one ofGL.DEPTH_TEST
,GL.SCISSOR_TEST
,GL.BLEND
,GL.POINT_SMOOTH
,GL.LINE_SMOOTH
,GL.LINE_STIPPLE
,GL.POLYGON_SMOOTH
,GL.POLYGON_OFFSET_POINT
,GL.POLYGON_OFFSET_LINE
,GL.POLYGON_OFFSET_FILL
,GL.FOG
. -
VALUE
: 1 for enabling the capability, 0 for disabling it, or -1 for flipping its enable state.
-
-
OLDSTATE
: anint32
vector of the same size and format asKV_PAIRS
containing the old enable state of the requested capabilities. It can be passed to a laterglc.toggle
call to restore that state.
Example:
% enable depth testing and blending
glcall(glc.toggle, [GL.DEPTH_TEST 1, GL.BLEND 1]);
Pushes or pops the matrix or server attribute
stack. WHAT
is a vector of constants denoting what to push or pop: allowed
values are
GL.PROJECTION
,GL.MODELVIEW
andGL.TEXTURE
for the respective matrices- The
GL.*_BIT
constants for the sets of attributes documented inglPushAttrib
Sets the GL and FreeGLUT state variable denoted by WHAT
to a new
value. WHAT
can be one of the following named Gleemex constants:
-
GL.MENU_ENABLE
:VALUE
is a scalar logical of whether to enable the menu in the current window. -
GL.MOUSE_POS
:VALUE
is a 2-vector of typedouble
whose elements are passed toglutWarpPointer
. The values must be greater or equal 0 and less that or equal to the width/height of the window. -
GL.WINDOW_ID
: TODO -
GL.WINDOW_SIZE
: TODO -
GL.POINT_SIZE
:VALUE
is adouble
-typed scalar passed toglPointSize
. -
GL.LINE_WIDTH
:VALUE
is adouble
-typed scalar passed toglLineWidth
. -
GL.LINE_STIPPLE_PATTERN
:VALUE
is auint16
-typed scalar passed as the pattern toglLineStipple
. For the factor argument, 1 is passed. -
GL.BLEND_EQUATION
:VALUE
is a GL constant permissible toglBlendEquation
:GL.MIN
,GL.MAX
,GL.FUNC_ADD
,GL.FUNC_SUBTRACT
orGL.FUNC_REVERSE_SUBTRACT
. -
GL.DEPTH_FUNC
:VALUE
is a GL constant permissible toglDepthFunc
:GL.NEVER
,GL.LESS
,GL.EQUAL
,GL.LEQUAL
,GL.GREATER
,GL.NOTEQUAL
,GL.GEQUAL
orGL.ALWAYS
. -
GL.DEPTH_WRITEMASK
:VALUE
is a scalar logical, whose corresponding GL value (GL.TRUE
orGL.FALSE
) is passed toglDepthMask
. -
GL.POLYGON_OFFSET
:VALUE
is a pair ofsingle
-typed values, which are passed as the two arguments factor and units ofglPolygonOffset
.
Gets the current value of the GL or FreeGLUT state variable denoted by WHAT
.
GL.WINDOW_ID
: seeglc.set
GL.WINDOW_SIZE
: seeglc.set
GL.WINDOW_POS
: TODOGL.POINT_SIZE
GL.PROJECTION_MATRIX
,GL.MODELVIEW_MATRIX
:VALUE
is a 4-by-4double
-typed matrix.
Sets the GL.PROJECTION
or GL.MODELVIEW
matrix (selected by WHICH
) to M
,
which must be a double
-typed array and can be one of the following:
- An empty array
[]
is interpreted to reset the respective matrix to the identity matrix. - A 4-by-4 matrix is passed unmodified to
glLoadMatrixd
. - For
GL.PROJECTION
, it is possible to pass a vector of length 4 or 6.- The elements of a 4-vector are passed to
gluPerspective
. - The elements of a 6-vector are passed to
glOrtho
.
- The elements of a 4-vector are passed to
Multiplies the GL.PROJECTION
or GL.MODELVIEW
matrix (selected by WHICH
)
with M
, which must be a double
-typed array and can be one of the following:
- A 4-by-4 matrix is passed unmodified to
glMultMatrixd
. - The elements of a 3-vector are passed to
glTranslated
. - The elements of a 4-vector are passed to
glRotated
.
Sets the fog parameters and color.
FOG_MODE
: one ofGL.LINEAR
,GL.EXP
orGL.EXP2
FOG_PARAM
: forGL.LINEAR
fog, a 2-vector specifying the near and far distances for the linear fog equation. Otherwise, the fog density. Must have numeric typesingle
.FOG_COLOR
: a 4-vector ofsingle
numeric type specifying the color of the fog
Clears the depth buffer to 1. Also, if COLOR
is provided as an
(R, G, B [, A])
vector of type double
, the color buffer is cleared to that
value.
Passes vertex data to OpenGL, instructing it to draw them as primitives of
PRIMITIVE_TYPE
and optionally providing face indices, colors and/or texture
coordinates.
-
PRIMITIVE_TYPE
: The kind of geometric primitive to draw, one of
GL.POINTS
,GL.LINES
,GL.LINE_LOOP
,GL.LINE_STRIP
,GL.TRIANGLES
,GL.TRIANGLE_STRIP
,GL.TRIANGLE_FAN
,GL.QUADS
,GL.QUAD_STRIP
orGL.POLYGON
.
If 16 is added toPRIMITIVE_TYPE
, only the outlines of polygons are drawn. (TODO: make a symbolic constant?) -
VERTEXDATA
: A(K, NumTotalVerts)
matrix of floating numeric type containing the vertex coordinates of the primitives.K
: The number of dimensions. Can be 2, 3 or 4, corresponding to x, y, z and/or w coordinates.NumTotalVerts
: The total number of vertices, must be consistent with the givenPRIMITIVE_TYPE
. For example, requestingGL.LINES
expectsNumTotalVerts
to be even.
-
OPTSTRUCT
: A struct that can be used to pass additional data. May contain the following fields:-
colors
: The(R, G, B [, A])
colors. Can be either a vector of length 3 or 4, in which case all vertices are given that color, or a(3 or 4, NumTotalVerts)
matrix, specifying a separate color for each vertex. Must have typedouble
,single
oruint8
.
If no colors are passed, the default one is white when a texture is provided, and (0.5, 0.5, 0.5) otherwise.
As a special convenience feature, if a 5-tuple[R G B A true]
is passed, then blending is enabled temporarily. -
indices
: Zero-based indices into the columns ofVERTEXDATA
used to construct the primitives. SeeglDrawElements
. Must have index type (uint8
oruint32
).
Whenindices
are passed, the number of drawn vertices equals the number of elements inindices
(the dimensions don't matter), and each of its elements must be less thanNumTotalVerts
. This bound check has to be done everyglc.draw
call, so providing a large amount of indices may be expensive. -
normals
: a floating type matrix of the same size asVERTEXDATA
, giving the normals for each vertex. -
tex
: The OpenGL texture name (a non-zerouint32
number as returned byglc.texture
) with which the primitives are to be textured. -
texcoords
: The s and optionally t texture coordinates at each vertex. Must be a(1 or 2, NumTotalVerts)
matrix of floating numeric type. Must be passed whenevertex
is passed.
-
Renders a line of text using a FreeGLUT's Roman stroke font.
Assuming that glc_setup2d
has been used to set up a 2D view,
the string TEXT
is drawn at pixel position POS
and with height HEIGHT
(which should be a double
-typed 2-vector and scalar, respectively). TEXT
should not contain newlines.
-
XYALIGN
: an optionaldouble
-typed 2-vector[xalign yalign]
specifying the horizontal and vertical alignment of the text.- -1: align on left/bottom (i.e. towards negative coordinates)
- 0: align at the center
- 1: align on right/top
-
OPTS
: an option struct which may contain the following fields:colors
: a 3-vector of typedouble
giving the(R, G, B)
color of the textxgap
: The distance between successive characters, expressed as a proportion of the width of the space character. The default is a value that was experimentally determined to look good. Must havedouble
type.mono
: a scalar logical of whether to use the monospaced Roman font
With no additional arguments, issues glutPostRedisplay
. If NOW
is
passed, it should be a scalar logical; if NOW
is true, glutSwapBuffers
is
issued instead.
Reads a block of pixels from the framebuffer using the GL_RGB
format. If XYWH
is passed (which must be a double
-typed 4-vector), its
elements are passed to the x, y, width and height arguments of
glReadPixels
. Otherwise, the default is to grab the whole window.
PIXELS
is returned as a 3-by-width-by-height uint8
array.
Uploads an image TEXIMG
for a texture, either creating a new
GL texture name TEXID
(first form) or reusing an already given texture name
(second form). Various options in OPTS
allow either modifying certain aspects
of the texture rendering such as its filtering, or control how TEXIMG
itself
is interpreted.
The format and type of a color component of the texture is determined by
various properties of TEXIMG
:
-
TEXIMG
can be awidth
-by-height
matrix. In this case, it is uploaded using theGL_LUMINANCE
format. As a special case, ifOPTS.u32rgba
is given and true,TEXIMG
must have classuint32
and the 32-bit unsigned integers are interpreted as RGBA quadruplets (least significant byte is red). -
TEXIMG
can be ak
-by-width
-by-height
array, withk
being the number of color components in the texture. It can be one of 2, 3 or 4, in which case the texture is uploaded inGL_LUMINANCE_ALPHA
,GL_RGB
orGL_RGBA
format, respectively. -
TEXIMG
may have eithersingle
numeric class, or one of[u]int{8,16,32}
.
OPTS
may be a struct containing the following fields:
-
u32rgba
: described above -
minmag
: a scalar or 2-vector containing the GL constants denoting the minification and magnification filters. Each one can beGL.NEAREST
orGL.LINEAR
. If a scalar is passed, both filters are set to the given mode. The default isGL.LINEAR
.
Currently, there is no way to set the texture's wrapping mode: it is always set
to GL_CLAMP_TO_EDGE
. Uploading mipmaps is not supported, either.
Deletes the textures named by the elements of the vector
TEXIDS
.
Uploads a colormap texture and binds it as a one-dimensional texture to a
texture unit different from GL_TEXTURE0
. The texture is set to linear
filtering and GL_CLAMP_TO_EDGE
wrapping.
COLORMAP
: must be a 3-by-256uint8
matrix of (R, B, G) colors.
This command allows using the so registered colormap from fragment shaders. See the notes labeled COLORMAP_DEF below.
Creates a program object to be run on the programmable vertex and/or fragment
processor of the graphics processing unit. The program can have at most one
vertex shader and at most one fragment shader attached. Their
sources are provided in FRAGSHADERSRC
and VERTSHADERSRC
, respectively,
where passing an empty string means that the particular shader should not be
compiled as part of the program.
Vertex and fragment shaders are written in the OpenGL Shading Language. See the 1.20 or 1.50 specification for an easier introduction, or the newer versions for a more complete overview.
If either the creation of a shader or program object failed, or there was an error with compilation or linking, an M error is issued.
COLORMAP_DEF: If the fragment shader contains a uniform variable named
cmap
, it must be declared with uniform sampler1D
type. The vertex shader
must not contain a variable with that name. In the shader, you can sample the
colormap texture, for example
uniform sampler1D cmap;
int main(void) {
// ...
float val = /* (some value in [0 .. 1] */;
vec3 rgb = texture1D(cmap, val).rgb; // get the RGB triplet for 'val'
// ...
}
On success, returns
-
PROGID
: an identifier by which the created program can be referenced. The program is not enabled by creating it, useglc.useprogram
for this. -
UNIFORMS
: a struct mapping active uniform variable names that are also valid MATLAB identifiers to Gleemex-specific handles permissible toglc.setuniform
. Only names of user-defined uniform variables with the following types are listed (the variables may be either scalars or arrays of these base types):- base scalars:
GL_BOOL
,GL_FLOAT
,GL_INT
- base vectors:
GL_{BOOL,INT,FLOAT}_VEC{2,3,4}
- base scalars:
If PROGID
is passed, enables usage of that program previously
created with glc.newprogram
. Otherwise, disables any program for the
programmable processors and reverts to OpenGL fixed functionality for both
vertex and fragment processing.
COLORMAP_DEF: When enabling a program, if the fragment shader contains
a cmap
uniform variable, it it set to the texture unit to which the texture
uploaded with glc.colormap
binds.
Sets the value of a uniform variable in the currently active program.
-
UNIFORMHANDLE
: The Gleemex handle denoting a uniform variable as returned as one of the keys of theUNIFORMS
mapping fromglc.newprogram
. -
VAL
: A value consistent with the type and size of the corresponding uniform variable.-
For
GL_FLOAT
-typed uniforms, values of M typesingle
are expected. For uniforms of typeGL_BOOL
orGL_INT
, values of M typeint32
should be passed. -
For scalar uniforms,
VAL
should contain as many elements as suggested by the base type: a single element forGL_{BOOL,FLOAT,INT}
and 2, 3 or 4 forGL_*_VEC{2,3,4}
(respectively). -
For array uniforms,
VAL
should have length equal to the length of the array, times the base element count as described with the previous point.
-
GL2PS is a library that can output geometry passed to OpenGL in
various vector formats. Gleemex provides an interface to GL2PS if it was
compiled with GL2PS support (see mkglcall
).
The constants needed by the interface reside in the GL
struct under names
like GL.PS_TIGHT_BOUNDING_BOX
. That is, they're like the corresponding
GL2PS_*
C defines with the 2
omitted.
An example of GL2PS usage is given by the simpleplot
application packaged
together with Gleemex.
Return whether Gleemex was compiled with GL2PS support, that is, if the
glc.beginpage
command is available.
Begin collecting OpenGL drawing commands for eventual output
to file FILENAME
and issue a redisplay request to
FreeGLUT. The collection will last until the ensuing display callback returns,
after which a call to gl2psEndPage()
is issued. Thus, whether it succeeded
only becomes known afterwards.
-
FORMAT
: one ofGL.PS_PS
,GL.PS_EPS
,GL.PS_PDF
orGL.PS_SVG
. The two LaTeX formats are not (yet) available. -
SORTMODE
: one ofGL.PS_NO_SORT
,GL.PS_SIMPLE_SORT
orGL.PS_BSP_SORT
. -
OPTIONS
: a bitwise-OR of individualGL.PS_*
plot option bits, except that the following ones are not available:PS_SILENT
,PS_NO_TEXT
,PS_NO_PIXMAP
; andPS_USE_CURRENT_VIEWPORT
which is automatically set by Gleemex. If no options are to be passed,GL.PS_NONE
should be used. -
BUFSIZE
: the size of the feedback buffer -
FILENAME
: the name of the file where the output is to be written -
STATUS
: an indication of success or failure.- 0: starting the geometry collection was successful
- 1: failed to open a write-only file named
FILENAME
- 2:
gl2psBeginPage()
returnedGL2PS_ERROR
. This could mean that the width or height of the current viewport is zero.
As noted above, the knowledge of ultimate success only becomes available after
the return of the subsequent display callback. The following form of
glc.beginpage
allows one to examine this status then.
(Note that there is no separate "glc.endpage
" command.)
Retrieves the return value of the last gl2psEndPage()
call as one of the GL2PS status constants: GL.PS_SUCCESS
, GL.PS_ERROR
,
GL.PS_NO_FEEDBACK
, GL.PS_OVERFLOW
or GL.PS_UNINITIALIZED
.
Currently, when glcall(glc.beginpage, ...)
returned 2 for STATUS
or this
form's ENDSTATUS
is anything other than GL.PS_SUCCESS
, the file FILENAME
remains on the system and may be empty.
Returns a string for the status code of gl2psEndPage()
. It is the lowercased
version of the corresponding GL.PS_*
error code define, for example
'no_feedback'
for GL.PS_NO_FEEDBACK
.
Calls glcall(glc.beginpage, ...)
with the provided arguments, expect that
FILEPREFIX
automatically gets an extension appended based on the value of
FORMAT
and the GL.PS_COMPRESS
bit of OPTIONS
.
STATUS
: one of theglcall(glc.beginpage, ...)
return values (0, 1 or 2), or -1 if Gleemex was compiled without GL2PS support.FILENAME
: In case of success (STATUS
is 0),FILEPREFIX
with an appended extension.
Gleemex provides a number of convenience functions built on top of the basic
glcall
routines as well as helper routines designed to aid in application
development.
Sets up the viewport and projection matrix suitable for 2D drawing in a window
of size WIDTH
and HEIGHT
, and resets the modelview matrix to the identity
matrix. In the so constructed view, position (1, 1) denotes the center of the
leftmost and bottommost pixel.
NOTE: glc_setup2d
achieves the above-mentioned convention by calling
glc.setmatrix
/ GL.PROJECTION
with a 6-vector, where the
first four values are 0, WIDTH
, 0 and HEIGHT
, to all of which 0.5 is added.
The last two values are those given by ZRANGE
, or [-1 1]
by default.
Sets up an "axes" as a rectangular region of the current window given by
VIEWPORT_XYWH
, which should be a 4-vector permissible to
glc.viewport
. Drawing commands between a call to
glc_axes_setup
and a closing glc_axes_finish
will never draw outside this
region. The PROJECTION
argument can be anything permissible to
glc.setmatrix
; the modelview matrix is reset to the
identity matrix.
Always returns true
.
NOTE: glc_axes_setup
pushes the following matrices and server-side attribute
bits: GL.PROJECTION
, GL.MODELVIEW
,
GL.VIEWPORT_BIT+GL.SCISSOR_BIT+GL.ENABLE_BIT
. Additional attribute bits may
be pushed by passing ADDITIONAL_BITS
.
Restores the matrices and server attributes pushed by glc_axes_setup
.
TODO
TODO
TODO
Returns the value VAL
of the variable named VARNAME
in the base workspace if
one exists. OK
is true then.
If no variable named VARNAME
exists, OK
is false and the empty array []
is returned for VAL
.
Using the GLCApplicationData
handle class provided by Gleemex, it is possible
to create Gleemex applications that may be present in multiple instances at the
same time. For a particular application, the user creates a class derived from
GLCApplicationData
and populates it with the desired application-specific
functionality.
In the following, assume that MyApplicationData
is a classdef class derived
from GLCApplicationData
.
Creates an object of MyApplicationData
; each object represents an instance of
a particular application, similar to the relation of a process to one
particular program at the OS level.
The GLCApplicationData
constructor initializes some of its members to default
values:
ad.mxy = [1 1] % current mouse position
ad.mbutton = 0 % currently pressed mouse buttons
ad.wh = [800 600] % width and height of the app window
CAUTION: These members may become private in the future.
The initial height and width may be overridden by passing a WH
pair to the
GLCApplicationData
constructor in that of the derived class, like this:
function self = MyApplicationData(wh)
self@GLCApplicationData(wh);
% additional initialization goes here...
end
Registers an object obj
of a class derived from GLCApplicationData
with the
window identifier winid
, as returned by
glc.newwindow
. This association is not cleared until
another call of GLCApplicationData.register
with the same winid
-- for
example, it persists after closing the app's window.
Retrieves all objects and window identifiers of the class named className
--
for example, 'MyApplicationData'
-- previously registered with
GLCApplicationData.register
.
-
activep
: Should be a scalar logical telling whether active, i.e. currently open windows should be considered. If false, those that are not active are returned -
objs
: a cell array vector having as many elements as there are (active or passive, depending onactivep
) windows of classclassName
. -
winids
: in the case ofactivep
being true, a vector of the same length, containing the respective Gleemex window identifiers
Registers callbacks for the current window. For each of the strings
'display'
, 'reshape'
, 'keyboard'
, 'mouse'
, 'motion'
and 'position'
,
a function name is constructed by concatenating it in between prefix
(which
must be non-empty) and suffix
(which is empty by default). Then, if a file
existence check for this name suffixed with '.m'
yields a positive result,
the corresponding callback function is registered.
The returned value nset
is the number of successfully registered callbacks.
Retrieves the object obj
previously registered with
GLCApplicationData.register
for the current window, as obtained with
glcall(glc.get, GL.WINDOW_ID)
. If no application data was registered with the
current window, the behavior is undefined.
Updates the window position with the new width w
and height h
, as obtained
from the reshape callback. If setup2d
is passed, it must be a
scalar logical; in case it is true, glc_setup2d
(w, h)
is
also called.
Updates the current mouse pointer position with the new mouse button state
buttons
and coordinates (x
, y
), as obtained from the mouse motion
callback. Internally, x
is stored as obtained, but the stored y
is the difference of the current window width and the passed y
.
Creates a new window and stores the Gleemex and FreeGLUT
window indices in private fields. The former one is returned in winid
.
The optional input argument opts
is passed to the glc.newwindow
call.
Tries to make the window of this GLCApplicationData
object current. A call to
the attachNewWindow
method must have previously taken place, otherwise an
error is issued. Before the switch, the window index of the old current window
is backed up in a private field, for later restoration by restoreOldWindow
.
-
ok
: a logical of whether making the application window succeeded. Failure can for example occur because the window has been destroyed. -
oldwinid
: the Gleemex window identifier of the window that was current prior to the call toad.makeCurrent
.
Changes the current window to that which was current before the last call to
the makeCurrent
method. The output argument ok
tells whether that
succeeded.
Calls glc.redisplay
for this ad
's window (registered with
attachNewWindow
), but wrapping it in backup and restoration of the current
one. The output argument ok
is from ad.makeCurrent()
and tells whether
this operation was performed.