LABTITLE=: 'OpenGL Introduction'
LABFOCUS=: 0

NB. =========================================================
Lab Section Introduction
OpenGL is a software interface to graphics hardware that allows you to create interactive, 3D images. As a J programmer, you have complete access to OpenGL.

OpenGL is available in the Windows JFE and in the Java JFE under Linux and Mac OS X.
)
PREPARE
clear''		NB. clear base locale
require 'gl2'
require 'gl3'
coinsert 'jgl2'
coinsert 'jgl3'
nextijs=: 3 : 0
if. -. '\' e. y. do.
y.=.jpath'~system\examples\graphics\opengl\lab\',y. end.
if. -. '.' e. y. do. y.=. y.,'.ijs' end.
d=.1!:1<y.
f=.jpath '~temp\ogl.ijs'
d 1!:2 <f
smopen_jijs_ f
smwrite_jijs_ ,d
smfocus_jijs_ ''
erase 'a_g_char a_g_size a_g_paint'
load f
)

testdlls=: 3 : 0
0!:0 <jpath'~system\extras\util\testogl.ijs'
'All OK.'
)

try=: load bind (jpath '~system\examples\graphics\opengl\simple\gldemos.ijs')
a_jctrl_fkey=: 3 : 0 :: ]
smselout_jijs_ ''
smfocus_jijs_ ''
lab_j_ 0
)
PREPARE

NB. =========================================================
Lab Section
This lab introduces the basic ideas of programming OpenGL. Everything is done directly and little use is made of utilities.

After you have mastered the basics you will probably want to make your life easier with the utilities provided to make your programming with OpenGL more effective. See the lab "OpenGL Utilities"
)

NB. =========================================================
Lab Section Demo
If you would like to see what can be done with OpenGL, try the OpenGL demo with menu command Studio|Demos...
)

NB. =========================================================
Lab Section System Requirements
3D Graphics requires lots of processor power, memory, and video capabilty.

3D graphics greatly benefits from a fast video card.
)

NB. =========================================================
Lab Section Color
Color is very important in 3D graphics. You can run with 8bit (256 color) or even 4bit (16), but you really will not see what is going on unless you have at least 16bit, i.e. 65536.

If high resolution prevents you from running with 16bit color due to insufficient video card memory, you should probably reconfigure to run at a lower resolution (even VGA) in order to get as many colors as possible.
)

NB. =========================================================
Lab Section J Forms
This lab assumes familiarity with J, the form editor, forms, controls, and the isigraph control.

If you are not familiar with the above, you might want to study them first.
)

NB. =========================================================
Lab Section OpenGL dlls
In the Windows JFE OpenGL requires system dlls opengl32.dll and glu32.dll.

These dlls are a standard part of NT and newer versions of Win95 systems (OSR2) and should be available in the windows system directories.

These dlls are not normally on older Win95 systems.

In the Java JFE OpenGL requires a support library in addition system OpenGL libraries.  This support library is distributed with J.  Most Linux systems have the necessary system libraries, and Mac OS X ships with the necessary OpenGL system libraries.

The next section tests to see if the OpenGL dlls are available.
)

NB. =========================================================
Lab Section
)
testdlls''

NB. =========================================================
Lab Section Isigraph Control
OpenGL drawing is done in an isigraph control.

The next step creates a new window ogl.ijs to define a form with an isigraph control. If you wish, rearrange the windows on the screen.

The contents of ogl.ijs are copied from directory examples\graphics\opengl\lab.

The ijs script is run so you do not need to do Ctrl+W.

Study the ogl.ijs window, then advance to the next lab section.
)

NB. =========================================================
Lab Section
)
nextijs'ogl1'
wd :: ] 'smtile'

NB. =========================================================
Lab Section
In the ijs window note the form definition A.

Styles ws_clipchildren ws_clipsiblings MUST be set for an isigraph control to be used with OpenGL.
)

NB. =========================================================
Lab Section glaRC
The verb a_run runs the form.

When an isigraph control is created it is set for 2D (GDI) commands and 3D OpenGL commands will fail.

A glaRC (Render Context) command prepares the control for OpenGL commands.

The glaRC'' command is in verb a_run.
)

NB. =========================================================
Lab Section OpenGL Commands
OpenGL commands are in 3 families:

  gl...  OpenGL commands
  glu... OpenGL utilities
  gla... additional utilities required by J or Windows
)

NB. =========================================================
Lab Section
All gl... commands need an isigraph control as the target.
)

NB. =========================================================
Lab Section
All the gl... commands are verbs defined as an 11!:x foreign conjunction. 3D graphics x values are in the range 3001-3999.
)
glaRC
glColor

NB. =========================================================
Lab Section Running the Form
The next step runs the form.

The form will be in the upper left of the screen. You can move and resize the control as you wish.

It will look funny because the isigraph control is not painted, so the control contains whatever was already on the screen.

You can press Esc to close the form, if it has the focus. You can always run it again, by executing:  a_run''
)

