/* -LICENSE-START-
 ** Copyright (c) 2010 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
 ** this license (the "Software") to use, reproduce, display, distribute,
 ** execute, and transmit the Software, and to prepare derivative works of the
 ** Software, and to permit third-parties to whom the Software is furnished to
 ** do so, all subject to the following:
 ** 
 ** The copyright notices in the Software and this entire statement, including
 ** the above license grant, this restriction and the following disclaimer,
 ** must be included in all copies of the Software, in whole or in part, and
 ** all derivative works of the Software, unless such copies or derivative
 ** works are solely in the form of machine-executable object code generated by
 ** a source language processor.
 ** 
 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 ** DEALINGS IN THE SOFTWARE.
 ** -LICENSE-END-
 */
//
//	GLScene.mm
//  OpenGLOutput
//

#include "GLScene.h"

GLScene::GLScene()
	: flRtri(0.0f), flRquad(0.0f)
{
	pMutex = [NSLock alloc];
}

GLScene::~GLScene()
{
	[pMutex release];
}

void GLScene::InitScene()
{
	[pMutex lock];
	
	glShadeModel( GL_SMOOTH );                // Enable smooth shading
    glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );   // Black background
	glClearDepth( 1.0f );                     // Depth buffer setup
	glEnable( GL_DEPTH_TEST );                // Enable depth testing
	glDepthFunc( GL_LEQUAL );                 // Type of depth test to do
	glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

	[pMutex unlock];
}

