this repo has no description
0
fork

Configure Feed

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

Big overhaul of matrix functions and the related camera parts so they can be used to set up projections and such.

+638 -180
+9 -2
Android.mk
··· 15 15 $(SDL_GPU_DIR)/src/SDL_gpu_shapes.c \ 16 16 $(SDL_GPU_DIR)/src/renderer_GLES_1.c \ 17 17 $(SDL_GPU_DIR)/src/renderer_GLES_2.c \ 18 + $(SDL_GPU_DIR)/src/renderer_GLES_3.c \ 18 19 $(STB_IMAGE_DIR)/stb_image.c \ 19 20 $(STB_IMAGE_DIR)/stb_image_write.c 20 21 21 22 22 23 LOCAL_CFLAGS += -DSDL_GPU_DISABLE_OPENGL -DSTBI_FAILURE_USERMSG -O3 23 - #LOCAL_LDLIBS += -llog -lGLESv1_CM 24 - LOCAL_LDLIBS += -llog -lGLESv2 -lGLESv1_CM 24 + 25 + LOCAL_LDLIBS += -llog -lGLESv1_CM 26 + LOCAL_LDLIBS += -lGLESv2 27 + 28 + # Disable GLES version 3 support for now, since some environments aren't set up for it yet 29 + # Enable it if you want it! 30 + LOCAL_CFLAGS += -DSDL_GPU_DISABLE_GLES_3 31 + #LOCAL_LDLIBS += -lGLESv3 25 32 26 33 LOCAL_SHARED_LIBRARIES := SDL2 27 34
+53 -4
include/SDL_gpu.h
··· 362 362 363 363 /*! Perspective and object viewing transforms. */ 364 364 GPU_Camera camera; 365 + Uint8 use_camera; 365 366 366 367 /*! Renderer context data. NULL if the target does not represent a window or rendering context. */ 367 368 GPU_Context* context; ··· 902 903 * \return The old camera. */ 903 904 DECLSPEC GPU_Camera SDLCALL GPU_SetCamera(GPU_Target* target, GPU_Camera* cam); 904 905 906 + /*! Enables or disables using the built-in camera matrix transforms. */ 907 + DECLSPEC void SDLCALL GPU_EnableCamera(GPU_Target* target, Uint8 use_camera); 908 + 909 + /*! Returns 1 if the camera transforms are enabled, 0 otherwise. */ 910 + DECLSPEC Uint8 SDLCALL GPU_IsCameraEnabled(GPU_Target* target); 911 + 905 912 /*! \return The RGBA color of a pixel. */ 906 913 DECLSPEC SDL_Color SDLCALL GPU_GetPixel(GPU_Target* target, Sint16 x, Sint16 y); 907 914 ··· 1087 1094 /*! \ingroup Matrix 1088 1095 * @{ */ 1089 1096 1097 + // Basic vector operations (3D) 1098 + 1099 + /*! Returns the magnitude (length) of the given vector. */ 1100 + DECLSPEC float SDLCALL GPU_VectorLength(float* vec3); 1101 + 1102 + /*! Modifies the given vector so that it has a new length of 1. */ 1103 + DECLSPEC void SDLCALL GPU_VectorNormalize(float* vec3); 1104 + 1105 + /*! Returns the dot product of two vectors. */ 1106 + DECLSPEC float SDLCALL GPU_VectorDot(float* A, float* B); 1107 + 1108 + /*! Performs the cross product of vectors A and B (result = A x B). Do not use A or B as 'result'. */ 1109 + DECLSPEC void SDLCALL GPU_VectorCross(float* result, float* A, float* B); 1110 + 1111 + /*! Overwrite 'result' vector with the values from vector A. */ 1112 + DECLSPEC void SDLCALL GPU_VectorCopy(float* result, float* A); 1113 + 1114 + /*! Multiplies the given matrix into the given vector (vec3 = matrix*vec3). */ 1115 + DECLSPEC void SDLCALL GPU_VectorApplyMatrix(float* vec3, float* matrix_4x4); 1116 + 1117 + 1090 1118 1091 1119 // Basic matrix operations (4x4) 1092 1120 1093 - /*! Copy matrix A to the given 'result' matrix. */ 1121 + /*! Overwrite 'result' matrix with the values from matrix A. */ 1094 1122 DECLSPEC void SDLCALL GPU_MatrixCopy(float* result, const float* A); 1095 1123 1096 1124 /*! Fills 'result' matrix with the identity matrix. */ 1097 1125 DECLSPEC void SDLCALL GPU_MatrixIdentity(float* result); 1098 1126 1127 + /*! Multiplies an orthographic projection matrix into the given matrix. */ 1128 + DECLSPEC void SDLCALL GPU_MatrixOrtho(float* result, float left, float right, float bottom, float top, float near, float far); 1129 + 1130 + /*! Multiplies a perspective projection matrix into the given matrix. */ 1131 + DECLSPEC void SDLCALL GPU_MatrixFrustum(float* result, float left, float right, float bottom, float top, float near, float far); 1132 + 1133 + /*! Multiplies a perspective projection matrix into the given matrix. */ 1134 + DECLSPEC void SDLCALL GPU_MatrixPerspective(float* result, float fovy, float aspect, float zNear, float zFar); 1135 + 1136 + /*! Multiplies a view matrix into the given matrix. */ 1137 + DECLSPEC void SDLCALL 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); 1138 + 1139 + /*! Adds a translation into the given matrix. */ 1140 + DECLSPEC void SDLCALL GPU_MatrixTranslate(float* result, float x, float y, float z); 1141 + 1142 + /*! Multiplies a scaling matrix into the given matrix. */ 1143 + DECLSPEC void SDLCALL GPU_MatrixScale(float* result, float sx, float sy, float sz); 1144 + 1145 + /*! Multiplies a rotation matrix into the given matrix. */ 1146 + DECLSPEC void SDLCALL GPU_MatrixRotate(float* result, float degrees, float x, float y, float z); 1147 + 1099 1148 /*! Multiplies matrices A and B and stores the result in the given 'result' matrix (result = A*B). Do not use A or B as 'result'. 1100 1149 * \see GPU_MultiplyAndAssign 1101 1150 */ 1102 1151 DECLSPEC void SDLCALL GPU_Multiply4x4(float* result, float* A, float* B); 1103 1152 1104 - /*! Multiplies matrices 'result' and A and stores the result in the given 'result' matrix (result = result * A). */ 1105 - DECLSPEC void SDLCALL GPU_MultiplyAndAssign(float* result, float* A); 1153 + /*! Multiplies matrices 'result' and B and stores the result in the given 'result' matrix (result = result * B). */ 1154 + DECLSPEC void SDLCALL GPU_MultiplyAndAssign(float* result, float* B); 1106 1155 1107 1156 1108 1157 // Matrix stack accessors ··· 1141 1190 DECLSPEC void SDLCALL GPU_Ortho(float left, float right, float bottom, float top, float near, float far); 1142 1191 1143 1192 /*! Multiplies a perspective projection matrix into the current matrix. */ 1144 - DECLSPEC void SDLCALL GPU_Frustum(float right, float left, float bottom, float top, float near, float far); 1193 + DECLSPEC void SDLCALL GPU_Frustum(float left, float right, float bottom, float top, float near, float far); 1145 1194 1146 1195 /*! Adds a translation into the current matrix. */ 1147 1196 DECLSPEC void SDLCALL GPU_Translate(float x, float y, float z);
+16 -1
src/SDL_gpu.c
··· 880 880 MAKE_CURRENT_IF_NONE(target); 881 881 if(_gpu_current_renderer->current_context_target == NULL) 882 882 return GPU_GetDefaultCamera(); 883 + // TODO: Remove from renderer and flush here 884 + return _gpu_current_renderer->impl->SetCamera(_gpu_current_renderer, target, cam); 885 + } 883 886 884 - return _gpu_current_renderer->impl->SetCamera(_gpu_current_renderer, target, cam); 887 + void GPU_EnableCamera(GPU_Target* target, Uint8 use_camera) 888 + { 889 + if (target == NULL) 890 + return; 891 + // TODO: Flush here 892 + target->use_camera = use_camera; 893 + } 894 + 895 + Uint8 GPU_IsCameraEnabled(GPU_Target* target) 896 + { 897 + if (target == NULL) 898 + return 0; 899 + return target->use_camera; 885 900 } 886 901 887 902 GPU_Image* GPU_CreateImage(Uint16 w, Uint16 h, GPU_FormatEnum format)
+259 -139
src/SDL_gpu_matrix.c
··· 50 50 #endif 51 51 52 52 53 - // Implementations based on Wayne Cochran's (wcochran) matrix.c 54 53 55 54 // Column-major 56 55 #define INDEX(row,col) ((col)*4 + (row)) 57 56 57 + 58 + float GPU_VectorLength(float* vec3) 59 + { 60 + return sqrtf(vec3[0] * vec3[0] + vec3[1] * vec3[1] + vec3[2] * vec3[2]); 61 + } 62 + 63 + void GPU_VectorNormalize(float* vec3) 64 + { 65 + float mag = GPU_VectorLength(vec3); 66 + vec3[0] /= mag; 67 + vec3[1] /= mag; 68 + vec3[2] /= mag; 69 + } 70 + 71 + float GPU_VectorDot(float* A, float* B) 72 + { 73 + return A[0] * B[0] + A[1] * B[1] + A[2] * B[2]; 74 + } 75 + 76 + void GPU_VectorCross(float* result, float* A, float* B) 77 + { 78 + result[0] = A[1] * B[2] - A[2] * B[1]; 79 + result[1] = A[2] * B[0] - A[0] * B[2]; 80 + result[2] = A[0] * B[1] - A[1] * B[0]; 81 + } 82 + 83 + void GPU_VectorCopy(float* result, float* A) 84 + { 85 + result[0] = A[0]; 86 + result[1] = A[1]; 87 + result[2] = A[2]; 88 + } 89 + 90 + void GPU_VectorApplyMatrix(float* vec3, float* matrix_4x4) 91 + { 92 + float x = matrix_4x4[INDEX(0, 0)] * vec3[0] + matrix_4x4[INDEX(0, 1)] * vec3[1] + matrix_4x4[INDEX(0, 2)] * vec3[2] + matrix_4x4[INDEX(0, 3)]; 93 + float y = matrix_4x4[INDEX(1, 0)] * vec3[0] + matrix_4x4[INDEX(1, 1)] * vec3[1] + matrix_4x4[INDEX(1, 2)] * vec3[2] + matrix_4x4[INDEX(1, 3)]; 94 + float z = matrix_4x4[INDEX(2, 0)] * vec3[0] + matrix_4x4[INDEX(2, 1)] * vec3[1] + matrix_4x4[INDEX(2, 2)] * vec3[2] + matrix_4x4[INDEX(2, 3)]; 95 + float w = matrix_4x4[INDEX(3, 0)] * vec3[0] + matrix_4x4[INDEX(3, 1)] * vec3[1] + matrix_4x4[INDEX(3, 2)] * vec3[2] + matrix_4x4[INDEX(3, 3)]; 96 + vec3[0] = x / w; 97 + vec3[1] = y / w; 98 + vec3[2] = z / w; 99 + } 100 + 101 + 102 + // Matrix math implementations based on Wayne Cochran's (wcochran) matrix.c 103 + 58 104 #define FILL_MATRIX_4x4(A, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) \ 59 105 A[0] = a0; \ 60 106 A[1] = a1; \ ··· 84 130 result[0] = result[5] = result[10] = result[15] = 1; 85 131 } 86 132 133 + 134 + void GPU_MatrixOrtho(float* result, float left, float right, float bottom, float top, float near, float far) 135 + { 136 + if(result == NULL) 137 + return; 138 + 139 + { 140 + #ifdef ROW_MAJOR 141 + float A[16]; 142 + FILL_MATRIX_4x4(A, 143 + 2/(right - left), 0, 0, -(right + left)/(right - left), 144 + 0, 2/(top - bottom), 0, -(top + bottom)/(top - bottom), 145 + 0, 0, -2/(far - near), -(far + near)/(far - near), 146 + 0, 0, 0, 1 147 + ); 148 + #else 149 + float A[16]; 150 + FILL_MATRIX_4x4(A, 151 + 2 / (right - left), 0, 0, 0, 152 + 0, 2 / (top - bottom), 0, 0, 153 + 0, 0, -2 / (far - near), 0, 154 + -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(far + near) / (far - near), 1 155 + ); 156 + #endif 157 + 158 + GPU_MultiplyAndAssign(result, A); 159 + } 160 + } 161 + 162 + 163 + void GPU_MatrixFrustum(float* result, float left, float right, float bottom, float top, float near, float far) 164 + { 165 + if(result == NULL) 166 + return; 167 + 168 + { 169 + float A[16]; 170 + FILL_MATRIX_4x4(A, 171 + 2 * near / (right - left), 0, 0, 0, 172 + 0, 2 * near / (top - bottom), 0, 0, 173 + (right + left) / (right - left), (top + bottom) / (top - bottom), -(far + near) / (far - near), -1, 174 + 0, 0, -(2 * far * near) / (far - near), 0 175 + ); 176 + 177 + GPU_MultiplyAndAssign(result, A); 178 + } 179 + } 180 + 181 + void GPU_MatrixPerspective(float* result, float fovy, float aspect, float zNear, float zFar) 182 + { 183 + float fW, fH; 184 + 185 + // Make it left-handed? 186 + fovy = -fovy; 187 + aspect = -aspect; 188 + 189 + fH = tanf(fovy / 360 * M_PI) * zNear; 190 + fW = fH * aspect; 191 + GPU_MatrixFrustum(result, -fW, fW, -fH, fH, zNear, zFar); 192 + } 193 + 194 + void 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) 195 + { 196 + float forward[3] = {target_x - eye_x, target_y - eye_y, target_z - eye_z}; 197 + float up[3] = {up_x, up_y, up_z}; 198 + float side[3]; 199 + float view[16]; 200 + 201 + GPU_VectorNormalize(forward); 202 + GPU_VectorNormalize(up); 203 + 204 + // Calculate sideways vector 205 + GPU_VectorCross(side, forward, up); 206 + 207 + // Calculate new up vector 208 + GPU_VectorCross(up, side, forward); 209 + 210 + // Set up view matrix 211 + view[0] = side[0]; 212 + view[4] = side[1]; 213 + view[8] = side[2]; 214 + view[12] = 0.0f; 215 + 216 + view[1] = up[0]; 217 + view[5] = up[1]; 218 + view[9] = up[2]; 219 + view[13] = 0.0f; 220 + 221 + view[2] = -forward[0]; 222 + view[6] = -forward[1]; 223 + view[10] = -forward[2]; 224 + view[14] = 0.0f; 225 + 226 + view[3] = view[7] = view[11] = 0.0f; 227 + view[15] = 1.0f; 228 + 229 + GPU_MultiplyAndAssign(matrix, view); 230 + GPU_MatrixTranslate(matrix, -eye_x, -eye_y, -eye_z); 231 + } 232 + 233 + void GPU_MatrixTranslate(float* result, float x, float y, float z) 234 + { 235 + if(result == NULL) 236 + return; 237 + 238 + { 239 + #ifdef ROW_MAJOR 240 + float A[16]; 241 + FILL_MATRIX_4x4(A, 242 + 1, 0, 0, x, 243 + 0, 1, 0, y, 244 + 0, 0, 1, z, 245 + 0, 0, 0, 1 246 + ); 247 + #else 248 + float A[16]; 249 + FILL_MATRIX_4x4(A, 250 + 1, 0, 0, 0, 251 + 0, 1, 0, 0, 252 + 0, 0, 1, 0, 253 + x, y, z, 1 254 + ); 255 + #endif 256 + 257 + GPU_MultiplyAndAssign(result, A); 258 + } 259 + } 260 + 261 + void GPU_MatrixScale(float* result, float sx, float sy, float sz) 262 + { 263 + if(result == NULL) 264 + return; 265 + 266 + { 267 + float A[16]; 268 + FILL_MATRIX_4x4(A, 269 + sx, 0, 0, 0, 270 + 0, sy, 0, 0, 271 + 0, 0, sz, 0, 272 + 0, 0, 0, 1 273 + ); 274 + 275 + GPU_MultiplyAndAssign(result, A); 276 + } 277 + } 278 + 279 + void GPU_MatrixRotate(float* result, float degrees, float x, float y, float z) 280 + { 281 + float p, radians, c, s, c_, zc_, yc_, xzc_, xyc_, yzc_, xs, ys, zs; 282 + 283 + if(result == NULL) 284 + return; 285 + 286 + p = 1/sqrtf(x*x + y*y + z*z); 287 + x *= p; y *= p; z *= p; 288 + radians = degrees * (M_PI/180); 289 + c = cosf(radians); 290 + s = sinf(radians); 291 + c_ = 1 - c; 292 + zc_ = z*c_; 293 + yc_ = y*c_; 294 + xzc_ = x*zc_; 295 + xyc_ = x*y*c_; 296 + yzc_ = y*zc_; 297 + xs = x*s; 298 + ys = y*s; 299 + zs = z*s; 300 + 301 + { 302 + #ifdef ROW_MAJOR 303 + float A[16]; 304 + FILL_MATRIX_4x4(A, 305 + x*x*c_ + c, xyc_ - zs, xzc_ + ys, 0, 306 + xyc_ + zs, y*yc_ + c, yzc_ - xs, 0, 307 + xzc_ - ys, yzc_ + xs, z*zc_ + c, 0, 308 + 0, 0, 0, 1 309 + ); 310 + #else 311 + float A[16]; 312 + FILL_MATRIX_4x4(A, 313 + x*x*c_ + c, xyc_ + zs, xzc_ - ys, 0, 314 + xyc_ - zs, y*yc_ + c, yzc_ + xs, 0, 315 + xzc_ + ys, yzc_ - xs, z*zc_ + c, 0, 316 + 0, 0, 0, 1 317 + ); 318 + #endif 319 + 320 + GPU_MultiplyAndAssign(result, A); 321 + } 322 + } 323 + 87 324 // Matrix multiply: result = A * B 88 325 void GPU_Multiply4x4(float* result, float* A, float* B) 89 326 { ··· 102 339 } 103 340 } 104 341 105 - void GPU_MultiplyAndAssign(float* result, float* A) 342 + void GPU_MultiplyAndAssign(float* result, float* B) 106 343 { 107 344 float temp[16]; 108 - GPU_Multiply4x4(temp, result, A); 345 + GPU_Multiply4x4(temp, result, B); 109 346 GPU_MatrixCopy(result, temp); 110 347 } 111 348 ··· 211 448 212 449 if(target == NULL || target->context == NULL) 213 450 return; 214 - 451 + 452 + GPU_FlushBlitBuffer(); 215 453 stack = (target->context->matrix_mode == GPU_MODELVIEW? &target->context->modelview_matrix : &target->context->projection_matrix); 216 454 if(stack->size == 0) 217 455 { ··· 225 463 { 226 464 float* result = GPU_GetCurrentMatrix(); 227 465 if(result == NULL) 228 - return; 466 + return; 467 + 468 + GPU_FlushBlitBuffer(); 229 469 GPU_MatrixIdentity(result); 230 470 } 231 471 232 472 void GPU_Ortho(float left, float right, float bottom, float top, float near, float far) 233 473 { 234 - float* result = GPU_GetCurrentMatrix(); 235 - if(result == NULL) 236 - return; 237 - 238 - { 239 - #ifdef ROW_MAJOR 240 - float A[16]; 241 - FILL_MATRIX_4x4(A, 242 - 2/(right - left), 0, 0, -(right + left)/(right - left), 243 - 0, 2/(top - bottom), 0, -(top + bottom)/(top - bottom), 244 - 0, 0, -2/(far - near), -(far + near)/(far - near), 245 - 0, 0, 0, 1 246 - ); 247 - #else 248 - float A[16]; 249 - FILL_MATRIX_4x4(A, 250 - 2 / (right - left), 0, 0, 0, 251 - 0, 2 / (top - bottom), 0, 0, 252 - 0, 0, -2 / (far - near), 0, 253 - -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(far + near) / (far - near), 1 254 - ); 255 - #endif 256 - 257 - GPU_MultiplyAndAssign(result, A); 258 - } 474 + GPU_FlushBlitBuffer(); 475 + GPU_MatrixOrtho(GPU_GetCurrentMatrix(), left, right, bottom, top, near, far); 259 476 } 260 477 261 - void GPU_Frustum(float right, float left, float bottom, float top, float near, float far) 478 + void GPU_Frustum(float left, float right, float bottom, float top, float near, float far) 262 479 { 263 - float* result = GPU_GetCurrentMatrix(); 264 - if(result == NULL) 265 - return; 266 - 267 - { 268 - #ifdef ROW_MAJOR 269 - float A[16]; 270 - FILL_MATRIX_4x4(A, 271 - 2 * near / (right - left), 0, 0, 0, 272 - 0, 2 * near / (top - bottom), 0, 0, 273 - (right + left) / (right - left), (top + bottom) / (top - bottom), -(far + near) / (far - near), -1, 274 - 0, 0, -(2 * far * near) / (far - near), 0 275 - ); 276 - #else 277 - float A[16]; 278 - FILL_MATRIX_4x4(A, 279 - 2 * near / (right - left), 0, (right + left) / (right - left), 0, 280 - 0, 2 * near / (top - bottom), (top + bottom) / (top - bottom), 0, 281 - 0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near), 282 - 0, 0, -1, 0 283 - ); 284 - #endif 285 - 286 - GPU_MultiplyAndAssign(result, A); 287 - } 480 + GPU_FlushBlitBuffer(); 481 + GPU_MatrixFrustum(GPU_GetCurrentMatrix(), left, right, bottom, top, near, far); 288 482 } 289 483 290 484 void GPU_Translate(float x, float y, float z) 291 485 { 292 - float* result = GPU_GetCurrentMatrix(); 293 - if(result == NULL) 294 - return; 295 - 296 - { 297 - #ifdef ROW_MAJOR 298 - float A[16]; 299 - FILL_MATRIX_4x4(A, 300 - 1, 0, 0, x, 301 - 0, 1, 0, y, 302 - 0, 0, 1, z, 303 - 0, 0, 0, 1 304 - ); 305 - #else 306 - float A[16]; 307 - FILL_MATRIX_4x4(A, 308 - 1, 0, 0, 0, 309 - 0, 1, 0, 0, 310 - 0, 0, 1, 0, 311 - x, y, z, 1 312 - ); 313 - #endif 314 - 315 - GPU_MultiplyAndAssign(result, A); 316 - } 486 + GPU_FlushBlitBuffer(); 487 + GPU_MatrixTranslate(GPU_GetCurrentMatrix(), x, y, z); 317 488 } 318 489 319 490 void GPU_Scale(float sx, float sy, float sz) 320 491 { 321 - float* result = GPU_GetCurrentMatrix(); 322 - if(result == NULL) 323 - return; 324 - 325 - { 326 - float A[16]; 327 - FILL_MATRIX_4x4(A, 328 - sx, 0, 0, 0, 329 - 0, sy, 0, 0, 330 - 0, 0, sz, 0, 331 - 0, 0, 0, 1 332 - ); 333 - 334 - GPU_MultiplyAndAssign(result, A); 335 - } 492 + GPU_FlushBlitBuffer(); 493 + GPU_MatrixScale(GPU_GetCurrentMatrix(), sx, sy, sz); 336 494 } 337 495 338 496 void GPU_Rotate(float degrees, float x, float y, float z) 339 497 { 340 - float p, radians, c, s, c_, zc_, yc_, xzc_, xyc_, yzc_, xs, ys, zs; 341 - float* result; 342 - 343 - p = 1/sqrtf(x*x + y*y + z*z); 344 - x *= p; y *= p; z *= p; 345 - radians = degrees * (M_PI/180); 346 - c = cosf(radians); 347 - s = sinf(radians); 348 - c_ = 1 - c; 349 - zc_ = z*c_; 350 - yc_ = y*c_; 351 - xzc_ = x*zc_; 352 - xyc_ = x*y*c_; 353 - yzc_ = y*zc_; 354 - xs = x*s; 355 - ys = y*s; 356 - zs = z*s; 357 - 358 - result = GPU_GetCurrentMatrix(); 359 - if(result == NULL) 360 - return; 361 - 362 - { 363 - #ifdef ROW_MAJOR 364 - float A[16]; 365 - FILL_MATRIX_4x4(A, 366 - x*x*c_ + c, xyc_ - zs, xzc_ + ys, 0, 367 - xyc_ + zs, y*yc_ + c, yzc_ - xs, 0, 368 - xzc_ - ys, yzc_ + xs, z*zc_ + c, 0, 369 - 0, 0, 0, 1 370 - ); 371 - #else 372 - float A[16]; 373 - FILL_MATRIX_4x4(A, 374 - x*x*c_ + c, xyc_ + zs, xzc_ - ys, 0, 375 - xyc_ - zs, y*yc_ + c, yzc_ + xs, 0, 376 - xzc_ + ys, yzc_ - xs, z*zc_ + c, 0, 377 - 0, 0, 0, 1 378 - ); 379 - #endif 380 - 381 - GPU_MultiplyAndAssign(result, A); 382 - } 498 + GPU_FlushBlitBuffer(); 499 + GPU_MatrixRotate(GPU_GetCurrentMatrix(), degrees, x, y, z); 383 500 } 384 501 385 502 void GPU_MultMatrix(float* A) ··· 387 504 float* result = GPU_GetCurrentMatrix(); 388 505 if(result == NULL) 389 506 return; 507 + GPU_FlushBlitBuffer(); 508 + // BIG FIXME: All of these matrix stack manipulators should be flushing the blit buffer. 509 + // A better solution would be to minimize the matrix stack API and make it clear that MultMatrix flushes. 390 510 GPU_MultiplyAndAssign(result, A); 391 511 } 392 512
+104 -28
src/renderer_GL_common.inl
··· 903 903 static void applyTargetCamera(GPU_Target* target) 904 904 { 905 905 GPU_CONTEXT_DATA* cdata = (GPU_CONTEXT_DATA*)GPU_GetContextTarget()->context->data; 906 - Uint8 invert = (target->image != NULL); 907 - float offsetX, offsetY; 908 906 909 907 cdata->last_camera = target->camera; 908 + cdata->last_camera_inverted = (target->image != NULL); 909 + } 910 910 911 - cdata->last_camera_inverted = invert; 911 + static Uint8 equal_cameras(GPU_Camera a, GPU_Camera b) 912 + { 913 + return (a.x == b.x && a.y == b.y && a.z == b.z && a.angle == b.angle && a.zoom == b.zoom); 914 + } 912 915 913 - GPU_MatrixMode( GPU_PROJECTION ); 914 - GPU_LoadIdentity(); 916 + static void changeCamera(GPU_Target* target) 917 + { 918 + //GPU_CONTEXT_DATA* cdata = (GPU_CONTEXT_DATA*)GPU_GetContextTarget()->context->data; 915 919 916 - if((!invert ^ GPU_GetCoordinateMode())) 917 - GPU_Ortho(target->camera.x, target->w + target->camera.x, target->h + target->camera.y, target->camera.y, -1.0f, 1.0f); 918 - else 919 - GPU_Ortho(target->camera.x, target->w + target->camera.x, target->camera.y, target->h + target->camera.y, -1.0f, 1.0f); // Special inverted orthographic projection because tex coords are inverted already for render-to-texture 920 + //if(cdata->last_camera_target != target || !equal_cameras(cdata->last_camera, target->camera)) 921 + { 922 + applyTargetCamera(target); 923 + } 924 + } 920 925 921 - GPU_MatrixMode( GPU_MODELVIEW ); 922 - GPU_LoadIdentity(); 926 + static void get_camera_matrix(float* result, GPU_Camera camera) 927 + { 928 + GPU_CONTEXT_DATA* cdata = (GPU_CONTEXT_DATA*)GPU_GetContextTarget()->context->data; 929 + GPU_Target* target = cdata->last_target; 930 + Uint8 invert = cdata->last_camera_inverted; 931 + float offsetX, offsetY; 923 932 933 + GPU_MatrixIdentity(result); 924 934 935 + // Now multiply in the projection part 936 + if(!invert ^ GPU_GetCoordinateMode()) 937 + GPU_MatrixOrtho(result, target->camera.x, target->w + target->camera.x, target->h + target->camera.y, target->camera.y, -1.0f, 1.0f); 938 + else 939 + GPU_MatrixOrtho(result, target->camera.x, target->w + target->camera.x, target->camera.y, target->h + target->camera.y, -1.0f, 1.0f); // Special inverted orthographic projection because tex coords are inverted already for render-to-texture 940 + 941 + // First the modelview part 925 942 offsetX = target->w/2.0f; 926 943 offsetY = target->h/2.0f; 927 - GPU_Translate(offsetX, offsetY, 0); 928 - GPU_Rotate(target->camera.angle, 0, 0, 1); 929 - GPU_Translate(-offsetX, -offsetY, 0); 944 + GPU_MatrixTranslate(result, offsetX, offsetY, 0); 945 + GPU_MatrixRotate(result, target->camera.angle, 0, 0, 1); 946 + GPU_MatrixTranslate(result, -offsetX, -offsetY, 0); 947 + 948 + GPU_MatrixTranslate(result, target->camera.x + offsetX, target->camera.y + offsetY, 0); 949 + GPU_MatrixScale(result, target->camera.zoom, target->camera.zoom, 1.0f); 950 + GPU_MatrixTranslate(result, -target->camera.x - offsetX, -target->camera.y - offsetY, 0); 930 951 931 - GPU_Translate(target->camera.x + offsetX, target->camera.y + offsetY, 0); 932 - GPU_Scale(target->camera.zoom, target->camera.zoom, 1.0f); 933 - GPU_Translate(-target->camera.x - offsetX, -target->camera.y - offsetY, 0); 934 952 } 935 953 936 - static Uint8 equal_cameras(GPU_Camera a, GPU_Camera b) 954 + static void get_camera_projection(float* result, GPU_Camera camera) 937 955 { 938 - return (a.x == b.x && a.y == b.y && a.z == b.z && a.angle == b.angle && a.zoom == b.zoom); 956 + GPU_CONTEXT_DATA* cdata = (GPU_CONTEXT_DATA*)GPU_GetContextTarget()->context->data; 957 + GPU_Target* target = cdata->last_target; 958 + Uint8 invert = cdata->last_camera_inverted; 959 + 960 + GPU_MatrixIdentity(result); 961 + 962 + if(!invert ^ GPU_GetCoordinateMode()) 963 + GPU_MatrixOrtho(result, target->camera.x, target->w + target->camera.x, target->h + target->camera.y, target->camera.y, -1.0f, 1.0f); 964 + else 965 + GPU_MatrixOrtho(result, target->camera.x, target->w + target->camera.x, target->camera.y, target->h + target->camera.y, -1.0f, 1.0f); // Special inverted orthographic projection because tex coords are inverted already for render-to-texture 939 966 } 940 967 941 - static void changeCamera(GPU_Target* target) 968 + static void get_camera_modelview(float* result, GPU_Camera camera) 942 969 { 943 - //GPU_CONTEXT_DATA* cdata = (GPU_CONTEXT_DATA*)GPU_GetContextTarget()->context->data; 970 + GPU_CONTEXT_DATA* cdata = (GPU_CONTEXT_DATA*)GPU_GetContextTarget()->context->data; 971 + GPU_Target* target = cdata->last_target; 972 + float offsetX, offsetY; 973 + 974 + GPU_MatrixIdentity(result); 944 975 945 - //if(cdata->last_camera_target != target || !equal_cameras(cdata->last_camera, target->camera)) 946 - { 947 - applyTargetCamera(target); 948 - } 976 + offsetX = target->w/2.0f; 977 + offsetY = target->h/2.0f; 978 + GPU_MatrixTranslate(result, offsetX, offsetY, 0); 979 + GPU_MatrixRotate(result, target->camera.angle, 0, 0, 1); 980 + GPU_MatrixTranslate(result, -offsetX, -offsetY, 0); 981 + 982 + GPU_MatrixTranslate(result, target->camera.x + offsetX, target->camera.y + offsetY, 0); 983 + GPU_MatrixScale(result, target->camera.zoom, target->camera.zoom, 1.0f); 984 + GPU_MatrixTranslate(result, -target->camera.x - offsetX, -target->camera.y - offsetY, 0); 949 985 } 950 986 987 + 988 + 951 989 #ifdef SDL_GPU_APPLY_TRANSFORMS_TO_GL_STACK 952 990 static void applyTransforms(void) 953 991 { 992 + GPU_CONTEXT_DATA* cdata = (GPU_CONTEXT_DATA*)GPU_GetContextTarget()->context->data; 954 993 float* p = GPU_GetProjection(); 955 994 float* m = GPU_GetModelView(); 995 + 996 + float cam_matrix[16]; 997 + get_camera_matrix(cam_matrix, cdata->last_camera); 998 + 999 + GPU_MultiplyAndAssign(m, cam_matrix); 1000 + 956 1001 glMatrixMode(GL_PROJECTION); 957 1002 glLoadMatrixf(p); 958 1003 glMatrixMode(GL_MODELVIEW); ··· 1338 1383 1339 1384 target->viewport = GPU_MakeRect(0, 0, target->context->drawable_w, target->context->drawable_h); 1340 1385 target->camera = GPU_GetDefaultCamera(); 1386 + target->use_camera = 1; 1341 1387 1342 1388 target->context->line_thickness = 1.0f; 1343 1389 target->context->use_texturing = 1; ··· 3679 3725 result->viewport = GPU_MakeRect(0, 0, result->w, result->h); 3680 3726 3681 3727 result->camera = GPU_GetDefaultCamera(); 3728 + result->use_camera = 1; 3682 3729 3683 3730 result->use_clip_rect = 0; 3684 3731 result->clip_rect.x = 0; ··· 4486 4533 #endif 4487 4534 } 4488 4535 4536 + 4537 + 4489 4538 // Assumes the right format 4490 4539 static void TriangleBatch(GPU_Renderer* renderer, GPU_Image* image, GPU_Target* target, unsigned short num_vertices, float* values, unsigned int num_indices, unsigned short* indices, GPU_BatchFlagEnum flags) 4491 4540 { ··· 4725 4774 if(cdata->current_shader_block.modelViewProjection_loc >= 0) 4726 4775 { 4727 4776 float mvp[16]; 4777 + float cam_matrix[16]; 4728 4778 GPU_GetModelViewProjection(mvp); 4779 + get_camera_matrix(cam_matrix, cdata->last_camera); 4780 + 4781 + GPU_MultiplyAndAssign(mvp, cam_matrix); 4782 + 4729 4783 glUniformMatrix4fv(cdata->current_shader_block.modelViewProjection_loc, 1, 0, mvp); 4730 4784 } 4731 4785 ··· 5022 5076 } 5023 5077 } 5024 5078 5025 - static void DoPartialFlush(GPU_Renderer* renderer, GPU_CONTEXT_DATA* cdata, unsigned short num_vertices, float* blit_buffer, unsigned int num_indices, unsigned short* index_buffer) 5079 + static void DoPartialFlush(GPU_Renderer* renderer, GPU_Target* dest, GPU_CONTEXT_DATA* cdata, unsigned short num_vertices, float* blit_buffer, unsigned int num_indices, unsigned short* index_buffer) 5026 5080 { 5027 5081 (void)renderer; 5028 5082 #ifdef SDL_GPU_USE_ARRAY_PIPELINE ··· 5082 5136 // Upload our modelviewprojection matrix 5083 5137 if(cdata->current_shader_block.modelViewProjection_loc >= 0) 5084 5138 { 5139 + float p[16]; 5140 + float mv[16]; 5085 5141 float mvp[16]; 5086 - GPU_GetModelViewProjection(mvp); 5142 + 5143 + GPU_MatrixCopy(p, GPU_GetProjection()); 5144 + GPU_MatrixCopy(mv, GPU_GetModelView()); 5145 + 5146 + if(dest->use_camera) 5147 + { 5148 + float cam_matrix[16]; 5149 + get_camera_matrix(cam_matrix, cdata->last_camera); 5150 + 5151 + GPU_MultiplyAndAssign(cam_matrix, p); 5152 + GPU_MatrixCopy(p, cam_matrix); 5153 + } 5154 + 5155 + // MVP = P * MV 5156 + GPU_Multiply4x4(mvp, p, mv); 5157 + 5087 5158 glUniformMatrix4fv(cdata->current_shader_block.modelViewProjection_loc, 1, 0, mvp); 5088 5159 } 5089 5160 ··· 5185 5256 if(cdata->current_shader_block.modelViewProjection_loc >= 0) 5186 5257 { 5187 5258 float mvp[16]; 5259 + float cam_matrix[16]; 5188 5260 GPU_GetModelViewProjection(mvp); 5261 + get_camera_matrix(cam_matrix, cdata->last_camera); 5262 + 5263 + GPU_MultiplyAndAssign(mvp, cam_matrix); 5264 + 5189 5265 glUniformMatrix4fv(cdata->current_shader_block.modelViewProjection_loc, 1, 0, mvp); 5190 5266 } 5191 5267 ··· 5271 5347 num_vertices = MAX(cdata->blit_buffer_num_vertices, get_lowest_attribute_num_values(cdata, cdata->blit_buffer_num_vertices)); 5272 5348 num_indices = num_vertices * 3 / 2; // 6 indices per sprite / 4 vertices per sprite = 3/2 5273 5349 5274 - DoPartialFlush(renderer, cdata, num_vertices, blit_buffer, num_indices, index_buffer); 5350 + DoPartialFlush(renderer, dest, cdata, num_vertices, blit_buffer, num_indices, index_buffer); 5275 5351 5276 5352 cdata->blit_buffer_num_vertices -= num_vertices; 5277 5353 // Move our pointers ahead
-6
src/renderer_shapes_GL_common.inl
··· 203 203 c = cos(dt); 204 204 s = sin(dt); 205 205 206 - dx = 1.0f; 207 - dy = 0.0f; 208 - 209 206 // Rotate to start 210 207 start_angle *= M_PI/180; 211 208 dx = cos(start_angle); ··· 282 279 283 280 c = cos(dt); 284 281 s = sin(dt); 285 - 286 - dx = 1.0f; 287 - dy = 0.0f; 288 282 289 283 // Rotate to start 290 284 start_angle *= M_PI/180;
+3
tests/CMakeLists.txt
··· 127 127 add_executable(renderer-test renderer/main.c) 128 128 target_link_libraries (renderer-test ${TEST_LIBS}) 129 129 130 + add_executable(transform-matrix-test transform-matrix/main.c) 131 + target_link_libraries (transform-matrix-test ${TEST_LIBS}) 132 + 130 133 add_executable(video-test video/main.c) 131 134 target_link_libraries (video-test ${TEST_LIBS})
+194
tests/transform-matrix/main.c
··· 1 + #include "SDL.h" 2 + #include "SDL_gpu.h" 3 + #include "common.h" 4 + #include <math.h> 5 + 6 + // Column-major indexing 7 + #define INDEX(row,col) ((col)*4 + (row)) 8 + 9 + 10 + int main(int argc, char* argv[]) 11 + { 12 + GPU_Target* screen; 13 + 14 + printRenderers(); 15 + 16 + screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS); 17 + if(screen == NULL) 18 + return -1; 19 + 20 + printCurrentRenderer(); 21 + 22 + { 23 + Uint32 startTime; 24 + long frameCount; 25 + Uint8 done; 26 + SDL_Event event; 27 + 28 + GPU_Camera camera = GPU_GetDefaultCamera(); 29 + float matrix[16]; 30 + 31 + GPU_Image* image = GPU_LoadImage("data/test.bmp"); 32 + if(image == NULL) 33 + return -1; 34 + 35 + float x = screen->w/2; 36 + float y = screen->h/2; 37 + float z = 0; 38 + 39 + Uint8 use_camera = 0; 40 + Uint8 use_perspective = 1; 41 + Uint8 rotate_stuff = 0; 42 + 43 + GPU_EnableCamera(screen, use_camera); 44 + GPU_MatrixIdentity(matrix); 45 + 46 + startTime = SDL_GetTicks(); 47 + frameCount = 0; 48 + 49 + done = 0; 50 + while(!done) 51 + { 52 + while(SDL_PollEvent(&event)) 53 + { 54 + if(event.type == SDL_QUIT) 55 + done = 1; 56 + else if(event.type == SDL_KEYDOWN) 57 + { 58 + if(event.key.keysym.sym == SDLK_ESCAPE) 59 + done = 1; 60 + if(event.key.keysym.sym == SDLK_RETURN) 61 + rotate_stuff = !rotate_stuff; 62 + if(event.key.keysym.sym == SDLK_LEFT) 63 + x -= 30; 64 + if(event.key.keysym.sym == SDLK_RIGHT) 65 + x += 30; 66 + if(event.key.keysym.sym == SDLK_UP) 67 + y -= 30; 68 + if(event.key.keysym.sym == SDLK_DOWN) 69 + y += 30; 70 + if(event.key.keysym.sym == SDLK_a) 71 + camera.angle -= 30; 72 + if (event.key.keysym.sym == SDLK_d) 73 + camera.angle += 30; 74 + if (event.key.keysym.sym == SDLK_x) 75 + { 76 + z -= 0.5f; 77 + GPU_LogError("z: %.1f\n", z); 78 + } 79 + if (event.key.keysym.sym == SDLK_z) 80 + { 81 + z += 0.5f; 82 + GPU_LogError("z: %.1f\n", z); 83 + } 84 + if (event.key.keysym.sym == SDLK_p) 85 + { 86 + use_perspective = 1; 87 + use_camera = 0; 88 + GPU_EnableCamera(screen, use_camera); 89 + } 90 + if (event.key.keysym.sym == SDLK_o) 91 + { 92 + use_perspective = 0; 93 + use_camera = 0; 94 + GPU_EnableCamera(screen, use_camera); 95 + } 96 + if (event.key.keysym.sym == SDLK_c) 97 + { 98 + use_camera = 1; 99 + GPU_EnableCamera(screen, use_camera); 100 + } 101 + 102 + } 103 + } 104 + 105 + GPU_Clear(screen); 106 + 107 + 108 + GPU_MatrixMode(GPU_PROJECTION); 109 + GPU_LoadIdentity(); 110 + 111 + if (!use_camera) 112 + { 113 + // Apply projection matrix 114 + GPU_MatrixIdentity(matrix); 115 + 116 + if (use_perspective) 117 + { 118 + GPU_MatrixPerspective(matrix, 90, screen->w / (float)screen->h, 0.1, 2000); 119 + } 120 + else 121 + { 122 + GPU_MatrixOrtho(matrix, 0, 800, 600, 0, -1000, 1000); 123 + } 124 + 125 + GPU_MultMatrix(matrix); 126 + } 127 + 128 + 129 + GPU_MatrixMode(GPU_MODELVIEW); 130 + GPU_LoadIdentity(); 131 + 132 + if (!use_camera) 133 + { 134 + // Apply view matrix 135 + GPU_MatrixIdentity(matrix); 136 + 137 + if(use_perspective) 138 + { 139 + GPU_MatrixLookAt(matrix, screen->w/2, screen->h/2, 300, // eye 140 + screen->w/2, screen->h/2, 0, // target 141 + 0, 1, 0); // up 142 + } 143 + else 144 + { 145 + GPU_MatrixLookAt(matrix, 0, 0, 0.1, // eye 146 + 0, 0, 0, // target 147 + 0, 1, 0); // up 148 + } 149 + GPU_MultMatrix(matrix); 150 + } 151 + 152 + 153 + // Apply model matrix 154 + GPU_MatrixIdentity(matrix); 155 + 156 + GPU_MatrixTranslate(matrix, x, y, z); 157 + 158 + if (!use_camera) 159 + { 160 + // Rotate 161 + if(rotate_stuff) 162 + { 163 + float a = SDL_GetTicks() / 10.0f; 164 + GPU_MatrixRotate(matrix, a, 0.57, 0.57, 0.57); 165 + } 166 + } 167 + 168 + GPU_MultMatrix(matrix); 169 + 170 + 171 + GPU_SetCamera(screen, &camera); 172 + GPU_Blit(image, NULL, screen, 0, 0); 173 + 174 + 175 + GPU_BlitScale(image, NULL, screen, 200, 200, 0.5f, 0.5f); 176 + 177 + GPU_Flip(screen); 178 + 179 + frameCount++; 180 + if(frameCount%500 == 0) 181 + printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); 182 + } 183 + 184 + printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); 185 + 186 + GPU_FreeImage(image); 187 + } 188 + 189 + GPU_Quit(); 190 + 191 + return 0; 192 + } 193 + 194 +