=begin
/****************************************************************************
** $Id: qt/examples/glpixmap/glbox.cpp   2.2.2   edited 2000-08-31 $
**
** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
**
** This file is part of an example program for Qt.  This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/

/****************************************************************************
**
** This is a simple QGLWidget displaying a box
**
** The OpenGL code is mostly borrowed from Brian Pauls "spin" example
** in the Mesa distribution
**
****************************************************************************/
=end
#include <math.h>

#include "glbox.h"

#if defined(_CC_MSVC_)
#pragma warning(disable:4305) #// init: truncation from const double to float
#endif
require "opengl"
include GL
require "qt2"
include Qt2
require "qt2gl"
include Qt2gl
include Math
#/*!
#  Create a GLBox widget
#*/
class GLBox < QRGLWidget
attr_accessor :xRot,:yRot,:zRot
def initialize( parent, name, shareWidget=nil )
    super( parent, name, shareWidget )

    @xRot = @yRot = @zRot = 0.0		#// default object rotation
    @scale = 1.5			#// default object scale
    catchEvent
end



#/*!
#  Release allocated resources
#*/

def finalize()

    DeleteLists( @object, 1 )
end


#/*!
#  Set up the OpenGL rendering state, and define display list
#*/

def ruby_initializeGL()

    qglClearColor( Qt::green )		#// Let OpenGL clear to green
    @object = makeObject()		#// Make display list
    Enable( DEPTH_TEST )
end


#/*!
#  Set up the OpenGL view port, matrix mode, etc.
#*/

def ruby_resizeGL( w, h )

    Viewport( 0, 0, w, h )
    MatrixMode( PROJECTION )
    LoadIdentity()
    Frustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0)
end


#/*!
#  Paint the box. The actual openGL commands for drawing the box are
#  performed here.
#*/

def ruby_paintGL()

    Clear( COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT )

    MatrixMode( MODELVIEW )
    LoadIdentity()
    Translate( 0.0, 0.0, -3.0 )
    Scale( @scale, @scale, @scale )

    Rotate( @xRot, 1.0, 0.0, 0.0 )
    Rotate( @yRot, 0.0, 1.0, 0.0 )
    Rotate( @zRot, 0.0, 0.0, 1.0 )

    CallList( @object )
end






#/*!
#  Generate an OpenGL display list for the object to be shown, i.e. the box
#*/

def makeObject()
	
    list = GenLists( 1 )

    NewList( list, COMPILE )

#    float theta1, phi1, theta2, phi2
#    float v0[03], v1[3], v2[3], v3[3]
    v0=[]; v1=[]; v2=[]; v3=[]
#    float t0[03], t1[3], t2[3], t3[3]
    t0=[]; t1=[]; t2=[]; t3=[]
#    float n0[3], n1[3], n2[3], n3[3]
    n0=[]; n1=[]; n2=[]; n3=[]
    innerRadius=0.4
    outerRadius=0.8
#    float scalFac
    pi = 3.14159265358979323846

    rings = 8
    sides = 10
    scalFac=1/(outerRadius*2)

    for i in 0..( rings - 1 ) #(i = 0 i < rings i++)
        theta1 = i * 2.0 * pi / rings
        theta2 = (i + 1) * 2.0 * pi / rings
        for j in 0..( sides - 1 ) #(j = 0 j < sides j++)
            phi1 = j * 2.0 * pi / sides
            phi2 = (j + 1) * 2.0 * pi / sides

            v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1))
            v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1))
            v0[2] = innerRadius * sin(phi1)

            v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1))
            v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1))
            v1[2] = innerRadius * sin(phi1)
            v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2))
            v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2))
            v2[2] = innerRadius * sin(phi2)

            v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2))
            v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2))
            v3[2] = innerRadius * sin(phi2)

            n0[0] = cos(theta1) * (cos(phi1))
            n0[1] = -sin(theta1) * (cos(phi1))
            n0[2] = sin(phi1)

            n1[0] = cos(theta2) * (cos(phi1))
            n1[1] = -sin(theta2) * (cos(phi1))
            n1[2] = sin(phi1)

            n2[0] = cos(theta2) * (cos(phi2))
            n2[1] = -sin(theta2) * (cos(phi2))
            n2[2] = sin(phi2)

            n3[0] = cos(theta1) * (cos(phi2))
            n3[1] = -sin(theta1) * (cos(phi2))
            n3[2] = sin(phi2)

            t0[0] = v0[0]*scalFac + 0.5
            t0[1] = v0[1]*scalFac + 0.5
            t0[2] = v0[2]*scalFac + 0.5

            t1[0] = v1[0]*scalFac + 0.5
            t1[1] = v1[1]*scalFac + 0.5
            t1[2] = v1[2]*scalFac + 0.5

            t2[0] = v2[0]*scalFac + 0.5
            t2[1] = v2[1]*scalFac + 0.5
            t2[2] = v2[2]*scalFac + 0.5

            t3[0] = v3[0]*scalFac + 0.5
            t3[1] = v3[1]*scalFac + 0.5
            t3[2] = v3[2]*scalFac + 0.5

	    #// Create blue-black checkered coloring
	    if ( (i+j) % 2 == 0)
		qglColor( Qt::black )
	    else
		qglColor( QColor( "steel blue" ) )
                 end

            Begin(POLYGON)
                Normal(n3); TexCoord(t3); Vertex(v3)
                Normal(n2); TexCoord(t2); Vertex(v2)
                Normal(n1); TexCoord(t1); Vertex(v1)
                Normal(n0); TexCoord(t0); Vertex(v0)
            End()
        end
    end
    EndList()

    return list
end


#/*!
#  Set the rotation angle of the object to \e degrees around the X axis.
#*/

def setXRotation( degrees )

    @xRot = (degrees % 360)
    updateGL()
end


#/*!
#  Set the rotation angle of the object to \e degrees around the Y axis.
#*/

def setYRotation( degrees )

    @yRot = (degrees % 360)
    updateGL()
end


#/*!
#  Set the rotation angle of the object to \e degrees around the Z axis.
#*/

def setZRotation( degrees )

    @zRot = (degrees % 360)
    updateGL()
end





#/*!
#  Sets the rotation angles of self object to that of \a fromBox
#*/

def copyRotation( fromBox )

    @xRot = fromBox.xRot
    @yRot = fromBox.yRot
    @zRot = fromBox.zRot
end

end