void GLScene::DrawScene(GLint x, GLint y, GLsizei w, GLsizei h)
{
	[pMutex lock];
	
	// draw OpenGL scene
	glViewport (x, y, w, h);
	
	glMatrixMode( GL_PROJECTION );   // Select the projection matrix
	glLoadIdentity();                // and reset it
	
	// Calculate the aspect ratio of the view
	gluPerspective( 45.0f, (GLdouble)w / (GLdouble)h, 0.1f, 100.0f );
	glMatrixMode( GL_MODELVIEW );    // Select the modelview matrix
	glLoadIdentity();                // and reset it
	
	// Clear the screen and depth buffer
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	
	glLoadIdentity();   // Reset the current modelview matrix

	glTranslatef( -1.5f, 0.0f, -6.0f );   // Left 1.5 units, into screen 6.0
	// Rotate triangle on Y axis
	glRotatef( flRtri, 0.0f, 1.0f, 0.0f );
	
	glBegin( GL_TRIANGLES );              // Draw a triangle
	glColor3f( 1.0f, 0.0f, 0.0f );        // Set color to red
	glVertex3f(  0.0f,  1.0f, 0.0f );     // Top of front
	glColor3f( 0.0f, 1.0f, 0.0f );        // Set color to green
	glVertex3f( -1.0f, -1.0f, 1.0f );     // Bottom left of front
	glColor3f( 0.0f, 0.0f, 1.0f );        // Set color to blue
	glVertex3f(  1.0f, -1.0f, 1.0f );     // Bottom right of front
	
	glColor3f( 1.0f, 0.0f, 0.0f );        // Red
	glVertex3f( 0.0f, 1.0f, 0.0f );       // Top of right side
	glColor3f( 0.0f, 0.0f, 1.0f );        // Blue
	glVertex3f( 1.0f, -1.0f, 1.0f );      // Left of right side
	glColor3f( 0.0f, 1.0f, 0.0f );        // Green
	glVertex3f( 1.0f, -1.0f, -1.0f );     // Right of right side
	
	glColor3f( 1.0f, 0.0f, 0.0f );        // Red
	glVertex3f( 0.0f, 1.0f, 0.0f );       // Top of back side
	glColor3f( 0.0f, 1.0f, 0.0f );        // Green
	glVertex3f( 1.0f, -1.0f, -1.0f );     // Left of back side
	glColor3f( 0.0f, 0.0f, 1.0f );        // Blue
	glVertex3f( -1.0f, -1.0f, -1.0f );    // Right of back side
	
	glColor3f( 1.0f, 0.0f, 0.0f );        // Red
	glVertex3f( 0.0f, 1.0f, 0.0f );       // Top of left side
	glColor3f( 0.0f, 0.0f, 1.0f );        // Blue
	glVertex3f( -1.0f, -1.0f, -1.0f );    // Left of left side
	glColor3f( 0.0f, 1.0f, 0.0f );        // Green
	glVertex3f( -1.0f, -1.0f, 1.0f );     // Right of left side
	glEnd();                              // Done with triangle
	
	glLoadIdentity();                       // Reset current modelview matrix
	glTranslatef( 1.5f, 0.0f, -7.0f );      // Move right and into screen
	// Rotate quad on all axes
	glRotatef( flRquad, 1.0f, 1.0f, 1.0f );
	glBegin( GL_QUADS );                 // Draw quads
	glColor3f( 0.0f, 1.0f, 0.0f );       // Green
	glVertex3f(  1.0f,  1.0f, -1.0f );   // Top right of top side
	glVertex3f( -1.0f,  1.0f, -1.0f );   // Top left of top side
	glVertex3f( -1.0f,  1.0f,  1.0f );   // Bottom left of top side
	glVertex3f(  1.0f,  1.0f,  1.0f );   // Bottom right of top side
	
	glColor3f( 1.0f, 0.5f, 0.0f );       // Orange
	glVertex3f(  1.0f, -1.0f,  1.0f );   // Top right of bottom side
	glVertex3f( -1.0f, -1.0f,  1.0f );   // Top left of bottom side
	glVertex3f( -1.0f, -1.0f, -1.0f );   // Bottom left of bottom side
	glVertex3f(  1.0f, -1.0f, -1.0f );   // Bottom right of bottom side
	
	glColor3f( 1.0f, 0.0f, 0.0f );       // Red  
	glVertex3f(  1.0f,  1.0f,  1.0f );   // Top right of front side
	glVertex3f( -1.0f,  1.0f,  1.0f );   // Top left of front side
	glVertex3f( -1.0f, -1.0f,  1.0f );   // Bottom left of front side
	glVertex3f(  1.0f, -1.0f,  1.0f );   // Bottom right of front side
	
	glColor3f( 1.0f, 1.0f, 0.0f );       // Yellow
	glVertex3f(  1.0f, -1.0f, -1.0f );   // Bottom left of back side
	glVertex3f( -1.0f, -1.0f, -1.0f );   // Bottom right of back side
	glVertex3f( -1.0f,  1.0f, -1.0f );   // Top right of back side
	glVertex3f(  1.0f,  1.0f, -1.0f );   // Top left of back side
	
	glColor3f( 0.0f, 0.0f, 1.0f );       // Blue
	glVertex3f( -1.0f,  1.0f,  1.0f );   // Top right of left side
	glVertex3f( -1.0f,  1.0f, -1.0f );   // Top left of left side
	glVertex3f( -1.0f, -1.0f, -1.0f );   // Bottom left of left side
	glVertex3f( -1.0f, -1.0f,  1.0f );   // Bottom right of left side
	
	glColor3f( 1.0f, 0.0f, 1.0f );       // Violet 
	glVertex3f(  1.0f,  1.0f, -1.0f );   // Top right of right side
	glVertex3f(  1.0f,  1.0f,  1.0f );   // Top left of right side
	glVertex3f(  1.0f, -1.0f,  1.0f );   // Bottom left of right side
	glVertex3f(  1.0f, -1.0f, -1.0f );   // Bottom right of right side
	glEnd();                             // Quads are complete
	
	glFinish();
	
	flRtri += 0.8f;     // Increase the rotation variable for the triangle
	flRquad -= 0.60f;   // Decrease the rotation variable for the quad	

	[pMutex unlock];
}

