Mercurial > sdl-ios-xcode
comparison src/video/SDL_renderer_gl.c @ 5143:e743b9c3f6d6
Making the API simpler, the blend modes are "none, blend, add" and are supported by all renderers.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 31 Jan 2011 23:23:57 -0800 |
parents | da10636e5eca |
children | 31e7f523ab3d |
comparison
equal
deleted
inserted
replaced
5142:57851a238c8f | 5143:e743b9c3f6d6 |
---|---|
81 int firstcolor, int ncolors); | 81 int firstcolor, int ncolors); |
82 static int GL_SetTextureColorMod(SDL_Renderer * renderer, | 82 static int GL_SetTextureColorMod(SDL_Renderer * renderer, |
83 SDL_Texture * texture); | 83 SDL_Texture * texture); |
84 static int GL_SetTextureAlphaMod(SDL_Renderer * renderer, | 84 static int GL_SetTextureAlphaMod(SDL_Renderer * renderer, |
85 SDL_Texture * texture); | 85 SDL_Texture * texture); |
86 static int GL_SetTextureBlendMode(SDL_Renderer * renderer, | |
87 SDL_Texture * texture); | |
88 static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 86 static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
89 const SDL_Rect * rect, const void *pixels, | 87 const SDL_Rect * rect, const void *pixels, |
90 int pitch); | 88 int pitch); |
91 static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 89 static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
92 const SDL_Rect * rect, int markDirty, void **pixels, | 90 const SDL_Rect * rect, int markDirty, void **pixels, |
120 "opengl", | 118 "opengl", |
121 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD | | 119 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD | |
122 SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED), | 120 SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED), |
123 (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | | 121 (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | |
124 SDL_TEXTUREMODULATE_ALPHA), | 122 SDL_TEXTUREMODULATE_ALPHA), |
125 (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | | |
126 SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD), | |
127 15, | 123 15, |
128 { | 124 { |
129 SDL_PIXELFORMAT_INDEX1LSB, | 125 SDL_PIXELFORMAT_INDEX1LSB, |
130 SDL_PIXELFORMAT_INDEX1MSB, | 126 SDL_PIXELFORMAT_INDEX1MSB, |
131 SDL_PIXELFORMAT_INDEX8, | 127 SDL_PIXELFORMAT_INDEX8, |
173 PFNGLGENPROGRAMSARBPROC glGenProgramsARB; | 169 PFNGLGENPROGRAMSARBPROC glGenProgramsARB; |
174 PFNGLBINDPROGRAMARBPROC glBindProgramARB; | 170 PFNGLBINDPROGRAMARBPROC glBindProgramARB; |
175 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB; | 171 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB; |
176 | 172 |
177 /* (optional) fragment programs */ | 173 /* (optional) fragment programs */ |
178 GLuint fragment_program_mask; | |
179 GLuint fragment_program_UYVY; | 174 GLuint fragment_program_UYVY; |
180 } GL_RenderData; | 175 } GL_RenderData; |
181 | 176 |
182 typedef struct | 177 typedef struct |
183 { | 178 { |
296 renderer->QueryTexturePixels = GL_QueryTexturePixels; | 291 renderer->QueryTexturePixels = GL_QueryTexturePixels; |
297 renderer->SetTexturePalette = GL_SetTexturePalette; | 292 renderer->SetTexturePalette = GL_SetTexturePalette; |
298 renderer->GetTexturePalette = GL_GetTexturePalette; | 293 renderer->GetTexturePalette = GL_GetTexturePalette; |
299 renderer->SetTextureColorMod = GL_SetTextureColorMod; | 294 renderer->SetTextureColorMod = GL_SetTextureColorMod; |
300 renderer->SetTextureAlphaMod = GL_SetTextureAlphaMod; | 295 renderer->SetTextureAlphaMod = GL_SetTextureAlphaMod; |
301 renderer->SetTextureBlendMode = GL_SetTextureBlendMode; | |
302 renderer->UpdateTexture = GL_UpdateTexture; | 296 renderer->UpdateTexture = GL_UpdateTexture; |
303 renderer->LockTexture = GL_LockTexture; | 297 renderer->LockTexture = GL_LockTexture; |
304 renderer->UnlockTexture = GL_UnlockTexture; | 298 renderer->UnlockTexture = GL_UnlockTexture; |
305 renderer->DirtyTexture = GL_DirtyTexture; | 299 renderer->DirtyTexture = GL_DirtyTexture; |
306 renderer->RenderClear = GL_RenderClear; | 300 renderer->RenderClear = GL_RenderClear; |
542 } | 536 } |
543 | 537 |
544 return program; | 538 return program; |
545 } | 539 } |
546 | 540 |
547 | |
548 /* | |
549 * Fragment program that implements mask semantics | |
550 */ | |
551 static const char *fragment_program_mask_source_code = "!!ARBfp1.0\n" | |
552 "OUTPUT output = result.color;\n" | |
553 "TEMP value;\n" | |
554 "TEX value, fragment.texcoord[0], texture[0], %TEXTURETARGET%;\n" | |
555 "MUL value, fragment.color, value;\n" | |
556 "SGE value.a, value.a, 0.001;\n" | |
557 "MOV output, value;\n" | |
558 "END"; | |
559 | 541 |
560 /* | 542 /* |
561 * Fragment program that renders from UYVY textures. | 543 * Fragment program that renders from UYVY textures. |
562 * The UYVY to RGB equasion is: | 544 * The UYVY to RGB equasion is: |
563 * R = 1.164(Y-16) + 1.596(Cr-128) | 545 * R = 1.164(Y-16) + 1.596(Cr-128) |
976 { | 958 { |
977 return 0; | 959 return 0; |
978 } | 960 } |
979 | 961 |
980 static int | 962 static int |
981 GL_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) | |
982 { | |
983 switch (texture->blendMode) { | |
984 case SDL_BLENDMODE_NONE: | |
985 case SDL_BLENDMODE_MASK: | |
986 case SDL_BLENDMODE_BLEND: | |
987 case SDL_BLENDMODE_ADD: | |
988 case SDL_BLENDMODE_MOD: | |
989 return 0; | |
990 default: | |
991 SDL_Unsupported(); | |
992 texture->blendMode = SDL_BLENDMODE_NONE; | |
993 return -1; | |
994 } | |
995 } | |
996 | |
997 static int | |
998 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 963 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
999 const SDL_Rect * rect, const void *pixels, int pitch) | 964 const SDL_Rect * rect, const void *pixels, int pitch) |
1000 { | 965 { |
1001 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; | 966 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; |
1002 GL_TextureData *data = (GL_TextureData *) texture->driverdata; | 967 GL_TextureData *data = (GL_TextureData *) texture->driverdata; |
1052 SDL_AddDirtyRect(&data->dirty, &rects[i]); | 1017 SDL_AddDirtyRect(&data->dirty, &rects[i]); |
1053 } | 1018 } |
1054 } | 1019 } |
1055 | 1020 |
1056 static void | 1021 static void |
1057 GL_SetBlendMode(GL_RenderData * data, int blendMode, int isprimitive) | 1022 GL_SetBlendMode(GL_RenderData * data, int blendMode) |
1058 { | 1023 { |
1059 if (blendMode != data->blendMode) { | 1024 if (blendMode != data->blendMode) { |
1060 switch (blendMode) { | 1025 switch (blendMode) { |
1061 case SDL_BLENDMODE_NONE: | 1026 case SDL_BLENDMODE_NONE: |
1062 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | 1027 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
1063 data->glDisable(GL_BLEND); | 1028 data->glDisable(GL_BLEND); |
1064 break; | |
1065 case SDL_BLENDMODE_MASK: | |
1066 if (isprimitive) { | |
1067 /* The same as SDL_BLENDMODE_NONE */ | |
1068 blendMode = SDL_BLENDMODE_NONE; | |
1069 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |
1070 data->glDisable(GL_BLEND); | |
1071 } else { | |
1072 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |
1073 data->glEnable(GL_BLEND); | |
1074 data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
1075 } | |
1076 break; | 1029 break; |
1077 case SDL_BLENDMODE_BLEND: | 1030 case SDL_BLENDMODE_BLEND: |
1078 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | 1031 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
1079 data->glEnable(GL_BLEND); | 1032 data->glEnable(GL_BLEND); |
1080 data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 1033 data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
1082 case SDL_BLENDMODE_ADD: | 1035 case SDL_BLENDMODE_ADD: |
1083 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | 1036 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
1084 data->glEnable(GL_BLEND); | 1037 data->glEnable(GL_BLEND); |
1085 data->glBlendFunc(GL_SRC_ALPHA, GL_ONE); | 1038 data->glBlendFunc(GL_SRC_ALPHA, GL_ONE); |
1086 break; | 1039 break; |
1087 case SDL_BLENDMODE_MOD: | |
1088 data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
1089 data->glEnable(GL_BLEND); | |
1090 data->glBlendFunc(GL_ZERO, GL_SRC_COLOR); | |
1091 break; | |
1092 } | 1040 } |
1093 data->blendMode = blendMode; | 1041 data->blendMode = blendMode; |
1094 } | 1042 } |
1095 } | 1043 } |
1096 | 1044 |
1114 int count) | 1062 int count) |
1115 { | 1063 { |
1116 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; | 1064 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; |
1117 int i; | 1065 int i; |
1118 | 1066 |
1119 GL_SetBlendMode(data, renderer->blendMode, 1); | 1067 GL_SetBlendMode(data, renderer->blendMode); |
1120 | 1068 |
1121 data->glColor4f((GLfloat) renderer->r * inv255f, | 1069 data->glColor4f((GLfloat) renderer->r * inv255f, |
1122 (GLfloat) renderer->g * inv255f, | 1070 (GLfloat) renderer->g * inv255f, |
1123 (GLfloat) renderer->b * inv255f, | 1071 (GLfloat) renderer->b * inv255f, |
1124 (GLfloat) renderer->a * inv255f); | 1072 (GLfloat) renderer->a * inv255f); |
1137 int count) | 1085 int count) |
1138 { | 1086 { |
1139 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; | 1087 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; |
1140 int i; | 1088 int i; |
1141 | 1089 |
1142 GL_SetBlendMode(data, renderer->blendMode, 1); | 1090 GL_SetBlendMode(data, renderer->blendMode); |
1143 | 1091 |
1144 data->glColor4f((GLfloat) renderer->r * inv255f, | 1092 data->glColor4f((GLfloat) renderer->r * inv255f, |
1145 (GLfloat) renderer->g * inv255f, | 1093 (GLfloat) renderer->g * inv255f, |
1146 (GLfloat) renderer->b * inv255f, | 1094 (GLfloat) renderer->b * inv255f, |
1147 (GLfloat) renderer->a * inv255f); | 1095 (GLfloat) renderer->a * inv255f); |
1205 GL_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) | 1153 GL_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) |
1206 { | 1154 { |
1207 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; | 1155 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; |
1208 int i, x, y; | 1156 int i, x, y; |
1209 | 1157 |
1210 GL_SetBlendMode(data, renderer->blendMode, 1); | 1158 GL_SetBlendMode(data, renderer->blendMode); |
1211 | 1159 |
1212 data->glColor4f((GLfloat) renderer->r * inv255f, | 1160 data->glColor4f((GLfloat) renderer->r * inv255f, |
1213 (GLfloat) renderer->g * inv255f, | 1161 (GLfloat) renderer->g * inv255f, |
1214 (GLfloat) renderer->b * inv255f, | 1162 (GLfloat) renderer->b * inv255f, |
1215 (GLfloat) renderer->a * inv255f); | 1163 (GLfloat) renderer->a * inv255f); |
1243 GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) | 1191 GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) |
1244 { | 1192 { |
1245 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; | 1193 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; |
1246 int i; | 1194 int i; |
1247 | 1195 |
1248 GL_SetBlendMode(data, renderer->blendMode, 1); | 1196 GL_SetBlendMode(data, renderer->blendMode); |
1249 | 1197 |
1250 data->glColor4f((GLfloat) renderer->r * inv255f, | 1198 data->glColor4f((GLfloat) renderer->r * inv255f, |
1251 (GLfloat) renderer->g * inv255f, | 1199 (GLfloat) renderer->g * inv255f, |
1252 (GLfloat) renderer->b * inv255f, | 1200 (GLfloat) renderer->b * inv255f, |
1253 (GLfloat) renderer->a * inv255f); | 1201 (GLfloat) renderer->a * inv255f); |
1265 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | 1213 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, |
1266 const SDL_Rect * srcrect, const SDL_Rect * dstrect) | 1214 const SDL_Rect * srcrect, const SDL_Rect * dstrect) |
1267 { | 1215 { |
1268 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; | 1216 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; |
1269 GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; | 1217 GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; |
1270 GLuint shader = 0; | |
1271 int minx, miny, maxx, maxy; | 1218 int minx, miny, maxx, maxy; |
1272 GLfloat minu, maxu, minv, maxv; | 1219 GLfloat minu, maxu, minv, maxv; |
1273 | 1220 |
1274 if (texturedata->dirty.list) { | 1221 if (texturedata->dirty.list) { |
1275 SDL_DirtyRect *dirty; | 1222 SDL_DirtyRect *dirty; |
1317 (GLfloat) texture->a * inv255f); | 1264 (GLfloat) texture->a * inv255f); |
1318 } else { | 1265 } else { |
1319 data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | 1266 data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
1320 } | 1267 } |
1321 | 1268 |
1322 GL_SetBlendMode(data, texture->blendMode, 0); | 1269 GL_SetBlendMode(data, texture->blendMode); |
1323 | 1270 |
1324 /* Set up the shader for the copy, we have a special one for MASK */ | 1271 /* Set up the shader for the copy, if any */ |
1325 shader = texturedata->shader; | 1272 if (texturedata->shader) { |
1326 if (texture->blendMode == SDL_BLENDMODE_MASK && !shader) { | |
1327 if (data->fragment_program_mask == 0) { | |
1328 data->fragment_program_mask = | |
1329 compile_shader(data, GL_FRAGMENT_PROGRAM_ARB, | |
1330 fragment_program_mask_source_code); | |
1331 if (data->fragment_program_mask == 0) { | |
1332 /* That's okay, we'll just miss some of the blend semantics */ | |
1333 data->fragment_program_mask = ~0; | |
1334 } | |
1335 } | |
1336 if (data->fragment_program_mask != ~0) { | |
1337 shader = data->fragment_program_mask; | |
1338 } | |
1339 } | |
1340 | |
1341 if (shader) { | |
1342 data->glEnable(GL_FRAGMENT_PROGRAM_ARB); | 1273 data->glEnable(GL_FRAGMENT_PROGRAM_ARB); |
1343 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader); | 1274 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, texturedata->shader); |
1344 } | 1275 } |
1345 | 1276 |
1346 data->glBegin(GL_TRIANGLE_STRIP); | 1277 data->glBegin(GL_TRIANGLE_STRIP); |
1347 data->glTexCoord2f(minu, minv); | 1278 data->glTexCoord2f(minu, minv); |
1348 data->glVertex2f((GLfloat) minx, (GLfloat) miny); | 1279 data->glVertex2f((GLfloat) minx, (GLfloat) miny); |
1352 data->glVertex2f((GLfloat) minx, (GLfloat) maxy); | 1283 data->glVertex2f((GLfloat) minx, (GLfloat) maxy); |
1353 data->glTexCoord2f(maxu, maxv); | 1284 data->glTexCoord2f(maxu, maxv); |
1354 data->glVertex2f((GLfloat) maxx, (GLfloat) maxy); | 1285 data->glVertex2f((GLfloat) maxx, (GLfloat) maxy); |
1355 data->glEnd(); | 1286 data->glEnd(); |
1356 | 1287 |
1357 if (shader) { | 1288 if (texturedata->shader) { |
1358 data->glDisable(GL_FRAGMENT_PROGRAM_ARB); | 1289 data->glDisable(GL_FRAGMENT_PROGRAM_ARB); |
1359 } | 1290 } |
1360 | 1291 |
1361 data->glDisable(texturedata->type); | 1292 data->glDisable(texturedata->type); |
1362 | 1293 |
1492 if (data) { | 1423 if (data) { |
1493 if (data->context) { | 1424 if (data->context) { |
1494 if (data->GL_ARB_fragment_program_supported) { | 1425 if (data->GL_ARB_fragment_program_supported) { |
1495 data->glDisable(GL_FRAGMENT_PROGRAM_ARB); | 1426 data->glDisable(GL_FRAGMENT_PROGRAM_ARB); |
1496 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0); | 1427 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0); |
1497 if (data->fragment_program_mask && | |
1498 data->fragment_program_mask != ~0) { | |
1499 data->glDeleteProgramsARB(1, | |
1500 &data->fragment_program_mask); | |
1501 } | |
1502 if (data->fragment_program_UYVY && | 1428 if (data->fragment_program_UYVY && |
1503 data->fragment_program_UYVY != ~0) { | 1429 data->fragment_program_UYVY != ~0) { |
1504 data->glDeleteProgramsARB(1, | 1430 data->glDeleteProgramsARB(1, |
1505 &data->fragment_program_UYVY); | 1431 &data->fragment_program_UYVY); |
1506 } | 1432 } |