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 }