'
' This is the BaCon port of the 'Blender' OpenGL program.
'
' See also: http://www.opengl.org/resources/code/samples/glut_examples/examples/examples.html
'
' Port by Peter van Eerten - January 2010.
'
' Copyright (c) Mark J. Kilgard, 1994.
'
' This program is freely distributable without licensing fees
' and is provided without guarantee or warrantee expressed or
' implied. This program is -not- in the public domain.
'
' blender renders two spinning icosahedrons (red and green).
' The blending factors for the two icosahedrons vary sinusoidally
' and slightly out of phase.  blender also renders two lines of
' text in a stroke font: one line antialiased, the other not.  */

INCLUDE "gl.bac"
INCLUDE "glu.bac"
INCLUDE "glut.bac"

DECLARE light0_ambient[] = {0.2, 0.2, 0.2, 1.0} TYPE float
DECLARE light0_diffuse[] = {0.0, 0.0, 0.0, 1.0} TYPE float
DECLARE light1_diffuse[] = {1.0, 0.0, 0.0, 1.0} TYPE float
DECLARE light1_position[] = {1.0, 1.0, 1.0, 0.0} TYPE float
DECLARE light2_diffuse[] = {0.0, 1.0, 0.0, 1.0} TYPE float
DECLARE light2_position[] = {-1.0, -1.0, 1.0, 0.0} TYPE float
DECLARE s TYPE float
DECLARE angle1, angle2 TYPE float

s = 0.0
angle1 = 0.0
angle2 = 0.0

SUB output(float x, float y, STRING text$)

    LOCAL p

    glPushMatrix
    glTranslatef(x, y, 0)
    FOR p = 1 TO LEN(text$)
        glutStrokeCharacter(GLUT_STROKE_ROMAN, ASC(MID$(text$, p)))
    NEXT
    glPopMatrix

ENDSUB

SUB display(void)

    LOCAL amb[] = {0.4, 0.4, 0.4, 0.0} TYPE float
    LOCAL dif[] = {1.0, 1.0, 1.0, 0.0} TYPE float

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glEnable(GL_LIGHT1)
    glDisable(GL_LIGHT2)
    amb[3] = dif[3] = COS(s) / 2.0 + 0.5
    glMaterialfv(GL_FRONT, GL_AMBIENT, ADDRESS(amb))
    glMaterialfv(GL_FRONT, GL_DIFFUSE, ADDRESS(dif))

    glPushMatrix
    glTranslatef(-0.3, -0.3, 0.0)
    glRotatef(angle1, 1.0, 5.0, 0.0)
    glCallList(1)
    glPopMatrix

    glClear(GL_DEPTH_BUFFER_BIT)
    glEnable(GL_LIGHT2)
    glDisable(GL_LIGHT1)
    amb[3] = dif[3] = 0.5 - cos(s * .95) / 2.0
    glMaterialfv(GL_FRONT, GL_AMBIENT, ADDRESS(amb))
    glMaterialfv(GL_FRONT, GL_DIFFUSE, ADDRESS(dif))

    glPushMatrix
    glTranslatef(0.3, 0.3, 0.0)
    glRotatef(angle2, 1.0, 0.0, 5.0)
    glCallList(1)
    glPopMatrix

    glPushAttrib(GL_ENABLE_BIT)
    glDisable(GL_DEPTH_TEST)
    glDisable(GL_LIGHTING)
    glMatrixMode(GL_PROJECTION)
    glPushMatrix
    glLoadIdentity
    gluOrtho2D(0, 1500, 0, 1500)
    glMatrixMode(GL_MODELVIEW)
    glPushMatrix
    glLoadIdentity
    ' Rotate text slightly to help show jaggies.
    glRotatef(4, 0.0, 0.0, 1.0)
    output(200, 225, "This is antialiased.")
    glDisable(GL_LINE_SMOOTH)
    glDisable(GL_BLEND)
    output(160, 100, "This text is not.")
    glPopMatrix
    glMatrixMode(GL_PROJECTION)
    glPopMatrix
    glPopAttrib
    glMatrixMode(GL_MODELVIEW)

    glutSwapBuffers

END SUB

SUB idle

    angle1 = fmod(angle1 + 0.8, 360.0)
    angle2 = fmod(angle2 + 1.1, 360.0)
    s = s + 0.05
    glutPostRedisplay

END SUB

SUB visible(int vis)

    IF vis IS GLUT_VISIBLE THEN glutIdleFunc(ADDRESS(idle))
    ELSE glutIdleFunc(0)

END SUB

SUB mainprog

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
    glutCreateWindow("blender")
    glutDisplayFunc(ADDRESS(display))
    glutVisibilityFunc(ADDRESS(visible))

    'create ico display list
    glNewList(1, GL_COMPILE)
    glutSolidIcosahedron
    glEndList

    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glLightfv(GL_LIGHT0, GL_AMBIENT, ADDRESS(light0_ambient))
    glLightfv(GL_LIGHT0, GL_DIFFUSE, ADDRESS(light0_diffuse))
    glLightfv(GL_LIGHT1, GL_DIFFUSE, ADDRESS(light1_diffuse))
    glLightfv(GL_LIGHT1, GL_POSITION, ADDRESS(light1_position))
    glLightfv(GL_LIGHT2, GL_DIFFUSE, ADDRESS(light2_diffuse))
    glLightfv(GL_LIGHT2, GL_POSITION, ADDRESS(light2_position))
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_CULL_FACE)
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glEnable(GL_LINE_SMOOTH)
    glLineWidth(2.0)

    glMatrixMode(GL_PROJECTION)
    gluPerspective(40.0, 1.0, 1.0, 10.0)
    glMatrixMode(GL_MODELVIEW)
    gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.)
    glTranslatef(0.0, 0.6, -1.0)

    glutMainLoop

ENDSUB

mainprog