NB. =========================================================
Lab Section
)
a_run ''     NB. run form

NB. =========================================================
Lab Section Paint Event Handler
Unlike an isigraph 2D (GDI) control, or any other control, an isigraph 3D control must explicitly paint itself.

This is done by putting the appropriate commands in the paint event handler for the control.
)

NB. =========================================================
Lab Section
Event handlers have names in the pattern: form_control_event.

Here, the form is a, the control is g, and the event is paint so the paint event handler is: a_g_paint.
)

NB. =========================================================
Lab Section
The next step adds a paint handler to the ogl.ijs script.

It sets the clear color to be blue and draws the buffer.
)

NB. =========================================================
Lab Section
)
nextijs'ogl2'

NB. =========================================================
Lab Section
Now when you run the form the paint handler clears the drawing to be blue.
)
a_run''

NB. =========================================================
Lab Section Colors
Colors, such as the argument to glClearColor, are 4 numbers for the red, green, blue, and alpha components. The range of the numbers is from 0 to 1 and can be floating point.

For most purposes, the alpha component is set to 1.

The glClear argument is the value GL_COLOR_BUFFER_BIT. This value, and many others, are defined in main\gl3.ijs
)
GL_COLOR_BUFFER_BIT

NB. =========================================================
Lab Section Buffers
If drawing was done directly to the screen the image would appear haphazardly and with flicker. Instead, drawing is done into the backbuffer.

glaSwapBuffers makes the backbuffer the frontbuffer. The frontbuffer is the buffer that is drawn on the screen.
)

NB. =========================================================
Lab Section Draw Triangle
The next step adds the code to draw a triangle.
)

NB. =========================================================
Lab Section
)
nextijs'ogl3'

NB. =========================================================
Lab Section
The drawtriangle verb:

 sets the color to red
 begins the definition of a polygon
   defines 3 vertices in 3D space (x y z)
 ends the polygon definition

drawtriangle is called in the paint handler.

The next step runs the form.
)

NB. =========================================================
Lab Section
You should see a red triangle on a blue background.
)
a_run''

NB. =========================================================
Lab Section
Resize the form and note that the triangle stays the same size.
)

NB. =========================================================
Lab Section Size Handler
To handle size changes you need to provide a size handler.

The size handler is run when the size of the control changes.

The next step adds verb a_g_size to the script.
)

NB. =========================================================
Lab Section
)
nextijs'ogl4'

NB. =========================================================
Lab Section Control Size
qglwh returns the control width and height in pixels.

glViewport informs OpenGL that the drawing has its lower left corner at 0 0 and is as wide and high as the window.
)

NB. =========================================================
Lab Section
Now if you resize the window the triangle will resize.
)
a_run ''

NB. =========================================================
Lab Section
This looks like a boring 2D triangle in 2D space.

Let us start on the 3D stuff!

The next step adds a fancier size and drawtriangle.
)

NB. =========================================================
Lab Section
)
nextijs'ogl5'

NB. =========================================================
Lab Section 3D
The size handler verb describes a 3D space. Do not worry about the details for now.

The glOrtho command creates a 3D space that is a box in which drawing takes place.

The x y z coordinates run from 0 to 2.
)

NB. =========================================================
Lab Section
Now that we have a 3D space in which to draw we need to add some stuff to the drawing of our triangle.

Look at the definition of drawtriangle in the script. Again do not worry about the details yet.

The glTranslate shifts the triangle to the right along the x axes, up along the y axis, and back along the z axis so that it is in the middle of the box.

The glRotate commands rotate the triangle around an axis.
)

NB. =========================================================
Lab Section Rotation
drawtriangle uses global R to specify degrees of rotation for each axis.

This global R is initialized to 0 0 0 in a_run.

The next step runs the form. Do not close it just yet - the following steps assume it is open!
)

NB. =========================================================
Lab Section
)
a_run ''

NB. =========================================================
Lab Section
Let us change the R global and repaint the control.
)
PREPARE
wd 'psel a'
PREPARE
R =: 20 30 0
glpaintx ''

NB. =========================================================
Lab Section
Change R and repaint the control again.

Try your own experiments with changing the values of R.
)
PREPARE
wd 'psel a'
PREPARE
R =: 0 0 40
glpaintx''

NB. =========================================================
Lab Section
Let us simplify the definitions a bit.

All gl... verbs are rank 1 and apply to the rows of tables. This simplifies the use of glRotate and glVertex.

The next step changes the definition of drawtriangle.
)

NB. =========================================================
Lab Section
)
nextijs'ogl6'

NB. =========================================================
Lab Section
Experiment with changing R.
)
a_run''

R =: 30 30 30
glpaintx''

NB. =========================================================
Lab Section
Experiment with the glRotate and glVertex arguments to see how they work.
)

NB. =========================================================
Lab Section Key Handlers
We can add a handler for key strokes in the graph control so that pressing an x, y, or z key will cause a rotation.

The next step adds the a_g_char handler.
)

