this repo has no description
0
fork

Configure Feed

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

Fixed subpixel bug (thanks Vitaly!) Added disabling state for FBOs and blending extensions.

+405 -343
+10 -27
SDL_gpu/OpenGL_common/SDL_gpuShapes_OpenGL.c
··· 20 20 #endif 21 21 22 22 23 + 23 24 static void Circle(GPU_ShapeRenderer* renderer, GPU_Target* target, float x, float y, float radius, SDL_Color color); 24 25 25 26 27 + void extBindFramebuffer(GLuint handle); 26 28 27 - static inline void bindTexture(GPU_Renderer* renderer, GPU_Image* image) 28 - { 29 - // Bind the texture to which subsequent calls refer 30 - if(image != ((RendererData_OpenGL*)renderer->data)->last_image) 31 - { 32 - GLuint handle = ((ImageData_OpenGL*)image->data)->handle; 33 - renderer->FlushBlitBuffer(renderer); 34 - 35 - glBindTexture( GL_TEXTURE_2D, handle ); 36 - ((RendererData_OpenGL*)renderer->data)->last_image = image; 37 - } 38 - } 29 + void bindTexture(GPU_Renderer* renderer, GPU_Image* image); 39 30 40 - static inline void bindFramebuffer(GPU_Renderer* renderer, GPU_Target* target) 41 - { 42 - // Bind the FBO 43 - if(target != ((RendererData_OpenGL*)renderer->data)->last_target) 44 - { 45 - GLuint handle = ((TargetData_OpenGL*)target->data)->handle; 46 - renderer->FlushBlitBuffer(renderer); 47 - 48 - glBindFramebuffer(GL_FRAMEBUFFER, handle); 49 - ((RendererData_OpenGL*)renderer->data)->last_target = target; 50 - } 51 - } 31 + Uint8 bindFramebuffer(GPU_Renderer* renderer, GPU_Target* target); 52 32 53 33 54 34 #ifdef SDL_GPU_USE_SDL2 ··· 68 48 float z = ((RendererData_OpenGL*)renderer->renderer->data)->z; \ 69 49 \ 70 50 renderer->renderer->FlushBlitBuffer(renderer->renderer); \ 71 - bindFramebuffer(renderer->renderer, target); \ 51 + if(bindFramebuffer(renderer->renderer, target)) \ 52 + { \ 72 53 /*glPushAttrib(GL_COLOR_BUFFER_BIT);*/ \ 73 54 if(target->useClip) \ 74 55 { \ ··· 114 95 } \ 115 96 /*glPopAttrib();*/ \ 116 97 glColor4ub(255, 255, 255, 255); \ 117 - glEnable( GL_TEXTURE_2D ); 98 + glEnable( GL_TEXTURE_2D ); \ 99 + } 118 100 119 101 120 102 ··· 133 115 #ifdef SDL_GPU_USE_OPENGLv1 134 116 glBegin(prim_type); 135 117 int size = 3*num_vertices; 136 - for(int i = 0; i < size; i += 3) 118 + int i; 119 + for(i = 0; i < size; i += 3) 137 120 { 138 121 glVertex3f(glverts[i], glverts[i+1], glverts[i+2]); 139 122 }
+395 -316
SDL_gpu/OpenGL_common/SDL_gpu_OpenGL.c
··· 29 29 } 30 30 31 31 static Uint8 NPOT_enabled = 0; 32 + static Uint8 FBO_enabled = 0; 33 + static Uint8 BLENDEQ_enabled = 0; 34 + static Uint8 BLENDFUNCSEP_enabled = 0; 32 35 33 36 static void initNPOT(void) 34 37 { ··· 39 42 #endif 40 43 } 41 44 45 + static void initFBO(void) 46 + { 47 + #ifdef SDL_GPU_USE_OPENGL 48 + FBO_enabled = glewIsExtensionSupported("GL_EXT_framebuffer_object"); 49 + #elif defined(SDL_GPU_USE_OPENGLES) 50 + FBO_enabled = isExtensionSupported("GL_OES_framebuffer_object"); 51 + #endif 52 + } 53 + 54 + static void initBLEND(void) 55 + { 56 + #ifdef SDL_GPU_USE_OPENGL 57 + BLENDEQ_enabled = 1; 58 + BLENDFUNCSEP_enabled = 1; 59 + #elif defined(SDL_GPU_USE_OPENGLES) 60 + BLENDEQ_enabled = isExtensionSupported("GL_OES_blend_subtract"); 61 + BLENDFUNCSEP_enabled = isExtensionSupported("GL_OES_blend_func_separate"); 62 + #endif 63 + } 64 + 65 + void extBindFramebuffer(GLuint handle) 66 + { 67 + if(FBO_enabled) 68 + glBindFramebuffer(GL_FRAMEBUFFER, handle); 69 + } 42 70 43 71 44 72 static inline Uint8 isPowerOfTwo(unsigned int x) ··· 56 84 return x; 57 85 } 58 86 59 - static inline void bindTexture(GPU_Renderer* renderer, GPU_Image* image) 87 + void bindTexture(GPU_Renderer* renderer, GPU_Image* image) 60 88 { 61 89 // Bind the texture to which subsequent calls refer 62 90 if(image != ((RendererData_OpenGL*)renderer->data)->last_image) ··· 78 106 ((RendererData_OpenGL*)renderer->data)->last_image = NULL; 79 107 } 80 108 81 - static inline void bindFramebuffer(GPU_Renderer* renderer, GPU_Target* target) 109 + // Returns false if it can't be bound 110 + Uint8 bindFramebuffer(GPU_Renderer* renderer, GPU_Target* target) 82 111 { 83 - // Bind the FBO 84 - if(target != ((RendererData_OpenGL*)renderer->data)->last_target) 112 + if(FBO_enabled) 113 + { 114 + // Bind the FBO 115 + if(target != ((RendererData_OpenGL*)renderer->data)->last_target) 116 + { 117 + GLuint handle = ((TargetData_OpenGL*)target->data)->handle; 118 + renderer->FlushBlitBuffer(renderer); 119 + 120 + extBindFramebuffer(handle); 121 + ((RendererData_OpenGL*)renderer->data)->last_target = target; 122 + } 123 + return 1; 124 + } 125 + else 85 126 { 86 - GLuint handle = ((TargetData_OpenGL*)target->data)->handle; 87 - renderer->FlushBlitBuffer(renderer); 88 - 89 - glBindFramebuffer(GL_FRAMEBUFFER, handle); 90 - ((RendererData_OpenGL*)renderer->data)->last_target = target; 127 + return (target == renderer->display); 91 128 } 92 129 } 93 130 ··· 96 133 // Bind the FBO 97 134 renderer->FlushBlitBuffer(renderer); 98 135 99 - glBindFramebuffer(GL_FRAMEBUFFER, handle); 136 + extBindFramebuffer(handle); 100 137 ((RendererData_OpenGL*)renderer->data)->last_target = NULL; 101 138 } 102 139 ··· 119 156 120 157 static inline void flushBlitBufferIfCurrentFramebuffer(GPU_Renderer* renderer, GPU_Target* target) 121 158 { 122 - if(target == ((RendererData_OpenGL*)renderer->data)->last_target) 159 + if(target == ((RendererData_OpenGL*)renderer->data)->last_target 160 + || ((RendererData_OpenGL*)renderer->data)->last_target == NULL) 123 161 { 124 162 renderer->FlushBlitBuffer(renderer); 125 163 } ··· 127 165 128 166 static inline void flushAndClearBlitBufferIfCurrentFramebuffer(GPU_Renderer* renderer, GPU_Target* target) 129 167 { 130 - if(target == ((RendererData_OpenGL*)renderer->data)->last_target) 168 + if(target == ((RendererData_OpenGL*)renderer->data)->last_target 169 + || ((RendererData_OpenGL*)renderer->data)->last_target == NULL) 131 170 { 132 171 renderer->FlushBlitBuffer(renderer); 133 172 ((RendererData_OpenGL*)renderer->data)->last_target = NULL; ··· 211 250 #endif 212 251 213 252 initNPOT(); 253 + initFBO(); 254 + initBLEND(); 214 255 215 256 glEnable( GL_TEXTURE_2D ); 216 257 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); ··· 542 583 static void readTexPixels(GPU_Renderer* renderer, GPU_Target* source, unsigned int width, unsigned int height, GLint format, GLubyte* pixels) 543 584 { 544 585 flushBlitBufferIfCurrentFramebuffer(renderer, source); 545 - bindFramebuffer(renderer, source); 546 - glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels); 586 + if(bindFramebuffer(renderer, source)) 587 + glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels); 547 588 } 548 589 549 590 static unsigned char* getRawImageData(GPU_Renderer* renderer, GPU_Image* image) ··· 1142 1183 1143 1184 if(image->target != NULL) 1144 1185 return image->target; 1186 + 1187 + if(!FBO_enabled) 1188 + return NULL; 1145 1189 1146 1190 GLuint handle; 1147 1191 // Create framebuffer object ··· 1181 1225 { 1182 1226 if(target == NULL || target == renderer->display) 1183 1227 return; 1184 - 1185 - flushAndClearBlitBufferIfCurrentFramebuffer(renderer, target); 1186 - glDeleteFramebuffers(1, &((TargetData_OpenGL*)target->data)->handle); 1187 - 1228 + 1229 + if(FBO_enabled) 1230 + { 1231 + flushAndClearBlitBufferIfCurrentFramebuffer(renderer, target); 1232 + glDeleteFramebuffers(1, &((TargetData_OpenGL*)target->data)->handle); 1233 + } 1234 + 1188 1235 if(target->image != NULL) 1189 1236 target->image->target = NULL; // Remove reference to this object 1190 1237 free(target->data); ··· 1205 1252 bindTexture(renderer, src); 1206 1253 1207 1254 // Bind the FBO 1208 - bindFramebuffer(renderer, dest); 1209 - 1210 - Uint16 tex_w = ((ImageData_OpenGL*)src->data)->tex_w; 1211 - Uint16 tex_h = ((ImageData_OpenGL*)src->data)->tex_h; 1212 - 1213 - float x1, y1, x2, y2; 1214 - float dx1, dy1, dx2, dy2; 1215 - if(srcrect == NULL) 1255 + if(bindFramebuffer(renderer, dest)) 1216 1256 { 1217 - // Scale tex coords according to actual texture dims 1218 - x1 = 0.1f/tex_w; 1219 - y1 = 0.1f/tex_h; 1220 - x2 = ((float)src->w - 0.1f)/tex_w; 1221 - y2 = ((float)src->h - 0.1f)/tex_h; 1222 - // Center the image on the given coords 1223 - dx1 = x - src->w/2; 1224 - dy1 = y - src->h/2; 1225 - dx2 = x + src->w/2; 1226 - dy2 = y + src->h/2; 1227 - } 1228 - else 1229 - { 1230 - // Scale srcrect tex coords according to actual texture dims 1231 - x1 = (srcrect->x + 0.1f)/(float)tex_w; 1232 - y1 = (srcrect->y + 0.1f)/(float)tex_h; 1233 - x2 = (srcrect->x + srcrect->w - 0.1f)/(float)tex_w; 1234 - y2 = (srcrect->y + srcrect->h - 0.1f)/(float)tex_h; 1235 - // Center the image on the given coords 1236 - dx1 = x - srcrect->w/2; 1237 - dy1 = y - srcrect->h/2; 1238 - dx2 = x + srcrect->w/2; 1239 - dy2 = y + srcrect->h/2; 1240 - } 1241 - 1242 - RendererData_OpenGL* rdata = (RendererData_OpenGL*)renderer->data; 1243 - float* blit_buffer = rdata->blit_buffer; 1244 - 1245 - if(rdata->blit_buffer_size + 6 >= rdata->blit_buffer_max_size) 1246 - renderer->FlushBlitBuffer(renderer); 1257 + Uint16 tex_w = ((ImageData_OpenGL*)src->data)->tex_w; 1258 + Uint16 tex_h = ((ImageData_OpenGL*)src->data)->tex_h; 1259 + 1260 + float x1, y1, x2, y2; 1261 + float dx1, dy1, dx2, dy2; 1262 + if(srcrect == NULL) 1263 + { 1264 + // Scale tex coords according to actual texture dims 1265 + x1 = 0.1f/tex_w; 1266 + y1 = 0.1f/tex_h; 1267 + x2 = ((float)src->w - 0.1f)/tex_w; 1268 + y2 = ((float)src->h - 0.1f)/tex_h; 1269 + // Center the image on the given coords 1270 + dx1 = x - src->w/2.0f; 1271 + dy1 = y - src->h/2.0f; 1272 + dx2 = x + src->w/2.0f; 1273 + dy2 = y + src->h/2.0f; 1274 + } 1275 + else 1276 + { 1277 + // Scale srcrect tex coords according to actual texture dims 1278 + x1 = (srcrect->x + 0.1f)/(float)tex_w; 1279 + y1 = (srcrect->y + 0.1f)/(float)tex_h; 1280 + x2 = (srcrect->x + srcrect->w - 0.1f)/(float)tex_w; 1281 + y2 = (srcrect->y + srcrect->h - 0.1f)/(float)tex_h; 1282 + // Center the image on the given coords 1283 + dx1 = x - srcrect->w/2.0f; 1284 + dy1 = y - srcrect->h/2.0f; 1285 + dx2 = x + srcrect->w/2.0f; 1286 + dy2 = y + srcrect->h/2.0f; 1287 + } 1288 + 1289 + RendererData_OpenGL* rdata = (RendererData_OpenGL*)renderer->data; 1290 + float* blit_buffer = rdata->blit_buffer; 1247 1291 1248 - int vert_index = GPU_BLIT_BUFFER_VERTEX_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1249 - int tex_index = GPU_BLIT_BUFFER_TEX_COORD_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1292 + if(rdata->blit_buffer_size + 6 >= rdata->blit_buffer_max_size) 1293 + renderer->FlushBlitBuffer(renderer); 1294 + 1295 + int vert_index = GPU_BLIT_BUFFER_VERTEX_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1296 + int tex_index = GPU_BLIT_BUFFER_TEX_COORD_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1250 1297 1251 - blit_buffer[vert_index] = dx1; 1252 - blit_buffer[vert_index+1] = dy1; 1253 - blit_buffer[vert_index+2] = 0.0f; 1254 - blit_buffer[tex_index] = x1; 1255 - blit_buffer[tex_index+1] = y1; 1256 - 1257 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1258 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1259 - blit_buffer[vert_index] = dx2; 1260 - blit_buffer[vert_index+1] = dy1; 1261 - blit_buffer[vert_index+2] = 0.0f; 1262 - blit_buffer[tex_index] = x2; 1263 - blit_buffer[tex_index+1] = y1; 1264 - 1265 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1266 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1267 - blit_buffer[vert_index] = dx2; 1268 - blit_buffer[vert_index+1] = dy2; 1269 - blit_buffer[vert_index+2] = 0.0f; 1270 - blit_buffer[tex_index] = x2; 1271 - blit_buffer[tex_index+1] = y2; 1272 - 1273 - 1274 - // Second tri 1275 - 1276 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1277 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1278 - blit_buffer[vert_index] = dx1; 1279 - blit_buffer[vert_index+1] = dy1; 1280 - blit_buffer[vert_index+2] = 0.0f; 1281 - blit_buffer[tex_index] = x1; 1282 - blit_buffer[tex_index+1] = y1; 1283 - 1284 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1285 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1286 - blit_buffer[vert_index] = dx2; 1287 - blit_buffer[vert_index+1] = dy2; 1288 - blit_buffer[vert_index+2] = 0.0f; 1289 - blit_buffer[tex_index] = x2; 1290 - blit_buffer[tex_index+1] = y2; 1291 - 1292 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1293 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1294 - blit_buffer[vert_index] = dx1; 1295 - blit_buffer[vert_index+1] = dy2; 1296 - blit_buffer[vert_index+2] = 0.0f; 1297 - blit_buffer[tex_index] = x1; 1298 - blit_buffer[tex_index+1] = y2; 1299 - 1300 - rdata->blit_buffer_size += 6; 1298 + blit_buffer[vert_index] = dx1; 1299 + blit_buffer[vert_index+1] = dy1; 1300 + blit_buffer[vert_index+2] = 0.0f; 1301 + blit_buffer[tex_index] = x1; 1302 + blit_buffer[tex_index+1] = y1; 1303 + 1304 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1305 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1306 + blit_buffer[vert_index] = dx2; 1307 + blit_buffer[vert_index+1] = dy1; 1308 + blit_buffer[vert_index+2] = 0.0f; 1309 + blit_buffer[tex_index] = x2; 1310 + blit_buffer[tex_index+1] = y1; 1311 + 1312 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1313 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1314 + blit_buffer[vert_index] = dx2; 1315 + blit_buffer[vert_index+1] = dy2; 1316 + blit_buffer[vert_index+2] = 0.0f; 1317 + blit_buffer[tex_index] = x2; 1318 + blit_buffer[tex_index+1] = y2; 1319 + 1320 + 1321 + // Second tri 1322 + 1323 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1324 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1325 + blit_buffer[vert_index] = dx1; 1326 + blit_buffer[vert_index+1] = dy1; 1327 + blit_buffer[vert_index+2] = 0.0f; 1328 + blit_buffer[tex_index] = x1; 1329 + blit_buffer[tex_index+1] = y1; 1330 + 1331 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1332 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1333 + blit_buffer[vert_index] = dx2; 1334 + blit_buffer[vert_index+1] = dy2; 1335 + blit_buffer[vert_index+2] = 0.0f; 1336 + blit_buffer[tex_index] = x2; 1337 + blit_buffer[tex_index+1] = y2; 1338 + 1339 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1340 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1341 + blit_buffer[vert_index] = dx1; 1342 + blit_buffer[vert_index+1] = dy2; 1343 + blit_buffer[vert_index+2] = 0.0f; 1344 + blit_buffer[tex_index] = x1; 1345 + blit_buffer[tex_index+1] = y2; 1346 + 1347 + rdata->blit_buffer_size += 6; 1348 + } 1301 1349 1302 1350 return 0; 1303 1351 } ··· 1308 1356 if(src == NULL || dest == NULL) 1309 1357 return -1; 1310 1358 1311 - return renderer->BlitTransformX(renderer, src, srcrect, dest, x, y, src->w/2, src->h/2, angle, 1.0f, 1.0f); 1359 + return renderer->BlitTransformX(renderer, src, srcrect, dest, x, y, src->w/2.0f, src->h/2.0f, angle, 1.0f, 1.0f); 1312 1360 } 1313 1361 1314 1362 static int BlitScale(GPU_Renderer* renderer, GPU_Image* src, SDL_Rect* srcrect, GPU_Target* dest, float x, float y, float scaleX, float scaleY) ··· 1316 1364 if(src == NULL || dest == NULL) 1317 1365 return -1; 1318 1366 1319 - return renderer->BlitTransformX(renderer, src, srcrect, dest, x, y, src->w/2, src->h/2, 0.0f, scaleX, scaleY); 1367 + return renderer->BlitTransformX(renderer, src, srcrect, dest, x, y, src->w/2.0f, src->h/2.0f, 0.0f, scaleX, scaleY); 1320 1368 } 1321 1369 1322 1370 static int BlitTransform(GPU_Renderer* renderer, GPU_Image* src, SDL_Rect* srcrect, GPU_Target* dest, float x, float y, float angle, float scaleX, float scaleY) ··· 1324 1372 if(src == NULL || dest == NULL) 1325 1373 return -1; 1326 1374 1327 - return renderer->BlitTransformX(renderer, src, srcrect, dest, x, y, src->w/2, src->h/2, angle, scaleX, scaleY); 1375 + return renderer->BlitTransformX(renderer, src, srcrect, dest, x, y, src->w/2.0f, src->h/2.0f, angle, scaleX, scaleY); 1328 1376 } 1329 1377 1330 1378 static int BlitTransformX(GPU_Renderer* renderer, GPU_Image* src, SDL_Rect* srcrect, GPU_Target* dest, float x, float y, float pivot_x, float pivot_y, float angle, float scaleX, float scaleY) ··· 1339 1387 bindTexture(renderer, src); 1340 1388 1341 1389 // Bind the FBO 1342 - bindFramebuffer(renderer, dest); 1390 + if(bindFramebuffer(renderer, dest)) 1391 + { 1392 + Uint16 tex_w = ((ImageData_OpenGL*)src->data)->tex_w; 1393 + Uint16 tex_h = ((ImageData_OpenGL*)src->data)->tex_h; 1343 1394 1344 - Uint16 tex_w = ((ImageData_OpenGL*)src->data)->tex_w; 1345 - Uint16 tex_h = ((ImageData_OpenGL*)src->data)->tex_h; 1395 + float x1, y1, x2, y2; 1396 + /* 1397 + 1,1 --- 3,3 1398 + | | 1399 + | | 1400 + 4,4 --- 2,2 1401 + */ 1402 + float dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4; 1403 + if(srcrect == NULL) 1404 + { 1405 + // Scale tex coords according to actual texture dims 1406 + x1 = 0.1f/tex_w; 1407 + y1 = 0.1f/tex_h; 1408 + x2 = ((float)src->w - 0.1f)/tex_w; 1409 + y2 = ((float)src->h - 0.1f)/tex_h; 1410 + // Center the image on the given coords 1411 + dx1 = -src->w/2.0f; 1412 + dy1 = -src->h/2.0f; 1413 + dx2 = src->w/2.0f; 1414 + dy2 = src->h/2.0f; 1415 + } 1416 + else 1417 + { 1418 + // Scale srcrect tex coords according to actual texture dims 1419 + x1 = (srcrect->x + 0.1f)/(float)tex_w; 1420 + y1 = (srcrect->y + 0.1f)/(float)tex_h; 1421 + x2 = (srcrect->x + srcrect->w - 0.1f)/(float)tex_w; 1422 + y2 = (srcrect->y + srcrect->h - 0.1f)/(float)tex_h; 1423 + // Center the image on the given coords 1424 + dx1 = -srcrect->w/2.0f; 1425 + dy1 = -srcrect->h/2.0f; 1426 + dx2 = srcrect->w/2.0f; 1427 + dy2 = srcrect->h/2.0f; 1428 + } 1429 + 1430 + // Apply transforms 1431 + 1432 + // Scale 1433 + if(scaleX != 1.0f || scaleY != 1.0f) 1434 + { 1435 + float w = (dx2 - dx1)*scaleX; 1436 + float h = (dy2 - dy1)*scaleY; 1437 + dx1 = (dx2 + dx1)/2 - w/2; 1438 + dx2 = dx1 + w; 1439 + dy1 = (dy2 + dy1)/2 - h/2; 1440 + dy2 = dy1 + h; 1441 + } 1442 + 1443 + // Shift away from the center (these are relative to the image corner) 1444 + pivot_x -= src->w/2.0f; 1445 + pivot_y -= src->h/2.0f; 1346 1446 1347 - float x1, y1, x2, y2; 1348 - /* 1349 - 1,1 --- 3,3 1350 - | | 1351 - | | 1352 - 4,4 --- 2,2 1353 - */ 1354 - float dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4; 1355 - if(srcrect == NULL) 1356 - { 1357 - // Scale tex coords according to actual texture dims 1358 - x1 = 0.1f/tex_w; 1359 - y1 = 0.1f/tex_h; 1360 - x2 = ((float)src->w - 0.1f)/tex_w; 1361 - y2 = ((float)src->h - 0.1f)/tex_h; 1362 - // Center the image on the given coords 1363 - dx1 = -src->w/2; 1364 - dy1 = -src->h/2; 1365 - dx2 = src->w/2; 1366 - dy2 = src->h/2; 1367 - } 1368 - else 1369 - { 1370 - // Scale srcrect tex coords according to actual texture dims 1371 - x1 = (srcrect->x + 0.1f)/(float)tex_w; 1372 - y1 = (srcrect->y + 0.1f)/(float)tex_h; 1373 - x2 = (srcrect->x + srcrect->w - 0.1f)/(float)tex_w; 1374 - y2 = (srcrect->y + srcrect->h - 0.1f)/(float)tex_h; 1375 - // Center the image on the given coords 1376 - dx1 = -srcrect->w/2; 1377 - dy1 = -srcrect->h/2; 1378 - dx2 = srcrect->w/2; 1379 - dy2 = srcrect->h/2; 1380 - } 1381 - 1382 - // Apply transforms 1383 - 1384 - // Scale 1385 - if(scaleX != 1.0f || scaleY != 1.0f) 1386 - { 1387 - float w = (dx2 - dx1)*scaleX; 1388 - float h = (dy2 - dy1)*scaleY; 1389 - dx1 = (dx2 + dx1)/2 - w/2; 1390 - dx2 = dx1 + w; 1391 - dy1 = (dy2 + dy1)/2 - h/2; 1392 - dy2 = dy1 + h; 1393 - } 1394 - 1395 - // Shift away from the center (these are relative to the image corner) 1396 - pivot_x -= src->w/2; 1397 - pivot_y -= src->h/2; 1447 + // Translate origin to pivot 1448 + dx1 -= pivot_x*scaleX; 1449 + dy1 -= pivot_y*scaleY; 1450 + dx2 -= pivot_x*scaleX; 1451 + dy2 -= pivot_y*scaleY; 1452 + 1453 + // Get extra vertices for rotation 1454 + dx3 = dx2; 1455 + dy3 = dy1; 1456 + dx4 = dx1; 1457 + dy4 = dy2; 1458 + 1459 + // Rotate about origin (the pivot) 1460 + if(angle != 0.0f) 1461 + { 1462 + float cosA = cos(angle*M_PI/180); 1463 + float sinA = sin(angle*M_PI/180); 1464 + float tempX = dx1; 1465 + dx1 = dx1*cosA - dy1*sinA; 1466 + dy1 = tempX*sinA + dy1*cosA; 1467 + tempX = dx2; 1468 + dx2 = dx2*cosA - dy2*sinA; 1469 + dy2 = tempX*sinA + dy2*cosA; 1470 + tempX = dx3; 1471 + dx3 = dx3*cosA - dy3*sinA; 1472 + dy3 = tempX*sinA + dy3*cosA; 1473 + tempX = dx4; 1474 + dx4 = dx4*cosA - dy4*sinA; 1475 + dy4 = tempX*sinA + dy4*cosA; 1476 + } 1477 + 1478 + // Translate to pos 1479 + dx1 += x; 1480 + dx2 += x; 1481 + dx3 += x; 1482 + dx4 += x; 1483 + dy1 += y; 1484 + dy2 += y; 1485 + dy3 += y; 1486 + dy4 += y; 1487 + 1488 + RendererData_OpenGL* rdata = (RendererData_OpenGL*)renderer->data; 1489 + float* blit_buffer = rdata->blit_buffer; 1490 + 1491 + if(rdata->blit_buffer_size + 6 >= rdata->blit_buffer_max_size) 1492 + renderer->FlushBlitBuffer(renderer); 1493 + 1494 + int vert_index = GPU_BLIT_BUFFER_VERTEX_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1495 + int tex_index = GPU_BLIT_BUFFER_TEX_COORD_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1398 1496 1399 - // Translate origin to pivot 1400 - dx1 -= pivot_x*scaleX; 1401 - dy1 -= pivot_y*scaleY; 1402 - dx2 -= pivot_x*scaleX; 1403 - dy2 -= pivot_y*scaleY; 1404 - 1405 - // Get extra vertices for rotation 1406 - dx3 = dx2; 1407 - dy3 = dy1; 1408 - dx4 = dx1; 1409 - dy4 = dy2; 1410 - 1411 - // Rotate about origin (the pivot) 1412 - if(angle != 0.0f) 1413 - { 1414 - float cosA = cos(angle*M_PI/180); 1415 - float sinA = sin(angle*M_PI/180); 1416 - float tempX = dx1; 1417 - dx1 = dx1*cosA - dy1*sinA; 1418 - dy1 = tempX*sinA + dy1*cosA; 1419 - tempX = dx2; 1420 - dx2 = dx2*cosA - dy2*sinA; 1421 - dy2 = tempX*sinA + dy2*cosA; 1422 - tempX = dx3; 1423 - dx3 = dx3*cosA - dy3*sinA; 1424 - dy3 = tempX*sinA + dy3*cosA; 1425 - tempX = dx4; 1426 - dx4 = dx4*cosA - dy4*sinA; 1427 - dy4 = tempX*sinA + dy4*cosA; 1428 - } 1429 - 1430 - // Translate to pos 1431 - dx1 += x; 1432 - dx2 += x; 1433 - dx3 += x; 1434 - dx4 += x; 1435 - dy1 += y; 1436 - dy2 += y; 1437 - dy3 += y; 1438 - dy4 += y; 1439 - 1440 - RendererData_OpenGL* rdata = (RendererData_OpenGL*)renderer->data; 1441 - float* blit_buffer = rdata->blit_buffer; 1442 - 1443 - if(rdata->blit_buffer_size + 6 >= rdata->blit_buffer_max_size) 1444 - renderer->FlushBlitBuffer(renderer); 1497 + blit_buffer[vert_index] = dx1; 1498 + blit_buffer[vert_index+1] = dy1; 1499 + blit_buffer[vert_index+2] = 0.0f; 1500 + blit_buffer[tex_index] = x1; 1501 + blit_buffer[tex_index+1] = y1; 1502 + 1503 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1504 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1505 + blit_buffer[vert_index] = dx3; 1506 + blit_buffer[vert_index+1] = dy3; 1507 + blit_buffer[vert_index+2] = 0.0f; 1508 + blit_buffer[tex_index] = x2; 1509 + blit_buffer[tex_index+1] = y1; 1510 + 1511 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1512 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1513 + blit_buffer[vert_index] = dx2; 1514 + blit_buffer[vert_index+1] = dy2; 1515 + blit_buffer[vert_index+2] = 0.0f; 1516 + blit_buffer[tex_index] = x2; 1517 + blit_buffer[tex_index+1] = y2; 1518 + 1519 + 1520 + // Second tri 1521 + 1522 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1523 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1524 + blit_buffer[vert_index] = dx1; 1525 + blit_buffer[vert_index+1] = dy1; 1526 + blit_buffer[vert_index+2] = 0.0f; 1527 + blit_buffer[tex_index] = x1; 1528 + blit_buffer[tex_index+1] = y1; 1529 + 1530 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1531 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1532 + blit_buffer[vert_index] = dx2; 1533 + blit_buffer[vert_index+1] = dy2; 1534 + blit_buffer[vert_index+2] = 0.0f; 1535 + blit_buffer[tex_index] = x2; 1536 + blit_buffer[tex_index+1] = y2; 1445 1537 1446 - int vert_index = GPU_BLIT_BUFFER_VERTEX_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1447 - int tex_index = GPU_BLIT_BUFFER_TEX_COORD_OFFSET + rdata->blit_buffer_size*GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1448 - 1449 - blit_buffer[vert_index] = dx1; 1450 - blit_buffer[vert_index+1] = dy1; 1451 - blit_buffer[vert_index+2] = 0.0f; 1452 - blit_buffer[tex_index] = x1; 1453 - blit_buffer[tex_index+1] = y1; 1454 - 1455 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1456 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1457 - blit_buffer[vert_index] = dx3; 1458 - blit_buffer[vert_index+1] = dy3; 1459 - blit_buffer[vert_index+2] = 0.0f; 1460 - blit_buffer[tex_index] = x2; 1461 - blit_buffer[tex_index+1] = y1; 1462 - 1463 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1464 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1465 - blit_buffer[vert_index] = dx2; 1466 - blit_buffer[vert_index+1] = dy2; 1467 - blit_buffer[vert_index+2] = 0.0f; 1468 - blit_buffer[tex_index] = x2; 1469 - blit_buffer[tex_index+1] = y2; 1470 - 1538 + vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1539 + tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1540 + blit_buffer[vert_index] = dx4; 1541 + blit_buffer[vert_index+1] = dy4; 1542 + blit_buffer[vert_index+2] = 0.0f; 1543 + blit_buffer[tex_index] = x1; 1544 + blit_buffer[tex_index+1] = y2; 1545 + 1546 + rdata->blit_buffer_size += 6; 1547 + } 1471 1548 1472 - // Second tri 1473 - 1474 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1475 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1476 - blit_buffer[vert_index] = dx1; 1477 - blit_buffer[vert_index+1] = dy1; 1478 - blit_buffer[vert_index+2] = 0.0f; 1479 - blit_buffer[tex_index] = x1; 1480 - blit_buffer[tex_index+1] = y1; 1481 - 1482 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1483 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1484 - blit_buffer[vert_index] = dx2; 1485 - blit_buffer[vert_index+1] = dy2; 1486 - blit_buffer[vert_index+2] = 0.0f; 1487 - blit_buffer[tex_index] = x2; 1488 - blit_buffer[tex_index+1] = y2; 1489 - 1490 - vert_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1491 - tex_index += GPU_BLIT_BUFFER_FLOATS_PER_VERTEX; 1492 - blit_buffer[vert_index] = dx4; 1493 - blit_buffer[vert_index+1] = dy4; 1494 - blit_buffer[vert_index+2] = 0.0f; 1495 - blit_buffer[tex_index] = x1; 1496 - blit_buffer[tex_index+1] = y2; 1497 - 1498 - rdata->blit_buffer_size += 6; 1499 - 1500 1549 return 0; 1501 1550 } 1502 1551 ··· 1969 2018 return result; 1970 2019 1971 2020 flushBlitBufferIfCurrentFramebuffer(renderer, target); 1972 - bindFramebuffer(renderer, target); 2021 + if(bindFramebuffer(renderer, target)) 2022 + { 2023 + unsigned char pixels[4]; 2024 + glReadPixels(x, y, 1, 1, ((TargetData_OpenGL*)target->data)->format, GL_UNSIGNED_BYTE, pixels); 1973 2025 1974 - unsigned char pixels[4]; 1975 - glReadPixels(x, y, 1, 1, ((TargetData_OpenGL*)target->data)->format, GL_UNSIGNED_BYTE, pixels); 1976 - 1977 - result.r = pixels[0]; 1978 - result.g = pixels[1]; 1979 - result.b = pixels[2]; 1980 - #ifdef SDL_GPU_USE_SDL2 1981 - result.a = pixels[3]; 1982 - #else 1983 - result.unused = pixels[3]; 1984 - #endif 2026 + result.r = pixels[0]; 2027 + result.g = pixels[1]; 2028 + result.b = pixels[2]; 2029 + #ifdef SDL_GPU_USE_SDL2 2030 + result.a = pixels[3]; 2031 + #else 2032 + result.unused = pixels[3]; 2033 + #endif 2034 + } 1985 2035 1986 2036 return result; 1987 2037 } ··· 2029 2079 if(mode == GPU_BLEND_NORMAL) 2030 2080 { 2031 2081 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2082 + if(!BLENDEQ_enabled) 2083 + return; // TODO: Return false so we can avoid depending on it if it fails 2032 2084 glBlendEquation(GL_FUNC_ADD); 2033 2085 } 2034 2086 else if(mode == GPU_BLEND_MULTIPLY) 2035 2087 { 2088 + if(!BLENDFUNCSEP_enabled) 2089 + return; 2036 2090 glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2091 + if(!BLENDEQ_enabled) 2092 + return; 2037 2093 glBlendEquation(GL_FUNC_ADD); 2038 2094 } 2039 2095 else if(mode == GPU_BLEND_ADD) 2040 2096 { 2041 2097 glBlendFunc(GL_ONE, GL_ONE); 2098 + if(!BLENDEQ_enabled) 2099 + return; 2042 2100 glBlendEquation(GL_FUNC_ADD); 2043 2101 } 2044 2102 else if(mode == GPU_BLEND_SUBTRACT) 2045 2103 { 2104 + if(!BLENDEQ_enabled) 2105 + return; 2046 2106 glBlendFunc(GL_ONE, GL_ONE); 2047 2107 glBlendEquation(GL_FUNC_SUBTRACT); 2048 2108 } 2049 2109 else if(mode == GPU_BLEND_ADD_COLOR) 2050 2110 { 2111 + if(!BLENDFUNCSEP_enabled) 2112 + return; 2051 2113 glBlendFuncSeparate(GL_ONE, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2114 + if(!BLENDEQ_enabled) 2115 + return; 2052 2116 glBlendEquation(GL_FUNC_ADD); 2053 2117 } 2054 2118 else if(mode == GPU_BLEND_SUBTRACT_COLOR) 2055 2119 { 2120 + if(!BLENDFUNCSEP_enabled) 2121 + return; 2122 + if(!BLENDEQ_enabled) 2123 + return; 2056 2124 glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); 2057 2125 glBlendEquation(GL_FUNC_SUBTRACT); 2058 2126 } 2059 2127 else if(mode == GPU_BLEND_DIFFERENCE) 2060 2128 { 2129 + if(!BLENDFUNCSEP_enabled) 2130 + return; 2131 + if(!BLENDEQ_enabled) 2132 + return; 2061 2133 glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ZERO); 2062 2134 glBlendEquation(GL_FUNC_SUBTRACT); 2063 2135 } 2064 2136 else if(mode == GPU_BLEND_PUNCHOUT) 2065 2137 { 2138 + if(!BLENDEQ_enabled) 2139 + return; 2066 2140 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2067 2141 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); 2068 2142 } 2069 2143 else if(mode == GPU_BLEND_CUTOUT) 2070 2144 { 2145 + if(!BLENDEQ_enabled) 2146 + return; 2071 2147 glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); 2072 2148 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); 2073 2149 } ··· 2098 2174 return; 2099 2175 2100 2176 flushBlitBufferIfCurrentFramebuffer(renderer, target); 2101 - bindFramebuffer(renderer, target); 2102 - SDL_Rect viewport = getViewport(); 2103 - glViewport(0,0,target->w, target->h); 2104 - 2105 - if(target->useClip) 2177 + if(bindFramebuffer(renderer, target)) 2106 2178 { 2107 - glEnable(GL_SCISSOR_TEST); 2108 - int y = (renderer->display == target? renderer->display->h - (target->clipRect.y + target->clipRect.h) : target->clipRect.y); 2109 - float xFactor = ((float)renderer->window_w)/renderer->display->w; 2110 - float yFactor = ((float)renderer->window_h)/renderer->display->h; 2111 - glScissor(target->clipRect.x * xFactor, y * yFactor, target->clipRect.w * xFactor, target->clipRect.h * yFactor); 2112 - } 2179 + SDL_Rect viewport = getViewport(); 2180 + glViewport(0,0,target->w, target->h); 2113 2181 2114 - //glPushAttrib(GL_COLOR_BUFFER_BIT); 2182 + if(target->useClip) 2183 + { 2184 + glEnable(GL_SCISSOR_TEST); 2185 + int y = (renderer->display == target? renderer->display->h - (target->clipRect.y + target->clipRect.h) : target->clipRect.y); 2186 + float xFactor = ((float)renderer->window_w)/renderer->display->w; 2187 + float yFactor = ((float)renderer->window_h)/renderer->display->h; 2188 + glScissor(target->clipRect.x * xFactor, y * yFactor, target->clipRect.w * xFactor, target->clipRect.h * yFactor); 2189 + } 2115 2190 2116 - glClearColor(0,0,0,0); 2117 - glClear(GL_COLOR_BUFFER_BIT); 2118 - //glPopAttrib(); 2119 - glColor4ub(255, 255, 255, 255); 2191 + //glPushAttrib(GL_COLOR_BUFFER_BIT); 2120 2192 2121 - if(target->useClip) 2122 - { 2123 - glDisable(GL_SCISSOR_TEST); 2124 - } 2193 + glClearColor(0,0,0,0); 2194 + glClear(GL_COLOR_BUFFER_BIT); 2195 + //glPopAttrib(); 2196 + glColor4ub(255, 255, 255, 255); 2125 2197 2126 - setViewport(viewport); 2198 + if(target->useClip) 2199 + { 2200 + glDisable(GL_SCISSOR_TEST); 2201 + } 2202 + 2203 + setViewport(viewport); 2204 + } 2127 2205 } 2128 2206 2129 2207 ··· 2135 2213 return; 2136 2214 2137 2215 flushBlitBufferIfCurrentFramebuffer(renderer, target); 2138 - bindFramebuffer(renderer, target); 2216 + if(bindFramebuffer(renderer, target)) 2217 + { 2218 + SDL_Rect viewport = getViewport(); 2219 + glViewport(0,0,target->w, target->h); 2139 2220 2140 - SDL_Rect viewport = getViewport(); 2141 - glViewport(0,0,target->w, target->h); 2221 + if(target->useClip) 2222 + { 2223 + glEnable(GL_SCISSOR_TEST); 2224 + int y = (renderer->display == target? renderer->display->h - (target->clipRect.y + target->clipRect.h) : target->clipRect.y); 2225 + float xFactor = ((float)renderer->window_w)/renderer->display->w; 2226 + float yFactor = ((float)renderer->window_h)/renderer->display->h; 2227 + glScissor(target->clipRect.x * xFactor, y * yFactor, target->clipRect.w * xFactor, target->clipRect.h * yFactor); 2228 + } 2142 2229 2143 - if(target->useClip) 2144 - { 2145 - glEnable(GL_SCISSOR_TEST); 2146 - int y = (renderer->display == target? renderer->display->h - (target->clipRect.y + target->clipRect.h) : target->clipRect.y); 2147 - float xFactor = ((float)renderer->window_w)/renderer->display->w; 2148 - float yFactor = ((float)renderer->window_h)/renderer->display->h; 2149 - glScissor(target->clipRect.x * xFactor, y * yFactor, target->clipRect.w * xFactor, target->clipRect.h * yFactor); 2150 - } 2230 + glClearColor(r/255.0f, g/255.0f, b/255.0f, a/255.0f); 2231 + glClear(GL_COLOR_BUFFER_BIT); 2151 2232 2152 - glClearColor(r/255.0f, g/255.0f, b/255.0f, a/255.0f); 2153 - glClear(GL_COLOR_BUFFER_BIT); 2233 + glColor4ub(255, 255, 255, 255); 2154 2234 2155 - glColor4ub(255, 255, 255, 255); 2235 + if(target->useClip) 2236 + { 2237 + glDisable(GL_SCISSOR_TEST); 2238 + } 2156 2239 2157 - if(target->useClip) 2158 - { 2159 - glDisable(GL_SCISSOR_TEST); 2240 + setViewport(viewport); 2160 2241 } 2161 - 2162 - setViewport(viewport); 2163 2242 } 2164 2243 2165 2244 static void FlushBlitBuffer(GPU_Renderer* renderer)