00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdlib.h>
00027 #include <assert.h>
00028
00029 #include "matrix.h"
00030 #include "mat4stack.h"
00031
00032 km_mat4_stack* modelview_matrix_stack = NULL;
00033 km_mat4_stack* projection_matrix_stack = NULL;
00034 km_mat4_stack* texture_matrix_stack = NULL;
00035
00036 km_mat4_stack* current_stack = NULL;
00037
00038 static unsigned char initialized = 0;
00039
00040 void lazyInitialize()
00041 {
00042
00043 if (!initialized) {
00044
00045 modelview_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
00046 km_mat4_stack_initialize(modelview_matrix_stack);
00047
00048 projection_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
00049 km_mat4_stack_initialize(projection_matrix_stack);
00050
00051 texture_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
00052 km_mat4_stack_initialize(texture_matrix_stack);
00053
00054 current_stack = modelview_matrix_stack;
00055 initialized = 1;
00056
00057 kmMat4 identity;
00058 kmMat4Identity(&identity);
00059
00060
00061 km_mat4_stack_push(modelview_matrix_stack, &identity);
00062 km_mat4_stack_push(projection_matrix_stack, &identity);
00063 km_mat4_stack_push(texture_matrix_stack, &identity);
00064 }
00065 }
00066
00067 void kmGLMatrixMode(kmGLEnum mode)
00068 {
00069 lazyInitialize();
00070
00071 switch(mode)
00072 {
00073 case KM_GL_MODELVIEW:
00074 current_stack = modelview_matrix_stack;
00075 break;
00076 case KM_GL_PROJECTION:
00077 current_stack = projection_matrix_stack;
00078 break;
00079 case KM_GL_TEXTURE:
00080 current_stack = texture_matrix_stack;
00081 break;
00082 default:
00083 assert(0 && "Invalid matrix mode specified");
00084 break;
00085 }
00086 }
00087
00088 void kmGLPushMatrix(void)
00089 {
00090 lazyInitialize();
00091
00092
00093 km_mat4_stack_push(current_stack, current_stack->top);
00094 }
00095
00096 void kmGLPopMatrix(void)
00097 {
00098
00099 km_mat4_stack_pop(current_stack, NULL);
00100 }
00101
00102 void kmGLLoadIdentity()
00103 {
00104 lazyInitialize();
00105
00106 kmMat4Identity(current_stack->top);
00107 }
00108
00109 void kmGLFreeAll()
00110 {
00111
00112 km_mat4_stack_release(modelview_matrix_stack);
00113 km_mat4_stack_release(projection_matrix_stack);
00114 km_mat4_stack_release(texture_matrix_stack);
00115
00116
00117 free(modelview_matrix_stack);
00118 free(projection_matrix_stack);
00119 free(texture_matrix_stack);
00120
00121 initialized = 0;
00122
00123 current_stack = NULL;
00124 }
00125
00126 void kmGLMultMatrix(const kmMat4* pIn)
00127 {
00128 lazyInitialize();
00129 kmMat4Multiply(current_stack->top, pIn, current_stack->top);
00130 }
00131
00132 void kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut)
00133 {
00134 lazyInitialize();
00135
00136 switch(mode)
00137 {
00138 case KM_GL_MODELVIEW:
00139 kmMat4Assign(pOut, modelview_matrix_stack->top);
00140 break;
00141 case KM_GL_PROJECTION:
00142 kmMat4Assign(pOut, projection_matrix_stack->top);
00143 break;
00144 case KM_GL_TEXTURE:
00145 kmMat4Assign(pOut, texture_matrix_stack->top);
00146 break;
00147 default:
00148 assert(1 && "Invalid matrix mode specified");
00149 break;
00150 }
00151 }
00152
00153 void kmGLTranslatef(float x, float y, float z)
00154 {
00155 current_stack->top->mat[12] += x;
00156 current_stack->top->mat[13] += y;
00157 current_stack->top->mat[14] += z;
00158 }
00159
00160 void kmGLRotatef(float angle, float x, float y, float z)
00161 {
00162 kmVec3 axis;
00163 kmMat4 rotation;
00164
00165
00166 kmVec3Fill(&axis, x, y, z);
00167
00168
00169 kmMat4RotationAxis(&rotation, &axis, kmDegreesToRadians(angle));
00170
00171
00172 kmMat4Multiply(current_stack->top, &rotation, current_stack->top);
00173 }
00174
00175 void kmGLScalef(float x, float y, float z)
00176 {
00177 kmMat4 scaling;
00178 kmMat4Scaling(&scaling, x, y, z);
00179 kmMat4Multiply(current_stack->top, &scaling, current_stack->top);
00180 }