NB. =========================================================
Lab Section
)
nextijs'ogl7'

NB. =========================================================
Lab Section
Look at the definition for a_g_char. This verb runs when a key is pressed and the control has focus.

An x y or z key changes the corresponding element of R.

The glpaintx'' command causes a control paint.
)

NB. =========================================================
Lab Section
Press the x y and z keys to rotate the triangle.
)
a_run''

NB. =========================================================
Lab Section
The next step adds text display of the x y z rotation values.
)

NB. =========================================================
Lab Section
)
nextijs'ogl8'

NB. =========================================================
Lab Section
Press the x y and z keys to rotate the triangle.
)
a_run''

NB. =========================================================
Lab Section Add Vertex
The triangle is too flat to be of interest in this 3D world.

Adding a vertex to the object that is not in the same plane as the 3 points of the triangle gives a 3D object.

The next step adds a vertex to the triangle.
)

NB. =========================================================
Lab Section
)
nextijs'ogl9'

NB. =========================================================
Lab Section
Press the x y and z keys to rotate the object.
)
a_run''

NB. =========================================================
Lab Section Cube
The next step replaces the triangle drawing with a cube.
)

NB. =========================================================
Lab Section
Load the cube script.
)
nextijs'ogl10'

NB. =========================================================
Lab Section
Run the cube application.

Press the x y and z keys to rotate the object.
)
a_run''

NB. =========================================================
Lab Section Display Lists
Performance is not so important with simple drawings, but it becomes very important as drawings get more complex.

A key OpenGL feature for performance is the display list.

A display list is a set of commands that have been "compiled" and given a name, i.e. an integer.

When the drawing is painted, the display list can be called and the list commands execute more efficiently than if they were called directly.
)

NB. =========================================================
Lab Section Cube
The next step loads a script that uses a list to draw 2 cubes.
)

NB. =========================================================
Lab Section
)
nextijs'ogl11'

NB. =========================================================
Lab Section
The glNewList and glEndList bracket the drawing commands.

a_g_paint calls the list twice to draw 2 cubes as efficiently as possible.
)
a_run''

NB. =========================================================
Lab Section Keystate animation
You may have noticed that character events only see events for the last key press. Hold down the x, keep it down, and press z. The x rotation stops and z rotation starts.

What if you wanted to do both at once?
)

NB. =========================================================
Lab Section
You can do this by repainting the cube in a loop and at the top of the loop testing the state of the x y z keys and adjusting R accordingly.

The trick is to keep the object repainting with glpaintx'' as long as there might be changes.
available under the Java FE users of that FE will not be able to experience the improved key handling.
)

NB. =========================================================
Lab Section
The next step loads a cube with keystate animation.
)

NB. =========================================================
Lab Section
)
nextijs'ogl12'

NB. =========================================================
Lab Section
Hold down various simultaneous combinations of the x y z keys.
)
a_run''

NB. =========================================================
Lab Section Printing
Windows does not currently support directly printing high-resolution OpenGL images.

The good news is that there is an adequate workaround.

The Java FE does not support printing OpenGL images at all.
)

NB. =========================================================
Lab Section
The temporary solution for printing OpenGL images is to save the image as a bitmap and to print the bitmap.

The bits of the bitmap are stretched or shrunk to fit the printed image. If they are stretched a lot the image looks bad. You can specify the size of the bitmap that is saved.
)

NB. =========================================================
Lab Section
The next step loads a script that has a print button. The print button saves the pixel information from the drawing as a bitmap and then prints the bitmap
)

NB. =========================================================
Lab Section
)
nextijs'oglprint'

NB. =========================================================
Lab Section
Future releases of Windows may probably provide better support for printing OpenGL images. J will take advantage of that support when it is available.
)

NB. =========================================================
Lab Section The End
This is the end of the OpenGL lab.

You have just scratched the surface of what is possible.

But you have also just scratched the surface of what you will need to learn to be an effective OpenGL programmer.
)

NB. =========================================================
Lab Section Further Information
You can learn a lot by studying the example scripts and experimenting.

However, eventually you will probably want to get some books on OpenGL.

Perhaps the best book is the "OpenGL Programming Guide" by Jackie Neider, Tom Davis and Mason Woo and the companion "OpenGL Reference Book".

Although most OpenGL books use C, you should still find them valuable in understanding the concepts of 3D graphics and how the OpenGL commands work together.
)

NB. =========================================================
Lab Section OpenGL Utilities
Once you understand the basic concepts, you should take the lab: OpenGL Utilities.
)

NB. =========================================================
Lab Section Simple Examples
For more examples of the basic concepts, study the examples in examples\graphics\opengl\simple.

Most of these examples are based closely on examples in "OpenGL Programming Guide".

Many of the examples support interaction with the keyboard or mouse as documented in the help menu of each example.

The verb try lists the scripts in the directory and opens and runs the script that you selected. You can also run these scripts from the Studio|Demos|OpenGL... menu.

The next step runs try''
)

NB. =========================================================
Lab Section
)
try''
