this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 759 lines 20 kB view raw
1#include "SDL_gpu.h" 2#include <math.h> 3#include <string.h> 4 5#ifdef _MSC_VER 6#define __func__ __FUNCTION__ 7// Disable warning: selection for inlining 8#pragma warning(disable: 4514 4711) 9// Disable warning: Spectre mitigation 10#pragma warning(disable: 5045) 11#endif 12 13 14#ifndef PI 15#define PI 3.1415926f 16#endif 17 18#define RAD_PER_DEG 0.017453293f 19#define DEG_PER_RAD 57.2957795f 20 21 22// Visual C does not support static inline 23#ifndef static_inline 24 #ifdef _MSC_VER 25 #define static_inline static 26 #else 27 #define static_inline static inline 28 #endif 29#endif 30 31// Old Visual C did not support C99 (which includes a safe snprintf) 32#if defined(_MSC_VER) && (_MSC_VER < 1900) 33 #define snprintf c99_snprintf 34 // From Valentin Milea: http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 35 static_inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) 36 { 37 int count = -1; 38 39 if (size != 0) 40 count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); 41 if (count == -1) 42 count = _vscprintf(format, ap); 43 44 return count; 45 } 46 47 static_inline int c99_snprintf(char* str, size_t size, const char* format, ...) 48 { 49 int count; 50 va_list ap; 51 52 va_start(ap, format); 53 count = c99_vsnprintf(str, size, format, ap); 54 va_end(ap); 55 56 return count; 57 } 58#endif 59 60 61 62GPU_MatrixStack* GPU_CreateMatrixStack(void) 63{ 64 GPU_MatrixStack* stack = (GPU_MatrixStack*)SDL_malloc(sizeof(GPU_MatrixStack)); 65 stack->matrix = NULL; 66 stack->size = 0; 67 stack->storage_size = 0; 68 GPU_InitMatrixStack(stack); 69 return stack; 70} 71 72 73void GPU_FreeMatrixStack(GPU_MatrixStack* stack) 74{ 75 GPU_ClearMatrixStack(stack); 76 SDL_free(stack); 77} 78 79void GPU_InitMatrixStack(GPU_MatrixStack* stack) 80{ 81 if(stack == NULL) 82 return; 83 84 if (stack->storage_size != 0) 85 GPU_ClearMatrixStack(stack); 86 87 stack->storage_size = 1; 88 stack->size = 1; 89 90 stack->matrix = (float**)SDL_malloc(sizeof(float*) * stack->storage_size); 91 stack->matrix[0] = (float*)SDL_malloc(sizeof(float) * 16); 92 GPU_MatrixIdentity(stack->matrix[0]); 93} 94 95void GPU_CopyMatrixStack(const GPU_MatrixStack* source, GPU_MatrixStack* dest) 96{ 97 unsigned int i; 98 unsigned int matrix_size = sizeof(float) * 16; 99 if (source == NULL || dest == NULL) 100 return; 101 102 GPU_ClearMatrixStack(dest); 103 dest->matrix = (float**)SDL_malloc(sizeof(float*) * source->storage_size); 104 for (i = 0; i < source->storage_size; ++i) 105 { 106 dest->matrix[i] = (float*)SDL_malloc(matrix_size); 107 memcpy(dest->matrix[i], source->matrix[i], matrix_size); 108 } 109 dest->storage_size = source->storage_size; 110} 111 112void GPU_ClearMatrixStack(GPU_MatrixStack* stack) 113{ 114 unsigned int i; 115 for (i = 0; i < stack->storage_size; ++i) 116 { 117 SDL_free(stack->matrix[i]); 118 } 119 SDL_free(stack->matrix); 120 121 stack->matrix = NULL; 122 stack->storage_size = 0; 123} 124 125 126void GPU_ResetProjection(GPU_Target* target) 127{ 128 if(target == NULL) 129 return; 130 131 GPU_bool invert = (target->image != NULL); 132 133 // Set up default projection 134 float* projection_matrix = GPU_GetTopMatrix(&target->projection_matrix); 135 GPU_MatrixIdentity(projection_matrix); 136 137 if(!invert ^ GPU_GetCoordinateMode()) 138 GPU_MatrixOrtho(projection_matrix, 0, target->w, target->h, 0, target->camera.z_near, target->camera.z_far); 139 else 140 GPU_MatrixOrtho(projection_matrix, 0, target->w, 0, target->h, target->camera.z_near, target->camera.z_far); // Special inverted orthographic projection because tex coords are inverted already for render-to-texture 141} 142 143// Column-major 144#define INDEX(row,col) ((col)*4 + (row)) 145 146 147float GPU_VectorLength(const float* vec3) 148{ 149 return sqrtf(vec3[0] * vec3[0] + vec3[1] * vec3[1] + vec3[2] * vec3[2]); 150} 151 152void GPU_VectorNormalize(float* vec3) 153{ 154 float mag = GPU_VectorLength(vec3); 155 vec3[0] /= mag; 156 vec3[1] /= mag; 157 vec3[2] /= mag; 158} 159 160float GPU_VectorDot(const float* A, const float* B) 161{ 162 return A[0] * B[0] + A[1] * B[1] + A[2] * B[2]; 163} 164 165void GPU_VectorCross(float* result, const float* A, const float* B) 166{ 167 result[0] = A[1] * B[2] - A[2] * B[1]; 168 result[1] = A[2] * B[0] - A[0] * B[2]; 169 result[2] = A[0] * B[1] - A[1] * B[0]; 170} 171 172void GPU_VectorCopy(float* result, const float* A) 173{ 174 result[0] = A[0]; 175 result[1] = A[1]; 176 result[2] = A[2]; 177} 178 179void GPU_VectorApplyMatrix(float* vec3, const float* matrix_4x4) 180{ 181 float x = matrix_4x4[0] * vec3[0] + matrix_4x4[4] * vec3[1] + matrix_4x4[8] * vec3[2] + matrix_4x4[12]; 182 float y = matrix_4x4[1] * vec3[0] + matrix_4x4[5] * vec3[1] + matrix_4x4[9] * vec3[2] + matrix_4x4[13]; 183 float z = matrix_4x4[2] * vec3[0] + matrix_4x4[6] * vec3[1] + matrix_4x4[10] * vec3[2] + matrix_4x4[14]; 184 float w = matrix_4x4[3] * vec3[0] + matrix_4x4[7] * vec3[1] + matrix_4x4[11] * vec3[2] + matrix_4x4[15]; 185 vec3[0] = x / w; 186 vec3[1] = y / w; 187 vec3[2] = z / w; 188} 189 190void GPU_Vector4ApplyMatrix(float* vec4, const float* matrix_4x4) 191{ 192 float x = matrix_4x4[0] * vec4[0] + matrix_4x4[4] * vec4[1] + matrix_4x4[8] * vec4[2] + matrix_4x4[12] * vec4[3]; 193 float y = matrix_4x4[1] * vec4[0] + matrix_4x4[5] * vec4[1] + matrix_4x4[9] * vec4[2] + matrix_4x4[13] * vec4[3]; 194 float z = matrix_4x4[2] * vec4[0] + matrix_4x4[6] * vec4[1] + matrix_4x4[10] * vec4[2] + matrix_4x4[14] * vec4[3]; 195 float w = matrix_4x4[3] * vec4[0] + matrix_4x4[7] * vec4[1] + matrix_4x4[11] * vec4[2] + matrix_4x4[15] * vec4[3]; 196 197 vec4[0] = x; 198 vec4[1] = y; 199 vec4[2] = z; 200 vec4[3] = w; 201 if(w != 0.0f) 202 { 203 vec4[0] = x / w; 204 vec4[1] = y / w; 205 vec4[2] = z / w; 206 vec4[3] = 1; 207 } 208} 209 210 211// Matrix math implementations based on Wayne Cochran's (wcochran) matrix.c 212 213#define FILL_MATRIX_4x4(A, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) \ 214 A[0] = a0; \ 215 A[1] = a1; \ 216 A[2] = a2; \ 217 A[3] = a3; \ 218 A[4] = a4; \ 219 A[5] = a5; \ 220 A[6] = a6; \ 221 A[7] = a7; \ 222 A[8] = a8; \ 223 A[9] = a9; \ 224 A[10] = a10; \ 225 A[11] = a11; \ 226 A[12] = a12; \ 227 A[13] = a13; \ 228 A[14] = a14; \ 229 A[15] = a15; 230 231void GPU_MatrixCopy(float* result, const float* A) 232{ 233 memcpy(result, A, 16*sizeof(float)); 234} 235 236void GPU_MatrixIdentity(float* result) 237{ 238 memset(result, 0, 16*sizeof(float)); 239 result[0] = result[5] = result[10] = result[15] = 1; 240} 241 242 243void GPU_MatrixOrtho(float* result, float left, float right, float bottom, float top, float z_near, float z_far) 244{ 245 if(result == NULL) 246 return; 247 248 { 249#ifdef ROW_MAJOR 250 float A[16]; 251 FILL_MATRIX_4x4(A, 252 2/(right - left), 0, 0, -(right + left)/(right - left), 253 0, 2/(top - bottom), 0, -(top + bottom)/(top - bottom), 254 0, 0, -2/(z_far - z_near), -(z_far + z_near)/(z_far - z_near), 255 0, 0, 0, 1 256 ); 257#else 258 float A[16]; 259 FILL_MATRIX_4x4(A, 260 2 / (right - left), 0, 0, 0, 261 0, 2 / (top - bottom), 0, 0, 262 0, 0, -2 / (z_far - z_near), 0, 263 -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(z_far + z_near) / (z_far - z_near), 1 264 ); 265#endif 266 267 GPU_MultiplyAndAssign(result, A); 268 } 269} 270 271 272void GPU_MatrixFrustum(float* result, float left, float right, float bottom, float top, float z_near, float z_far) 273{ 274 if(result == NULL) 275 return; 276 277 { 278 float A[16]; 279 FILL_MATRIX_4x4(A, 280 2 * z_near / (right - left), 0, 0, 0, 281 0, 2 * z_near / (top - bottom), 0, 0, 282 (right + left) / (right - left), (top + bottom) / (top - bottom), -(z_far + z_near) / (z_far - z_near), -1, 283 0, 0, -(2 * z_far * z_near) / (z_far - z_near), 0 284 ); 285 286 GPU_MultiplyAndAssign(result, A); 287 } 288} 289 290void GPU_MatrixPerspective(float* result, float fovy, float aspect, float z_near, float z_far) 291{ 292 float fW, fH; 293 294 // Make it left-handed? 295 fovy = -fovy; 296 aspect = -aspect; 297 298 fH = tanf((fovy / 360) * PI) * z_near; 299 fW = fH * aspect; 300 GPU_MatrixFrustum(result, -fW, fW, -fH, fH, z_near, z_far); 301} 302 303void GPU_MatrixLookAt(float* matrix, float eye_x, float eye_y, float eye_z, float target_x, float target_y, float target_z, float up_x, float up_y, float up_z) 304{ 305 float forward[3] = {target_x - eye_x, target_y - eye_y, target_z - eye_z}; 306 float up[3] = {up_x, up_y, up_z}; 307 float side[3]; 308 float view[16]; 309 310 GPU_VectorNormalize(forward); 311 GPU_VectorNormalize(up); 312 313 // Calculate sideways vector 314 GPU_VectorCross(side, forward, up); 315 316 // Calculate new up vector 317 GPU_VectorCross(up, side, forward); 318 319 // Set up view matrix 320 view[0] = side[0]; 321 view[4] = side[1]; 322 view[8] = side[2]; 323 view[12] = 0.0f; 324 325 view[1] = up[0]; 326 view[5] = up[1]; 327 view[9] = up[2]; 328 view[13] = 0.0f; 329 330 view[2] = -forward[0]; 331 view[6] = -forward[1]; 332 view[10] = -forward[2]; 333 view[14] = 0.0f; 334 335 view[3] = view[7] = view[11] = 0.0f; 336 view[15] = 1.0f; 337 338 GPU_MultiplyAndAssign(matrix, view); 339 GPU_MatrixTranslate(matrix, -eye_x, -eye_y, -eye_z); 340} 341 342void GPU_MatrixTranslate(float* result, float x, float y, float z) 343{ 344 if(result == NULL) 345 return; 346 347 { 348#ifdef ROW_MAJOR 349 float A[16]; 350 FILL_MATRIX_4x4(A, 351 1, 0, 0, x, 352 0, 1, 0, y, 353 0, 0, 1, z, 354 0, 0, 0, 1 355 ); 356#else 357 float A[16]; 358 FILL_MATRIX_4x4(A, 359 1, 0, 0, 0, 360 0, 1, 0, 0, 361 0, 0, 1, 0, 362 x, y, z, 1 363 ); 364#endif 365 366 GPU_MultiplyAndAssign(result, A); 367 } 368} 369 370void GPU_MatrixScale(float* result, float sx, float sy, float sz) 371{ 372 if(result == NULL) 373 return; 374 375 { 376 float A[16]; 377 FILL_MATRIX_4x4(A, 378 sx, 0, 0, 0, 379 0, sy, 0, 0, 380 0, 0, sz, 0, 381 0, 0, 0, 1 382 ); 383 384 GPU_MultiplyAndAssign(result, A); 385 } 386} 387 388void GPU_MatrixRotate(float* result, float degrees, float x, float y, float z) 389{ 390 float p, radians, c, s, c_, zc_, yc_, xzc_, xyc_, yzc_, xs, ys, zs; 391 392 if(result == NULL) 393 return; 394 395 p = 1/sqrtf(x*x + y*y + z*z); 396 x *= p; y *= p; z *= p; 397 radians = degrees * RAD_PER_DEG; 398 c = cosf(radians); 399 s = sinf(radians); 400 c_ = 1 - c; 401 zc_ = z*c_; 402 yc_ = y*c_; 403 xzc_ = x*zc_; 404 xyc_ = x*y*c_; 405 yzc_ = y*zc_; 406 xs = x*s; 407 ys = y*s; 408 zs = z*s; 409 410 { 411#ifdef ROW_MAJOR 412 float A[16]; 413 FILL_MATRIX_4x4(A, 414 x*x*c_ + c, xyc_ - zs, xzc_ + ys, 0, 415 xyc_ + zs, y*yc_ + c, yzc_ - xs, 0, 416 xzc_ - ys, yzc_ + xs, z*zc_ + c, 0, 417 0, 0, 0, 1 418 ); 419#else 420 float A[16]; 421 FILL_MATRIX_4x4(A, 422 x*x*c_ + c, xyc_ + zs, xzc_ - ys, 0, 423 xyc_ - zs, y*yc_ + c, yzc_ + xs, 0, 424 xzc_ + ys, yzc_ - xs, z*zc_ + c, 0, 425 0, 0, 0, 1 426 ); 427#endif 428 429 GPU_MultiplyAndAssign(result, A); 430 } 431} 432 433// Matrix multiply: result = A * B 434void GPU_MatrixMultiply(float* result, const float* A, const float* B) 435{ 436 float (*matR)[4] = (float(*)[4])result; 437 float (*matA)[4] = (float(*)[4])A; 438 float (*matB)[4] = (float(*)[4])B; 439 matR[0][0] = matB[0][0] * matA[0][0] + matB[0][1] * matA[1][0] + matB[0][2] * matA[2][0] + matB[0][3] * matA[3][0]; 440 matR[0][1] = matB[0][0] * matA[0][1] + matB[0][1] * matA[1][1] + matB[0][2] * matA[2][1] + matB[0][3] * matA[3][1]; 441 matR[0][2] = matB[0][0] * matA[0][2] + matB[0][1] * matA[1][2] + matB[0][2] * matA[2][2] + matB[0][3] * matA[3][2]; 442 matR[0][3] = matB[0][0] * matA[0][3] + matB[0][1] * matA[1][3] + matB[0][2] * matA[2][3] + matB[0][3] * matA[3][3]; 443 matR[1][0] = matB[1][0] * matA[0][0] + matB[1][1] * matA[1][0] + matB[1][2] * matA[2][0] + matB[1][3] * matA[3][0]; 444 matR[1][1] = matB[1][0] * matA[0][1] + matB[1][1] * matA[1][1] + matB[1][2] * matA[2][1] + matB[1][3] * matA[3][1]; 445 matR[1][2] = matB[1][0] * matA[0][2] + matB[1][1] * matA[1][2] + matB[1][2] * matA[2][2] + matB[1][3] * matA[3][2]; 446 matR[1][3] = matB[1][0] * matA[0][3] + matB[1][1] * matA[1][3] + matB[1][2] * matA[2][3] + matB[1][3] * matA[3][3]; 447 matR[2][0] = matB[2][0] * matA[0][0] + matB[2][1] * matA[1][0] + matB[2][2] * matA[2][0] + matB[2][3] * matA[3][0]; 448 matR[2][1] = matB[2][0] * matA[0][1] + matB[2][1] * matA[1][1] + matB[2][2] * matA[2][1] + matB[2][3] * matA[3][1]; 449 matR[2][2] = matB[2][0] * matA[0][2] + matB[2][1] * matA[1][2] + matB[2][2] * matA[2][2] + matB[2][3] * matA[3][2]; 450 matR[2][3] = matB[2][0] * matA[0][3] + matB[2][1] * matA[1][3] + matB[2][2] * matA[2][3] + matB[2][3] * matA[3][3]; 451 matR[3][0] = matB[3][0] * matA[0][0] + matB[3][1] * matA[1][0] + matB[3][2] * matA[2][0] + matB[3][3] * matA[3][0]; 452 matR[3][1] = matB[3][0] * matA[0][1] + matB[3][1] * matA[1][1] + matB[3][2] * matA[2][1] + matB[3][3] * matA[3][1]; 453 matR[3][2] = matB[3][0] * matA[0][2] + matB[3][1] * matA[1][2] + matB[3][2] * matA[2][2] + matB[3][3] * matA[3][2]; 454 matR[3][3] = matB[3][0] * matA[0][3] + matB[3][1] * matA[1][3] + matB[3][2] * matA[2][3] + matB[3][3] * matA[3][3]; 455} 456 457void GPU_MultiplyAndAssign(float* result, const float* B) 458{ 459 float temp[16]; 460 GPU_MatrixMultiply(temp, result, B); 461 GPU_MatrixCopy(result, temp); 462} 463 464 465 466 467 468// Can be used up to two times per line evaluation... 469const char* GPU_GetMatrixString(const float* A) 470{ 471 static char buffer[512]; 472 static char buffer2[512]; 473 static char flip = 0; 474 475 char* b = (flip? buffer : buffer2); 476 flip = !flip; 477 478 snprintf(b, 512, "%.1f %.1f %.1f %.1f\n" 479 "%.1f %.1f %.1f %.1f\n" 480 "%.1f %.1f %.1f %.1f\n" 481 "%.1f %.1f %.1f %.1f", 482 A[0], A[1], A[2], A[3], 483 A[4], A[5], A[6], A[7], 484 A[8], A[9], A[10], A[11], 485 A[12], A[13], A[14], A[15]); 486 return b; 487} 488 489void GPU_MatrixMode(GPU_Target* target, int matrix_mode) 490{ 491 GPU_Target* context_target; 492 if(target == NULL) 493 return; 494 495 GPU_FlushBlitBuffer(); 496 target->matrix_mode = matrix_mode; 497 498 context_target = GPU_GetContextTarget(); 499 if(context_target != NULL && context_target == target->context_target) 500 context_target->context->active_target = target; 501} 502 503float* GPU_GetModel(void) 504{ 505 GPU_Target* target = GPU_GetActiveTarget(); 506 if(target == NULL) 507 return NULL; 508 return GPU_GetTopMatrix(&target->model_matrix); 509} 510 511float* GPU_GetView(void) 512{ 513 GPU_Target* target = GPU_GetActiveTarget(); 514 if(target == NULL) 515 return NULL; 516 return GPU_GetTopMatrix(&target->view_matrix); 517} 518 519float* GPU_GetProjection(void) 520{ 521 GPU_Target* target = GPU_GetActiveTarget(); 522 if(target == NULL) 523 return NULL; 524 return GPU_GetTopMatrix(&target->projection_matrix); 525} 526 527float* GPU_GetCurrentMatrix(void) 528{ 529 GPU_MatrixStack* stack; 530 GPU_Target* target = GPU_GetActiveTarget(); 531 if(target == NULL) 532 return NULL; 533 if(target->matrix_mode == GPU_MODEL) 534 stack = &target->model_matrix; 535 else if(target->matrix_mode == GPU_VIEW) 536 stack = &target->view_matrix; 537 else// if(target->matrix_mode == GPU_PROJECTION) 538 stack = &target->projection_matrix; 539 540 return GPU_GetTopMatrix(stack); 541} 542 543void GPU_PushMatrix(void) 544{ 545 GPU_MatrixStack* stack; 546 GPU_Target* target = GPU_GetActiveTarget(); 547 if(target == NULL) 548 return; 549 550 if(target->matrix_mode == GPU_MODEL) 551 stack = &target->model_matrix; 552 else if(target->matrix_mode == GPU_VIEW) 553 stack = &target->view_matrix; 554 else// if(target->matrix_mode == GPU_PROJECTION) 555 stack = &target->projection_matrix; 556 557 if(stack->size + 1 >= stack->storage_size) 558 { 559 // Grow matrix stack (1, 6, 16, 36, ...) 560 561 // Alloc new one 562 unsigned int new_storage_size = stack->storage_size*2 + 4; 563 float** new_stack = (float**)SDL_malloc(sizeof(float*) * new_storage_size); 564 unsigned int i; 565 for(i = 0; i < new_storage_size; ++i) 566 { 567 new_stack[i] = (float*)SDL_malloc(sizeof(float) * 16); 568 } 569 // Copy old one 570 for(i = 0; i < stack->size; ++i) 571 { 572 GPU_MatrixCopy(new_stack[i], stack->matrix[i]); 573 } 574 // Free old one 575 for(i = 0; i < stack->storage_size; ++i) 576 { 577 SDL_free(stack->matrix[i]); 578 } 579 SDL_free(stack->matrix); 580 581 // Switch to new one 582 stack->storage_size = new_storage_size; 583 stack->matrix = new_stack; 584 } 585 GPU_MatrixCopy(stack->matrix[stack->size], stack->matrix[stack->size-1]); 586 stack->size++; 587} 588 589void GPU_PopMatrix(void) 590{ 591 GPU_MatrixStack* stack; 592 593 GPU_Target* target = GPU_GetActiveTarget(); 594 if(target == NULL) 595 return; 596 597 // FIXME: Flushing here is not always necessary if this isn't the last target 598 GPU_FlushBlitBuffer(); 599 600 if(target->matrix_mode == GPU_MODEL) 601 stack = &target->model_matrix; 602 else if(target->matrix_mode == GPU_VIEW) 603 stack = &target->view_matrix; 604 else //if(target->matrix_mode == GPU_PROJECTION) 605 stack = &target->projection_matrix; 606 607 if(stack->size == 0) 608 { 609 GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Matrix stack is empty."); 610 } 611 else if(stack->size == 1) 612 { 613 GPU_PushErrorCode(__func__, GPU_ERROR_USER_ERROR, "Matrix stack would become empty!"); 614 } 615 else 616 stack->size--; 617} 618 619void GPU_SetProjection(const float* A) 620{ 621 GPU_Target* target = GPU_GetActiveTarget(); 622 if(target == NULL || A == NULL) 623 return; 624 625 GPU_FlushBlitBuffer(); 626 GPU_MatrixCopy(GPU_GetProjection(), A); 627} 628 629void GPU_SetModel(const float* A) 630{ 631 GPU_Target* target = GPU_GetActiveTarget(); 632 if(target == NULL || A == NULL) 633 return; 634 635 GPU_FlushBlitBuffer(); 636 GPU_MatrixCopy(GPU_GetModel(), A); 637} 638 639void GPU_SetView(const float* A) 640{ 641 GPU_Target* target = GPU_GetActiveTarget(); 642 if(target == NULL || A == NULL) 643 return; 644 645 GPU_FlushBlitBuffer(); 646 GPU_MatrixCopy(GPU_GetView(), A); 647} 648 649void GPU_SetProjectionFromStack(GPU_MatrixStack* stack) 650{ 651 GPU_Target* target = GPU_GetActiveTarget(); 652 if(target == NULL || stack == NULL) 653 return; 654 655 GPU_SetProjection(GPU_GetTopMatrix(stack)); 656} 657 658void GPU_SetModelFromStack(GPU_MatrixStack* stack) 659{ 660 GPU_Target* target = GPU_GetActiveTarget(); 661 if(target == NULL || stack == NULL) 662 return; 663 664 GPU_SetModel(GPU_GetTopMatrix(stack)); 665} 666 667void GPU_SetViewFromStack(GPU_MatrixStack* stack) 668{ 669 GPU_Target* target = GPU_GetActiveTarget(); 670 if(target == NULL || stack == NULL) 671 return; 672 673 GPU_SetView(GPU_GetTopMatrix(stack)); 674} 675 676float* GPU_GetTopMatrix(GPU_MatrixStack* stack) 677{ 678 if(stack == NULL || stack->size == 0) 679 return NULL; 680 return stack->matrix[stack->size-1]; 681} 682 683void GPU_LoadIdentity(void) 684{ 685 float* result = GPU_GetCurrentMatrix(); 686 if(result == NULL) 687 return; 688 689 GPU_FlushBlitBuffer(); 690 GPU_MatrixIdentity(result); 691} 692 693void GPU_LoadMatrix(const float* A) 694{ 695 float* result = GPU_GetCurrentMatrix(); 696 if(result == NULL) 697 return; 698 GPU_FlushBlitBuffer(); 699 GPU_MatrixCopy(result, A); 700} 701 702void GPU_Ortho(float left, float right, float bottom, float top, float z_near, float z_far) 703{ 704 GPU_FlushBlitBuffer(); 705 GPU_MatrixOrtho(GPU_GetCurrentMatrix(), left, right, bottom, top, z_near, z_far); 706} 707 708void GPU_Frustum(float left, float right, float bottom, float top, float z_near, float z_far) 709{ 710 GPU_FlushBlitBuffer(); 711 GPU_MatrixFrustum(GPU_GetCurrentMatrix(), left, right, bottom, top, z_near, z_far); 712} 713 714void GPU_Perspective(float fovy, float aspect, float z_near, float z_far) 715{ 716 GPU_FlushBlitBuffer(); 717 GPU_MatrixPerspective(GPU_GetCurrentMatrix(), fovy, aspect, z_near, z_far); 718} 719 720void GPU_LookAt(float eye_x, float eye_y, float eye_z, float target_x, float target_y, float target_z, float up_x, float up_y, float up_z) 721{ 722 GPU_FlushBlitBuffer(); 723 GPU_MatrixLookAt(GPU_GetCurrentMatrix(), eye_x, eye_y, eye_z, target_x, target_y, target_z, up_x, up_y, up_z); 724} 725 726 727void GPU_Translate(float x, float y, float z) 728{ 729 GPU_FlushBlitBuffer(); 730 GPU_MatrixTranslate(GPU_GetCurrentMatrix(), x, y, z); 731} 732 733void GPU_Scale(float sx, float sy, float sz) 734{ 735 GPU_FlushBlitBuffer(); 736 GPU_MatrixScale(GPU_GetCurrentMatrix(), sx, sy, sz); 737} 738 739void GPU_Rotate(float degrees, float x, float y, float z) 740{ 741 GPU_FlushBlitBuffer(); 742 GPU_MatrixRotate(GPU_GetCurrentMatrix(), degrees, x, y, z); 743} 744 745void GPU_MultMatrix(const float* A) 746{ 747 float* result = GPU_GetCurrentMatrix(); 748 if(result == NULL) 749 return; 750 GPU_FlushBlitBuffer(); 751 GPU_MultiplyAndAssign(result, A); 752} 753 754void GPU_GetModelViewProjection(float* result) 755{ 756 // MVP = P * V * M 757 GPU_MatrixMultiply(result, GPU_GetProjection(), GPU_GetView()); 758 GPU_MultiplyAndAssign(result, GPU_GetModel()); 759}