1 /**
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008, Luke Benstead.
  4  All rights reserved.
  5 
  6  Redistribution and use in source and binary forms, with or without modification,
  7  are permitted provided that the following conditions are met:
  8 
  9  Redistributions of source code must retain the above copyright notice,
 10  this list of conditions and the following disclaimer.
 11  Redistributions in binary form must reproduce the above copyright notice,
 12  this list of conditions and the following disclaimer in the documentation
 13  and/or other materials provided with the distribution.
 14 
 15  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 16  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 17  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 18  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 19  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 20  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 21  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 22  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 23  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 24  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 25  */
 26 
 27 cc.KM_GL_MODELVIEW = 0x1700;
 28 
 29 cc.KM_GL_PROJECTION = 0x1701;
 30 
 31 cc.KM_GL_TEXTURE = 0x1702;
 32 
 33 cc.modelview_matrix_stack = new cc.km_mat4_stack();
 34 cc.projection_matrix_stack = new cc.km_mat4_stack();
 35 cc.texture_matrix_stack = new cc.km_mat4_stack();
 36 
 37 cc.current_stack = null;
 38 
 39 cc.initialized = false;
 40 
 41 cc.lazyInitialize = function () {
 42     if (!cc.initialized) {
 43         var identity = new cc.kmMat4(); //Temporary identity matrix
 44 
 45         //Initialize all 3 stacks
 46         cc.km_mat4_stack_initialize(cc.modelview_matrix_stack);
 47         cc.km_mat4_stack_initialize(cc.projection_matrix_stack);
 48         cc.km_mat4_stack_initialize(cc.texture_matrix_stack);
 49 
 50         cc.current_stack = cc.modelview_matrix_stack;
 51         cc.initialized = true;
 52         cc.kmMat4Identity(identity);
 53 
 54         //Make sure that each stack has the identity matrix
 55         cc.km_mat4_stack_push(cc.modelview_matrix_stack, identity);
 56         cc.km_mat4_stack_push(cc.projection_matrix_stack, identity);
 57         cc.km_mat4_stack_push(cc.texture_matrix_stack, identity);
 58     }
 59 };
 60 
 61 cc.lazyInitialize();
 62 
 63 cc.kmGLFreeAll = function () {
 64     //Clear the matrix stacks
 65     cc.km_mat4_stack_release(cc.modelview_matrix_stack);
 66     cc.km_mat4_stack_release(cc.projection_matrix_stack);
 67     cc.km_mat4_stack_release(cc.texture_matrix_stack);
 68 
 69     //Delete the matrices
 70     cc.initialized = false; //Set to uninitialized
 71     cc.current_stack = null; //Set the current stack to point nowhere
 72 };
 73 
 74 cc.kmGLPushMatrix = function () {
 75     cc.km_mat4_stack_push(cc.current_stack, cc.current_stack.top);
 76 };
 77 
 78 cc.kmGLPushMatrixWitMat4 = function (saveMat) {
 79     cc.current_stack.stack.push(cc.current_stack.top);
 80     cc.kmMat4Assign(saveMat, cc.current_stack.top);
 81     cc.current_stack.top = saveMat;
 82 };
 83 
 84 cc.kmGLPopMatrix = function () {
 85     //No need to lazy initialize, you shouldnt be popping first anyway!
 86     //cc.km_mat4_stack_pop(cc.current_stack, null);
 87     cc.current_stack.top = cc.current_stack.stack.pop();
 88 };
 89 
 90 cc.kmGLMatrixMode = function (mode) {
 91     //cc.lazyInitialize();
 92     switch (mode) {
 93         case cc.KM_GL_MODELVIEW:
 94             cc.current_stack = cc.modelview_matrix_stack;
 95             break;
 96         case cc.KM_GL_PROJECTION:
 97             cc.current_stack = cc.projection_matrix_stack;
 98             break;
 99         case cc.KM_GL_TEXTURE:
100             cc.current_stack = cc.texture_matrix_stack;
101             break;
102         default:
103             throw "Invalid matrix mode specified";   //TODO: Proper error handling
104             break;
105     }
106 };
107 
108 cc.kmGLLoadIdentity = function () {
109     //cc.lazyInitialize();
110     cc.kmMat4Identity(cc.current_stack.top); //Replace the top matrix with the identity matrix
111 };
112 
113 cc.kmGLLoadMatrix = function (pIn) {
114     //cc.lazyInitialize();
115     cc.kmMat4Assign(cc.current_stack.top, pIn);
116 };
117 
118 cc.kmGLMultMatrix = function (pIn) {
119     //cc.lazyInitialize();
120     cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, pIn);
121 };
122 
123 cc.kmGLTranslatef = function (x, y, z) {
124     var translation = new cc.kmMat4();
125 
126     //Create a rotation matrix using the axis and the angle
127     cc.kmMat4Translation(translation, x, y, z);
128 
129     //Multiply the rotation matrix by the current matrix
130     cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, translation);
131 };
132 
133 cc.kmGLRotatef = function (angle, x, y, z) {
134     var axis = new cc.kmVec3(x, y, z);
135     var rotation = new cc.kmMat4();
136 
137     //Create a rotation matrix using the axis and the angle
138     cc.kmMat4RotationAxisAngle(rotation, axis, cc.kmDegreesToRadians(angle));
139 
140     //Multiply the rotation matrix by the current matrix
141     cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, rotation);
142 };
143 
144 cc.kmGLScalef = function (x, y, z) {
145     var scaling = new cc.kmMat4();
146     cc.kmMat4Scaling(scaling, x, y, z);
147     cc.kmMat4Multiply(cc.current_stack.top, cc.current_stack.top, scaling);
148 };
149 
150 cc.kmGLGetMatrix = function (mode, pOut) {
151     //cc.lazyInitialize();
152 
153     switch (mode) {
154         case cc.KM_GL_MODELVIEW:
155             cc.kmMat4Assign(pOut, cc.modelview_matrix_stack.top);
156             break;
157         case cc.KM_GL_PROJECTION:
158             cc.kmMat4Assign(pOut, cc.projection_matrix_stack.top);
159             break;
160         case cc.KM_GL_TEXTURE:
161             cc.kmMat4Assign(pOut, cc.texture_matrix_stack.top);
162             break;
163         default:
164             throw "Invalid matrix mode specified"; //TODO: Proper error handling
165             break;
166     }
167 };
168