'
' With the GL backend for canvas more things can be done. More fun!
'
' ---===> ATTENTION: NEEDS HUG 0.53 or higher! <===---
'
' June 2011, PvE - GPL.
'
'---------------------------------------------------------------------------------------------------------------------------------------------------

INCLUDE "hug.bac", INIT, HUGOPTIONS, WINDOW, FRAME, RADIO, CANVAS, DISPLAY, ATTACH, TIMEOUT, DRAW, GET, STOCK, CALLBACK, QUIT, HIDE, SHOW, MSGDIALOG, HUGLIB$, SYNC
INCLUDE "glut.bac"
INCLUDE "gl.bac"

INIT

' No scaling as GL canvas is not sensitive to GTK resizing
HUGOPTIONS("NOSCALING")

' Define OpenGL canvas
HUGOPTIONS("CANVAS GL")

' Some colors
DECLARE lightpos[] = { 2.0, 2.0, -8.0, 0.0 } TYPE float
DECLARE lightamb[] = { 0.15, 0.15, 0.15 } TYPE float

DECLARE cube_color[] = { 0.1, 0.2, 0.8, 0.5 } TYPE float
DECLARE torus_color[] = { 0.8, 0.2, 0.1, 0.5 } TYPE float
DECLARE teapot_color[] = { 0.1, 0.7, 0.1, 0.5 } TYPE float
DECLARE cone_color[] = { 0.8, 0.7, 0.1, 0.5 } TYPE float
DECLARE tetrahedron_color[] = { 0.8, 0.1, 0.8, 0.5 } TYPE float
DECLARE isocahedron_color[] = { 0.1, 0.7, 0.7, 0.5 } TYPE float

' Current position of primitive
DECLARE xpos, ypos TYPE FLOATING

' Window size
CONST xsize = 640
CONST ysize = 640

' Main window
screen = WINDOW("OpenGL and GTK demo", xsize, ysize)

frame = FRAME(xsize-10, ysize-90)
ATTACH(screen, frame, 5, 5)

canvas = CANVAS(xsize-20, ysize-100)
ATTACH(screen, canvas, 10, 10)

check1 = RADIO("Cube", 110, 20, 0)
check2 = RADIO("Torus", 110, 20, check1)
check3 = RADIO("Teapot", 110, 20, check1)
check4 = RADIO("Cone", 130, 20, check1)
check5 = RADIO("Tetrahedron", 130, 20, check1)
check6 = RADIO("Icosahedron", 130, 20, check1)

ATTACH(screen, check1, 5, ysize-80)
ATTACH(screen, check2, 5, ysize-55)
ATTACH(screen, check3, 5, ysize-30)
ATTACH(screen, check4, 115, ysize-80)
ATTACH(screen, check5, 115, ysize-55)
ATTACH(screen, check6, 115, ysize-30)

about = STOCK("gtk-about", 120, 50)
ATTACH(screen, about, xsize-260, ysize-60)
exitb = STOCK("gtk-quit", 120, 50)
ATTACH(screen, exitb, xsize-130, ysize-60)

IF HUGLIB$("glarea") != "notfound" THEN dialog = MSGDIALOG("Using OpenGL with GtkGlArea and GTK with HUG!\n\n\t\t\t\tJune 2011 - PvE.", 420, 150, 0, 2)
ELSE dialog = MSGDIALOG("Using OpenGL with GtkGlExt and GTK with HUG!\n\n\t\t\t\tJune 2011 - PvE.", 420, 150, 0, 2)

' Calback for ABOUT button
SUB Info_Dialog

        SHOW(dialog)

END SUB

' Here the actual drawing takes place. Continusouly being called by TIMEOUT
FUNCTION Draw_Primitive

        ' With non-HUG OpenGL drawing we MUST call this directive first to prepare the canvas
        DRAW(canvas)

        ' Now for some OpenGL magic - read your textbook on OpenGL to understand this all
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glShadeModel(GL_SMOOTH)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glLightfv(GL_LIGHT0, GL_POSITION, ADDRESS(lightpos))

        IF GET(check1) THEN glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ADDRESS(cube_color))
        IF GET(check2) THEN glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ADDRESS(torus_color))
        IF GET(check3) THEN glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ADDRESS(teapot_color))
        IF GET(check4) THEN glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ADDRESS(cone_color))
        IF GET(check5) THEN glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ADDRESS(tetrahedron_color))
        IF GET(check6) THEN glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ADDRESS(isocahedron_color))

        glMatrixMode(GL_MODELVIEW)
        glPushMatrix
                glRotated(xpos, 1.0, 0.1, 0.0)
                glRotated(ypos, 0.0, 1.0, 0.0)
                IF GET(check1) THEN glutSolidCube(0.8)
                IF GET(check2) THEN glutSolidTorus(0.2, 0.7, 100, 100)
                IF GET(check3) THEN glutSolidTeapot(0.6)
                IF GET(check4) THEN glutSolidCone(0.5, 0.9, 100, 100)
                IF GET(check5) THEN glutSolidTetrahedron()
                IF GET(check6) THEN glutSolidIcosahedron()
                glLoadIdentity
        glPopMatrix

        ' With non-HUG OpenGL drawing we MUST call this directive to display the result
        SYNC

        INCR xpos, 0.5
        INCR ypos, 1.0

        RETURN TRUE

END FUNCTION

' Define some callbacks
CALLBACK(exitb, QUIT)
CALLBACK(about, Info_Dialog)
CALLBACK(dialog, HIDE)

' Define GTK interruption on mainloop
TIMEOUT(50, Draw_Primitive)

' Endless GTK mainloop
DISPLAY